diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 5b6b78f36ae..ad2ab0cce9c 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -100,6 +100,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add `key` metricset to the Redis module. {issue}9582[9582] {pull}9657[9657] {pull}9746[9746] - Add `socket_summary` metricset to system defaults, removing experimental tag and supporting Windows {pull}9709[9709] +- Add docker `event` metricset. {pull}9856[9856] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index c0b04901ea1..2fa4c6ca352 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -2760,6 +2760,108 @@ type: scaled_float Number of reads and writes per second +-- + +[float] +== event fields + +Docker event + + + +*`docker.event.status`*:: ++ +-- +type: keyword + +Event status + + +-- + +*`docker.event.id`*:: ++ +-- +type: alias + +alias to: event.id + +Event id when available + + +-- + +*`docker.event.from`*:: ++ +-- +type: keyword + +Event source + + +-- + +*`docker.event.type`*:: ++ +-- +type: alias + +alias to: event.kind + +The type of object emitting the event + + +-- + +*`docker.event.action`*:: ++ +-- +type: alias + +alias to: event.action + +The type of event + + +-- + +*`docker.event.time`*:: ++ +-- +type: alias + +alias to: event.created + +Timestamp of event + + +-- + +[float] +== actor fields + +Actor + + + +*`docker.event.actor.id`*:: ++ +-- +type: keyword + +The ID of the object emitting the event + + +-- + +*`docker.event.actor.attributes`*:: ++ +-- +type: object + +Various key/value attributes of the object, depending on its type + + -- [float] diff --git a/metricbeat/docs/modules/docker.asciidoc b/metricbeat/docs/modules/docker.asciidoc index 689b1d31de1..b6c04236475 100644 --- a/metricbeat/docs/modules/docker.asciidoc +++ b/metricbeat/docs/modules/docker.asciidoc @@ -38,6 +38,7 @@ metricbeat.modules: - "container" - "cpu" - "diskio" + - "event" - "healthcheck" - "info" #- "image" @@ -71,6 +72,8 @@ The following metricsets are available: * <> +* <> + * <> * <> @@ -87,6 +90,8 @@ include::docker/cpu.asciidoc[] include::docker/diskio.asciidoc[] +include::docker/event.asciidoc[] + include::docker/healthcheck.asciidoc[] include::docker/image.asciidoc[] diff --git a/metricbeat/docs/modules/docker/event.asciidoc b/metricbeat/docs/modules/docker/event.asciidoc new file mode 100644 index 00000000000..fd187b0fb3b --- /dev/null +++ b/metricbeat/docs/modules/docker/event.asciidoc @@ -0,0 +1,21 @@ +//// +This file is generated! See scripts/docs_collector.py +//// + +[[metricbeat-metricset-docker-event]] +=== Docker event metricset + +include::../../../module/docker/event/_meta/docs.asciidoc[] + + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../module/docker/event/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index cf35597b884..80ff5cbd7be 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -22,9 +22,10 @@ This file is generated! See scripts/docs_collector.py |<> beta[] |<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | -.8+| .8+| |<> +.9+| .9+| |<> |<> |<> +|<> |<> |<> |<> diff --git a/metricbeat/include/list.go b/metricbeat/include/list.go index e2afb2060f6..f08861b04c2 100644 --- a/metricbeat/include/list.go +++ b/metricbeat/include/list.go @@ -46,6 +46,7 @@ import ( _ "github.com/elastic/beats/metricbeat/module/docker/container" _ "github.com/elastic/beats/metricbeat/module/docker/cpu" _ "github.com/elastic/beats/metricbeat/module/docker/diskio" + _ "github.com/elastic/beats/metricbeat/module/docker/event" _ "github.com/elastic/beats/metricbeat/module/docker/healthcheck" _ "github.com/elastic/beats/metricbeat/module/docker/image" _ "github.com/elastic/beats/metricbeat/module/docker/info" diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index f1a7c6563c2..26ad57ed02d 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -167,6 +167,7 @@ metricbeat.modules: - "container" - "cpu" - "diskio" + - "event" - "healthcheck" - "info" #- "image" diff --git a/metricbeat/module/docker/_meta/config.reference.yml b/metricbeat/module/docker/_meta/config.reference.yml index 2ac7c913ab3..f651b1385af 100644 --- a/metricbeat/module/docker/_meta/config.reference.yml +++ b/metricbeat/module/docker/_meta/config.reference.yml @@ -3,6 +3,7 @@ - "container" - "cpu" - "diskio" + - "event" - "healthcheck" - "info" #- "image" diff --git a/metricbeat/module/docker/_meta/config.yml b/metricbeat/module/docker/_meta/config.yml index 44d6b61b58b..340f2106bfc 100644 --- a/metricbeat/module/docker/_meta/config.yml +++ b/metricbeat/module/docker/_meta/config.yml @@ -3,6 +3,7 @@ # - container # - cpu # - diskio + # - event # - healthcheck # - info # - memory diff --git a/metricbeat/module/docker/event/_meta/data.json b/metricbeat/module/docker/event/_meta/data.json new file mode 100644 index 00000000000..305af3a0218 --- /dev/null +++ b/metricbeat/module/docker/event/_meta/data.json @@ -0,0 +1,31 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "agent": { + "hostname": "host.example.com", + "name": "host.example.com" + }, + "docker": { + "event": { + "actor": { + "attributes": { + "image": "busybox", + "name": "wizardly_knuth" + }, + "id": "9d4c3af1d4a0268940205aad04a3c6bf434b32f45e0784dec5c283201ef299fc" + }, + "from": "busybox", + "status": "create" + } + }, + "event": { + "action": "create", + "created": "2019-01-03T12:44:52+01:00", + "dataset": "event", + "id": "9d4c3af1d4a0268940205aad04a3c6bf434b32f45e0784dec5c283201ef299fc", + "kind": "container", + "module": "docker" + }, + "service": { + "type": "docker" + } +} \ No newline at end of file diff --git a/metricbeat/module/docker/event/_meta/docs.asciidoc b/metricbeat/module/docker/event/_meta/docs.asciidoc new file mode 100644 index 00000000000..0d4cc7a3db3 --- /dev/null +++ b/metricbeat/module/docker/event/_meta/docs.asciidoc @@ -0,0 +1 @@ +This is the event metricset of the module docker. diff --git a/metricbeat/module/docker/event/_meta/fields.yml b/metricbeat/module/docker/event/_meta/fields.yml new file mode 100644 index 00000000000..44b87db4c2d --- /dev/null +++ b/metricbeat/module/docker/event/_meta/fields.yml @@ -0,0 +1,52 @@ +- name: event + type: group + description: > + Docker event + release: ga + fields: + - name: status + type: keyword + description: > + Event status + - name: id + type: alias + path: event.id + migration: true + description: > + Event id when available + - name: from + type: keyword + description: > + Event source + - name: type + type: alias + path: event.kind + migration: true + description: > + The type of object emitting the event + - name: action + type: alias + path: event.action + migration: true + description: > + The type of event + - name: time + type: alias + path: event.created + migration: true + description: > + Timestamp of event + - name: actor + type: group + description: > + Actor + fields: + - name: id + type: keyword + description: > + The ID of the object emitting the event + - name: attributes + type: object + object_type: keyword + description: > + Various key/value attributes of the object, depending on its type diff --git a/metricbeat/module/docker/event/event.go b/metricbeat/module/docker/event/event.go new file mode 100644 index 00000000000..9fd16a29c36 --- /dev/null +++ b/metricbeat/module/docker/event/event.go @@ -0,0 +1,142 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package event + +import ( + "context" + "fmt" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/events" + "github.com/docker/docker/client" + + "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" +) + +// init registers the MetricSet with the central registry as soon as the program +// starts. The New function will be called later to instantiate an instance of +// the MetricSet for each host defined in the module's configuration. After the +// MetricSet has been created then Fetch will begin to be called periodically. +func init() { + mb.Registry.MustAddMetricSet("docker", "event", New, + mb.WithHostParser(docker.HostParser), + mb.DefaultMetricSet(), + ) +} + +// MetricSet holds any configuration or state information. It must implement +// the mb.MetricSet interface. And this is best achieved by embedding +// mb.BaseMetricSet because it implements all of the required mb.MetricSet +// interface methods except for Fetch. +type MetricSet struct { + mb.BaseMetricSet + dockerClient *client.Client + dedot bool + logger *logp.Logger +} + +// New creates a new instance of the MetricSet. New is responsible for unpacking +// any MetricSet specific configuration options if there are any. +func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + config := docker.DefaultConfig() + 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, + dedot: config.DeDot, + logger: logp.NewLogger("docker"), + }, nil +} + +// Run listens for docker events and reports them +func (m *MetricSet) Run(reporter mb.PushReporterV2) { + ctx, cancel := context.WithCancel(context.Background()) + options := types.EventsOptions{ + Since: fmt.Sprintf("%d", time.Now().Unix()), + } + + defer m.dockerClient.Close() + + for { + events, errors := m.dockerClient.Events(ctx, options) + + WATCH: + for { + select { + case event := <-events: + m.logger.Debug("Got a new docker event: %v", event) + m.reportEvent(reporter, event) + + case err := <-errors: + // Restart watch call + m.logger.Error("Error watching for docker events: %v", err) + time.Sleep(1 * time.Second) + break WATCH + + case <-reporter.Done(): + m.logger.Debug("docker", "event watcher stopped") + cancel() + return + } + } + } +} + +func (m *MetricSet) reportEvent(reporter mb.PushReporterV2, event events.Message) { + time := time.Unix(event.Time, 0) + + attributes := make(map[string]string, len(event.Actor.Attributes)) + for k, v := range event.Actor.Attributes { + if m.dedot { + k = common.DeDot(k) + } + attributes[k] = v + } + + reporter.Event(mb.Event{ + Timestamp: time, + RootFields: common.MapStr{ + "event": common.MapStr{ + "kind": event.Type, + "action": event.Action, + "created": time, + "id": event.ID, + }, + }, + MetricSetFields: common.MapStr{ + "status": event.Status, + "from": event.From, + "actor": common.MapStr{ + "id": event.Actor.ID, + "attributes": attributes, + }, + }, + }) +} diff --git a/metricbeat/module/docker/event/event_integration_test.go b/metricbeat/module/docker/event/event_integration_test.go new file mode 100644 index 00000000000..361cb0e5c95 --- /dev/null +++ b/metricbeat/module/docker/event/event_integration_test.go @@ -0,0 +1,102 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// +build integration + +package event + +import ( + "io" + "os" + "testing" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" + "golang.org/x/net/context" + + "github.com/elastic/beats/auditbeat/core" + "github.com/elastic/beats/metricbeat/mb" + mbtest "github.com/elastic/beats/metricbeat/mb/testing" +) + +func TestData(t *testing.T) { + ms := mbtest.NewPushMetricSetV2(t, getConfig()) + var events []mb.Event + done := make(chan interface{}) + go func() { + events = mbtest.RunPushMetricSetV2(10*time.Second, 1, ms) + close(done) + }() + + createEvent(t) + <-done + + if len(events) == 0 { + t.Fatal("received no events") + } + assertNoErrors(t, events) + + beatEvent := mbtest.StandardizeEvent(ms, events[0], core.AddDatasetToEvent) + mbtest.WriteEventToDataJSON(t, beatEvent, "") +} + +func assertNoErrors(t *testing.T, events []mb.Event) { + t.Helper() + + for _, e := range events { + t.Log(e) + + if e.Error != nil { + t.Errorf("received error: %+v", e.Error) + } + } +} + +func createEvent(t *testing.T) { + client, err := client.NewEnvClient() + if err != nil { + t.Fatal(err) + } + defer client.Close() + + reader, err := client.ImagePull(context.Background(), "busybox", types.ImagePullOptions{}) + if err != nil { + t.Fatal(err) + } + io.Copy(os.Stdout, reader) + reader.Close() + + resp, err := client.ContainerCreate(context.Background(), &container.Config{ + Image: "busybox", + Cmd: []string{"echo", "foo"}, + }, nil, nil, "") + if err != nil { + t.Fatal(err) + } + + client.ContainerRemove(context.Background(), resp.ID, types.ContainerRemoveOptions{}) +} + +func getConfig() map[string]interface{} { + return map[string]interface{}{ + "module": "docker", + "metricsets": []string{"event"}, + "hosts": []string{"unix:///var/run/docker.sock"}, + } +} diff --git a/metricbeat/module/docker/fields.go b/metricbeat/module/docker/fields.go index c544b4ee997..cfb3c3e2bf5 100644 --- a/metricbeat/module/docker/fields.go +++ b/metricbeat/module/docker/fields.go @@ -31,5 +31,5 @@ func init() { // Asset returns asset data func Asset() string { - return "eJzsm09v27gSwO/5FIO+wwMeGhtvUezBhwV2WyzWh7ZB25wNmhpJXEuklqTiuJ9+wT+yZYuSLEV2kqI+WvHMj/OfpHILG9wtIBJ0g/IGQDOd4QLefLBfvLkBiFBRyQrNBF/AbzcAAO4hKE20AiqyDKnGCGIpcv9sdgMgMUOicAEJuQFQqZB6RQWPWbKAmGQKbwBihlmkFlbqLXCSY43FfPSuMBKkKAv/TYDHfJY8FjIn5msgPLJwTGlGFZC1KLUX+18FsuSc8QSo4JowjlLNvJQ6TZ1o/5f7JyGwDria0fayIEctGd0rN59jk1WfU6xjtDwnPDp6VsFtcLcV8vRZB6L5vHcCQadEw5YowEekpXEv46BTbKxjFuaSSDSGuSKicRjUB6IRtik6goMJDZ/XFMYwUVCqKa1TqXaSw1pZsSJRJFEpvIju5R3s5besm30/NXE4YIetmX3HUNhCS5DWiaQQehWfmuMAlgmeBB72sNnPN6FJ5uBEDCTLbJTELENVBW1LtB4Bbi/B9tVTHYhsYqXkAWGNyKvwBSGBpoQnGIFinKJ7wAQPO1iTJBxaREqyG+bgZU4StBJnzdJXlE8pel9KrlmO8P7ufpp6t0HJMZsVVAdXryjJMFrFmSCnf+DawwIKlBS5JsnAGnS3/531p1kV454HVEEohj3liTWjm7DHAtHVl5F392DlnUegdkpj/gJsZvPUwTvrmazwdF3kU9vOiXUmDCsuFcoXYDBvJkPT5WBLe7EA69Nu3focxvq2j6dSkaSFjgqJs/+14on139h45L5cXdnbx4nBlEPvWlS7y/uXNTwoPpX5GuWB1IdHAHU/yTO1YeJJQzNTG1jOP0/TPCSS8EQ6Yir6ndIyLzPbu41cBVEpzbbC1LSMxfuuH9o8tIHWYUVxiWHp4MRR0Ae89U43httewCph2n58xgL+MD+18OPZZXMD0os+yLa0lBK59jYuTP1EKk62afWoDGdxR+mJsJBITfQt4NfZu7GZPAh0K1nDbpPkjxX86hJoHPVLySBDr5G/giTydj4nOJ87jc5DVWWeE3m6SZuwExH+WnPKtHpRoLQ731ebW7Y7VU54HUlWM3pP9Npx/5nyrBHeAdaKM0WS6ZSmSDdPmkAvcmwbE5YxnigtkWyCxmRcY9KIjB5LUcFpaf1pFGAEp8u/3MnoXwdze9lARYRB3fiAPLwdG1H+rDBv7KGHksijVeA0GrqOqs9AOrUH8igsqeYMqa9BYhV1s4hSF+Wpd6AnOEagtOjZu+aR6VUjguok4QwZZ5RGuO6P8vPjXf3Y+mHlTFM72GR72G8perCM7FAqYBFyzWLWPCfvyyTfRy4TNnDP2T9lxXqAhIQ9IIeyEByYVi1H5nXMglyQcnkA8w3eAr8FFgPTJqKVVm/dNek2ZTR1Q4DvwG5xEZNIdbazCpGflrQLXq/ZSz+W1+7ZHFH/HduEd03uKsJe5biQHBqHD0zqsjGfwNRXOdY0HXdJmJQZCZWmiS+7DAvJMqCEphg5LAVEKUGZ3RBo0QyyA3fQnxlZYzb2WHHU7LD0Ncjo7YG71r0X4/GTDi6XPBZVuYc1URiB4JBqXajFfB4JqmbuhYQZFfkcecI4ziXGKJFTnJOCzd3zlcRcaFyRgq0e/j/75d38P/OIqSIju1t3j3G7ZRHessP7D099o6B6LWKqpP78gNIG6dHl+eDULkipGiUPJsgpl1J8v8twigLvhzSZ/LskV4Bqf2ulSaW0KIqrmMprOosqtHG8BJPts12m6hmkRpUwP6H4aS8VSgeHqTCHrdpBluG3NK3WcFqalS7HXBwdRg2udR+thPHDbesOeUZF2bJR7Dxr6DTQn4SZUlRy3fbuUsZyFtYacEfXoVEPibebVRcmkWqyIvzl61fv6nHVd1T2TnCi5uLZk0tUNqtAobYzUMek35hT4JzggXOudc9E/9gCXRPcdp/f1Dna8ffK7TzHuz4nj8/g+I/ksaIOXO/Di3S1BW11L7y0dDqxa8XGUW+FfNKp6ScnYuKewEzNjgkN58aovl2B7kVbVS3zAh+Qk084715yKnLTsr0j/IvWh7PuoQn8XLchp7MIqxZmZbYnRyS759eepB5B5jUeCAtCN9gslbXzSSlFY4sEk42zTrzZM56P5P/gCiN2N1PtJPk6CfO51In4ERNGVAt7sQmzJ3w5CXM+0vUSppvp0GDWomz5Z45rdRn38vnxv1nYW6PT49/Xk0VTtZ3pwuFnu7lMu7li+rT0nB8wfaZqQtOnz8/mM7L5/BsAAP//24R2lA==" + return "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" } diff --git a/metricbeat/modules.d/docker.yml.disabled b/metricbeat/modules.d/docker.yml.disabled index 216a7a30f3c..f414279857e 100644 --- a/metricbeat/modules.d/docker.yml.disabled +++ b/metricbeat/modules.d/docker.yml.disabled @@ -6,6 +6,7 @@ # - container # - cpu # - diskio + # - event # - healthcheck # - info # - memory diff --git a/metricbeat/tests/system/test_docker.py b/metricbeat/tests/system/test_docker.py index df0e615e874..c757eea06f6 100644 --- a/metricbeat/tests/system/test_docker.py +++ b/metricbeat/tests/system/test_docker.py @@ -210,6 +210,32 @@ def test_image_fields(self): self.assert_fields_are_documented(evt) + @unittest.skipUnless(metricbeat.INTEGRATION_TESTS, "integration test") + def test_event_fields(self): + """ + test event fields + """ + self.render_config_template(modules=[{ + "name": "docker", + "metricsets": ["event"], + "hosts": ["unix:///var/run/docker.sock"], + "period": "10s", + }]) + + proc = self.start_beat() + self.wait_until(lambda: self.output_lines() > 0, max_timeout=20) + proc.check_kill_and_wait() + self.assert_no_logged_warnings(["Container stopped when recovering stats", + "An error occurred while getting docker stats"]) + + output = self.read_output_json() + evt = output[0] + + if 'attributes' in evt["docker"]["event"]["actor"]: + del evt["docker"]["event"]["actor"]["attributes"] + + self.assert_fields_are_documented(evt) + def remove_labels(self, evt): if 'labels' in evt["docker"]["container"]: diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 1dea6f6a90b..954e8e42d19 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -167,6 +167,7 @@ metricbeat.modules: - "container" - "cpu" - "diskio" + - "event" - "healthcheck" - "info" #- "image"