From 6208f0af3c2bf411291eebcad3a53e59a4ad927e Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 24 Nov 2021 09:19:20 +0200 Subject: [PATCH 01/37] Create cpu metricset of metricbeat containerd module initial commit --- metricbeat/docs/fields.asciidoc | 31 +++++++++++ metricbeat/docs/modules/containerd.asciidoc | 41 ++++++++++++++ .../docs/modules/containerd/cpu.asciidoc | 23 ++++++++ metricbeat/docs/modules_list.asciidoc | 3 ++ metricbeat/include/list_common.go | 2 + metricbeat/metricbeat.reference.yml | 8 +++ metricbeat/module/containerd/_meta/config.yml | 6 +++ .../module/containerd/_meta/docs.asciidoc | 2 + metricbeat/module/containerd/_meta/fields.yml | 10 ++++ .../module/containerd/cpu/_meta/data.json | 19 +++++++ .../module/containerd/cpu/_meta/docs.asciidoc | 1 + .../module/containerd/cpu/_meta/fields.yml | 10 ++++ metricbeat/module/containerd/cpu/cpu.go | 54 +++++++++++++++++++ metricbeat/module/containerd/doc.go | 2 + metricbeat/module/containerd/fields.go | 36 +++++++++++++ metricbeat/modules.d/containerd.yml.disabled | 9 ++++ 16 files changed, 257 insertions(+) create mode 100644 metricbeat/docs/modules/containerd.asciidoc create mode 100644 metricbeat/docs/modules/containerd/cpu.asciidoc create mode 100644 metricbeat/module/containerd/_meta/config.yml create mode 100644 metricbeat/module/containerd/_meta/docs.asciidoc create mode 100644 metricbeat/module/containerd/_meta/fields.yml create mode 100644 metricbeat/module/containerd/cpu/_meta/data.json create mode 100644 metricbeat/module/containerd/cpu/_meta/docs.asciidoc create mode 100644 metricbeat/module/containerd/cpu/_meta/fields.yml create mode 100644 metricbeat/module/containerd/cpu/cpu.go create mode 100644 metricbeat/module/containerd/doc.go create mode 100644 metricbeat/module/containerd/fields.go create mode 100644 metricbeat/modules.d/containerd.yml.disabled diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index c1e7087125c..4aecd991158 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -27,6 +27,7 @@ grouped in the following categories: * <> * <> * <> +* <> * <> * <> * <> @@ -10253,6 +10254,36 @@ type: long -- +[[exported-fields-containerd]] +== containerd fields + +containerd module + + + +[float] +=== containerd + + + + +[float] +=== cpu + +cpu + + + +*`containerd.cpu.example`*:: ++ +-- +Example field + + +type: keyword + +-- + [[exported-fields-coredns]] == Coredns fields diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc new file mode 100644 index 00000000000..2b610c98ab2 --- /dev/null +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -0,0 +1,41 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +:modulename: containerd + +[[metricbeat-module-containerd]] +== containerd module + +beta[] + +This is the containerd module. + + + +[float] +=== Example configuration + +The containerd module supports the standard configuration options that are described +in <>. Here is an example configuration: + +[source,yaml] +---- +metricbeat.modules: +- module: containerd + metricsets: ["cpu"] + enabled: false + period: 10s + hosts: ["localhost"] + +---- + +[float] +=== Metricsets + +The following metricsets are available: + +* <> + +include::containerd/cpu.asciidoc[] + diff --git a/metricbeat/docs/modules/containerd/cpu.asciidoc b/metricbeat/docs/modules/containerd/cpu.asciidoc new file mode 100644 index 00000000000..6b661c5f6da --- /dev/null +++ b/metricbeat/docs/modules/containerd/cpu.asciidoc @@ -0,0 +1,23 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-containerd-cpu]] +=== containerd cpu metricset + +beta[] + +include::../../../module/containerd/cpu/_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/containerd/cpu/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index ad5d929514f..1f127a8e2b2 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -72,6 +72,8 @@ This file is generated! See scripts/mage/docs_collector.go .1+| .1+| |<> beta[] |<> beta[] |image:./images/icon-yes.png[Prebuilt dashboards are available] | .1+| .1+| |<> beta[] +|<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | +.1+| .1+| |<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | .1+| .1+| |<> |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | @@ -322,6 +324,7 @@ include::modules/ceph.asciidoc[] include::modules/cloudfoundry.asciidoc[] include::modules/cockroachdb.asciidoc[] include::modules/consul.asciidoc[] +include::modules/containerd.asciidoc[] include::modules/coredns.asciidoc[] include::modules/couchbase.asciidoc[] include::modules/couchdb.asciidoc[] diff --git a/metricbeat/include/list_common.go b/metricbeat/include/list_common.go index d57ebf4631d..2edf0588864 100644 --- a/metricbeat/include/list_common.go +++ b/metricbeat/include/list_common.go @@ -44,6 +44,8 @@ import ( _ "github.com/elastic/beats/v7/metricbeat/module/ceph/pool_disk" _ "github.com/elastic/beats/v7/metricbeat/module/consul" _ "github.com/elastic/beats/v7/metricbeat/module/consul/agent" + _ "github.com/elastic/beats/v7/metricbeat/module/containerd" + _ "github.com/elastic/beats/v7/metricbeat/module/containerd/cpu" _ "github.com/elastic/beats/v7/metricbeat/module/couchbase" _ "github.com/elastic/beats/v7/metricbeat/module/couchbase/bucket" _ "github.com/elastic/beats/v7/metricbeat/module/couchbase/cluster" diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 7673d7b01b5..9b32966ce7c 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -210,6 +210,14 @@ metricbeat.modules: hosts: ["localhost:8500"] +#------------------------------ Containerd Module ------------------------------ +- module: containerd + metricsets: ["cpu"] + enabled: false + period: 10s + hosts: ["localhost"] + + #------------------------------ Couchbase Module ------------------------------ - module: couchbase metricsets: ["bucket", "cluster", "node"] diff --git a/metricbeat/module/containerd/_meta/config.yml b/metricbeat/module/containerd/_meta/config.yml new file mode 100644 index 00000000000..9259f622a1a --- /dev/null +++ b/metricbeat/module/containerd/_meta/config.yml @@ -0,0 +1,6 @@ +- module: containerd + metricsets: ["cpu"] + enabled: false + period: 10s + hosts: ["localhost"] + diff --git a/metricbeat/module/containerd/_meta/docs.asciidoc b/metricbeat/module/containerd/_meta/docs.asciidoc new file mode 100644 index 00000000000..95d2cfa1ba0 --- /dev/null +++ b/metricbeat/module/containerd/_meta/docs.asciidoc @@ -0,0 +1,2 @@ +This is the containerd module. + diff --git a/metricbeat/module/containerd/_meta/fields.yml b/metricbeat/module/containerd/_meta/fields.yml new file mode 100644 index 00000000000..e132d422858 --- /dev/null +++ b/metricbeat/module/containerd/_meta/fields.yml @@ -0,0 +1,10 @@ +- key: containerd + title: "containerd" + release: beta + description: > + containerd module + fields: + - name: containerd + type: group + description: > + fields: diff --git a/metricbeat/module/containerd/cpu/_meta/data.json b/metricbeat/module/containerd/cpu/_meta/data.json new file mode 100644 index 00000000000..b01c3095fd6 --- /dev/null +++ b/metricbeat/module/containerd/cpu/_meta/data.json @@ -0,0 +1,19 @@ +{ + "@timestamp":"2016-05-23T08:05:34.853Z", + "beat":{ + "hostname":"beathost", + "name":"beathost" + }, + "metricset":{ + "host":"localhost", + "module":"containerd", + "name":"cpu", + "rtt":44269 + }, + "containerd":{ + "cpu":{ + "example": "cpu" + } + }, + "type":"metricsets" +} diff --git a/metricbeat/module/containerd/cpu/_meta/docs.asciidoc b/metricbeat/module/containerd/cpu/_meta/docs.asciidoc new file mode 100644 index 00000000000..6cf8db33d3d --- /dev/null +++ b/metricbeat/module/containerd/cpu/_meta/docs.asciidoc @@ -0,0 +1 @@ +This is the cpu metricset of the module containerd. diff --git a/metricbeat/module/containerd/cpu/_meta/fields.yml b/metricbeat/module/containerd/cpu/_meta/fields.yml new file mode 100644 index 00000000000..03b7785afb0 --- /dev/null +++ b/metricbeat/module/containerd/cpu/_meta/fields.yml @@ -0,0 +1,10 @@ +- name: cpu + type: group + release: beta + description: > + cpu + fields: + - name: example + type: keyword + description: > + Example field diff --git a/metricbeat/module/containerd/cpu/cpu.go b/metricbeat/module/containerd/cpu/cpu.go new file mode 100644 index 00000000000..4726f546a8c --- /dev/null +++ b/metricbeat/module/containerd/cpu/cpu.go @@ -0,0 +1,54 @@ +package cpu + +import ( + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + "github.com/elastic/beats/v7/metricbeat/mb" +) + +// 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("containerd", "cpu", New) +} + +// 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 + counter int +} + +// 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) { + cfgwarn.Beta("The containerd cpu metricset is beta.") + + config := struct{}{} + if err := base.Module().UnpackConfig(&config); err != nil { + return nil, err + } + + return &MetricSet{ + BaseMetricSet: base, + counter: 1, + }, nil +} + +// Fetch methods implements the data gathering and data conversion to the right +// format. It publishes the event which is then forwarded to the output. In case +// of an error set the Error field of mb.Event or simply call report.Error(). +func (m *MetricSet) Fetch(report mb.ReporterV2) error { + report.Event(mb.Event{ + MetricSetFields: common.MapStr{ + "counter": m.counter, + }, + }) + m.counter++ + + return nil +} diff --git a/metricbeat/module/containerd/doc.go b/metricbeat/module/containerd/doc.go new file mode 100644 index 00000000000..0070177b74e --- /dev/null +++ b/metricbeat/module/containerd/doc.go @@ -0,0 +1,2 @@ +// Package containerd is a Metricbeat module that contains MetricSets. +package containerd diff --git a/metricbeat/module/containerd/fields.go b/metricbeat/module/containerd/fields.go new file mode 100644 index 00000000000..166178759c3 --- /dev/null +++ b/metricbeat/module/containerd/fields.go @@ -0,0 +1,36 @@ +// 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. + +// Code generated by beats/dev-tools/cmd/asset/asset.go - DO NOT EDIT. + +package containerd + +import ( + "github.com/elastic/beats/v7/libbeat/asset" +) + +func init() { + if err := asset.SetFields("metricbeat", "containerd", asset.ModuleFieldsPri, AssetContainerd); err != nil { + panic(err) + } +} + +// AssetContainerd returns asset data. +// This is the base64 encoded zlib format compressed contents of module/containerd. +func AssetContainerd() string { + return "eJyMj0EOgjAURPc9xYQ9F+jCnQepdDQNpW3KJ8rtDVQRSBe+5fzkzfwWPWeNLgYxLjBbBYgTT43mFzYKyPQ0IzVuFKMAy7HLLomLQeOiAOwsGKKdPBVwd/R21Ou9RTADT20LMidqPHKc0iep2I+ugy9NW1aTLZznf6kWFY7ac/l+AF9mSOu7e8qQnvMzbp/+UbtwLcJSqt4BAAD//4S1cSM=" +} diff --git a/metricbeat/modules.d/containerd.yml.disabled b/metricbeat/modules.d/containerd.yml.disabled new file mode 100644 index 00000000000..495e2792e2f --- /dev/null +++ b/metricbeat/modules.d/containerd.yml.disabled @@ -0,0 +1,9 @@ +# Module: containerd +# Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-containerd.html + +- module: containerd + metricsets: ["cpu"] + enabled: false + period: 10s + hosts: ["localhost"] + From 65503345f2bc7f375b3ea9a3be8212e7e38cd5d3 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 24 Nov 2021 11:24:04 +0200 Subject: [PATCH 02/37] Add cpu fields --- metricbeat/module/containerd/_meta/fields.yml | 5 ++- .../module/containerd/cpu/_meta/fields.yml | 40 ++++++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/metricbeat/module/containerd/_meta/fields.yml b/metricbeat/module/containerd/_meta/fields.yml index e132d422858..7e4f9c8cc4e 100644 --- a/metricbeat/module/containerd/_meta/fields.yml +++ b/metricbeat/module/containerd/_meta/fields.yml @@ -1,10 +1,11 @@ - key: containerd - title: "containerd" + title: "Containerd" release: beta description: > - containerd module + Containerd stats collected from containerd fields: - name: containerd type: group description: > + Information and statistics about containerd's running containers. fields: diff --git a/metricbeat/module/containerd/cpu/_meta/fields.yml b/metricbeat/module/containerd/cpu/_meta/fields.yml index 03b7785afb0..a8c92d63d1f 100644 --- a/metricbeat/module/containerd/cpu/_meta/fields.yml +++ b/metricbeat/module/containerd/cpu/_meta/fields.yml @@ -1,10 +1,40 @@ - name: cpu type: group - release: beta description: > - cpu + Containerd Runtime CPU metrics. + release: beta fields: - - name: example - type: keyword + - name: containerd + type: group description: > - Example field + fields: + - name: kernel.pct + type: scaled_float + format: percent + description: > + Percentage of time in kernel space. + - name: kernel.norm.pct + type: scaled_float + format: percent + description: > + Percentage of time in kernel space normalized by the number of CPU cores. + - name: total.pct + type: scaled_float + format: percent + description: > + Total CPU usage. + - name: total.norm.pct + type: scaled_float + format: percent + description: > + Total CPU usage normalized by the number of CPU cores. + - name: user.pct + type: scaled_float + format: percent + description: > + Percentage of time in user space. + - name: user.norm.pct + type: scaled_float + format: percent + description: > + Percentage of time in user space normalized by the number of CPU cores. From 928d3eacfdf13d42c1cb14ce5a096d4ddb648981 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 25 Nov 2021 14:52:37 +0200 Subject: [PATCH 03/37] Generate containerd cpu metrics --- metricbeat/module/containerd/_meta/config.yml | 2 +- .../module/containerd/cpu/_meta/fields.yml | 79 ++++++++------- metricbeat/module/containerd/cpu/cpu.go | 91 +++++++++--------- metricbeat/module/containerd/cpu/metricset.go | 96 +++++++++++++++++++ 4 files changed, 192 insertions(+), 76 deletions(-) create mode 100644 metricbeat/module/containerd/cpu/metricset.go diff --git a/metricbeat/module/containerd/_meta/config.yml b/metricbeat/module/containerd/_meta/config.yml index 9259f622a1a..e50613a47e7 100644 --- a/metricbeat/module/containerd/_meta/config.yml +++ b/metricbeat/module/containerd/_meta/config.yml @@ -2,5 +2,5 @@ metricsets: ["cpu"] enabled: false period: 10s - hosts: ["localhost"] + hosts: ["localhost:1338"] diff --git a/metricbeat/module/containerd/cpu/_meta/fields.yml b/metricbeat/module/containerd/cpu/_meta/fields.yml index a8c92d63d1f..ec8f5319274 100644 --- a/metricbeat/module/containerd/cpu/_meta/fields.yml +++ b/metricbeat/module/containerd/cpu/_meta/fields.yml @@ -4,37 +4,52 @@ Containerd Runtime CPU metrics. release: beta fields: - - name: containerd + - name: usage type: group - description: > fields: - - name: kernel.pct - type: scaled_float - format: percent - description: > - Percentage of time in kernel space. - - name: kernel.norm.pct - type: scaled_float - format: percent - description: > - Percentage of time in kernel space normalized by the number of CPU cores. - - name: total.pct - type: scaled_float - format: percent - description: > - Total CPU usage. - - name: total.norm.pct - type: scaled_float - format: percent - description: > - Total CPU usage normalized by the number of CPU cores. - - name: user.pct - type: scaled_float - format: percent - description: > - Percentage of time in user space. - - name: user.norm.pct - type: scaled_float - format: percent - description: > - Percentage of time in user space normalized by the number of CPU cores. + - name: kernel + type: group + fields: + - name: ns + type: double + description: > + CPU Kernel usage nanoseconds + - name: user + type: group + fields: + - name: ns + type: double + description: > + CPU User usage nanoseconds + - name: total + type: group + fields: + - name: ns + type: double + description: > + CPU total usage nanoseconds +# - name: kernel.norm.pct +# type: scaled_float +# format: percent +# description: > +# Percentage of time in kernel space normalized by the number of CPU cores. +# - name: total.pct +# type: scaled_float +# format: percent +# description: > +# Total CPU usage. +# - name: total.norm.pct +# type: scaled_float +# format: percent +# description: > +# Total CPU usage normalized by the number of CPU cores. +# - name: user.pct +# type: scaled_float +# format: percent +# description: > +# Percentage of time in user space. +# - name: user.norm.pct +# type: scaled_float +# format: percent +# description: > +# Percentage of time in user space normalized by the number of CPU cores. diff --git a/metricbeat/module/containerd/cpu/cpu.go b/metricbeat/module/containerd/cpu/cpu.go index 4726f546a8c..db7bd098774 100644 --- a/metricbeat/module/containerd/cpu/cpu.go +++ b/metricbeat/module/containerd/cpu/cpu.go @@ -1,54 +1,59 @@ +// 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 cpu import ( - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + p "github.com/elastic/beats/v7/metricbeat/helper/openmetrics" + "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/metricbeat/mb/parse" ) -// 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("containerd", "cpu", New) -} - -// 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 - counter int -} - -// 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) { - cfgwarn.Beta("The containerd cpu metricset is beta.") - - config := struct{}{} - if err := base.Module().UnpackConfig(&config); err != nil { - return nil, err - } +const ( + defaultScheme = "http" + defaultPath = "/v1/metrics" +) - return &MetricSet{ - BaseMetricSet: base, - counter: 1, - }, nil -} +var ( + // HostParser validates Prometheus URLs + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() +) -// Fetch methods implements the data gathering and data conversion to the right -// format. It publishes the event which is then forwarded to the output. In case -// of an error set the Error field of mb.Event or simply call report.Error(). -func (m *MetricSet) Fetch(report mb.ReporterV2) error { - report.Event(mb.Event{ - MetricSetFields: common.MapStr{ - "counter": m.counter, +// 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() { + // Mapping of state metrics + mapping := &prometheus.MetricsMapping{ + Metrics: map[string]prometheus.MetricMap{ + "container_cpu_total_nanoseconds": prometheus.Metric("usage.total.ns"), + "container_cpu_user_nanoseconds": prometheus.Metric("usage.user.ns"), + "container_cpu_kernel_nanoseconds": prometheus.Metric("usage.kernel.ns"), + }, + Labels: map[string]prometheus.LabelMap{ + "container_id": p.KeyLabel("id"), }, - }) - m.counter++ + } - return nil + mb.Registry.MustAddMetricSet("containerd", "cpu", + getMetricsetFactory(mapping), + mb.WithHostParser(hostParser), + ) } diff --git a/metricbeat/module/containerd/cpu/metricset.go b/metricbeat/module/containerd/cpu/metricset.go new file mode 100644 index 00000000000..11a54e46e48 --- /dev/null +++ b/metricbeat/module/containerd/cpu/metricset.go @@ -0,0 +1,96 @@ +// 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 cpu + +import ( + "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" + + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/metricbeat/helper/prometheus" + "github.com/elastic/beats/v7/metricbeat/mb" +) + +// Metricset for apiserver is a prometheus based metricset +type metricset struct { + mb.BaseMetricSet + prometheusClient prometheus.Prometheus + prometheusMappings *prometheus.MetricsMapping +} + +var _ mb.ReportingMetricSetV2Error = (*metricset)(nil) + +// getMetricsetFactory as required by` mb.Registry.MustAddMetricSet` +func getMetricsetFactory(prometheusMappings *prometheus.MetricsMapping) mb.MetricSetFactory { + return func(base mb.BaseMetricSet) (mb.MetricSet, error) { + pc, err := prometheus.NewPrometheusClient(base) + if err != nil { + return nil, err + } + return &metricset{ + BaseMetricSet: base, + prometheusClient: pc, + prometheusMappings: prometheusMappings, + }, nil + } +} + +// Fetch gathers information from the containerd and reports events with this information. +func (m *metricset) Fetch(reporter mb.ReporterV2) error { + events, err := m.prometheusClient.GetProcessedMetrics(m.prometheusMappings) + if err != nil { + return errors.Wrap(err, "error getting metrics") + } + m.Logger().Debugf("Events from containerd are %+v", events) + for _, event := range events { + // applying ECS to kubernetes.container.id in the form :// + // copy to ECS fields the kubernetes.container.image, kubernetes.container.name + containerFields := common.MapStr{} + if containerID, ok := event["id"]; ok { + // we don't expect errors here, but if any we would obtain an + // empty string + cID := (containerID).(string) + containerFields.Put("id", cID) + event.Delete("id") + } + + e, err := util.CreateEvent(event, "containerd.cpu") + if err != nil { + m.Logger().Error(err) + } + + if len(containerFields) > 0 { + if e.RootFields != nil { + e.RootFields.DeepUpdate(common.MapStr{ + "container": containerFields, + }) + } else { + e.RootFields = common.MapStr{ + "container": containerFields, + } + } + } + + if reported := reporter.Event(e); !reported { + return nil + } + } + + return nil +} From 64da17ebccd0b5c28c22d5e6c2851dcccabc3f3a Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Tue, 30 Nov 2021 12:44:33 +0200 Subject: [PATCH 04/37] Get cpu usage percentage --- metricbeat/module/containerd/cpu/cpu.go | 1 + metricbeat/module/containerd/cpu/metricset.go | 65 ++++++++++++++++--- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/metricbeat/module/containerd/cpu/cpu.go b/metricbeat/module/containerd/cpu/cpu.go index db7bd098774..5c7873af242 100644 --- a/metricbeat/module/containerd/cpu/cpu.go +++ b/metricbeat/module/containerd/cpu/cpu.go @@ -46,6 +46,7 @@ func init() { "container_cpu_total_nanoseconds": prometheus.Metric("usage.total.ns"), "container_cpu_user_nanoseconds": prometheus.Metric("usage.user.ns"), "container_cpu_kernel_nanoseconds": prometheus.Metric("usage.kernel.ns"), + "process_cpu_seconds_total": prometheus.Metric("system.total"), }, Labels: map[string]prometheus.LabelMap{ "container_id": p.KeyLabel("id"), diff --git a/metricbeat/module/containerd/cpu/metricset.go b/metricbeat/module/containerd/cpu/metricset.go index 11a54e46e48..6ebe55cf87c 100644 --- a/metricbeat/module/containerd/cpu/metricset.go +++ b/metricbeat/module/containerd/cpu/metricset.go @@ -30,8 +30,10 @@ import ( // Metricset for apiserver is a prometheus based metricset type metricset struct { mb.BaseMetricSet - prometheusClient prometheus.Prometheus - prometheusMappings *prometheus.MetricsMapping + prometheusClient prometheus.Prometheus + prometheusMappings *prometheus.MetricsMapping + preSystemCpuUsage float64 + preContainerCpuUsage map[string]float64 } var _ mb.ReportingMetricSetV2Error = (*metricset)(nil) @@ -44,9 +46,11 @@ func getMetricsetFactory(prometheusMappings *prometheus.MetricsMapping) mb.Metri return nil, err } return &metricset{ - BaseMetricSet: base, - prometheusClient: pc, - prometheusMappings: prometheusMappings, + BaseMetricSet: base, + prometheusClient: pc, + prometheusMappings: prometheusMappings, + preSystemCpuUsage: 0.0, + preContainerCpuUsage: map[string]float64{}, }, nil } } @@ -57,19 +61,34 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { if err != nil { return errors.Wrap(err, "error getting metrics") } - m.Logger().Debugf("Events from containerd are %+v", events) + var systemTotalNs int64 + elToDel := -1 + for i, event := range events { + systemTotalSeconds, err := event.GetValue("system.total") + if err == nil { + systemTotalNs = systemTotalSeconds.(int64) * 1000000000 + elToDel = i + break + } + } + if elToDel != -1 { + events[elToDel] = events[len(events)-1] // Copy last element to index i. + events[len(events)-1] = common.MapStr{} // Erase last element (write empty value). + events = events[:len(events)-1] + } + for _, event := range events { // applying ECS to kubernetes.container.id in the form :// // copy to ECS fields the kubernetes.container.image, kubernetes.container.name containerFields := common.MapStr{} + var cID string if containerID, ok := event["id"]; ok { // we don't expect errors here, but if any we would obtain an // empty string - cID := (containerID).(string) + cID = (containerID).(string) containerFields.Put("id", cID) event.Delete("id") } - e, err := util.CreateEvent(event, "containerd.cpu") if err != nil { m.Logger().Error(err) @@ -86,11 +105,37 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } } } - + cpuUsageTotal, err := event.GetValue("usage.total.ns") + if err == nil { + var contUsageDelta, systemUsageDelta, cpuUsagePct float64 + if cpuPreval, ok := m.preContainerCpuUsage[cID]; ok { + contUsageDelta = cpuUsageTotal.(float64) - cpuPreval + systemUsageDelta = float64(systemTotalNs) - m.preSystemCpuUsage + m.Logger().Infof("contUsageDelta is %+v - %+v == %+v", cpuUsageTotal, cpuPreval, contUsageDelta) + m.Logger().Infof("systemUsageDelta is %+v - %+v == %+v", systemTotalNs, m.preSystemCpuUsage, systemUsageDelta) + } else { + contUsageDelta = cpuUsageTotal.(float64) + systemUsageDelta = float64(systemTotalNs) + m.Logger().Infof("contUsageDelta is %+v - %+v == %+v", cpuUsageTotal, cpuPreval, contUsageDelta) + m.Logger().Infof("systemUsageDelta is %+v - %+v == %+v", systemTotalNs, m.preSystemCpuUsage, systemUsageDelta) + } + if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { + m.Logger().Infof("SOMETHING IS ZERO") + cpuUsagePct = 0.0 + } else { + cpuUsagePct = (contUsageDelta / systemUsageDelta) * 100 + } + m.Logger().Infof("cpuUsagePct for %+v is %+v", cID, cpuUsagePct) + e.MetricSetFields.Put("usage.total.pct", cpuUsagePct) + //Update values + m.preContainerCpuUsage[cID] = cpuUsageTotal.(float64) + } if reported := reporter.Event(e); !reported { return nil } } - + m.preSystemCpuUsage = float64(systemTotalNs) + m.Logger().Infof("preContainerCpuUsage is %+v", m.preContainerCpuUsage) + m.Logger().Infof("preSystemCpuUsage is %+v", m.preSystemCpuUsage) return nil } From 31672b5c688970ddeaa6ef49415a408f6b36fb7f Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 2 Dec 2021 13:54:20 +0200 Subject: [PATCH 05/37] New fields --- .../module/containerd/cpu/_meta/fields.yml | 45 ++--- metricbeat/module/containerd/cpu/cpu.go | 2 + metricbeat/module/containerd/cpu/metricset.go | 184 ++++++++++++++---- 3 files changed, 168 insertions(+), 63 deletions(-) diff --git a/metricbeat/module/containerd/cpu/_meta/fields.yml b/metricbeat/module/containerd/cpu/_meta/fields.yml index ec8f5319274..3fe155abc44 100644 --- a/metricbeat/module/containerd/cpu/_meta/fields.yml +++ b/metricbeat/module/containerd/cpu/_meta/fields.yml @@ -28,28 +28,23 @@ type: double description: > CPU total usage nanoseconds -# - name: kernel.norm.pct -# type: scaled_float -# format: percent -# description: > -# Percentage of time in kernel space normalized by the number of CPU cores. -# - name: total.pct -# type: scaled_float -# format: percent -# description: > -# Total CPU usage. -# - name: total.norm.pct -# type: scaled_float -# format: percent -# description: > -# Total CPU usage normalized by the number of CPU cores. -# - name: user.pct -# type: scaled_float -# format: percent -# description: > -# Percentage of time in user space. -# - name: user.norm.pct -# type: scaled_float -# format: percent -# description: > -# Percentage of time in user space normalized by the number of CPU cores. + - name: total.pct + type: scaled_float + format: percent + description: > + Percentage of total CPU time normalized by the number of CPU cores + - name: kernel.pct + type: scaled_float + format: percent + description: > + Percentage of time in kernel space normalized by the number of CPU cores. + - name: user.pct + type: scaled_float + format: percent + description: > + Percentage of time in user space normalized by the number of CPU cores. + - name: cpu.*.ns + type: object + object_type: double + description: > + CPU usage nanoseconds in this cpu. diff --git a/metricbeat/module/containerd/cpu/cpu.go b/metricbeat/module/containerd/cpu/cpu.go index 5c7873af242..6c4bc6876b8 100644 --- a/metricbeat/module/containerd/cpu/cpu.go +++ b/metricbeat/module/containerd/cpu/cpu.go @@ -46,10 +46,12 @@ func init() { "container_cpu_total_nanoseconds": prometheus.Metric("usage.total.ns"), "container_cpu_user_nanoseconds": prometheus.Metric("usage.user.ns"), "container_cpu_kernel_nanoseconds": prometheus.Metric("usage.kernel.ns"), + "container_per_cpu_nanoseconds": prometheus.Metric("usage.percpu.ns"), "process_cpu_seconds_total": prometheus.Metric("system.total"), }, Labels: map[string]prometheus.LabelMap{ "container_id": p.KeyLabel("id"), + "cpu": p.KeyLabel("cpu"), }, } diff --git a/metricbeat/module/containerd/cpu/metricset.go b/metricbeat/module/containerd/cpu/metricset.go index 6ebe55cf87c..aa0c8767ce8 100644 --- a/metricbeat/module/containerd/cpu/metricset.go +++ b/metricbeat/module/containerd/cpu/metricset.go @@ -18,6 +18,8 @@ package cpu import ( + "fmt" + "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" "github.com/pkg/errors" @@ -30,10 +32,12 @@ import ( // Metricset for apiserver is a prometheus based metricset type metricset struct { mb.BaseMetricSet - prometheusClient prometheus.Prometheus - prometheusMappings *prometheus.MetricsMapping - preSystemCpuUsage float64 - preContainerCpuUsage map[string]float64 + prometheusClient prometheus.Prometheus + prometheusMappings *prometheus.MetricsMapping + preSystemCpuUsage float64 + preContainerCpuTotalUsage map[string]float64 + preContainerCpuKernelUsage map[string]float64 + preContainerCpuUserUsage map[string]float64 } var _ mb.ReportingMetricSetV2Error = (*metricset)(nil) @@ -46,11 +50,13 @@ func getMetricsetFactory(prometheusMappings *prometheus.MetricsMapping) mb.Metri return nil, err } return &metricset{ - BaseMetricSet: base, - prometheusClient: pc, - prometheusMappings: prometheusMappings, - preSystemCpuUsage: 0.0, - preContainerCpuUsage: map[string]float64{}, + BaseMetricSet: base, + prometheusClient: pc, + prometheusMappings: prometheusMappings, + preSystemCpuUsage: 0.0, + preContainerCpuTotalUsage: map[string]float64{}, + preContainerCpuKernelUsage: map[string]float64{}, + preContainerCpuUserUsage: map[string]float64{}, }, nil } } @@ -62,29 +68,33 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { return errors.Wrap(err, "error getting metrics") } var systemTotalNs int64 + perContainerCpus := make(map[string]int) elToDel := -1 for i, event := range events { systemTotalSeconds, err := event.GetValue("system.total") if err == nil { - systemTotalNs = systemTotalSeconds.(int64) * 1000000000 + systemTotalNs = systemTotalSeconds.(int64) * 1e9 elToDel = i - break } + if _, err = event.GetValue("cpu"); err == nil { + // calculate cpus used by each container + setContCpus(event, perContainerCpus) + } + } + // Remove event containing system.total if elToDel != -1 { events[elToDel] = events[len(events)-1] // Copy last element to index i. events[len(events)-1] = common.MapStr{} // Erase last element (write empty value). events = events[:len(events)-1] } + //m.Logger().Infof("ContainerCpus are %+v", perContainerCpus) for _, event := range events { - // applying ECS to kubernetes.container.id in the form :// - // copy to ECS fields the kubernetes.container.image, kubernetes.container.name + // setting ECS container.id containerFields := common.MapStr{} var cID string if containerID, ok := event["id"]; ok { - // we don't expect errors here, but if any we would obtain an - // empty string cID = (containerID).(string) containerFields.Put("id", cID) event.Delete("id") @@ -105,37 +115,135 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } } } + contCpus, ok := perContainerCpus[cID] + if !ok { + contCpus = 1 + } + // calculate system usage delta + systemUsageDelta := float64(systemTotalNs) - m.preSystemCpuUsage + + // Calculate cpu total usage percentage cpuUsageTotal, err := event.GetValue("usage.total.ns") if err == nil { - var contUsageDelta, systemUsageDelta, cpuUsagePct float64 - if cpuPreval, ok := m.preContainerCpuUsage[cID]; ok { - contUsageDelta = cpuUsageTotal.(float64) - cpuPreval - systemUsageDelta = float64(systemTotalNs) - m.preSystemCpuUsage - m.Logger().Infof("contUsageDelta is %+v - %+v == %+v", cpuUsageTotal, cpuPreval, contUsageDelta) - m.Logger().Infof("systemUsageDelta is %+v - %+v == %+v", systemTotalNs, m.preSystemCpuUsage, systemUsageDelta) - } else { - contUsageDelta = cpuUsageTotal.(float64) - systemUsageDelta = float64(systemTotalNs) - m.Logger().Infof("contUsageDelta is %+v - %+v == %+v", cpuUsageTotal, cpuPreval, contUsageDelta) - m.Logger().Infof("systemUsageDelta is %+v - %+v == %+v", systemTotalNs, m.preSystemCpuUsage, systemUsageDelta) - } - if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { - m.Logger().Infof("SOMETHING IS ZERO") - cpuUsagePct = 0.0 - } else { - cpuUsagePct = (contUsageDelta / systemUsageDelta) * 100 + cpuUsageTotalPct := calcCpuTotalUsagePct(cpuUsageTotal.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuTotalUsage) + m.Logger().Infof("cpuUsageTotalPct for %+v is %+v", cID, cpuUsageTotalPct) + e.MetricSetFields.Put("usage.total.pct", cpuUsageTotalPct) + // Update values + m.preContainerCpuTotalUsage[cID] = cpuUsageTotal.(float64) + } + + // Calculate cpu kernel usage percentage + cpuUsageKernel, err := event.GetValue("usage.kernel.ns") + if err == nil { + cpuUsageKernelPct := calcCpuKernelUsagePct(cpuUsageKernel.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuKernelUsage) + m.Logger().Infof("cpuUsageKernelPct for %+v is %+v", cID, cpuUsageKernelPct) + e.MetricSetFields.Put("usage.kernel.pct", cpuUsageKernelPct) + // Update values + m.preContainerCpuKernelUsage[cID] = cpuUsageKernel.(float64) + } + + // Calculate cpu user usage percentage + cpuUsageUser, err := event.GetValue("usage.user.ns") + if err == nil { + cpuUsageUserPct := calcCpuUserUsagePct(cpuUsageUser.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuUserUsage) + m.Logger().Infof("cpuUsageUserPct for %+v is %+v", cID, cpuUsageUserPct) + e.MetricSetFields.Put("usage.user.pct", cpuUsageUserPct) + // Update values + m.preContainerCpuUserUsage[cID] = cpuUsageUser.(float64) + } + + if cpuId, err := event.GetValue("cpu"); err == nil { + perCpuNs, err := event.GetValue("usage.percpu.ns") + if err == nil { + key := fmt.Sprintf("usage.cpu.%s.ns", cpuId) + e.MetricSetFields.Put(key, perCpuNs) + e.MetricSetFields.Delete("cpu") + e.MetricSetFields.Delete("usage.percpu.ns") } - m.Logger().Infof("cpuUsagePct for %+v is %+v", cID, cpuUsagePct) - e.MetricSetFields.Put("usage.total.pct", cpuUsagePct) - //Update values - m.preContainerCpuUsage[cID] = cpuUsageTotal.(float64) } + if reported := reporter.Event(e); !reported { return nil } } m.preSystemCpuUsage = float64(systemTotalNs) - m.Logger().Infof("preContainerCpuUsage is %+v", m.preContainerCpuUsage) - m.Logger().Infof("preSystemCpuUsage is %+v", m.preSystemCpuUsage) return nil } + +func setContCpus(event common.MapStr, perContainerCpus map[string]int) { + val, err := event.GetValue("id") + if err != nil { + return + } + cid := val.(string) + _, err = event.GetValue("usage.percpu.ns") + if err != nil { + return + } + if _, ok := perContainerCpus[cid]; ok { + perContainerCpus[cid] += 1 + } else { + perContainerCpus[cid] = 1 + } + //if percpu.(float64) != 0.0 { + // if _, ok := perContainerCpus[cid]; ok { + // perContainerCpus[cid] += 1 + // } else { + // perContainerCpus[cid] = 1 + // } + //} +} + +func calcCpuTotalUsagePct(cpuUsageTotal, systemUsageDelta, contCpus float64, + cid string, preContainerCpuTotalUsage map[string]float64) float64 { + var contUsageDelta, cpuUsageTotalPct float64 + if cpuPreval, ok := preContainerCpuTotalUsage[cid]; ok { + contUsageDelta = cpuUsageTotal - cpuPreval + } else { + contUsageDelta = cpuUsageTotal + } + if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { + cpuUsageTotalPct = 0.0 + } else { + // normalize percentage with cpus used per container + cpuUsageTotalPct = (contUsageDelta / systemUsageDelta) / contCpus + } + return cpuUsageTotalPct +} + +func calcCpuKernelUsagePct(cpuUsageKernel, systemUsageDelta, contCpus float64, + cid string, preContainerCpuKernelUsage map[string]float64) float64 { + var contUsageDelta, cpuUsageKernelPct float64 + if cpuPreval, ok := preContainerCpuKernelUsage[cid]; ok { + contUsageDelta = cpuUsageKernel - cpuPreval + } else { + contUsageDelta = cpuUsageKernel + } + if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { + cpuUsageKernelPct = 0.0 + } else { + // normalize percentage with cpus used per container + cpuUsageKernelPct = (contUsageDelta / systemUsageDelta) / contCpus + } + return cpuUsageKernelPct +} + +func calcCpuUserUsagePct(cpuUsageUser, systemUsageDelta, contCpus float64, + cid string, preContainerCpuUserUsage map[string]float64) float64 { + var contUsageDelta, cpuUsageUserPct float64 + if cpuPreval, ok := preContainerCpuUserUsage[cid]; ok { + contUsageDelta = cpuUsageUser - cpuPreval + } else { + contUsageDelta = cpuUsageUser + } + if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { + cpuUsageUserPct = 0.0 + } else { + // normalize percentage with cpus used per container + cpuUsageUserPct = (contUsageDelta / systemUsageDelta) / contCpus + } + return cpuUsageUserPct +} From 512f5d4c2746d60fbe0c887ff403a62b79ce96de Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 2 Dec 2021 17:23:33 +0200 Subject: [PATCH 06/37] Make fmt --- metricbeat/module/containerd/doc.go | 17 +++++++++++++++++ metricbeat/module/containerd/fields.go | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/metricbeat/module/containerd/doc.go b/metricbeat/module/containerd/doc.go index 0070177b74e..6ce66eed2f9 100644 --- a/metricbeat/module/containerd/doc.go +++ b/metricbeat/module/containerd/doc.go @@ -1,2 +1,19 @@ +// 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 containerd is a Metricbeat module that contains MetricSets. package containerd diff --git a/metricbeat/module/containerd/fields.go b/metricbeat/module/containerd/fields.go index 166178759c3..08edb57394d 100644 --- a/metricbeat/module/containerd/fields.go +++ b/metricbeat/module/containerd/fields.go @@ -32,5 +32,5 @@ func init() { // AssetContainerd returns asset data. // This is the base64 encoded zlib format compressed contents of module/containerd. func AssetContainerd() string { - return "eJyMj0EOgjAURPc9xYQ9F+jCnQepdDQNpW3KJ8rtDVQRSBe+5fzkzfwWPWeNLgYxLjBbBYgTT43mFzYKyPQ0IzVuFKMAy7HLLomLQeOiAOwsGKKdPBVwd/R21Ou9RTADT20LMidqPHKc0iep2I+ugy9NW1aTLZznf6kWFY7ac/l+AF9mSOu7e8qQnvMzbp/+UbtwLcJSqt4BAAD//4S1cSM=" + return "eJzUlLFu3DAMhnc/BZGlQIH4ATx0yVR0CQpkDmSJvqiRKUGkhuvTF7J9d7ZP9l2ADglHivz5fzToR3jHYwPakyhLGE0FIFYcNvDwdE4+VAARHSrGBloUVQEYZB1tEOupgR8VAMClAViUMGjvHGpBA130/XJKZ9EZbobGRyDV48pGDjkGbOAQfQpTpjA2x0/qfOxVToOicb5lsZpBtT7JTPobQ0xElg6XJNeT0tzVwllI51zJ1o611WZ+JxLbIzw9v0CPEq0+D8+xXvMp1sbm5hKrAy5etixuKc3V3jESuqvnPck92bk0cfH5JG18at0a5BQ7251HXuuvgWBcC5Aiz6g9mevhlwVi/MrAL4zxA7jiRX3pDzwAfBS4Dlo2oVkrh+a1c16VisafSwMBo0YqVdzh/nlszqZ9NzEMNPl3QHmCs3/RQHsEeUOg1LcYc2ku0j7iGnB5sUW+O+husd0kW3FlGkuTKeCg9J109QZevs5PBpct/Q80HVL9vS5czYjm2z9Y4B7Tr7s3dRMse7u6oMwmb5YHY9W/AAAA///L3w+i" } From 287c9c43833c6b427b7e9e0741278ae17ae328d4 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Mon, 6 Dec 2021 13:21:43 +0200 Subject: [PATCH 07/37] Add config option for cpu pct calculation --- metricbeat/module/containerd/config.go | 13 ++ metricbeat/module/containerd/cpu/cpu.go | 5 +- metricbeat/module/containerd/cpu/metricset.go | 117 ++++++++++-------- 3 files changed, 77 insertions(+), 58 deletions(-) create mode 100644 metricbeat/module/containerd/config.go diff --git a/metricbeat/module/containerd/config.go b/metricbeat/module/containerd/config.go new file mode 100644 index 00000000000..6e86ce8176a --- /dev/null +++ b/metricbeat/module/containerd/config.go @@ -0,0 +1,13 @@ +package containerd + +// Config contains the config needed for containerd +type Config struct { + CalculatePct bool `config:"calcpct"` +} + +// DefaultConfig returns default module config +func DefaultConfig() Config { + return Config{ + CalculatePct: true, + } +} diff --git a/metricbeat/module/containerd/cpu/cpu.go b/metricbeat/module/containerd/cpu/cpu.go index 6c4bc6876b8..de24dafb95e 100644 --- a/metricbeat/module/containerd/cpu/cpu.go +++ b/metricbeat/module/containerd/cpu/cpu.go @@ -18,7 +18,6 @@ package cpu import ( - p "github.com/elastic/beats/v7/metricbeat/helper/openmetrics" "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" @@ -50,8 +49,8 @@ func init() { "process_cpu_seconds_total": prometheus.Metric("system.total"), }, Labels: map[string]prometheus.LabelMap{ - "container_id": p.KeyLabel("id"), - "cpu": p.KeyLabel("cpu"), + "container_id": prometheus.KeyLabel("id"), + "cpu": prometheus.KeyLabel("cpu"), }, } diff --git a/metricbeat/module/containerd/cpu/metricset.go b/metricbeat/module/containerd/cpu/metricset.go index aa0c8767ce8..4ba80a70c99 100644 --- a/metricbeat/module/containerd/cpu/metricset.go +++ b/metricbeat/module/containerd/cpu/metricset.go @@ -20,6 +20,8 @@ package cpu import ( "fmt" + "github.com/elastic/beats/v7/metricbeat/module/containerd" + "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" "github.com/pkg/errors" @@ -34,6 +36,7 @@ type metricset struct { mb.BaseMetricSet prometheusClient prometheus.Prometheus prometheusMappings *prometheus.MetricsMapping + calcPct bool preSystemCpuUsage float64 preContainerCpuTotalUsage map[string]float64 preContainerCpuKernelUsage map[string]float64 @@ -49,10 +52,15 @@ func getMetricsetFactory(prometheusMappings *prometheus.MetricsMapping) mb.Metri if err != nil { return nil, err } + config := containerd.DefaultConfig() + if err := base.Module().UnpackConfig(&config); err != nil { + return nil, err + } return &metricset{ BaseMetricSet: base, prometheusClient: pc, prometheusMappings: prometheusMappings, + calcPct: config.CalculatePct, preSystemCpuUsage: 0.0, preContainerCpuTotalUsage: map[string]float64{}, preContainerCpuKernelUsage: map[string]float64{}, @@ -67,30 +75,28 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { if err != nil { return errors.Wrap(err, "error getting metrics") } + var systemTotalNs int64 perContainerCpus := make(map[string]int) - elToDel := -1 - for i, event := range events { - systemTotalSeconds, err := event.GetValue("system.total") - if err == nil { - systemTotalNs = systemTotalSeconds.(int64) * 1e9 - elToDel = i - } - if _, err = event.GetValue("cpu"); err == nil { - // calculate cpus used by each container - setContCpus(event, perContainerCpus) - } + if m.calcPct { + for _, event := range events { + systemTotalSeconds, err := event.GetValue("system.total") + if err == nil { + systemTotalNs = systemTotalSeconds.(int64) * 1e9 + } + if _, err = event.GetValue("cpu"); err == nil { + // calculate cpus used by each container + setContCpus(event, perContainerCpus) + } + } } - // Remove event containing system.total - if elToDel != -1 { - events[elToDel] = events[len(events)-1] // Copy last element to index i. - events[len(events)-1] = common.MapStr{} // Erase last element (write empty value). - events = events[:len(events)-1] - } - //m.Logger().Infof("ContainerCpus are %+v", perContainerCpus) for _, event := range events { + // Discard event containing system.total + if _, err := event.GetValue("system.total"); err == nil { + continue + } // setting ECS container.id containerFields := common.MapStr{} var cID string @@ -115,46 +121,47 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } } } - contCpus, ok := perContainerCpus[cID] - if !ok { - contCpus = 1 - } - // calculate system usage delta - systemUsageDelta := float64(systemTotalNs) - m.preSystemCpuUsage - - // Calculate cpu total usage percentage - cpuUsageTotal, err := event.GetValue("usage.total.ns") - if err == nil { - cpuUsageTotalPct := calcCpuTotalUsagePct(cpuUsageTotal.(float64), systemUsageDelta, - float64(contCpus), cID, m.preContainerCpuTotalUsage) - m.Logger().Infof("cpuUsageTotalPct for %+v is %+v", cID, cpuUsageTotalPct) - e.MetricSetFields.Put("usage.total.pct", cpuUsageTotalPct) - // Update values - m.preContainerCpuTotalUsage[cID] = cpuUsageTotal.(float64) - } + if m.calcPct { + contCpus, ok := perContainerCpus[cID] + if !ok { + contCpus = 1 + } + // calculate system usage delta + systemUsageDelta := float64(systemTotalNs) - m.preSystemCpuUsage - // Calculate cpu kernel usage percentage - cpuUsageKernel, err := event.GetValue("usage.kernel.ns") - if err == nil { - cpuUsageKernelPct := calcCpuKernelUsagePct(cpuUsageKernel.(float64), systemUsageDelta, - float64(contCpus), cID, m.preContainerCpuKernelUsage) - m.Logger().Infof("cpuUsageKernelPct for %+v is %+v", cID, cpuUsageKernelPct) - e.MetricSetFields.Put("usage.kernel.pct", cpuUsageKernelPct) - // Update values - m.preContainerCpuKernelUsage[cID] = cpuUsageKernel.(float64) - } + // Calculate cpu total usage percentage + cpuUsageTotal, err := event.GetValue("usage.total.ns") + if err == nil { + cpuUsageTotalPct := calcCpuTotalUsagePct(cpuUsageTotal.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuTotalUsage) + m.Logger().Debugf("cpuUsageTotalPct for %+v is %+v", cID, cpuUsageTotalPct) + e.MetricSetFields.Put("usage.total.pct", cpuUsageTotalPct) + // Update values + m.preContainerCpuTotalUsage[cID] = cpuUsageTotal.(float64) + } - // Calculate cpu user usage percentage - cpuUsageUser, err := event.GetValue("usage.user.ns") - if err == nil { - cpuUsageUserPct := calcCpuUserUsagePct(cpuUsageUser.(float64), systemUsageDelta, - float64(contCpus), cID, m.preContainerCpuUserUsage) - m.Logger().Infof("cpuUsageUserPct for %+v is %+v", cID, cpuUsageUserPct) - e.MetricSetFields.Put("usage.user.pct", cpuUsageUserPct) - // Update values - m.preContainerCpuUserUsage[cID] = cpuUsageUser.(float64) - } + // Calculate cpu kernel usage percentage + cpuUsageKernel, err := event.GetValue("usage.kernel.ns") + if err == nil { + cpuUsageKernelPct := calcCpuKernelUsagePct(cpuUsageKernel.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuKernelUsage) + m.Logger().Debugf("cpuUsageKernelPct for %+v is %+v", cID, cpuUsageKernelPct) + e.MetricSetFields.Put("usage.kernel.pct", cpuUsageKernelPct) + // Update values + m.preContainerCpuKernelUsage[cID] = cpuUsageKernel.(float64) + } + // Calculate cpu user usage percentage + cpuUsageUser, err := event.GetValue("usage.user.ns") + if err == nil { + cpuUsageUserPct := calcCpuUserUsagePct(cpuUsageUser.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuUserUsage) + m.Logger().Debugf("cpuUsageUserPct for %+v is %+v", cID, cpuUsageUserPct) + e.MetricSetFields.Put("usage.user.pct", cpuUsageUserPct) + // Update values + m.preContainerCpuUserUsage[cID] = cpuUsageUser.(float64) + } + } if cpuId, err := event.GetValue("cpu"); err == nil { perCpuNs, err := event.GetValue("usage.percpu.ns") if err == nil { From e7f700c705e9db1c6fd192f93de6052ef5108045 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Mon, 6 Dec 2021 15:45:34 +0200 Subject: [PATCH 08/37] Move containerd to xpack --- metricbeat/metricbeat.reference.yml | 8 -------- metricbeat/modules.d/containerd.yml.disabled | 9 --------- .../module/containerd/_meta/config.yml | 0 .../module/containerd/_meta/docs.asciidoc | 0 .../module/containerd/_meta/fields.yml | 0 .../metricbeat}/module/containerd/config.go | 0 .../module/containerd/cpu/_meta/data.json | 0 .../module/containerd/cpu/_meta/docs.asciidoc | 0 .../module/containerd/cpu/_meta/fields.yml | 0 .../metricbeat}/module/containerd/cpu/cpu.go | 0 .../module/containerd/cpu/metricset.go | 0 .../metricbeat}/module/containerd/doc.go | 0 .../metricbeat}/module/containerd/fields.go | 19 +++---------------- 13 files changed, 3 insertions(+), 33 deletions(-) delete mode 100644 metricbeat/modules.d/containerd.yml.disabled rename {metricbeat => x-pack/metricbeat}/module/containerd/_meta/config.yml (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/_meta/docs.asciidoc (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/_meta/fields.yml (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/config.go (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/cpu/_meta/data.json (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/cpu/_meta/docs.asciidoc (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/cpu/_meta/fields.yml (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/cpu/cpu.go (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/cpu/metricset.go (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/doc.go (100%) rename {metricbeat => x-pack/metricbeat}/module/containerd/fields.go (56%) diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 9b32966ce7c..7673d7b01b5 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -210,14 +210,6 @@ metricbeat.modules: hosts: ["localhost:8500"] -#------------------------------ Containerd Module ------------------------------ -- module: containerd - metricsets: ["cpu"] - enabled: false - period: 10s - hosts: ["localhost"] - - #------------------------------ Couchbase Module ------------------------------ - module: couchbase metricsets: ["bucket", "cluster", "node"] diff --git a/metricbeat/modules.d/containerd.yml.disabled b/metricbeat/modules.d/containerd.yml.disabled deleted file mode 100644 index 495e2792e2f..00000000000 --- a/metricbeat/modules.d/containerd.yml.disabled +++ /dev/null @@ -1,9 +0,0 @@ -# Module: containerd -# Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-containerd.html - -- module: containerd - metricsets: ["cpu"] - enabled: false - period: 10s - hosts: ["localhost"] - diff --git a/metricbeat/module/containerd/_meta/config.yml b/x-pack/metricbeat/module/containerd/_meta/config.yml similarity index 100% rename from metricbeat/module/containerd/_meta/config.yml rename to x-pack/metricbeat/module/containerd/_meta/config.yml diff --git a/metricbeat/module/containerd/_meta/docs.asciidoc b/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc similarity index 100% rename from metricbeat/module/containerd/_meta/docs.asciidoc rename to x-pack/metricbeat/module/containerd/_meta/docs.asciidoc diff --git a/metricbeat/module/containerd/_meta/fields.yml b/x-pack/metricbeat/module/containerd/_meta/fields.yml similarity index 100% rename from metricbeat/module/containerd/_meta/fields.yml rename to x-pack/metricbeat/module/containerd/_meta/fields.yml diff --git a/metricbeat/module/containerd/config.go b/x-pack/metricbeat/module/containerd/config.go similarity index 100% rename from metricbeat/module/containerd/config.go rename to x-pack/metricbeat/module/containerd/config.go diff --git a/metricbeat/module/containerd/cpu/_meta/data.json b/x-pack/metricbeat/module/containerd/cpu/_meta/data.json similarity index 100% rename from metricbeat/module/containerd/cpu/_meta/data.json rename to x-pack/metricbeat/module/containerd/cpu/_meta/data.json diff --git a/metricbeat/module/containerd/cpu/_meta/docs.asciidoc b/x-pack/metricbeat/module/containerd/cpu/_meta/docs.asciidoc similarity index 100% rename from metricbeat/module/containerd/cpu/_meta/docs.asciidoc rename to x-pack/metricbeat/module/containerd/cpu/_meta/docs.asciidoc diff --git a/metricbeat/module/containerd/cpu/_meta/fields.yml b/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml similarity index 100% rename from metricbeat/module/containerd/cpu/_meta/fields.yml rename to x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml diff --git a/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go similarity index 100% rename from metricbeat/module/containerd/cpu/cpu.go rename to x-pack/metricbeat/module/containerd/cpu/cpu.go diff --git a/metricbeat/module/containerd/cpu/metricset.go b/x-pack/metricbeat/module/containerd/cpu/metricset.go similarity index 100% rename from metricbeat/module/containerd/cpu/metricset.go rename to x-pack/metricbeat/module/containerd/cpu/metricset.go diff --git a/metricbeat/module/containerd/doc.go b/x-pack/metricbeat/module/containerd/doc.go similarity index 100% rename from metricbeat/module/containerd/doc.go rename to x-pack/metricbeat/module/containerd/doc.go diff --git a/metricbeat/module/containerd/fields.go b/x-pack/metricbeat/module/containerd/fields.go similarity index 56% rename from metricbeat/module/containerd/fields.go rename to x-pack/metricbeat/module/containerd/fields.go index 08edb57394d..6d10a08330e 100644 --- a/metricbeat/module/containerd/fields.go +++ b/x-pack/metricbeat/module/containerd/fields.go @@ -1,19 +1,6 @@ -// 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. +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. // Code generated by beats/dev-tools/cmd/asset/asset.go - DO NOT EDIT. From 3f48a7cf743a73f458650b3f0e54d7f7a7706a7e Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Mon, 6 Dec 2021 16:57:26 +0200 Subject: [PATCH 09/37] a --- x-pack/metricbeat/modules.d/containerd.yml.disabled | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 x-pack/metricbeat/modules.d/containerd.yml.disabled diff --git a/x-pack/metricbeat/modules.d/containerd.yml.disabled b/x-pack/metricbeat/modules.d/containerd.yml.disabled new file mode 100644 index 00000000000..e69de29bb2d From 4b90344bd8a1a9b5aefa39e11bc02f5237f82906 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Mon, 6 Dec 2021 17:03:42 +0200 Subject: [PATCH 10/37] list common --- .../docs/modules/containerd/cpu.asciidoc | 23 ------------------- metricbeat/include/list_common.go | 2 -- 2 files changed, 25 deletions(-) delete mode 100644 metricbeat/docs/modules/containerd/cpu.asciidoc diff --git a/metricbeat/docs/modules/containerd/cpu.asciidoc b/metricbeat/docs/modules/containerd/cpu.asciidoc deleted file mode 100644 index 6b661c5f6da..00000000000 --- a/metricbeat/docs/modules/containerd/cpu.asciidoc +++ /dev/null @@ -1,23 +0,0 @@ -//// -This file is generated! See scripts/mage/docs_collector.go -//// - -[[metricbeat-metricset-containerd-cpu]] -=== containerd cpu metricset - -beta[] - -include::../../../module/containerd/cpu/_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/containerd/cpu/_meta/data.json[] ----- diff --git a/metricbeat/include/list_common.go b/metricbeat/include/list_common.go index 2edf0588864..d57ebf4631d 100644 --- a/metricbeat/include/list_common.go +++ b/metricbeat/include/list_common.go @@ -44,8 +44,6 @@ import ( _ "github.com/elastic/beats/v7/metricbeat/module/ceph/pool_disk" _ "github.com/elastic/beats/v7/metricbeat/module/consul" _ "github.com/elastic/beats/v7/metricbeat/module/consul/agent" - _ "github.com/elastic/beats/v7/metricbeat/module/containerd" - _ "github.com/elastic/beats/v7/metricbeat/module/containerd/cpu" _ "github.com/elastic/beats/v7/metricbeat/module/couchbase" _ "github.com/elastic/beats/v7/metricbeat/module/couchbase/bucket" _ "github.com/elastic/beats/v7/metricbeat/module/couchbase/cluster" From e61077cd88806ec2d01ccd13d11b8f0a0647d54b Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Tue, 7 Dec 2021 11:26:49 +0200 Subject: [PATCH 11/37] Update --- metricbeat/docs/fields.asciidoc | 83 +++++++++++++++++-- metricbeat/docs/modules/containerd.asciidoc | 7 +- .../docs/modules/containerd/cpu.asciidoc | 24 ++++++ metricbeat/docs/modules_list.asciidoc | 2 +- x-pack/metricbeat/include/list.go | 2 + x-pack/metricbeat/metricbeat.reference.yml | 8 ++ .../module/containerd/cpu/_meta/fields.yml | 30 +++---- .../module/containerd/cpu/metricset.go | 2 +- x-pack/metricbeat/module/containerd/fields.go | 2 +- .../modules.d/containerd.yml.disabled | 9 ++ 10 files changed, 142 insertions(+), 27 deletions(-) create mode 100644 metricbeat/docs/modules/containerd/cpu.asciidoc diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 4aecd991158..811f8b2236d 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -10255,32 +10255,103 @@ type: long -- [[exported-fields-containerd]] -== containerd fields +== Containerd fields -containerd module +Containerd stats collected from containerd [float] === containerd +Information and statistics about containerd's running containers. [float] === cpu -cpu +Containerd Runtime CPU metrics. -*`containerd.cpu.example`*:: + + +*`containerd.cpu.usage.kernel.ns`*:: + -- -Example field +CPU Kernel usage nanoseconds -type: keyword +type: double + +-- + + +*`containerd.cpu.usage.user.ns`*:: ++ +-- +CPU User usage nanoseconds + + +type: double + +-- + + +*`containerd.cpu.usage.total.ns`*:: ++ +-- +CPU total usage nanoseconds + + +type: double + +-- + +*`containerd.cpu.usage.total.pct`*:: ++ +-- +Percentage of total CPU time normalized by the number of CPU cores + + +type: scaled_float + +format: percent + +-- + +*`containerd.cpu.usage.kernel.pct`*:: ++ +-- +Percentage of time in kernel space normalized by the number of CPU cores. + + +type: scaled_float + +format: percent + +-- + +*`containerd.cpu.usage.user.pct`*:: ++ +-- +Percentage of time in user space normalized by the number of CPU cores. + + +type: scaled_float + +format: percent + +-- + +*`containerd.cpu.usage.cpu.*.ns`*:: ++ +-- +CPU usage nanoseconds in this cpu. + + +type: object -- diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index 2b610c98ab2..d0c3fde955f 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -5,7 +5,8 @@ This file is generated! See scripts/mage/docs_collector.go :modulename: containerd [[metricbeat-module-containerd]] -== containerd module +[role="xpack"] +== Containerd module beta[] @@ -16,7 +17,7 @@ This is the containerd module. [float] === Example configuration -The containerd module supports the standard configuration options that are described +The Containerd module supports the standard configuration options that are described in <>. Here is an example configuration: [source,yaml] @@ -26,7 +27,7 @@ metricbeat.modules: metricsets: ["cpu"] enabled: false period: 10s - hosts: ["localhost"] + hosts: ["localhost:1338"] ---- diff --git a/metricbeat/docs/modules/containerd/cpu.asciidoc b/metricbeat/docs/modules/containerd/cpu.asciidoc new file mode 100644 index 00000000000..d964455ccd6 --- /dev/null +++ b/metricbeat/docs/modules/containerd/cpu.asciidoc @@ -0,0 +1,24 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-containerd-cpu]] +[role="xpack"] +=== Containerd cpu metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/containerd/cpu/_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::../../../../x-pack/metricbeat/module/containerd/cpu/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index 1f127a8e2b2..083b4353660 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -72,7 +72,7 @@ This file is generated! See scripts/mage/docs_collector.go .1+| .1+| |<> beta[] |<> beta[] |image:./images/icon-yes.png[Prebuilt dashboards are available] | .1+| .1+| |<> beta[] -|<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | +|<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | .1+| .1+| |<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | .1+| .1+| |<> diff --git a/x-pack/metricbeat/include/list.go b/x-pack/metricbeat/include/list.go index f06eed2652a..86c616e1c57 100644 --- a/x-pack/metricbeat/include/list.go +++ b/x-pack/metricbeat/include/list.go @@ -25,6 +25,8 @@ import ( _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/cloudfoundry/counter" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/cloudfoundry/value" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/cockroachdb" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd/cpu" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/coredns" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/coredns/stats" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/enterprisesearch" diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index be4adb144c8..6a38649141a 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -427,6 +427,14 @@ metricbeat.modules: hosts: ["localhost:8500"] +#------------------------------ Containerd Module ------------------------------ +- module: containerd + metricsets: ["cpu"] + enabled: false + period: 10s + hosts: ["localhost:1338"] + + #------------------------------- Coredns Module ------------------------------- - module: coredns metricsets: ["stats"] diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml b/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml index 3fe155abc44..46558d494e8 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml @@ -33,18 +33,18 @@ format: percent description: > Percentage of total CPU time normalized by the number of CPU cores - - name: kernel.pct - type: scaled_float - format: percent - description: > - Percentage of time in kernel space normalized by the number of CPU cores. - - name: user.pct - type: scaled_float - format: percent - description: > - Percentage of time in user space normalized by the number of CPU cores. - - name: cpu.*.ns - type: object - object_type: double - description: > - CPU usage nanoseconds in this cpu. + - name: kernel.pct + type: scaled_float + format: percent + description: > + Percentage of time in kernel space normalized by the number of CPU cores. + - name: user.pct + type: scaled_float + format: percent + description: > + Percentage of time in user space normalized by the number of CPU cores. + - name: cpu.*.ns + type: object + object_type: double + description: > + CPU usage nanoseconds in this cpu. diff --git a/x-pack/metricbeat/module/containerd/cpu/metricset.go b/x-pack/metricbeat/module/containerd/cpu/metricset.go index 4ba80a70c99..c4d32b835c9 100644 --- a/x-pack/metricbeat/module/containerd/cpu/metricset.go +++ b/x-pack/metricbeat/module/containerd/cpu/metricset.go @@ -20,7 +20,7 @@ package cpu import ( "fmt" - "github.com/elastic/beats/v7/metricbeat/module/containerd" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" diff --git a/x-pack/metricbeat/module/containerd/fields.go b/x-pack/metricbeat/module/containerd/fields.go index 6d10a08330e..0021e171c33 100644 --- a/x-pack/metricbeat/module/containerd/fields.go +++ b/x-pack/metricbeat/module/containerd/fields.go @@ -19,5 +19,5 @@ func init() { // AssetContainerd returns asset data. // This is the base64 encoded zlib format compressed contents of module/containerd. func AssetContainerd() string { - return "eJzUlLFu3DAMhnc/BZGlQIH4ATx0yVR0CQpkDmSJvqiRKUGkhuvTF7J9d7ZP9l2ADglHivz5fzToR3jHYwPakyhLGE0FIFYcNvDwdE4+VAARHSrGBloUVQEYZB1tEOupgR8VAMClAViUMGjvHGpBA130/XJKZ9EZbobGRyDV48pGDjkGbOAQfQpTpjA2x0/qfOxVToOicb5lsZpBtT7JTPobQ0xElg6XJNeT0tzVwllI51zJ1o611WZ+JxLbIzw9v0CPEq0+D8+xXvMp1sbm5hKrAy5etixuKc3V3jESuqvnPck92bk0cfH5JG18at0a5BQ7251HXuuvgWBcC5Aiz6g9mevhlwVi/MrAL4zxA7jiRX3pDzwAfBS4Dlo2oVkrh+a1c16VisafSwMBo0YqVdzh/nlszqZ9NzEMNPl3QHmCs3/RQHsEeUOg1LcYc2ku0j7iGnB5sUW+O+husd0kW3FlGkuTKeCg9J109QZevs5PBpct/Q80HVL9vS5czYjm2z9Y4B7Tr7s3dRMse7u6oMwmb5YHY9W/AAAA///L3w+i" + return "eJzUlLGO2zAMhnc/BXFLgQLnB/DQ5aaiy6FA5kCW6ESNTAkiNaRPX8h2Esex3QS4IeFIUj//jwb9Dgc8VqA9ibKE0RQAYsVhBW8f5+RbARDRoWKsoEZRBYBB1tEGsZ4q+FEAAFweAIsSBu2dQy1ooIm+vZ7SWHSGq+7hO5BqcWIjhxwDVrCLPoUhMzM2x09qfGxVToOifr5lsZpB1T7JSPobQ0xElnaXJJeD0tjVlbOQzrk5WyvWJpv5nUhsi/DxuYEWJVp9Hp5juuZTTI2NzSVWO7yqLFlcUhqrHTASupvymuSa7FiaeLZ8kjY+1W4KcoqV7Y4jr/VXR9CvBUiRZ9SezO3wywIxvjLwhjE+gCte1Et/4A7gUeAyaFmEZq0cmm3jvJpr6n8uFQSMGmmu4w73n/3jbNo3A0NHk38HlCc4+xcN1EeQPQKltsaYW3OT9hGXAfubfTbCzGVpMAcclL6Ts1y91CfFzNa+BlKHVH4vZ2+ph/T1H5zdQV/Y/ufa7kDMLm/uK1PK3nJnsPgXAAD//17UE2I=" } diff --git a/x-pack/metricbeat/modules.d/containerd.yml.disabled b/x-pack/metricbeat/modules.d/containerd.yml.disabled index e69de29bb2d..50543b7e035 100644 --- a/x-pack/metricbeat/modules.d/containerd.yml.disabled +++ b/x-pack/metricbeat/modules.d/containerd.yml.disabled @@ -0,0 +1,9 @@ +# Module: containerd +# Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-containerd.html + +- module: containerd + metricsets: ["cpu"] + enabled: false + period: 10s + hosts: ["localhost:1338"] + From 5e5ee78540e1935e6cc556f3531ccd6c39e0f7f5 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Tue, 7 Dec 2021 11:30:11 +0200 Subject: [PATCH 12/37] Fmt --- x-pack/metricbeat/module/containerd/config.go | 4 ++++ .../metricbeat/module/containerd/cpu/cpu.go | 19 +++---------------- .../module/containerd/cpu/metricset.go | 19 +++---------------- x-pack/metricbeat/module/containerd/doc.go | 19 +++---------------- 4 files changed, 13 insertions(+), 48 deletions(-) diff --git a/x-pack/metricbeat/module/containerd/config.go b/x-pack/metricbeat/module/containerd/config.go index 6e86ce8176a..26e2333ac7c 100644 --- a/x-pack/metricbeat/module/containerd/config.go +++ b/x-pack/metricbeat/module/containerd/config.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + package containerd // Config contains the config needed for containerd diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index de24dafb95e..f941a159226 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -1,19 +1,6 @@ -// 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. +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. package cpu diff --git a/x-pack/metricbeat/module/containerd/cpu/metricset.go b/x-pack/metricbeat/module/containerd/cpu/metricset.go index c4d32b835c9..052250ac495 100644 --- a/x-pack/metricbeat/module/containerd/cpu/metricset.go +++ b/x-pack/metricbeat/module/containerd/cpu/metricset.go @@ -1,19 +1,6 @@ -// 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. +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. package cpu diff --git a/x-pack/metricbeat/module/containerd/doc.go b/x-pack/metricbeat/module/containerd/doc.go index 6ce66eed2f9..27f4fcf9471 100644 --- a/x-pack/metricbeat/module/containerd/doc.go +++ b/x-pack/metricbeat/module/containerd/doc.go @@ -1,19 +1,6 @@ -// 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. +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. // Package containerd is a Metricbeat module that contains MetricSets. package containerd From 3ac6dca0fe3ab7b8b178e176cc2273080824c39a Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 8 Dec 2021 11:39:38 +0200 Subject: [PATCH 13/37] Add memory metricset --- .../module/containerd/_meta/config.yml | 3 +- x-pack/metricbeat/module/containerd/fields.go | 2 +- .../module/containerd/memory/_meta/data.json | 19 ++++ .../containerd/memory/_meta/docs.asciidoc | 1 + .../module/containerd/memory/_meta/fields.yml | 36 +++++++ .../module/containerd/memory/memory.go | 42 ++++++++ .../module/containerd/memory/metricset.go | 101 ++++++++++++++++++ .../modules.d/containerd.yml.disabled | 3 +- 8 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 x-pack/metricbeat/module/containerd/memory/_meta/data.json create mode 100644 x-pack/metricbeat/module/containerd/memory/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/containerd/memory/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/containerd/memory/memory.go create mode 100644 x-pack/metricbeat/module/containerd/memory/metricset.go diff --git a/x-pack/metricbeat/module/containerd/_meta/config.yml b/x-pack/metricbeat/module/containerd/_meta/config.yml index e50613a47e7..bca8282473f 100644 --- a/x-pack/metricbeat/module/containerd/_meta/config.yml +++ b/x-pack/metricbeat/module/containerd/_meta/config.yml @@ -1,6 +1,7 @@ - module: containerd - metricsets: ["cpu"] + metricsets: ["cpu", "memory"] enabled: false period: 10s hosts: ["localhost:1338"] + calcpct: true diff --git a/x-pack/metricbeat/module/containerd/fields.go b/x-pack/metricbeat/module/containerd/fields.go index 0021e171c33..c765424e8c8 100644 --- a/x-pack/metricbeat/module/containerd/fields.go +++ b/x-pack/metricbeat/module/containerd/fields.go @@ -19,5 +19,5 @@ func init() { // AssetContainerd returns asset data. // This is the base64 encoded zlib format compressed contents of module/containerd. func AssetContainerd() string { - return "eJzUlLGO2zAMhnc/BXFLgQLnB/DQ5aaiy6FA5kCW6ESNTAkiNaRPX8h2Esex3QS4IeFIUj//jwb9Dgc8VqA9ibKE0RQAYsVhBW8f5+RbARDRoWKsoEZRBYBB1tEGsZ4q+FEAAFweAIsSBu2dQy1ooIm+vZ7SWHSGq+7hO5BqcWIjhxwDVrCLPoUhMzM2x09qfGxVToOifr5lsZpB1T7JSPobQ0xElnaXJJeD0tjVlbOQzrk5WyvWJpv5nUhsi/DxuYEWJVp9Hp5juuZTTI2NzSVWO7yqLFlcUhqrHTASupvymuSa7FiaeLZ8kjY+1W4KcoqV7Y4jr/VXR9CvBUiRZ9SezO3wywIxvjLwhjE+gCte1Et/4A7gUeAyaFmEZq0cmm3jvJpr6n8uFQSMGmmu4w73n/3jbNo3A0NHk38HlCc4+xcN1EeQPQKltsaYW3OT9hGXAfubfTbCzGVpMAcclL6Ts1y91CfFzNa+BlKHVH4vZ2+ph/T1H5zdQV/Y/ufa7kDMLm/uK1PK3nJnsPgXAAD//17UE2I=" + return "eJzUls1u2zAMx+95CqKXAQPqB/Bhl56GIUAxLOdClplUq0QZEg3Ue/pBkp04/pBToMNaHvVB/v7/iGbu4QW7EqQlForQ1TsAVqyxhLuH8+LdDsChRuGxhApZ7ABq9NKphpWlEr7tAAAuF8CzYA/Sao2SsYajs+a6ylGhrn0ZL94DCYMTjBDcNVjCydm26VcWyob4TkfrjAjLICjVV56V9CAq2/Io9RcPriVSdLos+qLPNKa6Imva89oSVgZt4szPllgZhIfHAxhkp+S5eIipzUNMwcZwrRcnvNpZQ1zLNM72go5Qz7ZzKXNpx6nJL24PqWvbVnoqZIiMu+MItv6ICpItQIKsR2mpnhe/GIjuMws+eHRvkMuWxaf+gaOAtwouGsmror0UGuuno7Zi6VD6uJTQoJNISyduoH9MlwO0PfYaoprwOaBQQas/WEPVAT8jUGsqdOFoOCStw3WBqWc/msKgS1EPB74R8kadRbZTP6jMgPY+ImXTFl+LxV5KIm31Gxc9SBtPG912g8RAOeuvoJKflY+AsxFp0FjXbU7JtQGXgZplzg1DrYyaWpNItKXTdBb2z6HqeNZdGy7tI1QqV7zDWN4od4g/RnIi/buavp+tuW7E6+qDWrBmy54bmEPsxetAHf1Yf/X/u6v3I8ohUxY4P0b/naW/4uS4NvVvAAAA//9ZFOcy" } diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/data.json b/x-pack/metricbeat/module/containerd/memory/_meta/data.json new file mode 100644 index 00000000000..61cd69542da --- /dev/null +++ b/x-pack/metricbeat/module/containerd/memory/_meta/data.json @@ -0,0 +1,19 @@ +{ + "@timestamp":"2016-05-23T08:05:34.853Z", + "beat":{ + "hostname":"beathost", + "name":"beathost" + }, + "metricset":{ + "host":"localhost", + "module":"containerd", + "name":"memory", + "rtt":44269 + }, + "containerd":{ + "memory":{ + "example": "memory" + } + }, + "type":"metricsets" +} diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/docs.asciidoc b/x-pack/metricbeat/module/containerd/memory/_meta/docs.asciidoc new file mode 100644 index 00000000000..64ce9bf9023 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/memory/_meta/docs.asciidoc @@ -0,0 +1 @@ +This is the memory metricset of the module containerd. diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml b/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml new file mode 100644 index 00000000000..6744e712dda --- /dev/null +++ b/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml @@ -0,0 +1,36 @@ +- name: memory + type: group + release: beta + description: > + memory + fields: + - name: limit + type: long + format: bytes + description: > + Memory limit. + - name: usage + type: group + description: > + Usage memory stats. + fields: + - name: max + type: long + format: bytes + description: > + Max memory usage. + - name: pct + type: scaled_float + format: percent + description: > + Memory usage percentage. + - name: total + type: long + format: bytes + description: > + Total memory usage. + - name: inactiveFiles + type: long + format: bytes + description: > + Total inactive files. diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go new file mode 100644 index 00000000000..2c3ca356e9c --- /dev/null +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -0,0 +1,42 @@ +package memory + +import ( + "github.com/elastic/beats/v7/metricbeat/helper/prometheus" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/metricbeat/mb/parse" +) + +const ( + defaultScheme = "http" + defaultPath = "/v1/metrics" +) + +var ( + // HostParser validates Prometheus URLs + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() +) + +// 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() { + // Mapping of state metrics + mapping := &prometheus.MetricsMapping{ + Metrics: map[string]prometheus.MetricMap{ + "container_memory_usage_max_bytes": prometheus.Metric("usage.max"), + "container_memory_usage_usage_bytes": prometheus.Metric("usage.total"), + "container_memory_total_inactive_file_bytes": prometheus.Metric("usage.inactiveFiles"), + "container_memory_usage_limit_bytes": prometheus.Metric("limit"), + }, + Labels: map[string]prometheus.LabelMap{ + "container_id": prometheus.KeyLabel("id"), + }, + } + + mb.Registry.MustAddMetricSet("containerd", "memory", + getMetricsetFactory(mapping), + mb.WithHostParser(hostParser), + ) +} diff --git a/x-pack/metricbeat/module/containerd/memory/metricset.go b/x-pack/metricbeat/module/containerd/memory/metricset.go new file mode 100644 index 00000000000..1b97b7e2a4c --- /dev/null +++ b/x-pack/metricbeat/module/containerd/memory/metricset.go @@ -0,0 +1,101 @@ +package memory + +import ( + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" + + "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/metricbeat/helper/prometheus" + "github.com/elastic/beats/v7/metricbeat/mb" +) + +// Metricset for apiserver is a prometheus based metricset +type metricset struct { + mb.BaseMetricSet + prometheusClient prometheus.Prometheus + prometheusMappings *prometheus.MetricsMapping + calcPct bool +} + +var _ mb.ReportingMetricSetV2Error = (*metricset)(nil) + +// getMetricsetFactory as required by` mb.Registry.MustAddMetricSet` +func getMetricsetFactory(prometheusMappings *prometheus.MetricsMapping) mb.MetricSetFactory { + return func(base mb.BaseMetricSet) (mb.MetricSet, error) { + pc, err := prometheus.NewPrometheusClient(base) + if err != nil { + return nil, err + } + config := containerd.DefaultConfig() + if err := base.Module().UnpackConfig(&config); err != nil { + return nil, err + } + return &metricset{ + BaseMetricSet: base, + prometheusClient: pc, + prometheusMappings: prometheusMappings, + calcPct: config.CalculatePct, + }, nil + } +} + +// Fetch gathers information from the containerd and reports events with this information. +func (m *metricset) Fetch(reporter mb.ReporterV2) error { + events, err := m.prometheusClient.GetProcessedMetrics(m.prometheusMappings) + if err != nil { + return errors.Wrap(err, "error getting metrics") + } + + for _, event := range events { + + // setting ECS container.id + containerFields := common.MapStr{} + var cID string + if containerID, ok := event["id"]; ok { + cID = (containerID).(string) + containerFields.Put("id", cID) + event.Delete("id") + } + e, err := util.CreateEvent(event, "containerd.memory") + if err != nil { + m.Logger().Error(err) + } + + if len(containerFields) > 0 { + if e.RootFields != nil { + e.RootFields.DeepUpdate(common.MapStr{ + "container": containerFields, + }) + } else { + e.RootFields = common.MapStr{ + "container": containerFields, + } + } + } + + // Calculate memory total usage percentage + if m.calcPct { + inactiveFiles, err := event.GetValue("usage.inactiveFiles") + if err == nil { + usageTotal, err := event.GetValue("usage.total") + if err == nil { + memoryLimit, err := event.GetValue("limit") + if err == nil { + usage := usageTotal.(float64) - inactiveFiles.(float64) + memoryUsagePct := usage / memoryLimit.(float64) + e.MetricSetFields.Put("usage.pct", memoryUsagePct) + m.Logger().Debugf("memoryUsagePct for %+v is %+v", cID, memoryUsagePct) + } + } + } + } + + if reported := reporter.Event(e); !reported { + return nil + } + } + return nil +} diff --git a/x-pack/metricbeat/modules.d/containerd.yml.disabled b/x-pack/metricbeat/modules.d/containerd.yml.disabled index 50543b7e035..800797b2f17 100644 --- a/x-pack/metricbeat/modules.d/containerd.yml.disabled +++ b/x-pack/metricbeat/modules.d/containerd.yml.disabled @@ -2,8 +2,9 @@ # Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-containerd.html - module: containerd - metricsets: ["cpu"] + metricsets: ["cpu", "memory"] enabled: false period: 10s hosts: ["localhost:1338"] + calcpct: true From 5be637e0cdd090d5d33bc655f244bc4d8db29e63 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 8 Dec 2021 15:37:32 +0200 Subject: [PATCH 14/37] Add more memory fields --- x-pack/metricbeat/module/containerd/fields.go | 2 +- .../module/containerd/memory/_meta/fields.yml | 76 ++++++++++++++++++- .../module/containerd/memory/memory.go | 16 +++- .../module/containerd/memory/metricset.go | 4 +- 4 files changed, 89 insertions(+), 9 deletions(-) diff --git a/x-pack/metricbeat/module/containerd/fields.go b/x-pack/metricbeat/module/containerd/fields.go index c765424e8c8..f1bd24f1381 100644 --- a/x-pack/metricbeat/module/containerd/fields.go +++ b/x-pack/metricbeat/module/containerd/fields.go @@ -19,5 +19,5 @@ func init() { // AssetContainerd returns asset data. // This is the base64 encoded zlib format compressed contents of module/containerd. func AssetContainerd() string { - return "eJzUls1u2zAMx+95CqKXAQPqB/Bhl56GIUAxLOdClplUq0QZEg3Ue/pBkp04/pBToMNaHvVB/v7/iGbu4QW7EqQlForQ1TsAVqyxhLuH8+LdDsChRuGxhApZ7ABq9NKphpWlEr7tAAAuF8CzYA/Sao2SsYajs+a6ylGhrn0ZL94DCYMTjBDcNVjCydm26VcWyob4TkfrjAjLICjVV56V9CAq2/Io9RcPriVSdLos+qLPNKa6Imva89oSVgZt4szPllgZhIfHAxhkp+S5eIipzUNMwcZwrRcnvNpZQ1zLNM72go5Qz7ZzKXNpx6nJL24PqWvbVnoqZIiMu+MItv6ICpItQIKsR2mpnhe/GIjuMws+eHRvkMuWxaf+gaOAtwouGsmror0UGuuno7Zi6VD6uJTQoJNISyduoH9MlwO0PfYaoprwOaBQQas/WEPVAT8jUGsqdOFoOCStw3WBqWc/msKgS1EPB74R8kadRbZTP6jMgPY+ImXTFl+LxV5KIm31Gxc9SBtPG912g8RAOeuvoJKflY+AsxFp0FjXbU7JtQGXgZplzg1DrYyaWpNItKXTdBb2z6HqeNZdGy7tI1QqV7zDWN4od4g/RnIi/buavp+tuW7E6+qDWrBmy54bmEPsxetAHf1Yf/X/u6v3I8ohUxY4P0b/naW/4uS4NvVvAAAA//9ZFOcy" + return "eJzUl99q2zAUxu/zFIfeDAb1A/hiN4XCGIWyrddFlo9TrbJkpOO16dMPSXbi2PKflIU4upTtc37fF32ScguvuEuBa0VMKDT5BoAESUzh5m4/ebMBMCiRWUwhQ2IbgBwtN6IioVUK3zYAAIcPwBIjC1xLiZwwh8Lo8rhLIVDmNvUf3oJiJfYw3KBdhSlsja6rZibS1o3vqtCmZG4amAr9hSXBLbBM19Qp/cWCqZUSanuYtElTqUt1RFbV+7kY1gRaz5mftSJRItw9PkGJZATfN3ejb3M7+mBduNqyLR49GUMcq9St9opGoRw8nio5VbZbWtno47Z0rutM9oW0Y8Ld7nC2/vAKgi2gmNIWuVb5sPnBQDTXLPjJojlBLmliV/0DewGnCk4qTqOiLWcS8+dCahZ7KWwuKVRoOKrYGwvoH8PHDloXjQavxm0HynWQ4gNzyHZALwiqLjM07lX3EtcGxwWGzK5NodMlVAMHtmJ8oc5kMqkrlenQ/o9IXtXJ1ySapSBSZ38w6kF48DyTtgUSHeUgX04lvQjrAQdHZImlNrvZU3LsgJuAGlSeOgyN7fsWOKRW2/5J2CyGbEeDbM149NunN4CBQStyVAQWCaz4wCRKxjiJv3gv5KDZ+QhDTyiExFAkjsYZf4nfIM4B5btN4Qh1Ca/arrNunXbfmun95FPWrCR/be5vDHMXtpK9j+4UEZ/mvFrA7MYDe2+pvR/j29mlt+uHDmVbaRJ4+n50PkuPNpUZUwsmZMJ1HTVlkbcLgO6ZkOCboBlHkaIU4xRnXIHd39VDxOMa/UPz6bw2fy6uL7At+OLcXioGDSitLQ0NV7HqUBwvz4lU2DfWX/mfzsSvN1ZdYSIC9urz4DFXlwZPte4sdJdlLwmbfwEAAP//syQPHQ==" } diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml b/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml index 6744e712dda..38da0567ec0 100644 --- a/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml +++ b/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml @@ -4,11 +4,26 @@ description: > memory fields: - - name: limit + - name: rss type: long format: bytes description: > - Memory limit. + Total memory resident set size. + - name: activeFiles + type: long + format: bytes + description: > + Total active file bytes. + - name: cache + type: long + format: bytes + description: > + Total cache bytes. + - name: inactiveFiles + type: long + format: bytes + description: > + Total inactive file bytes. - name: usage type: group description: > @@ -29,8 +44,61 @@ format: bytes description: > Total memory usage. - - name: inactiveFiles + - name: fail.count + type: scaled_float + description: > + Fail counter. + - name: limit + type: long + format: bytes + description: > + Memory usage limit. + - name: kernel + type: group + description: > + Kernel memory stats. + fields: + - name: max + type: long + format: bytes + description: > + Kernel max memory usage. + - name: total + type: long + format: bytes + description: > + Kernel total memory usage. + - name: fail.count + type: scaled_float + description: > + Kernel fail counter. + - name: limit + type: long + format: bytes + description: > + Kernel memory limit. + - name: swap + type: group + description: > + Swap memory stats. + fields: + - name: max + type: long + format: bytes + description: > + Swap max memory usage. + - name: total + type: long + format: bytes + description: > + Swap total memory usage. + - name: fail.count + type: scaled_float + description: > + Swap fail counter. + - name: limit type: long format: bytes description: > - Total inactive files. + Swap memory limit. + diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 2c3ca356e9c..3040763d705 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -27,8 +27,20 @@ func init() { Metrics: map[string]prometheus.MetricMap{ "container_memory_usage_max_bytes": prometheus.Metric("usage.max"), "container_memory_usage_usage_bytes": prometheus.Metric("usage.total"), - "container_memory_total_inactive_file_bytes": prometheus.Metric("usage.inactiveFiles"), - "container_memory_usage_limit_bytes": prometheus.Metric("limit"), + "container_memory_usage_limit_bytes": prometheus.Metric("usage.limit"), + "container_memory_usage_failcnt_total": prometheus.Metric("usage.fail.count"), + "container_memory_kernel_max_bytes": prometheus.Metric("kernel.max"), + "container_memory_kernel_usage_bytes": prometheus.Metric("kernel.total"), + "container_memory_kernel_limit_bytes": prometheus.Metric("kernel.limit"), + "container_memory_kernel_failcnt_total": prometheus.Metric("kernel.fail.count"), + "container_memory_swap_max_bytes": prometheus.Metric("swap.max"), + "container_memory_swap_usage_bytes": prometheus.Metric("swap.total"), + "container_memory_swap_limit_bytes": prometheus.Metric("swap.limit"), + "container_memory_swap_failcnt_total": prometheus.Metric("swap.fail.count"), + "container_memory_total_inactive_file_bytes": prometheus.Metric("inactiveFiles"), + "container_memory_total_active_file_bytes": prometheus.Metric("activeFiles"), + "container_memory_total_cache_bytes": prometheus.Metric("cache"), + "container_memory_total_rss_bytes": prometheus.Metric("rss"), }, Labels: map[string]prometheus.LabelMap{ "container_id": prometheus.KeyLabel("id"), diff --git a/x-pack/metricbeat/module/containerd/memory/metricset.go b/x-pack/metricbeat/module/containerd/memory/metricset.go index 1b97b7e2a4c..1d137e85f58 100644 --- a/x-pack/metricbeat/module/containerd/memory/metricset.go +++ b/x-pack/metricbeat/module/containerd/memory/metricset.go @@ -78,11 +78,11 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { // Calculate memory total usage percentage if m.calcPct { - inactiveFiles, err := event.GetValue("usage.inactiveFiles") + inactiveFiles, err := event.GetValue("inactiveFiles") if err == nil { usageTotal, err := event.GetValue("usage.total") if err == nil { - memoryLimit, err := event.GetValue("limit") + memoryLimit, err := event.GetValue("usage.limit") if err == nil { usage := usageTotal.(float64) - inactiveFiles.(float64) memoryUsagePct := usage / memoryLimit.(float64) From 10ab5ce99563ee0da0dce6c63b24a5cc5183412b Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 9 Dec 2021 13:02:13 +0200 Subject: [PATCH 15/37] Add blkio metricset --- .../module/containerd/_meta/config.yml | 2 +- .../module/containerd/blkio/_meta/data.json | 19 ++ .../containerd/blkio/_meta/docs.asciidoc | 1 + .../module/containerd/blkio/_meta/fields.yml | 49 ++++ .../module/containerd/blkio/blkio.go | 111 ++++++++ .../metricbeat/module/containerd/cpu/cpu.go | 195 +++++++++++++- .../module/containerd/cpu/metricset.go | 243 ------------------ x-pack/metricbeat/module/containerd/fields.go | 2 +- .../module/containerd/memory/memory.go | 97 ++++++- .../module/containerd/memory/metricset.go | 101 -------- .../modules.d/containerd.yml.disabled | 2 +- 11 files changed, 461 insertions(+), 361 deletions(-) create mode 100644 x-pack/metricbeat/module/containerd/blkio/_meta/data.json create mode 100644 x-pack/metricbeat/module/containerd/blkio/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/containerd/blkio/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/containerd/blkio/blkio.go delete mode 100644 x-pack/metricbeat/module/containerd/cpu/metricset.go delete mode 100644 x-pack/metricbeat/module/containerd/memory/metricset.go diff --git a/x-pack/metricbeat/module/containerd/_meta/config.yml b/x-pack/metricbeat/module/containerd/_meta/config.yml index bca8282473f..b69056ab085 100644 --- a/x-pack/metricbeat/module/containerd/_meta/config.yml +++ b/x-pack/metricbeat/module/containerd/_meta/config.yml @@ -1,5 +1,5 @@ - module: containerd - metricsets: ["cpu", "memory"] + metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s hosts: ["localhost:1338"] diff --git a/x-pack/metricbeat/module/containerd/blkio/_meta/data.json b/x-pack/metricbeat/module/containerd/blkio/_meta/data.json new file mode 100644 index 00000000000..67209b7c3f9 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/blkio/_meta/data.json @@ -0,0 +1,19 @@ +{ + "@timestamp":"2016-05-23T08:05:34.853Z", + "beat":{ + "hostname":"beathost", + "name":"beathost" + }, + "metricset":{ + "host":"localhost", + "module":"containerd", + "name":"blkio", + "rtt":44269 + }, + "containerd":{ + "blkio":{ + "example": "blkio" + } + }, + "type":"metricsets" +} diff --git a/x-pack/metricbeat/module/containerd/blkio/_meta/docs.asciidoc b/x-pack/metricbeat/module/containerd/blkio/_meta/docs.asciidoc new file mode 100644 index 00000000000..4faa70acb6d --- /dev/null +++ b/x-pack/metricbeat/module/containerd/blkio/_meta/docs.asciidoc @@ -0,0 +1 @@ +This is the blkio metricset of the module containerd. diff --git a/x-pack/metricbeat/module/containerd/blkio/_meta/fields.yml b/x-pack/metricbeat/module/containerd/blkio/_meta/fields.yml new file mode 100644 index 00000000000..adcd4228888 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/blkio/_meta/fields.yml @@ -0,0 +1,49 @@ +- name: blkio + type: group + release: beta + description: > + Block I/O metrics. + fields: + - name: read + type: group + description: > + Accumulated reads during the life of the container + fields: + - name: ops + type: long + description: > + Number of reads during the life of the container + - name: bytes + type: long + format: bytes + description: > + Bytes read during the life of the container + - name: write + type: group + description: > + Accumulated writes during the life of the container + fields: + - name: ops + type: long + description: > + Number of writes during the life of the container + - name: bytes + type: long + format: bytes + description: > + Bytes written during the life of the container + - name: summary + type: group + description: > + Accumulated reads and writes during the life of the container + fields: + - name: ops + type: long + description: > + Number of I/O operations during the life of the container + - name: bytes + type: long + format: bytes + description: > + Bytes read and written during the life of the container + diff --git a/x-pack/metricbeat/module/containerd/blkio/blkio.go b/x-pack/metricbeat/module/containerd/blkio/blkio.go new file mode 100644 index 00000000000..2252ac85ff6 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/blkio/blkio.go @@ -0,0 +1,111 @@ +package blkio + +import ( + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/metricbeat/helper/prometheus" + "github.com/elastic/beats/v7/metricbeat/mb" + "github.com/elastic/beats/v7/metricbeat/mb/parse" +) + +const ( + defaultScheme = "http" + defaultPath = "/v1/metrics" +) + +var ( + // HostParser validates Prometheus URLs + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() + + // Mapping of state metrics + mapping = &prometheus.MetricsMapping{ + Metrics: map[string]prometheus.MetricMap{ + "container_blkio_io_serviced_recursive_total": prometheus.Metric("", prometheus.OpFilterMap( + "op", map[string]string{ + "Read": "read.ops", + "Write": "write.ops", + "Total": "summary.ops", + }, + )), + "container_blkio_io_service_bytes_recursive_bytes": prometheus.Metric("", prometheus.OpFilterMap( + "op", map[string]string{ + "Read": "read.bytes", + "Write": "write.bytes", + "Total": "summary.bytes", + }, + )), + }, + Labels: map[string]prometheus.LabelMap{ + "container_id": prometheus.KeyLabel("id"), + "device": prometheus.KeyLabel("device"), + }, + } +) + +// Metricset for containerd blkio is a prometheus based metricset +type metricset struct { + mb.BaseMetricSet + prometheusClient prometheus.Prometheus +} + +// 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() { + mb.Registry.MustAddMetricSet("containerd", "blkio", New, + mb.WithHostParser(hostParser), + mb.DefaultMetricSet(), + ) +} + +// 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) { + cfgwarn.Beta("The containerd blkio metricset is beta.") + + pc, err := prometheus.NewPrometheusClient(base) + if err != nil { + return nil, err + } + + return &metricset{ + BaseMetricSet: base, + prometheusClient: pc, + }, nil +} + +// Fetch gathers information from the containerd and reports events with this information. +func (m *metricset) Fetch(reporter mb.ReporterV2) error { + events, err := m.prometheusClient.GetProcessedMetrics(mapping) + if err != nil { + return errors.Wrap(err, "error getting metrics") + } + for _, event := range events { + + // setting ECS container.id + rootFields := common.MapStr{} + containerFields := common.MapStr{} + var cID string + if containerID, ok := event["id"]; ok { + cID = (containerID).(string) + containerFields.Put("id", cID) + event.Delete("id") + } + + if len(containerFields) > 0 { + rootFields.Put("container", containerFields) + } + + reporter.Event(mb.Event{ + RootFields: rootFields, + MetricSetFields: event, + Namespace: "containerd.blkio", + }) + } + return nil +} diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index f941a159226..ace9780f330 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -5,9 +5,17 @@ package cpu import ( + "fmt" + + "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" ) const ( @@ -21,13 +29,9 @@ var ( DefaultScheme: defaultScheme, DefaultPath: defaultPath, }.Build() -) -// 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() { // Mapping of state metrics - mapping := &prometheus.MetricsMapping{ + mapping = &prometheus.MetricsMapping{ Metrics: map[string]prometheus.MetricMap{ "container_cpu_total_nanoseconds": prometheus.Metric("usage.total.ns"), "container_cpu_user_nanoseconds": prometheus.Metric("usage.user.ns"), @@ -40,9 +44,186 @@ func init() { "cpu": prometheus.KeyLabel("cpu"), }, } +) - mb.Registry.MustAddMetricSet("containerd", "cpu", - getMetricsetFactory(mapping), +// Metricset for containerd is a prometheus based metricset +type metricset struct { + mb.BaseMetricSet + prometheusClient prometheus.Prometheus + calcPct bool + preSystemCpuUsage float64 + preContainerCpuTotalUsage map[string]float64 + preContainerCpuKernelUsage map[string]float64 + preContainerCpuUserUsage map[string]float64 +} + +// 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() { + mb.Registry.MustAddMetricSet("containerd", "cpu", New, mb.WithHostParser(hostParser), + mb.DefaultMetricSet(), ) } + +// 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) { + cfgwarn.Beta("The containerd cpu metricset is beta.") + + pc, err := prometheus.NewPrometheusClient(base) + if err != nil { + return nil, err + } + config := containerd.DefaultConfig() + if err := base.Module().UnpackConfig(&config); err != nil { + return nil, err + } + + return &metricset{ + BaseMetricSet: base, + prometheusClient: pc, + calcPct: config.CalculatePct, + preSystemCpuUsage: 0.0, + preContainerCpuTotalUsage: map[string]float64{}, + preContainerCpuKernelUsage: map[string]float64{}, + preContainerCpuUserUsage: map[string]float64{}, + }, nil +} + +// Fetch gathers information from the containerd and reports events with this information. +func (m *metricset) Fetch(reporter mb.ReporterV2) error { + events, err := m.prometheusClient.GetProcessedMetrics(mapping) + if err != nil { + return errors.Wrap(err, "error getting metrics") + } + + var systemTotalNs int64 + perContainerCpus := make(map[string]int) + + if m.calcPct { + for _, event := range events { + systemTotalSeconds, err := event.GetValue("system.total") + if err == nil { + systemTotalNs = systemTotalSeconds.(int64) * 1e9 + } + if _, err = event.GetValue("cpu"); err == nil { + // calculate cpus used by each container + setContCpus(event, perContainerCpus) + } + } + } + + for _, event := range events { + // Discard event containing system.total + if _, err := event.GetValue("system.total"); err == nil { + continue + } + // setting ECS container.id + + rootFields := common.MapStr{} + containerFields := common.MapStr{} + var cID string + if containerID, ok := event["id"]; ok { + cID = (containerID).(string) + containerFields.Put("id", cID) + event.Delete("id") + } + + if len(containerFields) > 0 { + rootFields.Put("container", containerFields) + } + if m.calcPct { + contCpus, ok := perContainerCpus[cID] + if !ok { + contCpus = 1 + } + // calculate system usage delta + systemUsageDelta := float64(systemTotalNs) - m.preSystemCpuUsage + + // Calculate cpu total usage percentage + cpuUsageTotal, err := event.GetValue("usage.total.ns") + if err == nil { + cpuUsageTotalPct := calcUsagePct(cpuUsageTotal.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuTotalUsage) + m.Logger().Debugf("cpuUsageTotalPct for %+v is %+v", cID, cpuUsageTotalPct) + event.Put("usage.total.pct", cpuUsageTotalPct) + // Update values + m.preContainerCpuTotalUsage[cID] = cpuUsageTotal.(float64) + } + + // Calculate cpu kernel usage percentage + cpuUsageKernel, err := event.GetValue("usage.kernel.ns") + if err == nil { + cpuUsageKernelPct := calcUsagePct(cpuUsageKernel.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuKernelUsage) + m.Logger().Debugf("cpuUsageKernelPct for %+v is %+v", cID, cpuUsageKernelPct) + event.Put("usage.kernel.pct", cpuUsageKernelPct) + // Update values + m.preContainerCpuKernelUsage[cID] = cpuUsageKernel.(float64) + } + + // Calculate cpu user usage percentage + cpuUsageUser, err := event.GetValue("usage.user.ns") + if err == nil { + cpuUsageUserPct := calcUsagePct(cpuUsageUser.(float64), systemUsageDelta, + float64(contCpus), cID, m.preContainerCpuUserUsage) + m.Logger().Debugf("cpuUsageUserPct for %+v is %+v", cID, cpuUsageUserPct) + event.Put("usage.user.pct", cpuUsageUserPct) + // Update values + m.preContainerCpuUserUsage[cID] = cpuUsageUser.(float64) + } + } + if cpuId, err := event.GetValue("cpu"); err == nil { + perCpuNs, err := event.GetValue("usage.percpu.ns") + if err == nil { + key := fmt.Sprintf("usage.cpu.%s.ns", cpuId) + event.Put(key, perCpuNs) + event.Delete("cpu") + event.Delete("usage.percpu.ns") + } + } + + reporter.Event(mb.Event{ + RootFields: rootFields, + MetricSetFields: event, + Namespace: "containerd.cpu", + }) + } + m.preSystemCpuUsage = float64(systemTotalNs) + return nil +} + +func setContCpus(event common.MapStr, perContainerCpus map[string]int) { + val, err := event.GetValue("id") + if err != nil { + return + } + cid := val.(string) + _, err = event.GetValue("usage.percpu.ns") + if err != nil { + return + } + if _, ok := perContainerCpus[cid]; ok { + perContainerCpus[cid] += 1 + } else { + perContainerCpus[cid] = 1 + } +} + +func calcUsagePct(newValue, systemUsageDelta, contCpus float64, + cid string, oldValuesMap map[string]float64) float64 { + var usageDelta, usagePct float64 + if oldValue, ok := oldValuesMap[cid]; ok { + usageDelta = newValue - oldValue + } else { + usageDelta = newValue + } + if usageDelta == 0.0 || systemUsageDelta == 0.0 { + usagePct = 0.0 + } else { + // normalize percentage with cpus used per container + usagePct = (usageDelta / systemUsageDelta) / contCpus + } + return usagePct +} diff --git a/x-pack/metricbeat/module/containerd/cpu/metricset.go b/x-pack/metricbeat/module/containerd/cpu/metricset.go deleted file mode 100644 index 052250ac495..00000000000 --- a/x-pack/metricbeat/module/containerd/cpu/metricset.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package cpu - -import ( - "fmt" - - "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" - - "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" - - "github.com/pkg/errors" - - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/metricbeat/helper/prometheus" - "github.com/elastic/beats/v7/metricbeat/mb" -) - -// Metricset for apiserver is a prometheus based metricset -type metricset struct { - mb.BaseMetricSet - prometheusClient prometheus.Prometheus - prometheusMappings *prometheus.MetricsMapping - calcPct bool - preSystemCpuUsage float64 - preContainerCpuTotalUsage map[string]float64 - preContainerCpuKernelUsage map[string]float64 - preContainerCpuUserUsage map[string]float64 -} - -var _ mb.ReportingMetricSetV2Error = (*metricset)(nil) - -// getMetricsetFactory as required by` mb.Registry.MustAddMetricSet` -func getMetricsetFactory(prometheusMappings *prometheus.MetricsMapping) mb.MetricSetFactory { - return func(base mb.BaseMetricSet) (mb.MetricSet, error) { - pc, err := prometheus.NewPrometheusClient(base) - if err != nil { - return nil, err - } - config := containerd.DefaultConfig() - if err := base.Module().UnpackConfig(&config); err != nil { - return nil, err - } - return &metricset{ - BaseMetricSet: base, - prometheusClient: pc, - prometheusMappings: prometheusMappings, - calcPct: config.CalculatePct, - preSystemCpuUsage: 0.0, - preContainerCpuTotalUsage: map[string]float64{}, - preContainerCpuKernelUsage: map[string]float64{}, - preContainerCpuUserUsage: map[string]float64{}, - }, nil - } -} - -// Fetch gathers information from the containerd and reports events with this information. -func (m *metricset) Fetch(reporter mb.ReporterV2) error { - events, err := m.prometheusClient.GetProcessedMetrics(m.prometheusMappings) - if err != nil { - return errors.Wrap(err, "error getting metrics") - } - - var systemTotalNs int64 - perContainerCpus := make(map[string]int) - - if m.calcPct { - for _, event := range events { - systemTotalSeconds, err := event.GetValue("system.total") - if err == nil { - systemTotalNs = systemTotalSeconds.(int64) * 1e9 - } - if _, err = event.GetValue("cpu"); err == nil { - // calculate cpus used by each container - setContCpus(event, perContainerCpus) - } - } - } - - for _, event := range events { - // Discard event containing system.total - if _, err := event.GetValue("system.total"); err == nil { - continue - } - // setting ECS container.id - containerFields := common.MapStr{} - var cID string - if containerID, ok := event["id"]; ok { - cID = (containerID).(string) - containerFields.Put("id", cID) - event.Delete("id") - } - e, err := util.CreateEvent(event, "containerd.cpu") - if err != nil { - m.Logger().Error(err) - } - - if len(containerFields) > 0 { - if e.RootFields != nil { - e.RootFields.DeepUpdate(common.MapStr{ - "container": containerFields, - }) - } else { - e.RootFields = common.MapStr{ - "container": containerFields, - } - } - } - if m.calcPct { - contCpus, ok := perContainerCpus[cID] - if !ok { - contCpus = 1 - } - // calculate system usage delta - systemUsageDelta := float64(systemTotalNs) - m.preSystemCpuUsage - - // Calculate cpu total usage percentage - cpuUsageTotal, err := event.GetValue("usage.total.ns") - if err == nil { - cpuUsageTotalPct := calcCpuTotalUsagePct(cpuUsageTotal.(float64), systemUsageDelta, - float64(contCpus), cID, m.preContainerCpuTotalUsage) - m.Logger().Debugf("cpuUsageTotalPct for %+v is %+v", cID, cpuUsageTotalPct) - e.MetricSetFields.Put("usage.total.pct", cpuUsageTotalPct) - // Update values - m.preContainerCpuTotalUsage[cID] = cpuUsageTotal.(float64) - } - - // Calculate cpu kernel usage percentage - cpuUsageKernel, err := event.GetValue("usage.kernel.ns") - if err == nil { - cpuUsageKernelPct := calcCpuKernelUsagePct(cpuUsageKernel.(float64), systemUsageDelta, - float64(contCpus), cID, m.preContainerCpuKernelUsage) - m.Logger().Debugf("cpuUsageKernelPct for %+v is %+v", cID, cpuUsageKernelPct) - e.MetricSetFields.Put("usage.kernel.pct", cpuUsageKernelPct) - // Update values - m.preContainerCpuKernelUsage[cID] = cpuUsageKernel.(float64) - } - - // Calculate cpu user usage percentage - cpuUsageUser, err := event.GetValue("usage.user.ns") - if err == nil { - cpuUsageUserPct := calcCpuUserUsagePct(cpuUsageUser.(float64), systemUsageDelta, - float64(contCpus), cID, m.preContainerCpuUserUsage) - m.Logger().Debugf("cpuUsageUserPct for %+v is %+v", cID, cpuUsageUserPct) - e.MetricSetFields.Put("usage.user.pct", cpuUsageUserPct) - // Update values - m.preContainerCpuUserUsage[cID] = cpuUsageUser.(float64) - } - } - if cpuId, err := event.GetValue("cpu"); err == nil { - perCpuNs, err := event.GetValue("usage.percpu.ns") - if err == nil { - key := fmt.Sprintf("usage.cpu.%s.ns", cpuId) - e.MetricSetFields.Put(key, perCpuNs) - e.MetricSetFields.Delete("cpu") - e.MetricSetFields.Delete("usage.percpu.ns") - } - } - - if reported := reporter.Event(e); !reported { - return nil - } - } - m.preSystemCpuUsage = float64(systemTotalNs) - return nil -} - -func setContCpus(event common.MapStr, perContainerCpus map[string]int) { - val, err := event.GetValue("id") - if err != nil { - return - } - cid := val.(string) - _, err = event.GetValue("usage.percpu.ns") - if err != nil { - return - } - if _, ok := perContainerCpus[cid]; ok { - perContainerCpus[cid] += 1 - } else { - perContainerCpus[cid] = 1 - } - //if percpu.(float64) != 0.0 { - // if _, ok := perContainerCpus[cid]; ok { - // perContainerCpus[cid] += 1 - // } else { - // perContainerCpus[cid] = 1 - // } - //} -} - -func calcCpuTotalUsagePct(cpuUsageTotal, systemUsageDelta, contCpus float64, - cid string, preContainerCpuTotalUsage map[string]float64) float64 { - var contUsageDelta, cpuUsageTotalPct float64 - if cpuPreval, ok := preContainerCpuTotalUsage[cid]; ok { - contUsageDelta = cpuUsageTotal - cpuPreval - } else { - contUsageDelta = cpuUsageTotal - } - if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { - cpuUsageTotalPct = 0.0 - } else { - // normalize percentage with cpus used per container - cpuUsageTotalPct = (contUsageDelta / systemUsageDelta) / contCpus - } - return cpuUsageTotalPct -} - -func calcCpuKernelUsagePct(cpuUsageKernel, systemUsageDelta, contCpus float64, - cid string, preContainerCpuKernelUsage map[string]float64) float64 { - var contUsageDelta, cpuUsageKernelPct float64 - if cpuPreval, ok := preContainerCpuKernelUsage[cid]; ok { - contUsageDelta = cpuUsageKernel - cpuPreval - } else { - contUsageDelta = cpuUsageKernel - } - if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { - cpuUsageKernelPct = 0.0 - } else { - // normalize percentage with cpus used per container - cpuUsageKernelPct = (contUsageDelta / systemUsageDelta) / contCpus - } - return cpuUsageKernelPct -} - -func calcCpuUserUsagePct(cpuUsageUser, systemUsageDelta, contCpus float64, - cid string, preContainerCpuUserUsage map[string]float64) float64 { - var contUsageDelta, cpuUsageUserPct float64 - if cpuPreval, ok := preContainerCpuUserUsage[cid]; ok { - contUsageDelta = cpuUsageUser - cpuPreval - } else { - contUsageDelta = cpuUsageUser - } - if contUsageDelta == 0.0 || systemUsageDelta == 0.0 { - cpuUsageUserPct = 0.0 - } else { - // normalize percentage with cpus used per container - cpuUsageUserPct = (contUsageDelta / systemUsageDelta) / contCpus - } - return cpuUsageUserPct -} diff --git a/x-pack/metricbeat/module/containerd/fields.go b/x-pack/metricbeat/module/containerd/fields.go index f1bd24f1381..feb306a36f0 100644 --- a/x-pack/metricbeat/module/containerd/fields.go +++ b/x-pack/metricbeat/module/containerd/fields.go @@ -19,5 +19,5 @@ func init() { // AssetContainerd returns asset data. // This is the base64 encoded zlib format compressed contents of module/containerd. func AssetContainerd() string { - return "eJzUl99q2zAUxu/zFIfeDAb1A/hiN4XCGIWyrddFlo9TrbJkpOO16dMPSXbi2PKflIU4upTtc37fF32ScguvuEuBa0VMKDT5BoAESUzh5m4/ebMBMCiRWUwhQ2IbgBwtN6IioVUK3zYAAIcPwBIjC1xLiZwwh8Lo8rhLIVDmNvUf3oJiJfYw3KBdhSlsja6rZibS1o3vqtCmZG4amAr9hSXBLbBM19Qp/cWCqZUSanuYtElTqUt1RFbV+7kY1gRaz5mftSJRItw9PkGJZATfN3ejb3M7+mBduNqyLR49GUMcq9St9opGoRw8nio5VbZbWtno47Z0rutM9oW0Y8Ld7nC2/vAKgi2gmNIWuVb5sPnBQDTXLPjJojlBLmliV/0DewGnCk4qTqOiLWcS8+dCahZ7KWwuKVRoOKrYGwvoH8PHDloXjQavxm0HynWQ4gNzyHZALwiqLjM07lX3EtcGxwWGzK5NodMlVAMHtmJ8oc5kMqkrlenQ/o9IXtXJ1ySapSBSZ38w6kF48DyTtgUSHeUgX04lvQjrAQdHZImlNrvZU3LsgJuAGlSeOgyN7fsWOKRW2/5J2CyGbEeDbM149NunN4CBQStyVAQWCaz4wCRKxjiJv3gv5KDZ+QhDTyiExFAkjsYZf4nfIM4B5btN4Qh1Ca/arrNunXbfmun95FPWrCR/be5vDHMXtpK9j+4UEZ/mvFrA7MYDe2+pvR/j29mlt+uHDmVbaRJ4+n50PkuPNpUZUwsmZMJ1HTVlkbcLgO6ZkOCboBlHkaIU4xRnXIHd39VDxOMa/UPz6bw2fy6uL7At+OLcXioGDSitLQ0NV7HqUBwvz4lU2DfWX/mfzsSvN1ZdYSIC9urz4DFXlwZPte4sdJdlLwmbfwEAAP//syQPHQ==" + return "eJzUmEtv2zAMx+/5FEQvAwY0u+cwYC1QoBi6Fdt6LmSZTrXoYeixNv30g2Q7cWz5kaBBbJ0C2SJ/pPin5FzDBrcroEpawiTqdAFgmeW4gqvb3eTVAkAjR2JwBQlasgBI0VDNcsuUXMHXBQDAfgEYS6wBqjhHajGFTCtx6CVjyFOzCguvQRKBDQw/7DbHFay1cnk5E3Hrx73MlBbETwORhX9mLKMGSKKcrZn+ZEA7KZlc7yfNsrRUp6qTJXzD1G42BuZHM0fV6ID244YruoH7Lz9BoNWM7khiNHUijSQ9eNAFNQDgxzdKnXCc+J3ydg2kTvsE2RcEzjIElYXfu4Q1TMRA67AqN61nFS9Xch15OIDsxw8nEtSe7STo2u5uLR4NWBRc9+IRAdz4pQH+OPaK+1Uzi+cogmB4dlVwGvVUysDTW5SnVYJxQhC9PV9D8E11nlXhe6vKUYfDYbbVEZpEtQlHlUnrLKO5GzzJerhqp/wvJy0TCLePT7Hjq+s47DvWnCHr8S1tqLY2qCXyzk2LmewzWzctY9u5N50ql/BmINUYset++LR+DxEUaQFJpDJIlUzbzvcJjNTwjAJ+MqiPCNcqS2a9wSGAYwNe5tR2Bm0o4Zg+Z1yR2EtVS8pRU5SxN0bQPxaLPbRvPCGGEI1vB9J74OwdU0i2oSvJXTf2L1GlI83wULNTi9DHxWQJByYndGScy16lTjRMj/YxQdLcLT8vo1oqglTJX4zmoHjwPKC2ESF6ypa+fJT2hZkA2DoiBQp1cJv6sO+9luXebzzTzFvnZaPvojGQoz9BvQUYaDQsRWnBoAXD3nEZJSPUsn94x3jL2fkIC5+QMY6FkTgaJfQlfoM4B1Tw1ofD5CVyVXkdzNZx960B309BZWUlhb+Amo1h6MImyNsFrtgP5K2iDvnobmeXbtcPNcrKUi9w//3ofCk9aCoDSc0I40uqXDQpo3I7AuiOMA7BCepuFM4E66Y4YwXW9zVAxOUa/aA5Wa/lx8X8BFuBj9btpWRQgtqpqaHkyiYtisPy7FGFeSXNyj9ZE79fST5DRRTYk9dDwJycGgLVtLVQL8uGEhb/AwAA///GKMXX" } diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 3040763d705..b0ef9348650 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -1,9 +1,15 @@ package memory import ( + "github.com/pkg/errors" + + "github.com/elastic/beats/v7/libbeat/common/cfgwarn" + + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" ) const ( @@ -17,13 +23,9 @@ var ( DefaultScheme: defaultScheme, DefaultPath: defaultPath, }.Build() -) -// 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() { // Mapping of state metrics - mapping := &prometheus.MetricsMapping{ + mapping = &prometheus.MetricsMapping{ Metrics: map[string]prometheus.MetricMap{ "container_memory_usage_max_bytes": prometheus.Metric("usage.max"), "container_memory_usage_usage_bytes": prometheus.Metric("usage.total"), @@ -46,9 +48,90 @@ func init() { "container_id": prometheus.KeyLabel("id"), }, } +) - mb.Registry.MustAddMetricSet("containerd", "memory", - getMetricsetFactory(mapping), +// Metricset for containerd memory is a prometheus based metricset +type metricset struct { + mb.BaseMetricSet + prometheusClient prometheus.Prometheus + calcPct bool +} + +// 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() { + mb.Registry.MustAddMetricSet("containerd", "memory", New, mb.WithHostParser(hostParser), + mb.DefaultMetricSet(), ) } + +// 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) { + cfgwarn.Beta("The containerd cpu metricset is beta.") + + pc, err := prometheus.NewPrometheusClient(base) + if err != nil { + return nil, err + } + config := containerd.DefaultConfig() + if err := base.Module().UnpackConfig(&config); err != nil { + return nil, err + } + + return &metricset{ + BaseMetricSet: base, + prometheusClient: pc, + calcPct: config.CalculatePct, + }, nil +} + +// Fetch gathers information from the containerd and reports events with this information. +func (m *metricset) Fetch(reporter mb.ReporterV2) error { + events, err := m.prometheusClient.GetProcessedMetrics(mapping) + if err != nil { + return errors.Wrap(err, "error getting metrics") + } + + for _, event := range events { + + // setting ECS container.id + rootFields := common.MapStr{} + containerFields := common.MapStr{} + var cID string + if containerID, ok := event["id"]; ok { + cID = (containerID).(string) + containerFields.Put("id", cID) + event.Delete("id") + } + + if len(containerFields) > 0 { + rootFields.Put("container", containerFields) + } + + // Calculate memory total usage percentage + if m.calcPct { + inactiveFiles, err := event.GetValue("inactiveFiles") + if err == nil { + usageTotal, err := event.GetValue("usage.total") + if err == nil { + memoryLimit, err := event.GetValue("usage.limit") + if err == nil { + usage := usageTotal.(float64) - inactiveFiles.(float64) + memoryUsagePct := usage / memoryLimit.(float64) + event.Put("usage.pct", memoryUsagePct) + m.Logger().Debugf("memoryUsagePct for %+v is %+v", cID, memoryUsagePct) + } + } + } + } + + reporter.Event(mb.Event{ + RootFields: rootFields, + MetricSetFields: event, + Namespace: "containerd.memory", + }) + } + return nil +} diff --git a/x-pack/metricbeat/module/containerd/memory/metricset.go b/x-pack/metricbeat/module/containerd/memory/metricset.go deleted file mode 100644 index 1d137e85f58..00000000000 --- a/x-pack/metricbeat/module/containerd/memory/metricset.go +++ /dev/null @@ -1,101 +0,0 @@ -package memory - -import ( - "github.com/pkg/errors" - - "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" - - "github.com/elastic/beats/v7/metricbeat/module/kubernetes/util" - - "github.com/elastic/beats/v7/libbeat/common" - "github.com/elastic/beats/v7/metricbeat/helper/prometheus" - "github.com/elastic/beats/v7/metricbeat/mb" -) - -// Metricset for apiserver is a prometheus based metricset -type metricset struct { - mb.BaseMetricSet - prometheusClient prometheus.Prometheus - prometheusMappings *prometheus.MetricsMapping - calcPct bool -} - -var _ mb.ReportingMetricSetV2Error = (*metricset)(nil) - -// getMetricsetFactory as required by` mb.Registry.MustAddMetricSet` -func getMetricsetFactory(prometheusMappings *prometheus.MetricsMapping) mb.MetricSetFactory { - return func(base mb.BaseMetricSet) (mb.MetricSet, error) { - pc, err := prometheus.NewPrometheusClient(base) - if err != nil { - return nil, err - } - config := containerd.DefaultConfig() - if err := base.Module().UnpackConfig(&config); err != nil { - return nil, err - } - return &metricset{ - BaseMetricSet: base, - prometheusClient: pc, - prometheusMappings: prometheusMappings, - calcPct: config.CalculatePct, - }, nil - } -} - -// Fetch gathers information from the containerd and reports events with this information. -func (m *metricset) Fetch(reporter mb.ReporterV2) error { - events, err := m.prometheusClient.GetProcessedMetrics(m.prometheusMappings) - if err != nil { - return errors.Wrap(err, "error getting metrics") - } - - for _, event := range events { - - // setting ECS container.id - containerFields := common.MapStr{} - var cID string - if containerID, ok := event["id"]; ok { - cID = (containerID).(string) - containerFields.Put("id", cID) - event.Delete("id") - } - e, err := util.CreateEvent(event, "containerd.memory") - if err != nil { - m.Logger().Error(err) - } - - if len(containerFields) > 0 { - if e.RootFields != nil { - e.RootFields.DeepUpdate(common.MapStr{ - "container": containerFields, - }) - } else { - e.RootFields = common.MapStr{ - "container": containerFields, - } - } - } - - // Calculate memory total usage percentage - if m.calcPct { - inactiveFiles, err := event.GetValue("inactiveFiles") - if err == nil { - usageTotal, err := event.GetValue("usage.total") - if err == nil { - memoryLimit, err := event.GetValue("usage.limit") - if err == nil { - usage := usageTotal.(float64) - inactiveFiles.(float64) - memoryUsagePct := usage / memoryLimit.(float64) - e.MetricSetFields.Put("usage.pct", memoryUsagePct) - m.Logger().Debugf("memoryUsagePct for %+v is %+v", cID, memoryUsagePct) - } - } - } - } - - if reported := reporter.Event(e); !reported { - return nil - } - } - return nil -} diff --git a/x-pack/metricbeat/modules.d/containerd.yml.disabled b/x-pack/metricbeat/modules.d/containerd.yml.disabled index 800797b2f17..de854afdf15 100644 --- a/x-pack/metricbeat/modules.d/containerd.yml.disabled +++ b/x-pack/metricbeat/modules.d/containerd.yml.disabled @@ -2,7 +2,7 @@ # Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-containerd.html - module: containerd - metricsets: ["cpu", "memory"] + metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s hosts: ["localhost:1338"] From cf1243e7ae8fdaac0f137424597cebd7091dd738 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 9 Dec 2021 17:50:39 +0200 Subject: [PATCH 16/37] format code --- x-pack/metricbeat/module/containerd/blkio/blkio.go | 4 ++++ x-pack/metricbeat/module/containerd/memory/memory.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/x-pack/metricbeat/module/containerd/blkio/blkio.go b/x-pack/metricbeat/module/containerd/blkio/blkio.go index 2252ac85ff6..65458605875 100644 --- a/x-pack/metricbeat/module/containerd/blkio/blkio.go +++ b/x-pack/metricbeat/module/containerd/blkio/blkio.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + package blkio import ( diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index b0ef9348650..0d1f7ac3027 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + package memory import ( From de9b9a88f1929e01612f5a27e0d22ab5f9e2895d Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Tue, 14 Dec 2021 15:38:37 +0200 Subject: [PATCH 17/37] Add cache for containerd metrics --- .../module/containerd/blkio/blkio.go | 18 ++- .../module/containerd/containerd.go | 112 ++++++++++++++++++ .../metricbeat/module/containerd/cpu/cpu.go | 19 ++- .../module/containerd/memory/memory.go | 16 ++- 4 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 x-pack/metricbeat/module/containerd/containerd.go diff --git a/x-pack/metricbeat/module/containerd/blkio/blkio.go b/x-pack/metricbeat/module/containerd/blkio/blkio.go index 65458605875..e7623bc8442 100644 --- a/x-pack/metricbeat/module/containerd/blkio/blkio.go +++ b/x-pack/metricbeat/module/containerd/blkio/blkio.go @@ -5,8 +5,12 @@ package blkio import ( + "fmt" + "github.com/pkg/errors" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" + "github.com/elastic/beats/v7/libbeat/common/cfgwarn" "github.com/elastic/beats/v7/libbeat/common" @@ -56,6 +60,7 @@ var ( type metricset struct { mb.BaseMetricSet prometheusClient prometheus.Prometheus + mod containerd.Module } // init registers the MetricSet with the central registry. @@ -77,17 +82,26 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { return nil, err } + mod, ok := base.Module().(containerd.Module) + if !ok { + return nil, fmt.Errorf("must be child of kubernetes module") + } return &metricset{ BaseMetricSet: base, prometheusClient: pc, + mod: mod, }, nil } // Fetch gathers information from the containerd and reports events with this information. func (m *metricset) Fetch(reporter mb.ReporterV2) error { - events, err := m.prometheusClient.GetProcessedMetrics(mapping) + families, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) + if err != nil { + return errors.Wrap(err, "error getting families") + } + events, err := m.prometheusClient.ProcessMetrics(families, mapping) if err != nil { - return errors.Wrap(err, "error getting metrics") + return errors.Wrap(err, "error getting events") } for _, event := range events { diff --git a/x-pack/metricbeat/module/containerd/containerd.go b/x-pack/metricbeat/module/containerd/containerd.go new file mode 100644 index 00000000000..c846847b882 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/containerd.go @@ -0,0 +1,112 @@ +package containerd + +import ( + "sync" + "time" + + "github.com/mitchellh/hashstructure" + "github.com/pkg/errors" + dto "github.com/prometheus/client_model/go" + + p "github.com/elastic/beats/v7/metricbeat/helper/prometheus" + "github.com/elastic/beats/v7/metricbeat/mb" +) + +// 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. + +func init() { + // Register the ModuleFactory function for the "containerd" module. + if err := mb.Registry.AddModule("containerd", ModuleBuilder()); err != nil { + panic(err) + } +} + +type Module interface { + mb.Module + GetContainerdMetricsFamilies(prometheus p.Prometheus) ([]*dto.MetricFamily, error) +} + +type familiesCache struct { + sharedFamilies []*dto.MetricFamily + lastFetchErr error + lastFetchTimestamp time.Time +} + +type containerdMetricsCache struct { + cacheMap map[uint64]*familiesCache + lock sync.Mutex +} + +func (c *containerdMetricsCache) getCacheMapEntry(hash uint64) *familiesCache { + if _, ok := c.cacheMap[hash]; !ok { + c.cacheMap[hash] = &familiesCache{} + } + return c.cacheMap[hash] +} + +type module struct { + mb.BaseModule + + containerdMetricsCache *containerdMetricsCache + cacheHash uint64 +} + +func ModuleBuilder() func(base mb.BaseModule) (mb.Module, error) { + containerdMetricsCache := &containerdMetricsCache{ + cacheMap: make(map[uint64]*familiesCache), + } + + return func(base mb.BaseModule) (mb.Module, error) { + hash, err := generateCacheHash(base.Config().Hosts) + if err != nil { + return nil, errors.Wrap(err, "error generating cache hash for containerdMetricsCache") + } + m := module{ + BaseModule: base, + containerdMetricsCache: containerdMetricsCache, + cacheHash: hash, + } + return &m, nil + } +} + +func (m *module) GetContainerdMetricsFamilies(prometheus p.Prometheus) ([]*dto.MetricFamily, error) { + m.containerdMetricsCache.lock.Lock() + defer m.containerdMetricsCache.lock.Unlock() + + now := time.Now() + // NOTE: These entries will be never removed, this can be a leak if + // metricbeat is used to monitor clusters dynamically created. + // (https://github.com/elastic/beats/pull/25640#discussion_r633395213) + familiesCache := m.containerdMetricsCache.getCacheMapEntry(m.cacheHash) + + if familiesCache.lastFetchTimestamp.IsZero() || now.Sub(familiesCache.lastFetchTimestamp) > m.Config().Period { + familiesCache.sharedFamilies, familiesCache.lastFetchErr = prometheus.GetFamilies() + familiesCache.lastFetchTimestamp = now + } + + return familiesCache.sharedFamilies, familiesCache.lastFetchErr +} + +func generateCacheHash(host []string) (uint64, error) { + id, err := hashstructure.Hash(host, nil) + if err != nil { + return 0, err + } + return id, nil +} diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index ace9780f330..611e026aae9 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -7,6 +7,8 @@ package cpu import ( "fmt" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" + "github.com/elastic/beats/v7/libbeat/common/cfgwarn" "github.com/pkg/errors" @@ -15,7 +17,6 @@ import ( "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" - "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" ) const ( @@ -50,6 +51,7 @@ var ( type metricset struct { mb.BaseMetricSet prometheusClient prometheus.Prometheus + mod containerd.Module calcPct bool preSystemCpuUsage float64 preContainerCpuTotalUsage map[string]float64 @@ -79,10 +81,14 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { if err := base.Module().UnpackConfig(&config); err != nil { return nil, err } - + mod, ok := base.Module().(containerd.Module) + if !ok { + return nil, fmt.Errorf("must be child of kubernetes module") + } return &metricset{ BaseMetricSet: base, prometheusClient: pc, + mod: mod, calcPct: config.CalculatePct, preSystemCpuUsage: 0.0, preContainerCpuTotalUsage: map[string]float64{}, @@ -93,9 +99,14 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // Fetch gathers information from the containerd and reports events with this information. func (m *metricset) Fetch(reporter mb.ReporterV2) error { - events, err := m.prometheusClient.GetProcessedMetrics(mapping) + families, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) + if err != nil { + return errors.Wrap(err, "error getting families") + } + + events, err := m.prometheusClient.ProcessMetrics(families, mapping) if err != nil { - return errors.Wrap(err, "error getting metrics") + return errors.Wrap(err, "error getting events") } var systemTotalNs int64 diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 0d1f7ac3027..3ba1132dbf0 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -5,6 +5,8 @@ package memory import ( + "fmt" + "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" @@ -58,6 +60,7 @@ var ( type metricset struct { mb.BaseMetricSet prometheusClient prometheus.Prometheus + mod containerd.Module calcPct bool } @@ -84,18 +87,27 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { return nil, err } + mod, ok := base.Module().(containerd.Module) + if !ok { + return nil, fmt.Errorf("must be child of kubernetes module") + } return &metricset{ BaseMetricSet: base, prometheusClient: pc, + mod: mod, calcPct: config.CalculatePct, }, nil } // Fetch gathers information from the containerd and reports events with this information. func (m *metricset) Fetch(reporter mb.ReporterV2) error { - events, err := m.prometheusClient.GetProcessedMetrics(mapping) + families, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) + if err != nil { + return errors.Wrap(err, "error getting families") + } + events, err := m.prometheusClient.ProcessMetrics(families, mapping) if err != nil { - return errors.Wrap(err, "error getting metrics") + return errors.Wrap(err, "error getting events") } for _, event := range events { From 578736a2299732f89c5339f3075204b70299bcc5 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 15 Dec 2021 14:28:40 +0200 Subject: [PATCH 18/37] Update method of cpu percentage calculation --- .../module/containerd/blkio/blkio.go | 2 +- .../module/containerd/containerd.go | 6 +-- .../module/containerd/cpu/_meta/fields.yml | 4 ++ .../metricbeat/module/containerd/cpu/cpu.go | 38 +++++++------------ .../module/containerd/memory/memory.go | 2 +- 5 files changed, 23 insertions(+), 29 deletions(-) diff --git a/x-pack/metricbeat/module/containerd/blkio/blkio.go b/x-pack/metricbeat/module/containerd/blkio/blkio.go index e7623bc8442..2519ddee36a 100644 --- a/x-pack/metricbeat/module/containerd/blkio/blkio.go +++ b/x-pack/metricbeat/module/containerd/blkio/blkio.go @@ -95,7 +95,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // Fetch gathers information from the containerd and reports events with this information. func (m *metricset) Fetch(reporter mb.ReporterV2) error { - families, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) + families, _, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) if err != nil { return errors.Wrap(err, "error getting families") } diff --git a/x-pack/metricbeat/module/containerd/containerd.go b/x-pack/metricbeat/module/containerd/containerd.go index c846847b882..e613bf563bc 100644 --- a/x-pack/metricbeat/module/containerd/containerd.go +++ b/x-pack/metricbeat/module/containerd/containerd.go @@ -38,7 +38,7 @@ func init() { type Module interface { mb.Module - GetContainerdMetricsFamilies(prometheus p.Prometheus) ([]*dto.MetricFamily, error) + GetContainerdMetricsFamilies(prometheus p.Prometheus) ([]*dto.MetricFamily, time.Time, error) } type familiesCache struct { @@ -85,7 +85,7 @@ func ModuleBuilder() func(base mb.BaseModule) (mb.Module, error) { } } -func (m *module) GetContainerdMetricsFamilies(prometheus p.Prometheus) ([]*dto.MetricFamily, error) { +func (m *module) GetContainerdMetricsFamilies(prometheus p.Prometheus) ([]*dto.MetricFamily, time.Time, error) { m.containerdMetricsCache.lock.Lock() defer m.containerdMetricsCache.lock.Unlock() @@ -100,7 +100,7 @@ func (m *module) GetContainerdMetricsFamilies(prometheus p.Prometheus) ([]*dto.M familiesCache.lastFetchTimestamp = now } - return familiesCache.sharedFamilies, familiesCache.lastFetchErr + return familiesCache.sharedFamilies, familiesCache.lastFetchTimestamp, familiesCache.lastFetchErr } func generateCacheHash(host []string) (uint64, error) { diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml b/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml index 46558d494e8..81459e4ebf0 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml @@ -4,6 +4,10 @@ Containerd Runtime CPU metrics. release: beta fields: + - name: system.total + type: double + description: > + Total user and system CPU time spent in seconds. - name: usage type: group fields: diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index 611e026aae9..46011558dbc 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -6,6 +6,7 @@ package cpu import ( "fmt" + "time" "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" @@ -53,7 +54,7 @@ type metricset struct { prometheusClient prometheus.Prometheus mod containerd.Module calcPct bool - preSystemCpuUsage float64 + preTimestamp time.Time preContainerCpuTotalUsage map[string]float64 preContainerCpuKernelUsage map[string]float64 preContainerCpuUserUsage map[string]float64 @@ -90,7 +91,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { prometheusClient: pc, mod: mod, calcPct: config.CalculatePct, - preSystemCpuUsage: 0.0, + preTimestamp: time.Time{}, preContainerCpuTotalUsage: map[string]float64{}, preContainerCpuKernelUsage: map[string]float64{}, preContainerCpuUserUsage: map[string]float64{}, @@ -99,7 +100,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // Fetch gathers information from the containerd and reports events with this information. func (m *metricset) Fetch(reporter mb.ReporterV2) error { - families, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) + families, timestamp, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) if err != nil { return errors.Wrap(err, "error getting families") } @@ -109,15 +110,10 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { return errors.Wrap(err, "error getting events") } - var systemTotalNs int64 perContainerCpus := make(map[string]int) if m.calcPct { for _, event := range events { - systemTotalSeconds, err := event.GetValue("system.total") - if err == nil { - systemTotalNs = systemTotalSeconds.(int64) * 1e9 - } if _, err = event.GetValue("cpu"); err == nil { // calculate cpus used by each container setContCpus(event, perContainerCpus) @@ -126,12 +122,7 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } for _, event := range events { - // Discard event containing system.total - if _, err := event.GetValue("system.total"); err == nil { - continue - } // setting ECS container.id - rootFields := common.MapStr{} containerFields := common.MapStr{} var cID string @@ -140,7 +131,6 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { containerFields.Put("id", cID) event.Delete("id") } - if len(containerFields) > 0 { rootFields.Put("container", containerFields) } @@ -149,13 +139,12 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { if !ok { contCpus = 1 } - // calculate system usage delta - systemUsageDelta := float64(systemTotalNs) - m.preSystemCpuUsage - + // calculate timestamp delta + timestampDelta := timestamp.UnixNano() - m.preTimestamp.UnixNano() // Calculate cpu total usage percentage cpuUsageTotal, err := event.GetValue("usage.total.ns") if err == nil { - cpuUsageTotalPct := calcUsagePct(cpuUsageTotal.(float64), systemUsageDelta, + cpuUsageTotalPct := calcUsagePct(timestampDelta, cpuUsageTotal.(float64), float64(contCpus), cID, m.preContainerCpuTotalUsage) m.Logger().Debugf("cpuUsageTotalPct for %+v is %+v", cID, cpuUsageTotalPct) event.Put("usage.total.pct", cpuUsageTotalPct) @@ -166,7 +155,7 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { // Calculate cpu kernel usage percentage cpuUsageKernel, err := event.GetValue("usage.kernel.ns") if err == nil { - cpuUsageKernelPct := calcUsagePct(cpuUsageKernel.(float64), systemUsageDelta, + cpuUsageKernelPct := calcUsagePct(timestampDelta, cpuUsageKernel.(float64), float64(contCpus), cID, m.preContainerCpuKernelUsage) m.Logger().Debugf("cpuUsageKernelPct for %+v is %+v", cID, cpuUsageKernelPct) event.Put("usage.kernel.pct", cpuUsageKernelPct) @@ -177,7 +166,7 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { // Calculate cpu user usage percentage cpuUsageUser, err := event.GetValue("usage.user.ns") if err == nil { - cpuUsageUserPct := calcUsagePct(cpuUsageUser.(float64), systemUsageDelta, + cpuUsageUserPct := calcUsagePct(timestampDelta, cpuUsageUser.(float64), float64(contCpus), cID, m.preContainerCpuUserUsage) m.Logger().Debugf("cpuUsageUserPct for %+v is %+v", cID, cpuUsageUserPct) event.Put("usage.user.pct", cpuUsageUserPct) @@ -201,7 +190,8 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { Namespace: "containerd.cpu", }) } - m.preSystemCpuUsage = float64(systemTotalNs) + // set Timestamp of previous event + m.preTimestamp = timestamp return nil } @@ -222,7 +212,7 @@ func setContCpus(event common.MapStr, perContainerCpus map[string]int) { } } -func calcUsagePct(newValue, systemUsageDelta, contCpus float64, +func calcUsagePct(timestampDelta int64, newValue, contCpus float64, cid string, oldValuesMap map[string]float64) float64 { var usageDelta, usagePct float64 if oldValue, ok := oldValuesMap[cid]; ok { @@ -230,11 +220,11 @@ func calcUsagePct(newValue, systemUsageDelta, contCpus float64, } else { usageDelta = newValue } - if usageDelta == 0.0 || systemUsageDelta == 0.0 { + if usageDelta == 0.0 || float64(timestampDelta) == 0.0 { usagePct = 0.0 } else { // normalize percentage with cpus used per container - usagePct = (usageDelta / systemUsageDelta) / contCpus + usagePct = (usageDelta / float64(timestampDelta)) / contCpus } return usagePct } diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 3ba1132dbf0..4f66c785776 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -101,7 +101,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // Fetch gathers information from the containerd and reports events with this information. func (m *metricset) Fetch(reporter mb.ReporterV2) error { - families, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) + families, _, err := m.mod.GetContainerdMetricsFamilies(m.prometheusClient) if err != nil { return errors.Wrap(err, "error getting families") } From d1b61d9884517d841a749ae64170bbcd03271496 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 15 Dec 2021 16:25:35 +0200 Subject: [PATCH 19/37] Calculate workingset.pct --- x-pack/metricbeat/include/list.go | 2 ++ x-pack/metricbeat/metricbeat.reference.yml | 3 ++- x-pack/metricbeat/module/containerd/containerd.go | 4 ++++ x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml | 4 ++-- x-pack/metricbeat/module/containerd/fields.go | 2 +- .../metricbeat/module/containerd/memory/_meta/fields.yml | 7 ++++++- x-pack/metricbeat/module/containerd/memory/memory.go | 8 ++++++-- 7 files changed, 23 insertions(+), 7 deletions(-) diff --git a/x-pack/metricbeat/include/list.go b/x-pack/metricbeat/include/list.go index 86c616e1c57..3fdd6556b58 100644 --- a/x-pack/metricbeat/include/list.go +++ b/x-pack/metricbeat/include/list.go @@ -26,7 +26,9 @@ import ( _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/cloudfoundry/value" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/cockroachdb" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd/blkio" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd/cpu" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd/memory" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/coredns" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/coredns/stats" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/enterprisesearch" diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 6a38649141a..58a0c77cc7b 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -429,10 +429,11 @@ metricbeat.modules: #------------------------------ Containerd Module ------------------------------ - module: containerd - metricsets: ["cpu"] + metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s hosts: ["localhost:1338"] + calcpct: true #------------------------------- Coredns Module ------------------------------- diff --git a/x-pack/metricbeat/module/containerd/containerd.go b/x-pack/metricbeat/module/containerd/containerd.go index e613bf563bc..2b0c1fd7e09 100644 --- a/x-pack/metricbeat/module/containerd/containerd.go +++ b/x-pack/metricbeat/module/containerd/containerd.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + package containerd import ( diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml b/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml index 81459e4ebf0..e2a99f3d432 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/fields.yml @@ -6,8 +6,8 @@ fields: - name: system.total type: double - description: > - Total user and system CPU time spent in seconds. + description: > + Total user and system CPU time spent in seconds. - name: usage type: group fields: diff --git a/x-pack/metricbeat/module/containerd/fields.go b/x-pack/metricbeat/module/containerd/fields.go index feb306a36f0..b54d522b3bc 100644 --- a/x-pack/metricbeat/module/containerd/fields.go +++ b/x-pack/metricbeat/module/containerd/fields.go @@ -19,5 +19,5 @@ func init() { // AssetContainerd returns asset data. // This is the base64 encoded zlib format compressed contents of module/containerd. func AssetContainerd() string { - return "eJzUmEtv2zAMx+/5FEQvAwY0u+cwYC1QoBi6Fdt6LmSZTrXoYeixNv30g2Q7cWz5kaBBbJ0C2SJ/pPin5FzDBrcroEpawiTqdAFgmeW4gqvb3eTVAkAjR2JwBQlasgBI0VDNcsuUXMHXBQDAfgEYS6wBqjhHajGFTCtx6CVjyFOzCguvQRKBDQw/7DbHFay1cnk5E3Hrx73MlBbETwORhX9mLKMGSKKcrZn+ZEA7KZlc7yfNsrRUp6qTJXzD1G42BuZHM0fV6ID244YruoH7Lz9BoNWM7khiNHUijSQ9eNAFNQDgxzdKnXCc+J3ydg2kTvsE2RcEzjIElYXfu4Q1TMRA67AqN61nFS9Xch15OIDsxw8nEtSe7STo2u5uLR4NWBRc9+IRAdz4pQH+OPaK+1Uzi+cogmB4dlVwGvVUysDTW5SnVYJxQhC9PV9D8E11nlXhe6vKUYfDYbbVEZpEtQlHlUnrLKO5GzzJerhqp/wvJy0TCLePT7Hjq+s47DvWnCHr8S1tqLY2qCXyzk2LmewzWzctY9u5N50ql/BmINUYset++LR+DxEUaQFJpDJIlUzbzvcJjNTwjAJ+MqiPCNcqS2a9wSGAYwNe5tR2Bm0o4Zg+Z1yR2EtVS8pRU5SxN0bQPxaLPbRvPCGGEI1vB9J74OwdU0i2oSvJXTf2L1GlI83wULNTi9DHxWQJByYndGScy16lTjRMj/YxQdLcLT8vo1oqglTJX4zmoHjwPKC2ESF6ypa+fJT2hZkA2DoiBQp1cJv6sO+9luXebzzTzFvnZaPvojGQoz9BvQUYaDQsRWnBoAXD3nEZJSPUsn94x3jL2fkIC5+QMY6FkTgaJfQlfoM4B1Tw1ofD5CVyVXkdzNZx960B309BZWUlhb+Amo1h6MImyNsFrtgP5K2iDvnobmeXbtcPNcrKUi9w//3ofCk9aCoDSc0I40uqXDQpo3I7AuiOMA7BCepuFM4E66Y4YwXW9zVAxOUa/aA5Wa/lx8X8BFuBj9btpWRQgtqpqaHkyiYtisPy7FGFeSXNyj9ZE79fST5DRRTYk9dDwJycGgLVtLVQL8uGEhb/AwAA///GKMXX" + return "eJzUmE1r20AQhu/+FUMuhULcuw+FJhAIJW1om3NYr0bO1qtdsR91nF9fZiU5srz6sImxtKcgWbPPjN53ZpVrWON2AVwrx4RCk8wAnHASF3B1u7t4NQMwKJFZXMASHZsBJGi5EbkTWi3g6wwA4P0BsI45C1xLidxhAqnR2f4uqUCZ2EV48BoUy7CBQcttc1zAymifl1ci29K6V6k2GaPLwFSxv7BOcAtsqb2rhf5kwXilhFq9X7TzMlKdqk62lGuhd1djYLSaNapWCzStG6n5Gu6//IQMnRF8RxKjqRMZZMnejTaoHgBa3zj3mZeM3hTFtZB4QwVyLwhSpAg6DX/vCtYIEQOtw+rcHtyreKVWq8jNHmRaP3y2RENsJ0HX3u7W4dGAheDaHx6QwA09GuCPY6+4N0Y4PIcIQuDJqeA06rHIgOgdqtOUYH2WMbM9X0OgpjpNVVBv1TmaMBwmq47QJKqXcJRMDmYZz33vJOvgqk35X145kSHcPj7FxlfbOOwaa3ZrHWZzpx2TUTUn2i9ls+n1lPEPRQNv0RSHg7BHoA74NkflQCiwyLVK9nJ4J/OWrYY32z7Vr9EobGbYHbIrbD20igkNugtYrQF6pEWl+x4yKMoCiildVq81Zar/lBN+Iv0MTzcm4Unl60rXHJXwPOeuNWnLmcTkOZWaxX5UNcscDUcV+8UA+sfiYYKmlhhy2Dld0Q5SvGECy23ol2o3J+hHXJtIm9737NgypLyEKuHA5owPzHPe6dSRphma+IckyXM//zyPeqlIUi//YrQGxY3nHrcNSJEoD/xFWboXYQPgwfDOMNN757wP+xI9iNw1pjfarIVaWXQRnfRqpFsfPYV7CJwVAVh0VRy2wvjoNrb5llsPbV0HtkGnjKKMYNCKhI4VxGfFWwsZ4078wzshDzY7H2GxJ6RCYhEkjsYZf4mfd84BFXbrwhHqErWqdu2t1nGnw569n0JPKJUU/pXWbGN9x8uMvV7gU+WBvVbUoR7tzffSw6V0gpSah4/ckrqtkcDgc935irvXXnrKmzIh51z7aHkGVXkA0B0TEsImaNpRpMhEO8UZtVgrVAERN270Q+xk55YfRdOzbgU+2MGXskEJ6sbmhpIrHbUp9uXZ4Qq7YU3ln+yJ3xuWT9ARBfbo/RAwR+eGQDVuL9Rl2XDC7H8AAAD//xQQIcM=" } diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml b/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml index 38da0567ec0..e637302364d 100644 --- a/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml +++ b/x-pack/metricbeat/module/containerd/memory/_meta/fields.yml @@ -4,6 +4,11 @@ description: > memory fields: + - name: workingset.pct + type: scaled_float + format: percent + description: > + Memory working set percentage. - name: rss type: long format: bytes @@ -38,7 +43,7 @@ type: scaled_float format: percent description: > - Memory usage percentage. + Total allocated memory percentage. - name: total type: long format: bytes diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 4f66c785776..c0778b69236 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -134,8 +134,12 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { if err == nil { memoryLimit, err := event.GetValue("usage.limit") if err == nil { - usage := usageTotal.(float64) - inactiveFiles.(float64) - memoryUsagePct := usage / memoryLimit.(float64) + // calculate working set memory usage + workingSetUsage := usageTotal.(float64) - inactiveFiles.(float64) + workingSetUsagePct := workingSetUsage / memoryLimit.(float64) + event.Put("workingset.pct", workingSetUsagePct) + + memoryUsagePct := usageTotal.(float64) / memoryLimit.(float64) event.Put("usage.pct", memoryUsagePct) m.Logger().Debugf("memoryUsagePct for %+v is %+v", cID, memoryUsagePct) } From b41c19c6b9cb24ef01cb7c35d42d2216ad7e012a Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 16 Dec 2021 12:16:46 +0200 Subject: [PATCH 20/37] Add tests --- .../containerd/_meta/test/containerd.v1.5.2 | 99 +++++ .../_meta/test/containerd.v1.5.2.expected | 35 ++ .../module/containerd/blkio/blkio_test.go | 42 ++ .../module/containerd/cpu/_meta/data.json | 42 +- .../cpu/_meta/test/containerd.v1.5.2.expected | 372 ++++++++++++++++ .../containerd/cpu/_meta/testdata/config.yml | 3 + .../containerd/cpu/_meta/testdata/docs.plain | 99 +++++ .../_meta/testdata/docs.plain-expected.json | 398 ++++++++++++++++++ .../metricbeat/module/containerd/cpu/cpu.go | 1 - .../containerd/cpu/cpu_integration_test.go | 54 +++ .../module/containerd/cpu/cpu_test.go | 31 ++ .../_meta/test/containerd.v1.5.2.expected | 54 +++ .../module/containerd/memory/memory_test.go | 26 ++ 13 files changed, 1240 insertions(+), 16 deletions(-) create mode 100644 x-pack/metricbeat/module/containerd/_meta/test/containerd.v1.5.2 create mode 100644 x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected create mode 100644 x-pack/metricbeat/module/containerd/blkio/blkio_test.go create mode 100644 x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected create mode 100644 x-pack/metricbeat/module/containerd/cpu/_meta/testdata/config.yml create mode 100644 x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain create mode 100644 x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json create mode 100644 x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go create mode 100644 x-pack/metricbeat/module/containerd/cpu/cpu_test.go create mode 100644 x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected create mode 100644 x-pack/metricbeat/module/containerd/memory/memory_test.go diff --git a/x-pack/metricbeat/module/containerd/_meta/test/containerd.v1.5.2 b/x-pack/metricbeat/module/containerd/_meta/test/containerd.v1.5.2 new file mode 100644 index 00000000000..f82e4d3c1d9 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/_meta/test/containerd.v1.5.2 @@ -0,0 +1,99 @@ +# TYPE container_blkio_io_service_bytes_recursive_bytes gauge +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Async"} 0 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Discard"} 0 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Read"} 6.9246976e+07 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Sync"} 6.9271552e+07 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Total"} 6.9271552e+07 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Write"} 24576 +# TYPE container_blkio_io_serviced_recursive_total gauge +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Async"} 0 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Discard"} 0 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Read"} 830 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Sync"} 832 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Total"} 832 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Write"} 2 +# TYPE container_cpu_kernel_nanoseconds gauge +container_cpu_kernel_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 5.3218e+11 +# TYPE container_cpu_throttle_periods_total gauge +container_cpu_throttle_periods_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_cpu_throttled_periods_total gauge +container_cpu_throttled_periods_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_cpu_throttled_time_nanoseconds gauge +container_cpu_throttled_time_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_cpu_total_nanoseconds gauge +container_cpu_total_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.236339003984e+12 +# TYPE container_cpu_user_nanoseconds gauge +container_cpu_user_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 5.2547e+11 +# TYPE container_memory_active_anon_bytes gauge +container_memory_active_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_active_file_bytes gauge +container_memory_active_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.216512e+06 +# TYPE container_memory_cache_bytes gauge +container_memory_cache_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.40980224e+08 +# TYPE container_memory_dirty_bytes gauge +container_memory_dirty_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_inactive_anon_bytes gauge +container_memory_inactive_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.4048384e+07 +# TYPE container_memory_inactive_file_bytes gauge +container_memory_inactive_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.3928448e+08 +# TYPE container_memory_kernel_failcnt_total gauge +container_memory_kernel_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_kernel_limit_bytes gauge +container_memory_kernel_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 9.223372036854772e+18 +# TYPE container_memory_kernel_max_bytes gauge +container_memory_kernel_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 6.496256e+06 +# TYPE container_memory_kernel_usage_bytes gauge +container_memory_kernel_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 6.459392e+06 +# TYPE container_memory_kerneltcp_failcnt_total gauge +container_memory_kerneltcp_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_kerneltcp_limit_bytes gauge +container_memory_kerneltcp_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 9.223372036854772e+18 +# TYPE container_memory_kerneltcp_max_bytes gauge +container_memory_kerneltcp_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_kerneltcp_usage_bytes gauge +container_memory_kerneltcp_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_rss_bytes gauge +container_memory_rss_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.3794432e+07 +# TYPE container_memory_rss_huge_bytes gauge +container_memory_rss_huge_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_swap_failcnt_total gauge +container_memory_swap_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_swap_limit_bytes gauge +container_memory_swap_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 9.223372036854772e+18 +# TYPE container_memory_swap_max_bytes gauge +container_memory_swap_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 2.09727488e+08 +# TYPE container_memory_swap_usage_bytes gauge +container_memory_swap_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.9195904e+08 +# TYPE container_memory_total_active_anon_bytes gauge +container_memory_total_active_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_total_active_file_bytes gauge +container_memory_total_active_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.216512e+06 +# TYPE container_memory_total_cache_bytes gauge +container_memory_total_cache_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.40980224e+08 +# TYPE container_memory_total_inactive_anon_bytes gauge +container_memory_total_inactive_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.4048384e+07 +# TYPE container_memory_total_inactive_file_bytes gauge +container_memory_total_inactive_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.3928448e+08 +# TYPE container_memory_total_rss_bytes gauge +container_memory_total_rss_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.3794432e+07 +# TYPE container_memory_usage_failcnt_total gauge +container_memory_usage_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_usage_limit_bytes gauge +container_memory_usage_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 2.097152e+08 +# TYPE container_memory_usage_max_bytes gauge +container_memory_usage_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 2.09608704e+08 +# TYPE container_memory_usage_usage_bytes gauge +container_memory_usage_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.91848448e+08 +# TYPE container_per_cpu_nanoseconds gauge +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="0",namespace="k8s.io"} 9.913781757e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="1",namespace="k8s.io"} 1.16475261138e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="10",namespace="k8s.io"} 1.0670990577e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="11",namespace="k8s.io"} 1.0487838037e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="2",namespace="k8s.io"} 1.05305653633e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="3",namespace="k8s.io"} 1.01195506344e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="4",namespace="k8s.io"} 1.05731762224e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="5",namespace="k8s.io"} 9.8155683224e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="6",namespace="k8s.io"} 9.5075348914e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="7",namespace="k8s.io"} 9.713478277e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="8",namespace="k8s.io"} 1.04266711568e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="9",namespace="k8s.io"} 1.02272190459e+11 diff --git a/x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected b/x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected new file mode 100644 index 00000000000..6f90702c3b0 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected @@ -0,0 +1,35 @@ +[ + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "device": "/dev/vda", + "read": { + "bytes": 69246976, + "ops": 830 + }, + "summary": { + "bytes": 69271552, + "ops": 832 + }, + "write": { + "bytes": 24576, + "ops": 2 + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.blkio", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + } +] \ No newline at end of file diff --git a/x-pack/metricbeat/module/containerd/blkio/blkio_test.go b/x-pack/metricbeat/module/containerd/blkio/blkio_test.go new file mode 100644 index 00000000000..25eed0d2887 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/blkio/blkio_test.go @@ -0,0 +1,42 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// 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. + +//go:build !integration +// +build !integration + +package blkio + +import ( + "testing" + + "github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" +) + +func TestEventMapping(t *testing.T) { + ptest.TestMetricSet(t, "containerd", "blkio", + ptest.TestCases{ + { + MetricsFile: "../_meta/test/containerd.v1.5.2", + ExpectedFile: "./_meta/test/containerd.v1.5.2.expected", + }, + }, + ) +} diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/data.json b/x-pack/metricbeat/module/containerd/cpu/_meta/data.json index b01c3095fd6..1e02d74bfb9 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/data.json +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/data.json @@ -1,19 +1,31 @@ { - "@timestamp":"2016-05-23T08:05:34.853Z", - "beat":{ - "hostname":"beathost", - "name":"beathost" + "@timestamp": "2019-03-01T08:05:34.853Z", + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" }, - "metricset":{ - "host":"localhost", - "module":"containerd", - "name":"cpu", - "rtt":44269 - }, - "containerd":{ - "cpu":{ - "example": "cpu" + "containerd": { + "cpu": { + "usage": { + "cpu": { + "10": { + "ns": 106709905770 + } + }, + "percpu": {} + } } }, - "type":"metricsets" -} + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected b/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected new file mode 100644 index 00000000000..f97033d75d2 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected @@ -0,0 +1,372 @@ +[ + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "7": { + "ns": 97134782770 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "4": { + "ns": 105731762224 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "8": { + "ns": 104266711568 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "9": { + "ns": 102272190459 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "10": { + "ns": 106709905770 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "5": { + "ns": 98155683224 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "2": { + "ns": 105305653633 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "kernel": { + "ns": 532180000000, + "pct": 5.257648295643049e-9 + }, + "total": { + "ns": 1236339003984, + "pct": 1.2214355400679284e-8 + }, + "user": { + "ns": 525470000000, + "pct": 5.19135715342845e-9 + } + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "3": { + "ns": 101195506344 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "0": { + "ns": 99137817570 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "1": { + "ns": 116475261138 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "6": { + "ns": 95075348914 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + }, + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "usage": { + "cpu": { + "11": { + "ns": 104878380370 + } + }, + "percpu": {} + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.cpu", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + } +] \ No newline at end of file diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/config.yml b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/config.yml new file mode 100644 index 00000000000..e19c22ddc90 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/config.yml @@ -0,0 +1,3 @@ +type: http +url: "/v1/metrics" +suffix: plain diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain new file mode 100644 index 00000000000..f82e4d3c1d9 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain @@ -0,0 +1,99 @@ +# TYPE container_blkio_io_service_bytes_recursive_bytes gauge +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Async"} 0 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Discard"} 0 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Read"} 6.9246976e+07 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Sync"} 6.9271552e+07 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Total"} 6.9271552e+07 +container_blkio_io_service_bytes_recursive_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Write"} 24576 +# TYPE container_blkio_io_serviced_recursive_total gauge +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Async"} 0 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Discard"} 0 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Read"} 830 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Sync"} 832 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Total"} 832 +container_blkio_io_serviced_recursive_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",device="/dev/vda",major="254",minor="0",namespace="k8s.io",op="Write"} 2 +# TYPE container_cpu_kernel_nanoseconds gauge +container_cpu_kernel_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 5.3218e+11 +# TYPE container_cpu_throttle_periods_total gauge +container_cpu_throttle_periods_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_cpu_throttled_periods_total gauge +container_cpu_throttled_periods_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_cpu_throttled_time_nanoseconds gauge +container_cpu_throttled_time_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_cpu_total_nanoseconds gauge +container_cpu_total_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.236339003984e+12 +# TYPE container_cpu_user_nanoseconds gauge +container_cpu_user_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 5.2547e+11 +# TYPE container_memory_active_anon_bytes gauge +container_memory_active_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_active_file_bytes gauge +container_memory_active_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.216512e+06 +# TYPE container_memory_cache_bytes gauge +container_memory_cache_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.40980224e+08 +# TYPE container_memory_dirty_bytes gauge +container_memory_dirty_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_inactive_anon_bytes gauge +container_memory_inactive_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.4048384e+07 +# TYPE container_memory_inactive_file_bytes gauge +container_memory_inactive_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.3928448e+08 +# TYPE container_memory_kernel_failcnt_total gauge +container_memory_kernel_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_kernel_limit_bytes gauge +container_memory_kernel_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 9.223372036854772e+18 +# TYPE container_memory_kernel_max_bytes gauge +container_memory_kernel_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 6.496256e+06 +# TYPE container_memory_kernel_usage_bytes gauge +container_memory_kernel_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 6.459392e+06 +# TYPE container_memory_kerneltcp_failcnt_total gauge +container_memory_kerneltcp_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_kerneltcp_limit_bytes gauge +container_memory_kerneltcp_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 9.223372036854772e+18 +# TYPE container_memory_kerneltcp_max_bytes gauge +container_memory_kerneltcp_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_kerneltcp_usage_bytes gauge +container_memory_kerneltcp_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_rss_bytes gauge +container_memory_rss_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.3794432e+07 +# TYPE container_memory_rss_huge_bytes gauge +container_memory_rss_huge_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_swap_failcnt_total gauge +container_memory_swap_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_swap_limit_bytes gauge +container_memory_swap_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 9.223372036854772e+18 +# TYPE container_memory_swap_max_bytes gauge +container_memory_swap_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 2.09727488e+08 +# TYPE container_memory_swap_usage_bytes gauge +container_memory_swap_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.9195904e+08 +# TYPE container_memory_total_active_anon_bytes gauge +container_memory_total_active_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_total_active_file_bytes gauge +container_memory_total_active_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.216512e+06 +# TYPE container_memory_total_cache_bytes gauge +container_memory_total_cache_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.40980224e+08 +# TYPE container_memory_total_inactive_anon_bytes gauge +container_memory_total_inactive_anon_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.4048384e+07 +# TYPE container_memory_total_inactive_file_bytes gauge +container_memory_total_inactive_file_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.3928448e+08 +# TYPE container_memory_total_rss_bytes gauge +container_memory_total_rss_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 4.3794432e+07 +# TYPE container_memory_usage_failcnt_total gauge +container_memory_usage_failcnt_total{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 0 +# TYPE container_memory_usage_limit_bytes gauge +container_memory_usage_limit_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 2.097152e+08 +# TYPE container_memory_usage_max_bytes gauge +container_memory_usage_max_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 2.09608704e+08 +# TYPE container_memory_usage_usage_bytes gauge +container_memory_usage_usage_bytes{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",namespace="k8s.io"} 1.91848448e+08 +# TYPE container_per_cpu_nanoseconds gauge +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="0",namespace="k8s.io"} 9.913781757e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="1",namespace="k8s.io"} 1.16475261138e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="10",namespace="k8s.io"} 1.0670990577e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="11",namespace="k8s.io"} 1.0487838037e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="2",namespace="k8s.io"} 1.05305653633e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="3",namespace="k8s.io"} 1.01195506344e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="4",namespace="k8s.io"} 1.05731762224e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="5",namespace="k8s.io"} 9.8155683224e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="6",namespace="k8s.io"} 9.5075348914e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="7",namespace="k8s.io"} 9.713478277e+10 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="8",namespace="k8s.io"} 1.04266711568e+11 +container_per_cpu_nanoseconds{container_id="7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d",cpu="9",namespace="k8s.io"} 1.02272190459e+11 diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json new file mode 100644 index 00000000000..bc307a96049 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json @@ -0,0 +1,398 @@ +[ + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "10": { + "ns": 106709905770 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "9": { + "ns": 102272190459 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "kernel": { + "ns": 532180000000, + "pct": 5.257648295639088e-9 + }, + "total": { + "ns": 1236339003984, + "pct": 1.2214355400670084e-8 + }, + "user": { + "ns": 525470000000, + "pct": 5.191357153424541e-9 + } + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "1": { + "ns": 116475261138 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "4": { + "ns": 105731762224 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "3": { + "ns": 101195506344 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "7": { + "ns": 97134782770 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "8": { + "ns": 104266711568 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "0": { + "ns": 99137817570 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "5": { + "ns": 98155683224 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "6": { + "ns": 95075348914 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "11": { + "ns": 104878380370 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + }, + { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + }, + "containerd": { + "cpu": { + "usage": { + "cpu": { + "2": { + "ns": 105305653633 + } + }, + "percpu": {} + } + } + }, + "event": { + "dataset": "containerd.cpu", + "duration": 115000, + "module": "containerd" + }, + "metricset": { + "name": "cpu", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "containerd" + } + } +] \ No newline at end of file diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index 46011558dbc..92ab2db07ee 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -111,7 +111,6 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } perContainerCpus := make(map[string]int) - if m.calcPct { for _, event := range events { if _, err = event.GetValue("cpu"); err == nil { diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go b/x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go new file mode 100644 index 00000000000..3a46d14835d --- /dev/null +++ b/x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go @@ -0,0 +1,54 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +//go:build integration && linux +// +build integration,linux + +// 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 cpu + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" +) + +func TestFetchMetricset(t *testing.T) { + config := GetContainerdConfig(t, "cpu") + metricSet := mbtest.NewFetcher(t, config) + events, errs := metricSet.FetchEvents() + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + assert.NotEmpty(t, events) +} + +// GetContainerdConfig function returns configuration for talking to containerd. +func GetContainerdConfig(t *testing.T, metricSetName string) map[string]interface{} { + t.Helper() + return map[string]interface{}{ + "module": "containerd", + "metricsets": []string{metricSetName}, + "hosts": []string{"localhost:1338"}, + "calcpct": true, + } +} diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu_test.go b/x-pack/metricbeat/module/containerd/cpu/cpu_test.go new file mode 100644 index 00000000000..e7b67c45406 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/cpu/cpu_test.go @@ -0,0 +1,31 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +//go:build !integration +// +build !integration + +package cpu + +import ( + "testing" + + "github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest" + mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" +) + +func TestEventMapping(t *testing.T) { + ptest.TestMetricSet(t, "containerd", "cpu", + ptest.TestCases{ + { + MetricsFile: "../_meta/test/containerd.v1.5.2", + ExpectedFile: "./_meta/test/containerd.v1.5.2.expected", + }, + }, + ) +} + +func TestData(t *testing.T) { + mbtest.TestDataFiles(t, "containerd", "cpu") +} diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected b/x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected new file mode 100644 index 00000000000..de58cab43cc --- /dev/null +++ b/x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected @@ -0,0 +1,54 @@ +[ + { + "RootFields": { + "container": { + "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" + } + }, + "ModuleFields": null, + "MetricSetFields": { + "activeFiles": 1216512, + "cache": 140980224, + "inactiveFiles": 139284480, + "kernel": { + "fail": { + "count": 0 + }, + "limit": 9223372036854772000, + "max": 6496256, + "total": 6459392 + }, + "rss": 43794432, + "swap": { + "fail": { + "count": 0 + }, + "limit": 9223372036854772000, + "max": 209727488, + "total": 191959040 + }, + "usage": { + "fail": { + "count": 0 + }, + "limit": 209715200, + "max": 209608704, + "pct": 0.9148046875, + "total": 191848448 + }, + "workingset": { + "pct": 0.25064453125 + } + }, + "Index": "", + "ID": "", + "Namespace": "containerd.memory", + "Timestamp": "0001-01-01T00:00:00Z", + "Error": null, + "Host": "", + "Service": "", + "Took": 0, + "Period": 0, + "DisableTimeSeries": false + } +] \ No newline at end of file diff --git a/x-pack/metricbeat/module/containerd/memory/memory_test.go b/x-pack/metricbeat/module/containerd/memory/memory_test.go new file mode 100644 index 00000000000..027ea9b598f --- /dev/null +++ b/x-pack/metricbeat/module/containerd/memory/memory_test.go @@ -0,0 +1,26 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +//go:build !integration +// +build !integration + +package memory + +import ( + "testing" + + "github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" +) + +func TestEventMapping(t *testing.T) { + ptest.TestMetricSet(t, "containerd", "memory", + ptest.TestCases{ + { + MetricsFile: "../_meta/test/containerd.v1.5.2", + ExpectedFile: "./_meta/test/containerd.v1.5.2.expected", + }, + }, + ) +} From e293e5e0e540e29754cf2c6eaf49a2128cc14512 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 16 Dec 2021 13:50:40 +0200 Subject: [PATCH 21/37] Make update --- metricbeat/docs/fields.asciidoc | 342 ++++++++++++++++++ metricbeat/docs/modules/containerd.asciidoc | 11 +- .../docs/modules/containerd/blkio.asciidoc | 25 ++ .../docs/modules/containerd/cpu.asciidoc | 1 + .../docs/modules/containerd/memory.asciidoc | 25 ++ metricbeat/docs/modules_list.asciidoc | 4 +- 6 files changed, 406 insertions(+), 2 deletions(-) create mode 100644 metricbeat/docs/modules/containerd/blkio.asciidoc create mode 100644 metricbeat/docs/modules/containerd/memory.asciidoc diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 811f8b2236d..e37ba5f4954 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -10268,6 +10268,100 @@ Information and statistics about containerd's running containers. +[float] +=== blkio + +Block I/O metrics. + + + +[float] +=== read + +Accumulated reads during the life of the container + + + +*`containerd.blkio.read.ops`*:: ++ +-- +Number of reads during the life of the container + + +type: long + +-- + +*`containerd.blkio.read.bytes`*:: ++ +-- +Bytes read during the life of the container + + +type: long + +format: bytes + +-- + +[float] +=== write + +Accumulated writes during the life of the container + + + +*`containerd.blkio.write.ops`*:: ++ +-- +Number of writes during the life of the container + + +type: long + +-- + +*`containerd.blkio.write.bytes`*:: ++ +-- +Bytes written during the life of the container + + +type: long + +format: bytes + +-- + +[float] +=== summary + +Accumulated reads and writes during the life of the container + + + +*`containerd.blkio.summary.ops`*:: ++ +-- +Number of I/O operations during the life of the container + + +type: long + +-- + +*`containerd.blkio.summary.bytes`*:: ++ +-- +Bytes read and written during the life of the container + + +type: long + +format: bytes + +-- + [float] === cpu @@ -10275,6 +10369,16 @@ Containerd Runtime CPU metrics. +*`containerd.cpu.system.total`*:: ++ +-- +Total user and system CPU time spent in seconds. + + +type: double + +-- + *`containerd.cpu.usage.kernel.ns`*:: @@ -10355,6 +10459,244 @@ type: object -- +[float] +=== memory + +memory + + + +*`containerd.memory.workingset.pct`*:: ++ +-- +Memory working set percentage. + + +type: scaled_float + +format: percent + +-- + +*`containerd.memory.rss`*:: ++ +-- +Total memory resident set size. + + +type: long + +format: bytes + +-- + +*`containerd.memory.activeFiles`*:: ++ +-- +Total active file bytes. + + +type: long + +format: bytes + +-- + +*`containerd.memory.cache`*:: ++ +-- +Total cache bytes. + + +type: long + +format: bytes + +-- + +*`containerd.memory.inactiveFiles`*:: ++ +-- +Total inactive file bytes. + + +type: long + +format: bytes + +-- + +[float] +=== usage + +Usage memory stats. + + + +*`containerd.memory.usage.max`*:: ++ +-- +Max memory usage. + + +type: long + +format: bytes + +-- + +*`containerd.memory.usage.pct`*:: ++ +-- +Total allocated memory percentage. + + +type: scaled_float + +format: percent + +-- + +*`containerd.memory.usage.total`*:: ++ +-- +Total memory usage. + + +type: long + +format: bytes + +-- + +*`containerd.memory.usage.fail.count`*:: ++ +-- +Fail counter. + + +type: scaled_float + +-- + +*`containerd.memory.usage.limit`*:: ++ +-- +Memory usage limit. + + +type: long + +format: bytes + +-- + +[float] +=== kernel + +Kernel memory stats. + + + +*`containerd.memory.kernel.max`*:: ++ +-- +Kernel max memory usage. + + +type: long + +format: bytes + +-- + +*`containerd.memory.kernel.total`*:: ++ +-- +Kernel total memory usage. + + +type: long + +format: bytes + +-- + +*`containerd.memory.kernel.fail.count`*:: ++ +-- +Kernel fail counter. + + +type: scaled_float + +-- + +*`containerd.memory.kernel.limit`*:: ++ +-- +Kernel memory limit. + + +type: long + +format: bytes + +-- + +[float] +=== swap + +Swap memory stats. + + + +*`containerd.memory.swap.max`*:: ++ +-- +Swap max memory usage. + + +type: long + +format: bytes + +-- + +*`containerd.memory.swap.total`*:: ++ +-- +Swap total memory usage. + + +type: long + +format: bytes + +-- + +*`containerd.memory.swap.fail.count`*:: ++ +-- +Swap fail counter. + + +type: scaled_float + +-- + +*`containerd.memory.swap.limit`*:: ++ +-- +Swap memory limit. + + +type: long + +format: bytes + +-- + [[exported-fields-coredns]] == Coredns fields diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index d0c3fde955f..930d9badf75 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -24,10 +24,11 @@ in <>. Here is an example configuration: ---- metricbeat.modules: - module: containerd - metricsets: ["cpu"] + metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s hosts: ["localhost:1338"] + calcpct: true ---- @@ -36,7 +37,15 @@ metricbeat.modules: The following metricsets are available: +* <> + * <> +* <> + +include::containerd/blkio.asciidoc[] + include::containerd/cpu.asciidoc[] +include::containerd/memory.asciidoc[] + diff --git a/metricbeat/docs/modules/containerd/blkio.asciidoc b/metricbeat/docs/modules/containerd/blkio.asciidoc new file mode 100644 index 00000000000..6618e45bcd2 --- /dev/null +++ b/metricbeat/docs/modules/containerd/blkio.asciidoc @@ -0,0 +1,25 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-containerd-blkio]] +[role="xpack"] +=== Containerd blkio metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/containerd/blkio/_meta/docs.asciidoc[] + +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. + +==== 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::../../../../x-pack/metricbeat/module/containerd/blkio/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules/containerd/cpu.asciidoc b/metricbeat/docs/modules/containerd/cpu.asciidoc index d964455ccd6..0d14f45da3e 100644 --- a/metricbeat/docs/modules/containerd/cpu.asciidoc +++ b/metricbeat/docs/modules/containerd/cpu.asciidoc @@ -10,6 +10,7 @@ beta[] include::../../../../x-pack/metricbeat/module/containerd/cpu/_meta/docs.asciidoc[] +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. ==== Fields diff --git a/metricbeat/docs/modules/containerd/memory.asciidoc b/metricbeat/docs/modules/containerd/memory.asciidoc new file mode 100644 index 00000000000..a09ff8fd762 --- /dev/null +++ b/metricbeat/docs/modules/containerd/memory.asciidoc @@ -0,0 +1,25 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-containerd-memory]] +[role="xpack"] +=== Containerd memory metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/containerd/memory/_meta/docs.asciidoc[] + +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. + +==== 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::../../../../x-pack/metricbeat/module/containerd/memory/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index 083b4353660..30177e13624 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -73,7 +73,9 @@ This file is generated! See scripts/mage/docs_collector.go |<> beta[] |image:./images/icon-yes.png[Prebuilt dashboards are available] | .1+| .1+| |<> beta[] |<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | -.1+| .1+| |<> beta[] +.3+| .3+| |<> beta[] +|<> beta[] +|<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | .1+| .1+| |<> |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | From 8339a525a669a4f871ec8ac22f56bcd7c6ba30eb Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Thu, 16 Dec 2021 15:28:19 +0200 Subject: [PATCH 22/37] Add check for timestampDelta --- .../cpu/_meta/test/containerd.v1.5.2.expected | 48 +++++++++---------- .../metricbeat/module/containerd/cpu/cpu.go | 5 +- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected b/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected index f97033d75d2..89f7eb37dbf 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected @@ -204,18 +204,12 @@ "ModuleFields": null, "MetricSetFields": { "usage": { - "kernel": { - "ns": 532180000000, - "pct": 5.257648295643049e-9 - }, - "total": { - "ns": 1236339003984, - "pct": 1.2214355400679284e-8 + "cpu": { + "3": { + "ns": 101195506344 + } }, - "user": { - "ns": 525470000000, - "pct": 5.19135715342845e-9 - } + "percpu": {} } }, "Index": "", @@ -239,8 +233,8 @@ "MetricSetFields": { "usage": { "cpu": { - "3": { - "ns": 101195506344 + "0": { + "ns": 99137817570 } }, "percpu": {} @@ -267,8 +261,8 @@ "MetricSetFields": { "usage": { "cpu": { - "0": { - "ns": 99137817570 + "1": { + "ns": 116475261138 } }, "percpu": {} @@ -295,8 +289,8 @@ "MetricSetFields": { "usage": { "cpu": { - "1": { - "ns": 116475261138 + "6": { + "ns": 95075348914 } }, "percpu": {} @@ -323,8 +317,8 @@ "MetricSetFields": { "usage": { "cpu": { - "6": { - "ns": 95075348914 + "11": { + "ns": 104878380370 } }, "percpu": {} @@ -350,12 +344,18 @@ "ModuleFields": null, "MetricSetFields": { "usage": { - "cpu": { - "11": { - "ns": 104878380370 - } + "kernel": { + "ns": 532180000000, + "pct": 0 }, - "percpu": {} + "total": { + "ns": 1236339003984, + "pct": 0 + }, + "user": { + "ns": 525470000000, + "pct": 0 + } } }, "Index": "", diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index 92ab2db07ee..9937693841b 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -139,7 +139,10 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { contCpus = 1 } // calculate timestamp delta - timestampDelta := timestamp.UnixNano() - m.preTimestamp.UnixNano() + timestampDelta := int64(0) + if !m.preTimestamp.IsZero() { + timestampDelta = timestamp.UnixNano() - m.preTimestamp.UnixNano() + } // Calculate cpu total usage percentage cpuUsageTotal, err := event.GetValue("usage.total.ns") if err == nil { From 3dea7e5c355831d480218fa056005470820c7ebd Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Fri, 17 Dec 2021 11:34:19 +0200 Subject: [PATCH 23/37] Add namespace modulefield --- .../module/containerd/_meta/fields.yml | 4 + .../_meta/test/containerd.v1.5.2.expected | 4 +- .../module/containerd/blkio/blkio.go | 19 +--- .../module/containerd/cpu/_meta/data.json | 7 +- .../cpu/_meta/test/containerd.v1.5.2.expected | 60 +++++++--- .../_meta/testdata/docs.plain-expected.json | 107 ++++++++++-------- .../metricbeat/module/containerd/cpu/cpu.go | 17 +-- .../containerd/cpu/cpu_integration_test.go | 54 --------- x-pack/metricbeat/module/containerd/fields.go | 2 +- x-pack/metricbeat/module/containerd/helper.go | 24 ++++ .../_meta/test/containerd.v1.5.2.expected | 4 +- .../module/containerd/memory/memory.go | 18 +-- 12 files changed, 155 insertions(+), 165 deletions(-) delete mode 100644 x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go create mode 100644 x-pack/metricbeat/module/containerd/helper.go diff --git a/x-pack/metricbeat/module/containerd/_meta/fields.yml b/x-pack/metricbeat/module/containerd/_meta/fields.yml index 7e4f9c8cc4e..9d5a0ccc29d 100644 --- a/x-pack/metricbeat/module/containerd/_meta/fields.yml +++ b/x-pack/metricbeat/module/containerd/_meta/fields.yml @@ -9,3 +9,7 @@ description: > Information and statistics about containerd's running containers. fields: + - name: namespace + type: keyword + description: > + Containerd namespace diff --git a/x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected b/x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected index 6f90702c3b0..35b67461d90 100644 --- a/x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected +++ b/x-pack/metricbeat/module/containerd/blkio/_meta/test/containerd.v1.5.2.expected @@ -5,7 +5,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "device": "/dev/vda", "read": { diff --git a/x-pack/metricbeat/module/containerd/blkio/blkio.go b/x-pack/metricbeat/module/containerd/blkio/blkio.go index 2519ddee36a..99805adb82f 100644 --- a/x-pack/metricbeat/module/containerd/blkio/blkio.go +++ b/x-pack/metricbeat/module/containerd/blkio/blkio.go @@ -13,7 +13,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common/cfgwarn" - "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" @@ -52,6 +51,7 @@ var ( Labels: map[string]prometheus.LabelMap{ "container_id": prometheus.KeyLabel("id"), "device": prometheus.KeyLabel("device"), + "namespace": prometheus.KeyLabel("namespace"), }, } ) @@ -104,23 +104,12 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { return errors.Wrap(err, "error getting events") } for _, event := range events { - - // setting ECS container.id - rootFields := common.MapStr{} - containerFields := common.MapStr{} - var cID string - if containerID, ok := event["id"]; ok { - cID = (containerID).(string) - containerFields.Put("id", cID) - event.Delete("id") - } - - if len(containerFields) > 0 { - rootFields.Put("container", containerFields) - } + // setting ECS container.id and containerd.namespace + rootFields, moduleFields, _ := containerd.SetCIDandNamespace(event) reporter.Event(mb.Event{ RootFields: rootFields, + ModuleFields: moduleFields, MetricSetFields: event, Namespace: "containerd.blkio", }) diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/data.json b/x-pack/metricbeat/module/containerd/cpu/_meta/data.json index 1e02d74bfb9..73210e76e26 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/data.json +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/data.json @@ -7,13 +7,14 @@ "cpu": { "usage": { "cpu": { - "10": { - "ns": 106709905770 + "4": { + "ns": 105731762224 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected b/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected index 89f7eb37dbf..e048515f8dd 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/test/containerd.v1.5.2.expected @@ -5,7 +5,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -33,7 +35,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -61,12 +65,14 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { - "8": { - "ns": 104266711568 + "9": { + "ns": 102272190459 } }, "percpu": {} @@ -89,12 +95,14 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { - "9": { - "ns": 102272190459 + "8": { + "ns": 104266711568 } }, "percpu": {} @@ -117,7 +125,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -145,7 +155,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -173,7 +185,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -201,7 +215,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -229,7 +245,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -257,7 +275,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -285,7 +305,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -313,7 +335,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "cpu": { @@ -341,7 +365,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "usage": { "kernel": { diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json index bc307a96049..61afe14be02 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/testdata/docs.plain-expected.json @@ -7,13 +7,14 @@ "cpu": { "usage": { "cpu": { - "10": { - "ns": 106709905770 + "4": { + "ns": 105731762224 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -37,13 +38,14 @@ "cpu": { "usage": { "cpu": { - "9": { - "ns": 102272190459 + "3": { + "ns": 101195506344 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -66,20 +68,15 @@ "containerd": { "cpu": { "usage": { - "kernel": { - "ns": 532180000000, - "pct": 5.257648295639088e-9 - }, - "total": { - "ns": 1236339003984, - "pct": 1.2214355400670084e-8 + "cpu": { + "0": { + "ns": 99137817570 + } }, - "user": { - "ns": 525470000000, - "pct": 5.191357153424541e-9 - } + "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -103,13 +100,14 @@ "cpu": { "usage": { "cpu": { - "1": { - "ns": 116475261138 + "9": { + "ns": 102272190459 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -133,13 +131,14 @@ "cpu": { "usage": { "cpu": { - "4": { - "ns": 105731762224 + "2": { + "ns": 105305653633 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -163,13 +162,14 @@ "cpu": { "usage": { "cpu": { - "3": { - "ns": 101195506344 + "8": { + "ns": 104266711568 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -199,7 +199,8 @@ }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -223,13 +224,14 @@ "cpu": { "usage": { "cpu": { - "8": { - "ns": 104266711568 + "5": { + "ns": 98155683224 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -253,13 +255,14 @@ "cpu": { "usage": { "cpu": { - "0": { - "ns": 99137817570 + "1": { + "ns": 116475261138 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -283,13 +286,14 @@ "cpu": { "usage": { "cpu": { - "5": { - "ns": 98155683224 + "10": { + "ns": 106709905770 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -312,14 +316,21 @@ "containerd": { "cpu": { "usage": { - "cpu": { - "6": { - "ns": 95075348914 - } + "kernel": { + "ns": 532180000000, + "pct": 0 }, - "percpu": {} + "total": { + "ns": 1236339003984, + "pct": 0 + }, + "user": { + "ns": 525470000000, + "pct": 0 + } } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -349,7 +360,8 @@ }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", @@ -373,13 +385,14 @@ "cpu": { "usage": { "cpu": { - "2": { - "ns": 105305653633 + "6": { + "ns": 95075348914 } }, "percpu": {} } - } + }, + "namespace": "k8s.io" }, "event": { "dataset": "containerd.cpu", diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index 9937693841b..6ab8a0f5dd8 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -43,6 +43,7 @@ var ( }, Labels: map[string]prometheus.LabelMap{ "container_id": prometheus.KeyLabel("id"), + "namespace": prometheus.KeyLabel("namespace"), "cpu": prometheus.KeyLabel("cpu"), }, } @@ -121,18 +122,9 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } for _, event := range events { - // setting ECS container.id - rootFields := common.MapStr{} - containerFields := common.MapStr{} - var cID string - if containerID, ok := event["id"]; ok { - cID = (containerID).(string) - containerFields.Put("id", cID) - event.Delete("id") - } - if len(containerFields) > 0 { - rootFields.Put("container", containerFields) - } + // setting ECS container.id and containerd.namespace + rootFields, moduleFields, cID := containerd.SetCIDandNamespace(event) + if m.calcPct { contCpus, ok := perContainerCpus[cID] if !ok { @@ -188,6 +180,7 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { reporter.Event(mb.Event{ RootFields: rootFields, + ModuleFields: moduleFields, MetricSetFields: event, Namespace: "containerd.cpu", }) diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go b/x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go deleted file mode 100644 index 3a46d14835d..00000000000 --- a/x-pack/metricbeat/module/containerd/cpu/cpu_integration_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -//go:build integration && linux -// +build integration,linux - -// 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 cpu - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" -) - -func TestFetchMetricset(t *testing.T) { - config := GetContainerdConfig(t, "cpu") - metricSet := mbtest.NewFetcher(t, config) - events, errs := metricSet.FetchEvents() - if len(errs) > 0 { - t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) - } - assert.NotEmpty(t, events) -} - -// GetContainerdConfig function returns configuration for talking to containerd. -func GetContainerdConfig(t *testing.T, metricSetName string) map[string]interface{} { - t.Helper() - return map[string]interface{}{ - "module": "containerd", - "metricsets": []string{metricSetName}, - "hosts": []string{"localhost:1338"}, - "calcpct": true, - } -} diff --git a/x-pack/metricbeat/module/containerd/fields.go b/x-pack/metricbeat/module/containerd/fields.go index b54d522b3bc..134bc54e6d0 100644 --- a/x-pack/metricbeat/module/containerd/fields.go +++ b/x-pack/metricbeat/module/containerd/fields.go @@ -19,5 +19,5 @@ func init() { // AssetContainerd returns asset data. // This is the base64 encoded zlib format compressed contents of module/containerd. func AssetContainerd() string { - return "eJzUmE1r20AQhu/+FUMuhULcuw+FJhAIJW1om3NYr0bO1qtdsR91nF9fZiU5srz6sImxtKcgWbPPjN53ZpVrWON2AVwrx4RCk8wAnHASF3B1u7t4NQMwKJFZXMASHZsBJGi5EbkTWi3g6wwA4P0BsI45C1xLidxhAqnR2f4uqUCZ2EV48BoUy7CBQcttc1zAymifl1ci29K6V6k2GaPLwFSxv7BOcAtsqb2rhf5kwXilhFq9X7TzMlKdqk62lGuhd1djYLSaNapWCzStG6n5Gu6//IQMnRF8RxKjqRMZZMnejTaoHgBa3zj3mZeM3hTFtZB4QwVyLwhSpAg6DX/vCtYIEQOtw+rcHtyreKVWq8jNHmRaP3y2RENsJ0HX3u7W4dGAheDaHx6QwA09GuCPY6+4N0Y4PIcIQuDJqeA06rHIgOgdqtOUYH2WMbM9X0OgpjpNVVBv1TmaMBwmq47QJKqXcJRMDmYZz33vJOvgqk35X145kSHcPj7FxlfbOOwaa3ZrHWZzpx2TUTUn2i9ls+n1lPEPRQNv0RSHg7BHoA74NkflQCiwyLVK9nJ4J/OWrYY32z7Vr9EobGbYHbIrbD20igkNugtYrQF6pEWl+x4yKMoCiildVq81Zar/lBN+Iv0MTzcm4Unl60rXHJXwPOeuNWnLmcTkOZWaxX5UNcscDUcV+8UA+sfiYYKmlhhy2Dld0Q5SvGECy23ol2o3J+hHXJtIm9737NgypLyEKuHA5owPzHPe6dSRphma+IckyXM//zyPeqlIUi//YrQGxY3nHrcNSJEoD/xFWboXYQPgwfDOMNN757wP+xI9iNw1pjfarIVaWXQRnfRqpFsfPYV7CJwVAVh0VRy2wvjoNrb5llsPbV0HtkGnjKKMYNCKhI4VxGfFWwsZ4078wzshDzY7H2GxJ6RCYhEkjsYZf4mfd84BFXbrwhHqErWqdu2t1nGnw569n0JPKJUU/pXWbGN9x8uMvV7gU+WBvVbUoR7tzffSw6V0gpSah4/ckrqtkcDgc935irvXXnrKmzIh51z7aHkGVXkA0B0TEsImaNpRpMhEO8UZtVgrVAERN270Q+xk55YfRdOzbgU+2MGXskEJ6sbmhpIrHbUp9uXZ4Qq7YU3ln+yJ3xuWT9ARBfbo/RAwR+eGQDVuL9Rl2XDC7H8AAAD//xQQIcM=" + return "eJzUmM1u2zAMx+95CqKXAQOa3XMYsBYoUAzdim09F4pMp1pkydDH0vTpB8p26tjyR4IGcXQYBjsmf6T+JKVewxq3C+BaOSYUmmQG4ISTuICr293DqxmAQYnM4gKW6NgMIEHLjcid0GoBX2cAAO8fgHXMWeBaSuQOE0iNzva9pAJlYhfhw2tQLMMGBi23zXEBK6N9Xj6JuKV1r1JtMkaPganCv7BOcAtsqb2rmf5kwXilhFq9P7Tz0lKdqk5G/9qccdy9qeDWuN3oHXAPYiNDbYuVr6VcC93yU08CreZ+jPB+IzVfw/2Xn5ChM4Lvoo5FXicyyJK9F11QAwC0vnHuMy8ZqYLsWki8oc1wLwhSpAg6Df/fbU7DRAy0Dqtz23pX8UqtVpGXA8i0fvhsiYbYjoKu7e7W4cGAhbi7Px4RwA19GuAPY6+4N0Y4PIUIguGLU8Fx1FORAdE7VMcpwfosY2Z7uoZADfwyVUG9VedowiC6WHWEJlFtwkEyac0ynvvBSTZuXv7yyokM4fbxKTa+usZh31izW+swmzvtmIyqOdF+KZtNbyCNf8gaeIumOIgEH4E64NsclQOhwCLXKtmL4Z3MW7Ya32yHVL9Go7AZYb/JPrN10yomNOhPYLVG6JEWpe57iKBICyimdJm9zpAp/5cc8BPpZ3y4MQlfVLyurJqDAp7n3HUGbTmTmDynUrPYj6pmmaPhqGK/GEH/WHxM0NQSQwy7SlfkQYo3TGC5Df1S7eYE/YhrE2nT+zU7tQgpLqFKOAjXl3FxznsrdaJhhib+IUHy3M8/z6O1VASpl38xmoPixfNAtY0IkShb9UVRuhdhA2BreGeY6b1z3ofdRFuW+8b0Rpu1UCuLLqKTQY3062MgcQ+BsyIAi66yw1YYH93GNne589DWd2Abdcoo0ggGrUjoWEF8Vrx1kDHuxD+8E7Ll7HSEhU9IhcTCSByNM/4SP++cAip468MR6hy5qrwOZuuw0+GA76fQE0olhT/bNdvY0PEyY69nuKo8sNeKOuSju/mee7iUlSCl5uGSW1J3NRIYfa47XXL32stAelMm5JxrH03PqCyPALpjQkJwgqYbRYpMdFOcUIu1RBUQ8cKNXsSOrtzyUnR5pVuBj67gc5VBCeqmVg0lVzrpotiXZ09V2A1rKv/omvi9YfkFVkSBPfl6CJiTq4ZANe1aqMuyUQmz/wEAAP//Ep8/EQ==" } diff --git a/x-pack/metricbeat/module/containerd/helper.go b/x-pack/metricbeat/module/containerd/helper.go new file mode 100644 index 00000000000..2bbce615673 --- /dev/null +++ b/x-pack/metricbeat/module/containerd/helper.go @@ -0,0 +1,24 @@ +package containerd + +import "github.com/elastic/beats/v7/libbeat/common" + +// SetCIDandNamespace sets container.id ECS field and containerd.namespace module field +func SetCIDandNamespace(event common.MapStr) (common.MapStr, common.MapStr, string) { + containerFields := common.MapStr{} + moduleFields := common.MapStr{} + rootFields := common.MapStr{} + var cID string + if containerID, ok := event["id"]; ok { + cID = (containerID).(string) + containerFields.Put("id", cID) + event.Delete("id") + } + if len(containerFields) > 0 { + rootFields.Put("container", containerFields) + } + if ns, ok := event["namespace"]; ok { + moduleFields.Put("namespace", ns) + event.Delete("namespace") + } + return rootFields, moduleFields, cID +} diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected b/x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected index de58cab43cc..016b938235b 100644 --- a/x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected +++ b/x-pack/metricbeat/module/containerd/memory/_meta/test/containerd.v1.5.2.expected @@ -5,7 +5,9 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" } }, - "ModuleFields": null, + "ModuleFields": { + "namespace": "k8s.io" + }, "MetricSetFields": { "activeFiles": 1216512, "cache": 140980224, diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index c0778b69236..5b559b7a3bf 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -11,7 +11,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common/cfgwarn" - "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/metricbeat/helper/prometheus" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/mb/parse" @@ -52,6 +51,7 @@ var ( }, Labels: map[string]prometheus.LabelMap{ "container_id": prometheus.KeyLabel("id"), + "namespace": prometheus.KeyLabel("namespace"), }, } ) @@ -112,19 +112,8 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { for _, event := range events { - // setting ECS container.id - rootFields := common.MapStr{} - containerFields := common.MapStr{} - var cID string - if containerID, ok := event["id"]; ok { - cID = (containerID).(string) - containerFields.Put("id", cID) - event.Delete("id") - } - - if len(containerFields) > 0 { - rootFields.Put("container", containerFields) - } + // setting ECS container.id and containerd.namespace + rootFields, moduleFields, cID := containerd.SetCIDandNamespace(event) // Calculate memory total usage percentage if m.calcPct { @@ -149,6 +138,7 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { reporter.Event(mb.Event{ RootFields: rootFields, + ModuleFields: moduleFields, MetricSetFields: event, Namespace: "containerd.memory", }) From a8b3fa16e4ca7cdeb3427346192287c4476e0315 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Fri, 17 Dec 2021 12:36:07 +0200 Subject: [PATCH 24/37] make update --- metricbeat/docs/fields.asciidoc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index e37ba5f4954..6428c06b742 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -10268,6 +10268,16 @@ Information and statistics about containerd's running containers. +*`containerd.namespace`*:: ++ +-- +Containerd namespace + + +type: keyword + +-- + [float] === blkio From de94d3eb557c576f4f51ea09659e811b0511cb5e Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Fri, 17 Dec 2021 13:01:36 +0200 Subject: [PATCH 25/37] fmt helper --- x-pack/metricbeat/module/containerd/helper.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-pack/metricbeat/module/containerd/helper.go b/x-pack/metricbeat/module/containerd/helper.go index 2bbce615673..cf7aedf613c 100644 --- a/x-pack/metricbeat/module/containerd/helper.go +++ b/x-pack/metricbeat/module/containerd/helper.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + package containerd import "github.com/elastic/beats/v7/libbeat/common" From 2358f5e7a99812a997c4af834d954daa2c9cb034 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Fri, 17 Dec 2021 13:09:11 +0200 Subject: [PATCH 26/37] Add changelog entry --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 15434665d0b..24c13807bd5 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -285,6 +285,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Preliminary AIX support {pull}27954[27954] - Add option to skip older k8s events {pull}29396[29396] - Add `add_resource_metadata` configuration to Kubernetes module. {pull}29133[29133] +- Add `containerd` module with `cpu`, `memory`, `blkio` metricsets. {pull}29247[29247] *Packetbeat* From d35b4ce634b6be98f0cf72d3cee9b32f5eaf74f1 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Mon, 20 Dec 2021 11:49:32 +0200 Subject: [PATCH 27/37] Add check for memoryLimit different than zero --- x-pack/metricbeat/module/containerd/memory/memory.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 5b559b7a3bf..e73dee49a70 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -122,7 +122,7 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { usageTotal, err := event.GetValue("usage.total") if err == nil { memoryLimit, err := event.GetValue("usage.limit") - if err == nil { + if err == nil && memoryLimit.(float64) != 0.0 { // calculate working set memory usage workingSetUsage := usageTotal.(float64) - inactiveFiles.(float64) workingSetUsagePct := workingSetUsage / memoryLimit.(float64) From 0486457d3b89dc1a8fcee70104f99c293e202fd7 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Mon, 20 Dec 2021 12:50:55 +0200 Subject: [PATCH 28/37] Prevent zero division --- x-pack/metricbeat/module/containerd/memory/memory.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index e73dee49a70..4b3f2e362e1 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -122,13 +122,14 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { usageTotal, err := event.GetValue("usage.total") if err == nil { memoryLimit, err := event.GetValue("usage.limit") - if err == nil && memoryLimit.(float64) != 0.0 { + mLfloat, ok := memoryLimit.(float64) + if err == nil && ok && mLfloat != 0.0 { // calculate working set memory usage workingSetUsage := usageTotal.(float64) - inactiveFiles.(float64) - workingSetUsagePct := workingSetUsage / memoryLimit.(float64) + workingSetUsagePct := workingSetUsage / mLfloat event.Put("workingset.pct", workingSetUsagePct) - memoryUsagePct := usageTotal.(float64) / memoryLimit.(float64) + memoryUsagePct := usageTotal.(float64) / mLfloat event.Put("usage.pct", memoryUsagePct) m.Logger().Debugf("memoryUsagePct for %+v is %+v", cID, memoryUsagePct) } From 5be9960ff9482e9b4b736f3fd742817293cf7c04 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 22 Dec 2021 10:35:57 +0200 Subject: [PATCH 29/37] Review updates --- .../module/containerd/_meta/config.yml | 3 ++- .../module/containerd/blkio/blkio.go | 15 +++++++++++-- x-pack/metricbeat/module/containerd/config.go | 6 ++++-- .../metricbeat/module/containerd/cpu/cpu.go | 15 ++++++++++--- x-pack/metricbeat/module/containerd/helper.go | 21 ++++++++----------- .../module/containerd/memory/memory.go | 17 ++++++++++++--- 6 files changed, 54 insertions(+), 23 deletions(-) diff --git a/x-pack/metricbeat/module/containerd/_meta/config.yml b/x-pack/metricbeat/module/containerd/_meta/config.yml index b69056ab085..cec6ac8a2f5 100644 --- a/x-pack/metricbeat/module/containerd/_meta/config.yml +++ b/x-pack/metricbeat/module/containerd/_meta/config.yml @@ -3,5 +3,6 @@ enabled: false period: 10s hosts: ["localhost:1338"] - calcpct: true + calcpct.cpu: true + calcpct.memory: true diff --git a/x-pack/metricbeat/module/containerd/blkio/blkio.go b/x-pack/metricbeat/module/containerd/blkio/blkio.go index 99805adb82f..7ffb30e4aec 100644 --- a/x-pack/metricbeat/module/containerd/blkio/blkio.go +++ b/x-pack/metricbeat/module/containerd/blkio/blkio.go @@ -7,6 +7,8 @@ package blkio import ( "fmt" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/pkg/errors" "github.com/elastic/beats/v7/x-pack/metricbeat/module/containerd" @@ -104,8 +106,17 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { return errors.Wrap(err, "error getting events") } for _, event := range events { - // setting ECS container.id and containerd.namespace - rootFields, moduleFields, _ := containerd.SetCIDandNamespace(event) + // setting ECS container.id and module field containerd.namespace + containerFields := common.MapStr{} + moduleFields := common.MapStr{} + rootFields := common.MapStr{} + + cID := containerd.GetAndDeleteCid(event) + namespace := containerd.GetAndDeleteNamespace(event) + + containerFields.Put("id", cID) + rootFields.Put("container", containerFields) + moduleFields.Put("namespace", namespace) reporter.Event(mb.Event{ RootFields: rootFields, diff --git a/x-pack/metricbeat/module/containerd/config.go b/x-pack/metricbeat/module/containerd/config.go index 26e2333ac7c..3c8910acba7 100644 --- a/x-pack/metricbeat/module/containerd/config.go +++ b/x-pack/metricbeat/module/containerd/config.go @@ -6,12 +6,14 @@ package containerd // Config contains the config needed for containerd type Config struct { - CalculatePct bool `config:"calcpct"` + CalculateCpuPct bool `config:"calcpct.cpu"` + CalculateMemPct bool `config:"calcpct.memory"` } // DefaultConfig returns default module config func DefaultConfig() Config { return Config{ - CalculatePct: true, + CalculateCpuPct: true, + CalculateMemPct: true, } } diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index 6ab8a0f5dd8..dc5e2d77be6 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -91,7 +91,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { BaseMetricSet: base, prometheusClient: pc, mod: mod, - calcPct: config.CalculatePct, + calcPct: config.CalculateCpuPct, preTimestamp: time.Time{}, preContainerCpuTotalUsage: map[string]float64{}, preContainerCpuKernelUsage: map[string]float64{}, @@ -122,8 +122,17 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } for _, event := range events { - // setting ECS container.id and containerd.namespace - rootFields, moduleFields, cID := containerd.SetCIDandNamespace(event) + // setting ECS container.id and module field containerd.namespace + containerFields := common.MapStr{} + moduleFields := common.MapStr{} + rootFields := common.MapStr{} + + cID := containerd.GetAndDeleteCid(event) + namespace := containerd.GetAndDeleteNamespace(event) + + containerFields.Put("id", cID) + rootFields.Put("container", containerFields) + moduleFields.Put("namespace", namespace) if m.calcPct { contCpus, ok := perContainerCpus[cID] diff --git a/x-pack/metricbeat/module/containerd/helper.go b/x-pack/metricbeat/module/containerd/helper.go index cf7aedf613c..b4fac5f72fd 100644 --- a/x-pack/metricbeat/module/containerd/helper.go +++ b/x-pack/metricbeat/module/containerd/helper.go @@ -6,23 +6,20 @@ package containerd import "github.com/elastic/beats/v7/libbeat/common" -// SetCIDandNamespace sets container.id ECS field and containerd.namespace module field -func SetCIDandNamespace(event common.MapStr) (common.MapStr, common.MapStr, string) { - containerFields := common.MapStr{} - moduleFields := common.MapStr{} - rootFields := common.MapStr{} - var cID string +// GetAndDeleteCid deletes and returns container id from an event +func GetAndDeleteCid(event common.MapStr) (cID string) { if containerID, ok := event["id"]; ok { cID = (containerID).(string) - containerFields.Put("id", cID) event.Delete("id") } - if len(containerFields) > 0 { - rootFields.Put("container", containerFields) - } + return +} + +// GetAndDeleteNamespace deletes and returns namespace from an event +func GetAndDeleteNamespace(event common.MapStr) (namespace string) { if ns, ok := event["namespace"]; ok { - moduleFields.Put("namespace", ns) + namespace = (ns).(string) event.Delete("namespace") } - return rootFields, moduleFields, cID + return } diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 4b3f2e362e1..829893393fc 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -7,6 +7,8 @@ package memory import ( "fmt" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/pkg/errors" "github.com/elastic/beats/v7/libbeat/common/cfgwarn" @@ -95,7 +97,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { BaseMetricSet: base, prometheusClient: pc, mod: mod, - calcPct: config.CalculatePct, + calcPct: config.CalculateMemPct, }, nil } @@ -112,8 +114,17 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { for _, event := range events { - // setting ECS container.id and containerd.namespace - rootFields, moduleFields, cID := containerd.SetCIDandNamespace(event) + // setting ECS container.id and module field containerd.namespace + containerFields := common.MapStr{} + moduleFields := common.MapStr{} + rootFields := common.MapStr{} + + cID := containerd.GetAndDeleteCid(event) + namespace := containerd.GetAndDeleteNamespace(event) + + containerFields.Put("id", cID) + rootFields.Put("container", containerFields) + moduleFields.Put("namespace", namespace) // Calculate memory total usage percentage if m.calcPct { From f75539b849ed2506f3c23485cfb35d8b3d6ebd4c Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 22 Dec 2021 12:23:09 +0200 Subject: [PATCH 30/37] Update data.json files --- .../module/containerd/blkio/_meta/data.json | 24 ++++++++++-- .../module/containerd/cpu/_meta/data.json | 22 +++++++---- .../module/containerd/memory/_meta/data.json | 38 +++++++++++++++++-- .../module/containerd/memory/memory.go | 34 +++++++++-------- 4 files changed, 87 insertions(+), 31 deletions(-) diff --git a/x-pack/metricbeat/module/containerd/blkio/_meta/data.json b/x-pack/metricbeat/module/containerd/blkio/_meta/data.json index 67209b7c3f9..d1f4774a706 100644 --- a/x-pack/metricbeat/module/containerd/blkio/_meta/data.json +++ b/x-pack/metricbeat/module/containerd/blkio/_meta/data.json @@ -10,10 +10,26 @@ "name":"blkio", "rtt":44269 }, - "containerd":{ - "blkio":{ - "example": "blkio" - } + "containerd": { + "blkio": { + "read": { + "ops": 168, + "bytes": 4952064 + }, + "summary": { + "ops": 168, + "bytes": 4952064 + }, + "write": { + "ops": 20, + "bytes": 123134 + }, + "device": "/dev/vda" + }, + "namespace": "k8s.io" + }, + "container": { + "id": "b4d9e874a2de96e4512a32a49df09641fa792a99bebcc6d353723850a50db831" }, "type":"metricsets" } diff --git a/x-pack/metricbeat/module/containerd/cpu/_meta/data.json b/x-pack/metricbeat/module/containerd/cpu/_meta/data.json index 73210e76e26..1dc40fe4cb7 100644 --- a/x-pack/metricbeat/module/containerd/cpu/_meta/data.json +++ b/x-pack/metricbeat/module/containerd/cpu/_meta/data.json @@ -4,17 +4,23 @@ "id": "7434687dbe3684407afa899582f2909203b9dc5537632b512f76798db5c0787d" }, "containerd": { + "namespace": "k8s.io", "cpu": { "usage": { - "cpu": { - "4": { - "ns": 105731762224 - } + "user": { + "ns": 22526620000000, + "pct": 0.2496932948025663 }, - "percpu": {} + "total": { + "pct": 0.24969398913655017, + "ns": 22554111128186 + }, + "kernel": { + "ns": 16740000000, + "pct": 0 + } } - }, - "namespace": "k8s.io" + } }, "event": { "dataset": "containerd.cpu", @@ -29,4 +35,4 @@ "address": "127.0.0.1:55555", "type": "containerd" } -} \ No newline at end of file +} diff --git a/x-pack/metricbeat/module/containerd/memory/_meta/data.json b/x-pack/metricbeat/module/containerd/memory/_meta/data.json index 61cd69542da..67eceb1ad10 100644 --- a/x-pack/metricbeat/module/containerd/memory/_meta/data.json +++ b/x-pack/metricbeat/module/containerd/memory/_meta/data.json @@ -10,9 +10,41 @@ "name":"memory", "rtt":44269 }, - "containerd":{ - "memory":{ - "example": "memory" + "containerd": { + "namespace": "k8s.io", + "memory": { + "activeFiles": 0, + "workingset": { + "pct": 0.07224264705882352 + }, + "swap": { + "limit": 9223372036854772000, + "total": 49373184, + "max": 49848320, + "fail": { + "count": 0 + } + }, + "kernel": { + "limit": 9223372036854772000, + "fail": { + "count": 0 + }, + "max": 843776, + "total": 827392 + }, + "rss": 13651968, + "cache": 33792000, + "usage": { + "fail": { + "count": 0 + }, + "limit": 178257920, + "total": 49373184, + "pct": 0.27697610294117647, + "max": 49848320 + }, + "inactiveFiles": 36495360 } }, "type":"metricsets" diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index 829893393fc..b2297e20c0e 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -129,22 +129,24 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { // Calculate memory total usage percentage if m.calcPct { inactiveFiles, err := event.GetValue("inactiveFiles") - if err == nil { - usageTotal, err := event.GetValue("usage.total") - if err == nil { - memoryLimit, err := event.GetValue("usage.limit") - mLfloat, ok := memoryLimit.(float64) - if err == nil && ok && mLfloat != 0.0 { - // calculate working set memory usage - workingSetUsage := usageTotal.(float64) - inactiveFiles.(float64) - workingSetUsagePct := workingSetUsage / mLfloat - event.Put("workingset.pct", workingSetUsagePct) - - memoryUsagePct := usageTotal.(float64) / mLfloat - event.Put("usage.pct", memoryUsagePct) - m.Logger().Debugf("memoryUsagePct for %+v is %+v", cID, memoryUsagePct) - } - } + if err != nil { + continue + } + usageTotal, err := event.GetValue("usage.total") + if err != nil { + continue + } + memoryLimit, err := event.GetValue("usage.limit") + mLfloat, ok := memoryLimit.(float64) + if err == nil && ok && mLfloat != 0.0 { + // calculate working set memory usage + workingSetUsage := usageTotal.(float64) - inactiveFiles.(float64) + workingSetUsagePct := workingSetUsage / mLfloat + event.Put("workingset.pct", workingSetUsagePct) + + memoryUsagePct := usageTotal.(float64) / mLfloat + event.Put("usage.pct", memoryUsagePct) + m.Logger().Debugf("memoryUsagePct for %+v is %+v", cID, memoryUsagePct) } } From 4cdb80598fe1d1f6c9d3201b1750ea612db73c7a Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 22 Dec 2021 13:40:16 +0200 Subject: [PATCH 31/37] Update yml files --- x-pack/metricbeat/metricbeat.reference.yml | 3 ++- x-pack/metricbeat/modules.d/containerd.yml.disabled | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 3370447cdbb..b06899889cf 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -433,7 +433,8 @@ metricbeat.modules: enabled: false period: 10s hosts: ["localhost:1338"] - calcpct: true + calcpct.cpu: true + calcpct.memory: true #------------------------------- Coredns Module ------------------------------- diff --git a/x-pack/metricbeat/modules.d/containerd.yml.disabled b/x-pack/metricbeat/modules.d/containerd.yml.disabled index de854afdf15..e3dcea8fa5e 100644 --- a/x-pack/metricbeat/modules.d/containerd.yml.disabled +++ b/x-pack/metricbeat/modules.d/containerd.yml.disabled @@ -6,5 +6,6 @@ enabled: false period: 10s hosts: ["localhost:1338"] - calcpct: true + calcpct.cpu: true + calcpct.memory: true From c641c388c9404be780bbd7a68f7a009c0ccdcf56 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 22 Dec 2021 13:46:54 +0200 Subject: [PATCH 32/37] Make update --- metricbeat/docs/modules/containerd.asciidoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index 930d9badf75..2b2817d175f 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -28,7 +28,8 @@ metricbeat.modules: enabled: false period: 10s hosts: ["localhost:1338"] - calcpct: true + calcpct.cpu: true + calcpct.memory: true ---- From 3ca0046eb4f32876891a0de728632df9985d174f Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 22 Dec 2021 16:51:16 +0200 Subject: [PATCH 33/37] Update containerd documentation --- metricbeat/docs/modules/containerd.asciidoc | 42 ++++++++++++++++++- x-pack/metricbeat/metricbeat.reference.yml | 4 ++ .../module/containerd/_meta/config.yml | 4 ++ .../module/containerd/_meta/docs.asciidoc | 38 ++++++++++++++++- .../modules.d/containerd.yml.disabled | 4 ++ 5 files changed, 90 insertions(+), 2 deletions(-) diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index 2b2817d175f..773bca08d09 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -10,7 +10,43 @@ This file is generated! See scripts/mage/docs_collector.go beta[] -This is the containerd module. +include::{libbeat-dir}/shared/integration-link.asciidoc[] + +:modulename!: + +Containerd module collects cpu, memory and blkio statistics about +running containers controlled by containerd runtime. + +The current metricsets are: `cpu`, `blkio` and `memory`. They are not enabled by default. + +[float] +=== Prerequisites +`Containerd` daemon has to be configured to provide metrics before enabling containerd module. + +In the configuration file located in `/etc/containerd/config.toml` metrics endpoint needs to +be set and containerd daemon needs to be restarted. + +``` +[metrics] + address = "127.0.0.1:1338" +``` + +[float] +=== Compatibility + +The Conatinerd module is tested with the following versions of Containerd: +v1.5.2 + +[float] +=== Module-specific configuration notes + +For cpu metricset if `calcpct.cpu` setting is set to true, cpu usage percentages will be calculated +and more specifically fields `containerd.cpu.usage.total.pct`, `containerd.cpu.usage.kernel.pct`, `containerd.cpu.usage.user.pct`. +Default value is true. + +For memory metricset if `calcpct.memory` setting is set to true, memory usage percentages will be calculated +and more specifically fields `containerd.memory.usage.pct` and `containerd.memory.workingset.pct`. +Default value is true. @@ -27,7 +63,11 @@ metricbeat.modules: metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s + # containerd metrics endpoint is configured in /etc/containerd/config.toml + # Metrics endpoint does not listen by default + # https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.toml.5.md hosts: ["localhost:1338"] + # if set to true, cpu and memory usage percentages will be calculated. Default is true calcpct.cpu: true calcpct.memory: true diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 96ad7cc6d0a..fe9d188a172 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -432,7 +432,11 @@ metricbeat.modules: metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s + # containerd metrics endpoint is configured in /etc/containerd/config.toml + # Metrics endpoint does not listen by default + # https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.toml.5.md hosts: ["localhost:1338"] + # if set to true, cpu and memory usage percentages will be calculated. Default is true calcpct.cpu: true calcpct.memory: true diff --git a/x-pack/metricbeat/module/containerd/_meta/config.yml b/x-pack/metricbeat/module/containerd/_meta/config.yml index cec6ac8a2f5..e1a3774a19c 100644 --- a/x-pack/metricbeat/module/containerd/_meta/config.yml +++ b/x-pack/metricbeat/module/containerd/_meta/config.yml @@ -2,7 +2,11 @@ metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s + # containerd metrics endpoint is configured in /etc/containerd/config.toml + # Metrics endpoint does not listen by default + # https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.toml.5.md hosts: ["localhost:1338"] + # if set to true, cpu and memory usage percentages will be calculated. Default is true calcpct.cpu: true calcpct.memory: true diff --git a/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc b/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc index 95d2cfa1ba0..c90470cbb4d 100644 --- a/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc @@ -1,2 +1,38 @@ -This is the containerd module. +include::{libbeat-dir}/shared/integration-link.asciidoc[] + +:modulename!: + +Containerd module collects cpu, memory and blkio statistics about +running containers controlled by containerd runtime. + +The current metricsets are: `cpu`, `blkio` and `memory`. They are not enabled by default. + +[float] +=== Prerequisites +`Containerd` daemon has to be configured to provide metrics before enabling containerd module. + +In the configuration file located in `/etc/containerd/config.toml` metrics endpoint needs to +be set and containerd daemon needs to be restarted. + +``` +[metrics] + address = "127.0.0.1:1338" +``` + +[float] +=== Compatibility + +The Conatinerd module is tested with the following versions of Containerd: +v1.5.2 + +[float] +=== Module-specific configuration notes + +For cpu metricset if `calcpct.cpu` setting is set to true, cpu usage percentages will be calculated +and more specifically fields `containerd.cpu.usage.total.pct`, `containerd.cpu.usage.kernel.pct`, `containerd.cpu.usage.user.pct`. +Default value is true. + +For memory metricset if `calcpct.memory` setting is set to true, memory usage percentages will be calculated +and more specifically fields `containerd.memory.usage.pct` and `containerd.memory.workingset.pct`. +Default value is true. diff --git a/x-pack/metricbeat/modules.d/containerd.yml.disabled b/x-pack/metricbeat/modules.d/containerd.yml.disabled index e3dcea8fa5e..0f4eca4bd76 100644 --- a/x-pack/metricbeat/modules.d/containerd.yml.disabled +++ b/x-pack/metricbeat/modules.d/containerd.yml.disabled @@ -5,7 +5,11 @@ metricsets: ["cpu", "memory", "blkio"] enabled: false period: 10s + # containerd metrics endpoint is configured in /etc/containerd/config.toml + # Metrics endpoint does not listen by default + # https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.toml.5.md hosts: ["localhost:1338"] + # if set to true, cpu and memory usage percentages will be calculated. Default is true calcpct.cpu: true calcpct.memory: true From 5d305731985b59f94312217276628cf9e12e7501 Mon Sep 17 00:00:00 2001 From: Michael Katsoulis Date: Tue, 4 Jan 2022 12:54:21 +0200 Subject: [PATCH 34/37] Update metricbeat/docs/modules/containerd.asciidoc Co-authored-by: hendry-lim <48344515+hendry-lim@users.noreply.github.com> --- metricbeat/docs/modules/containerd.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index 773bca08d09..7242a49af0d 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -34,7 +34,7 @@ be set and containerd daemon needs to be restarted. [float] === Compatibility -The Conatinerd module is tested with the following versions of Containerd: +The Containerd module is tested with the following versions of Containerd: v1.5.2 [float] From 0dcb148be51631484a30ed9f9e2ff15ac7a93a37 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Wed, 5 Jan 2022 10:20:03 +0200 Subject: [PATCH 35/37] Make update --- metricbeat/docs/modules/containerd.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index 7242a49af0d..773bca08d09 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -34,7 +34,7 @@ be set and containerd daemon needs to be restarted. [float] === Compatibility -The Containerd module is tested with the following versions of Containerd: +The Conatinerd module is tested with the following versions of Containerd: v1.5.2 [float] From 69f4b5f5b5803a8ac685cf82e977818711fe5b14 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Tue, 11 Jan 2022 11:12:18 +0200 Subject: [PATCH 36/37] Metricsets enabled by default --- metricbeat/docs/modules/containerd.asciidoc | 3 +-- x-pack/metricbeat/metricbeat.reference.yml | 1 - x-pack/metricbeat/module/containerd/_meta/config.yml | 1 - x-pack/metricbeat/module/containerd/_meta/docs.asciidoc | 2 +- x-pack/metricbeat/modules.d/containerd.yml.disabled | 1 - 5 files changed, 2 insertions(+), 6 deletions(-) diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index 773bca08d09..4cbe4fa907a 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -17,7 +17,7 @@ include::{libbeat-dir}/shared/integration-link.asciidoc[] Containerd module collects cpu, memory and blkio statistics about running containers controlled by containerd runtime. -The current metricsets are: `cpu`, `blkio` and `memory`. They are not enabled by default. +The current metricsets are: `cpu`, `blkio` and `memory` and are enabled by default. [float] === Prerequisites @@ -61,7 +61,6 @@ in <>. Here is an example configuration: metricbeat.modules: - module: containerd metricsets: ["cpu", "memory", "blkio"] - enabled: false period: 10s # containerd metrics endpoint is configured in /etc/containerd/config.toml # Metrics endpoint does not listen by default diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index fe9d188a172..c77fdff04f5 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -430,7 +430,6 @@ metricbeat.modules: #------------------------------ Containerd Module ------------------------------ - module: containerd metricsets: ["cpu", "memory", "blkio"] - enabled: false period: 10s # containerd metrics endpoint is configured in /etc/containerd/config.toml # Metrics endpoint does not listen by default diff --git a/x-pack/metricbeat/module/containerd/_meta/config.yml b/x-pack/metricbeat/module/containerd/_meta/config.yml index e1a3774a19c..6197801bfcb 100644 --- a/x-pack/metricbeat/module/containerd/_meta/config.yml +++ b/x-pack/metricbeat/module/containerd/_meta/config.yml @@ -1,6 +1,5 @@ - module: containerd metricsets: ["cpu", "memory", "blkio"] - enabled: false period: 10s # containerd metrics endpoint is configured in /etc/containerd/config.toml # Metrics endpoint does not listen by default diff --git a/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc b/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc index c90470cbb4d..8f1b23f77df 100644 --- a/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc @@ -5,7 +5,7 @@ include::{libbeat-dir}/shared/integration-link.asciidoc[] Containerd module collects cpu, memory and blkio statistics about running containers controlled by containerd runtime. -The current metricsets are: `cpu`, `blkio` and `memory`. They are not enabled by default. +The current metricsets are: `cpu`, `blkio` and `memory` and are enabled by default. [float] === Prerequisites diff --git a/x-pack/metricbeat/modules.d/containerd.yml.disabled b/x-pack/metricbeat/modules.d/containerd.yml.disabled index 0f4eca4bd76..cc735a455c7 100644 --- a/x-pack/metricbeat/modules.d/containerd.yml.disabled +++ b/x-pack/metricbeat/modules.d/containerd.yml.disabled @@ -3,7 +3,6 @@ - module: containerd metricsets: ["cpu", "memory", "blkio"] - enabled: false period: 10s # containerd metrics endpoint is configured in /etc/containerd/config.toml # Metrics endpoint does not listen by default From 34badbe81bad19e0a38cfc6443d1093b95316711 Mon Sep 17 00:00:00 2001 From: MichaelKatsoulis Date: Tue, 11 Jan 2022 13:20:02 +0200 Subject: [PATCH 37/37] Add debug message in case of inactiveFiles,usage.total or usage.limit not present in memory event --- metricbeat/docs/modules/containerd.asciidoc | 2 +- x-pack/metricbeat/module/containerd/_meta/docs.asciidoc | 2 +- x-pack/metricbeat/module/containerd/cpu/cpu.go | 1 + x-pack/metricbeat/module/containerd/memory/memory.go | 8 +++++++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/metricbeat/docs/modules/containerd.asciidoc b/metricbeat/docs/modules/containerd.asciidoc index 4cbe4fa907a..41c600b202b 100644 --- a/metricbeat/docs/modules/containerd.asciidoc +++ b/metricbeat/docs/modules/containerd.asciidoc @@ -34,7 +34,7 @@ be set and containerd daemon needs to be restarted. [float] === Compatibility -The Conatinerd module is tested with the following versions of Containerd: +The Containerd module is tested with the following versions of Containerd: v1.5.2 [float] diff --git a/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc b/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc index 8f1b23f77df..3ee37e6722c 100644 --- a/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/containerd/_meta/docs.asciidoc @@ -22,7 +22,7 @@ be set and containerd daemon needs to be restarted. [float] === Compatibility -The Conatinerd module is tested with the following versions of Containerd: +The Containerd module is tested with the following versions of Containerd: v1.5.2 [float] diff --git a/x-pack/metricbeat/module/containerd/cpu/cpu.go b/x-pack/metricbeat/module/containerd/cpu/cpu.go index dc5e2d77be6..135092f8184 100644 --- a/x-pack/metricbeat/module/containerd/cpu/cpu.go +++ b/x-pack/metricbeat/module/containerd/cpu/cpu.go @@ -156,6 +156,7 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { } // Calculate cpu kernel usage percentage + // If event does not contain usage.kernel.ns skip the calculation (event has only system.total) cpuUsageKernel, err := event.GetValue("usage.kernel.ns") if err == nil { cpuUsageKernelPct := calcUsagePct(timestampDelta, cpuUsageKernel.(float64), diff --git a/x-pack/metricbeat/module/containerd/memory/memory.go b/x-pack/metricbeat/module/containerd/memory/memory.go index b2297e20c0e..0bdc961a0e4 100644 --- a/x-pack/metricbeat/module/containerd/memory/memory.go +++ b/x-pack/metricbeat/module/containerd/memory/memory.go @@ -130,15 +130,21 @@ func (m *metricset) Fetch(reporter mb.ReporterV2) error { if m.calcPct { inactiveFiles, err := event.GetValue("inactiveFiles") if err != nil { + m.Logger().Debugf("memoryUsagePct calculation skipped. inactiveFiles not present in the event: %w", err) continue } usageTotal, err := event.GetValue("usage.total") if err != nil { + m.Logger().Debugf("memoryUsagePct calculation skipped. usage.total not present in the event: %w", err) continue } memoryLimit, err := event.GetValue("usage.limit") + if err != nil { + m.Logger().Debugf("memoryUsagePct calculation skipped. usage.limit not present in the event: %w", err) + continue + } mLfloat, ok := memoryLimit.(float64) - if err == nil && ok && mLfloat != 0.0 { + if ok && mLfloat != 0.0 { // calculate working set memory usage workingSetUsage := usageTotal.(float64) - inactiveFiles.(float64) workingSetUsagePct := workingSetUsage / mLfloat