Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metricbeat : new metricset image for docker module #3467

Merged
merged 14 commits into from
Feb 3, 2017
Merged
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ https://github.com/elastic/beats/compare/v5.1.1...master[Check the HEAD diff]
- Kafka consumer groups metricset. {pull}3240[3240]
- Add dynamic configuration reloading for modules. {pull}3281[3281]
- Add docker health metricset {pull}3357[3357]
- Add docker image metricset {pull}3467[3467]
- System module uses new matchers for white-listing processes. {pull}3469[3469]

*Packetbeat*
Expand Down
61 changes: 61 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,67 @@ type: integer
Healthcheck status code


[float]
== image Fields

Docker image metrics.



[float]
== id Fields

The image layers identifier.



[float]
=== docker.image.id.current

type: keyword

Unique image identifier given upon its creation.


[float]
=== docker.image.id.parent

type: keyword

Identifier of the image, if it exists, from which the current image directly descends.


[float]
=== docker.image.created

type: date

Date and time when the image was created.


[float]
== size Fields

Image size layers.



[float]
=== docker.image.size.virtual

type: long

Size of the image.


[float]
=== docker.image.size.regular

type: long

Total size of the all cached images associated to the current image.


[float]
== info Fields

Expand Down
4 changes: 4 additions & 0 deletions metricbeat/docs/modules/docker.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ The following metricsets are available:

* <<metricbeat-metricset-docker-healthcheck,healthcheck>>

* <<metricbeat-metricset-docker-image,image>>

* <<metricbeat-metricset-docker-info,info>>

* <<metricbeat-metricset-docker-memory,memory>>
Expand All @@ -60,6 +62,8 @@ include::docker/diskio.asciidoc[]

include::docker/healthcheck.asciidoc[]

include::docker/image.asciidoc[]

include::docker/info.asciidoc[]

include::docker/memory.asciidoc[]
Expand Down
19 changes: 19 additions & 0 deletions metricbeat/docs/modules/docker/image.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-image]]
include::../../../module/docker/image/_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/image/_meta/data.json[]
----
1 change: 1 addition & 0 deletions metricbeat/include/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
_ "github.com/elastic/beats/metricbeat/module/docker/cpu"
_ "github.com/elastic/beats/metricbeat/module/docker/diskio"
_ "github.com/elastic/beats/metricbeat/module/docker/healthcheck"
_ "github.com/elastic/beats/metricbeat/module/docker/image"
_ "github.com/elastic/beats/metricbeat/module/docker/info"
_ "github.com/elastic/beats/metricbeat/module/docker/memory"
_ "github.com/elastic/beats/metricbeat/module/docker/network"
Expand Down
31 changes: 31 additions & 0 deletions metricbeat/metricbeat.template-es2x.json
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,37 @@
}
}
},
"image": {
"properties": {
"created": {
"type": "date"
},
"id": {
"properties": {
"current": {
"ignore_above": 1024,
"index": "not_analyzed",
"type": "string"
},
"parent": {
"ignore_above": 1024,
"index": "not_analyzed",
"type": "string"
}
}
},
"size": {
"properties": {
"regular": {
"type": "long"
},
"virtual": {
"type": "long"
}
}
}
}
},
"info": {
"properties": {
"containers": {
Expand Down
29 changes: 29 additions & 0 deletions metricbeat/metricbeat.template.json
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,35 @@
}
}
},
"image": {
"properties": {
"created": {
"type": "date"
},
"id": {
"properties": {
"current": {
"ignore_above": 1024,
"type": "keyword"
},
"parent": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"size": {
"properties": {
"regular": {
"type": "long"
},
"virtual": {
"type": "long"
}
}
}
}
},
"info": {
"properties": {
"containers": {
Expand Down
19 changes: 19 additions & 0 deletions metricbeat/module/docker/image/_meta/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs update but I can do that after merging.

"@timestamp":"2016-05-23T08:05:34.853Z",
"beat":{
"hostname":"beathost",
"name":"beathost"
},
"metricset":{
"host":"localhost",
"module":"docker",
"name":"image",
"rtt":44269
},
"docker":{
"image":{
"example": "image"
}
},
"type":"metricsets"
}
3 changes: 3 additions & 0 deletions metricbeat/module/docker/image/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
=== docker image MetricSet

This is the image metricset of the module docker.
41 changes: 41 additions & 0 deletions metricbeat/module/docker/image/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
- name: image
type: group
description: >
Docker image metrics.
fields:
- name: id
type: group
description: >
The image layers identifier.
fields:
- name: current
type: keyword
description: >
Unique image identifier given upon its creation.
- name: parent
type: keyword
description: >
Identifier of the image, if it exists, from which the current image directly descends.
- name: created
type: date
description: >
Date and time when the image was created.
- name: size
type: group
description: >
Image size layers.
fields:
- name: virtual
type: long
description: >
Size of the image.
- name: regular
type: long
description: >
Total size of the all cached images associated to the current image.

# TODO : How to describe tags & labels list ?
# - name: tags
# type: list ?
# description: >
# Descriptive or given name(s) to the image.
37 changes: 37 additions & 0 deletions metricbeat/module/docker/image/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package image

import (
"github.com/elastic/beats/libbeat/common"

"github.com/elastic/beats/metricbeat/module/docker"
dc "github.com/fsouza/go-dockerclient"
"time"
)

func eventsMapping(imagesList []dc.APIImages) []common.MapStr {
events := []common.MapStr{}
for _, image := range imagesList {
events = append(events, eventMapping(&image))
}
return events
}

func eventMapping(image *dc.APIImages) common.MapStr {
event := common.MapStr{
"id": common.MapStr{
"current": image.ID,
"parent": image.ParentID,
},
"created": common.Time(time.Unix(image.Created, 0)),
"size": common.MapStr{
"regular": image.Size,
"virtual": image.VirtualSize,
},
"tags": image.RepoTags,
}
labels := docker.DeDotLabels(image.Labels)
if len(labels) > 0 {
event["labels"] = labels
}
return event
}
63 changes: 63 additions & 0 deletions metricbeat/module/docker/image/image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package image

import (
"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"

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

// init registers the MetricSet with the central registry.
// The New method will be called after the setup of the module and before starting to fetch data
func init() {
if err := mb.Registry.AddMetricSet("docker", "image", New); err != nil {
panic(err)
}
}

// MetricSet type defines all fields of the MetricSet
// As a minimum it must inherit the mb.BaseMetricSet fields, but can be extended with
// additional entries. These variables can be used to persist data or configuration between
// multiple fetch calls.
type MetricSet struct {
mb.BaseMetricSet
dockerClient *dc.Client
}

// New create a new instance of the MetricSet
// Part of new is also setting up the configuration by processing additional
// configuration entries if needed.
func New(base mb.BaseMetricSet) (mb.MetricSet, error) {

logp.Warn("EXPERIMENTAL: The docker info 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 methods implements the data gathering and data conversion to the right format
// It returns the event which is then forward to the output. In case of an error, a
// descriptive error must be returned.
func (m *MetricSet) Fetch() ([]common.MapStr, error) {

images, err := m.dockerClient.ListImages(dc.ListImagesOptions{})
if err != nil {
return nil, err
}

return eventsMapping(images), nil
}
23 changes: 23 additions & 0 deletions metricbeat/module/docker/image/image_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package image

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{"image"},
"hosts": []string{"unix:///var/run/docker.sock"},
}
}
Loading