Skip to content

Commit

Permalink
add healthcheck metricset in docker module
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienmusso committed Jan 20, 2017
1 parent b95e76a commit cd0cebc
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 0 deletions.
19 changes: 19 additions & 0 deletions metricbeat/docs/modules/docker/healthcheck.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
////
This file is generated! See scripts/docs_collector.py
////

[[metricbeat-metricset-docker-healthcheck]]
include::../../../module/docker/healthcheck/_meta/docs.asciidoc[]


==== Fields

For a description of each field in the metricset, see the
<<exported-fields-docker,exported fields>> section.

Here is an example document generated by this metricset:

[source,json]
----
include::../../../module/docker/healthcheck/_meta/data.json[]
----
24 changes: 24 additions & 0 deletions metricbeat/module/docker/healthcheck/_meta/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"@timestamp": "2016-05-23T08:05:34.853Z",
"beat": {
"hostname": "host.example.com",
"name": "host.example.com"
},
"docker": {
"healthcheck": {
"event_end_date": "2017-01-09T20:38:13.080472813+01:00",
"event_exit_code": 0,
"event_output": "this is an event output",
"event_start_date": "2017-01-09T20:38:12.999970865+01:00",
"failingstreak": 0,
"status": "healthy"
}
},
"metricset": {
"host": "/var/run/docker.sock",
"module": "docker",
"name": "container",
"rtt": 115
},
"type": "metricsets"
}
4 changes: 4 additions & 0 deletions metricbeat/module/docker/healthcheck/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
=== Docker Container Metricset

The Docker `container` metricset collects information and statistics about
running Docker containers.
29 changes: 29 additions & 0 deletions metricbeat/module/docker/healthcheck/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
- name: healthcheck
type: group
description: >
Docker container metrics.
fields:
- name: event_end_date
type: date
description: >
Healthcheck end date
- name: event_start_date
type: date
description: >
Healthcheck start date
- name: event_output
type: keyword
description: >
Healthcheck output
- name: event_exit_code
type: integer
description: >
Healthcheck status code
- name: failingstreak
type: integer
description: >
concurent failed check
- name: status
type: keyword
description: >
Healthcheck status code
25 changes: 25 additions & 0 deletions metricbeat/module/docker/healthcheck/container_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// +build integration

package healthcheck

import (
"testing"

mbtest "github.com/elastic/beats/metricbeat/mb/testing"
)

func TestData(t *testing.T) {
f := mbtest.NewEventsFetcher(t, getConfig())
err := mbtest.WriteEvents(f, t)
if err != nil {
t.Fatal("write", err)
}
}

func getConfig() map[string]interface{} {
return map[string]interface{}{
"module": "docker",
"metricsets": []string{"healthcheck"},
"hosts": []string{"unix:///var/run/docker.sock"},
}
}
50 changes: 50 additions & 0 deletions metricbeat/module/docker/healthcheck/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package healthcheck

import (
//"time"

"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/metricbeat/mb"
"github.com/elastic/beats/metricbeat/module/docker"

dc "github.com/fsouza/go-dockerclient"
"reflect"
"strings"
)

func eventsMapping(containersList []dc.APIContainers, m *MetricSet) []common.MapStr {
myEvents := []common.MapStr{}
emptyEvent := common.MapStr{}
for _, container := range containersList {
returnevent := eventMapping(&container, m)
if !reflect.DeepEqual(emptyEvent, returnevent) {
myEvents = append(myEvents, eventMapping(&container, m))
}
}
return myEvents
}

func eventMapping(cont *dc.APIContainers, m *MetricSet) common.MapStr {
event := common.MapStr{}
if strings.Contains(cont.Status, "(") && strings.Contains(cont.Status, ")") {
container, _ := m.dockerClient.InspectContainer(cont.ID)
last_event := len(container.State.Health.Log) - 1
if last_event >= 0 {
event = common.MapStr{
mb.ModuleData: common.MapStr{
"container": common.MapStr{
"name": docker.ExtractContainerName(cont.Names),
},
},
"status": container.State.Health.Status,
"failingstreak": container.State.Health.FailingStreak,
"event_start_date": common.Time(container.State.Health.Log[last_event].Start),
"event_end_date": common.Time(container.State.Health.Log[last_event].End),
"event_exit_code": container.State.Health.Log[last_event].ExitCode,
"event_output": container.State.Health.Log[last_event].Output,
}
}
}

return event
}
52 changes: 52 additions & 0 deletions metricbeat/module/docker/healthcheck/healthcheck.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package healthcheck

import (
dc "github.com/fsouza/go-dockerclient"

"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/logp"
"github.com/elastic/beats/metricbeat/mb"
"github.com/elastic/beats/metricbeat/module/docker"
)

func init() {
if err := mb.Registry.AddMetricSet("docker", "healthcheck", New, docker.HostParser); err != nil {
panic(err)
}
}

type MetricSet struct {
mb.BaseMetricSet
dockerClient *dc.Client
}

// New creates a new instance of the docker container MetricSet.
func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
logp.Warn("EXPERIMENTAL: The docker healthcheck metricset is experimental")

config := docker.Config{}
if err := base.Module().UnpackConfig(&config); err != nil {
return nil, err
}

client, err := docker.NewDockerClient(base.HostData().URI, config)
if err != nil {
return nil, err
}

return &MetricSet{
BaseMetricSet: base,
dockerClient: client,
}, nil
}

// Fetch returns a list of all containers as events.
// This is based on https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-containers.
func (m *MetricSet) Fetch() ([]common.MapStr, error) {
// Fetch a list of all containers.
containers, err := m.dockerClient.ListContainers(dc.ListContainersOptions{})
if err != nil {
return nil, err
}
return eventsMapping(containers, m), nil
}

0 comments on commit cd0cebc

Please sign in to comment.