From 9f4af8b79767d27cb132f088bf8b492c0cb80a35 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Wed, 13 Jul 2022 13:28:32 -0700 Subject: [PATCH 01/12] generate network metrics with direction embedded --- .../kubeletstatsreceiver/documentation.md | 8 + .../internal/metadata/generated_metrics_v2.go | 520 ++++++++++++++++++ receiver/kubeletstatsreceiver/metadata.yaml | 84 +++ 3 files changed, 612 insertions(+) diff --git a/receiver/kubeletstatsreceiver/documentation.md b/receiver/kubeletstatsreceiver/documentation.md index ad116f508bcb..7611fa771cfd 100644 --- a/receiver/kubeletstatsreceiver/documentation.md +++ b/receiver/kubeletstatsreceiver/documentation.md @@ -31,7 +31,11 @@ These are the metrics available for this scraper. | **k8s.node.memory.usage** | Node memory usage | By | Gauge(Int) | | | **k8s.node.memory.working_set** | Node memory working_set | By | Gauge(Int) | | | **k8s.node.network.errors** | Node network errors | 1 | Sum(Int) | | +| **k8s.node.network.errors.receive** | Node network receive errors | 1 | Sum(Int) | | +| **k8s.node.network.errors.transmit** | Node network transmission errors | 1 | Sum(Int) | | | **k8s.node.network.io** | Node network IO | By | Sum(Int) | | +| **k8s.node.network.io.receive** | Node network IO received | By | Sum(Int) | | +| **k8s.node.network.io.transmit** | Node network IO transmitted | By | Sum(Int) | | | **k8s.pod.cpu.time** | Pod CPU time | s | Sum(Double) | | | **k8s.pod.cpu.utilization** | Pod CPU utilization | 1 | Gauge(Double) | | | **k8s.pod.filesystem.available** | Pod filesystem available | By | Gauge(Int) | | @@ -44,7 +48,11 @@ These are the metrics available for this scraper. | **k8s.pod.memory.usage** | Pod memory usage | By | Gauge(Int) | | | **k8s.pod.memory.working_set** | Pod memory working_set | By | Gauge(Int) | | | **k8s.pod.network.errors** | Pod network errors | 1 | Sum(Int) | | +| **k8s.pod.network.errors.receive** | Pod network receive errors | 1 | Sum(Int) | | +| **k8s.pod.network.errors.transmit** | Pod network transmission errors | 1 | Sum(Int) | | | **k8s.pod.network.io** | Pod network IO | By | Sum(Int) | | +| **k8s.pod.network.io.receive** | Pod network IO received | By | Sum(Int) | | +| **k8s.pod.network.io.transmit** | Pod network IO transmitted | By | Sum(Int) | | | **k8s.volume.available** | The number of available bytes in the volume. | By | Gauge(Int) | | | **k8s.volume.capacity** | The total capacity in bytes of the volume. | By | Gauge(Int) | | | **k8s.volume.inodes** | The total inodes in the filesystem. | 1 | Gauge(Int) | | diff --git a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go index f10c03a1e9b3..050d524549d7 100644 --- a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go +++ b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go @@ -40,7 +40,11 @@ type MetricsSettings struct { K8sNodeMemoryUsage MetricSettings `mapstructure:"k8s.node.memory.usage"` K8sNodeMemoryWorkingSet MetricSettings `mapstructure:"k8s.node.memory.working_set"` K8sNodeNetworkErrors MetricSettings `mapstructure:"k8s.node.network.errors"` + K8sNodeNetworkErrorsReceive MetricSettings `mapstructure:"k8s.node.network.errors.receive"` + K8sNodeNetworkErrorsTransmit MetricSettings `mapstructure:"k8s.node.network.errors.transmit"` K8sNodeNetworkIo MetricSettings `mapstructure:"k8s.node.network.io"` + K8sNodeNetworkIoReceive MetricSettings `mapstructure:"k8s.node.network.io.receive"` + K8sNodeNetworkIoTransmit MetricSettings `mapstructure:"k8s.node.network.io.transmit"` K8sPodCPUTime MetricSettings `mapstructure:"k8s.pod.cpu.time"` K8sPodCPUUtilization MetricSettings `mapstructure:"k8s.pod.cpu.utilization"` K8sPodFilesystemAvailable MetricSettings `mapstructure:"k8s.pod.filesystem.available"` @@ -53,7 +57,11 @@ type MetricsSettings struct { K8sPodMemoryUsage MetricSettings `mapstructure:"k8s.pod.memory.usage"` K8sPodMemoryWorkingSet MetricSettings `mapstructure:"k8s.pod.memory.working_set"` K8sPodNetworkErrors MetricSettings `mapstructure:"k8s.pod.network.errors"` + K8sPodNetworkErrorsReceive MetricSettings `mapstructure:"k8s.pod.network.errors.receive"` + K8sPodNetworkErrorsTransmit MetricSettings `mapstructure:"k8s.pod.network.errors.transmit"` K8sPodNetworkIo MetricSettings `mapstructure:"k8s.pod.network.io"` + K8sPodNetworkIoReceive MetricSettings `mapstructure:"k8s.pod.network.io.receive"` + K8sPodNetworkIoTransmit MetricSettings `mapstructure:"k8s.pod.network.io.transmit"` K8sVolumeAvailable MetricSettings `mapstructure:"k8s.volume.available"` K8sVolumeCapacity MetricSettings `mapstructure:"k8s.volume.capacity"` K8sVolumeInodes MetricSettings `mapstructure:"k8s.volume.inodes"` @@ -132,9 +140,21 @@ func DefaultMetricsSettings() MetricsSettings { K8sNodeNetworkErrors: MetricSettings{ Enabled: true, }, + K8sNodeNetworkErrorsReceive: MetricSettings{ + Enabled: true, + }, + K8sNodeNetworkErrorsTransmit: MetricSettings{ + Enabled: true, + }, K8sNodeNetworkIo: MetricSettings{ Enabled: true, }, + K8sNodeNetworkIoReceive: MetricSettings{ + Enabled: true, + }, + K8sNodeNetworkIoTransmit: MetricSettings{ + Enabled: true, + }, K8sPodCPUTime: MetricSettings{ Enabled: true, }, @@ -171,9 +191,21 @@ func DefaultMetricsSettings() MetricsSettings { K8sPodNetworkErrors: MetricSettings{ Enabled: true, }, + K8sPodNetworkErrorsReceive: MetricSettings{ + Enabled: true, + }, + K8sPodNetworkErrorsTransmit: MetricSettings{ + Enabled: true, + }, K8sPodNetworkIo: MetricSettings{ Enabled: true, }, + K8sPodNetworkIoReceive: MetricSettings{ + Enabled: true, + }, + K8sPodNetworkIoTransmit: MetricSettings{ + Enabled: true, + }, K8sVolumeAvailable: MetricSettings{ Enabled: true, }, @@ -1354,6 +1386,112 @@ func newMetricK8sNodeNetworkErrors(settings MetricSettings) metricK8sNodeNetwork return m } +type metricK8sNodeNetworkErrorsReceive struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.node.network.errors.receive metric with initial data. +func (m *metricK8sNodeNetworkErrorsReceive) init() { + m.data.SetName("k8s.node.network.errors.receive") + m.data.SetDescription("Node network receive errors") + m.data.SetUnit("1") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sNodeNetworkErrorsReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sNodeNetworkErrorsReceive) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sNodeNetworkErrorsReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sNodeNetworkErrorsReceive(settings MetricSettings) metricK8sNodeNetworkErrorsReceive { + m := metricK8sNodeNetworkErrorsReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricK8sNodeNetworkErrorsTransmit struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.node.network.errors.transmit metric with initial data. +func (m *metricK8sNodeNetworkErrorsTransmit) init() { + m.data.SetName("k8s.node.network.errors.transmit") + m.data.SetDescription("Node network transmission errors") + m.data.SetUnit("1") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sNodeNetworkErrorsTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sNodeNetworkErrorsTransmit) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sNodeNetworkErrorsTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sNodeNetworkErrorsTransmit(settings MetricSettings) metricK8sNodeNetworkErrorsTransmit { + m := metricK8sNodeNetworkErrorsTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricK8sNodeNetworkIo struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -1408,6 +1546,112 @@ func newMetricK8sNodeNetworkIo(settings MetricSettings) metricK8sNodeNetworkIo { return m } +type metricK8sNodeNetworkIoReceive struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.node.network.io.receive metric with initial data. +func (m *metricK8sNodeNetworkIoReceive) init() { + m.data.SetName("k8s.node.network.io.receive") + m.data.SetDescription("Node network IO received") + m.data.SetUnit("By") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sNodeNetworkIoReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sNodeNetworkIoReceive) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sNodeNetworkIoReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sNodeNetworkIoReceive(settings MetricSettings) metricK8sNodeNetworkIoReceive { + m := metricK8sNodeNetworkIoReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricK8sNodeNetworkIoTransmit struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.node.network.io.transmit metric with initial data. +func (m *metricK8sNodeNetworkIoTransmit) init() { + m.data.SetName("k8s.node.network.io.transmit") + m.data.SetDescription("Node network IO transmitted") + m.data.SetUnit("By") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sNodeNetworkIoTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sNodeNetworkIoTransmit) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sNodeNetworkIoTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sNodeNetworkIoTransmit(settings MetricSettings) metricK8sNodeNetworkIoTransmit { + m := metricK8sNodeNetworkIoTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricK8sPodCPUTime struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -2003,6 +2247,112 @@ func newMetricK8sPodNetworkErrors(settings MetricSettings) metricK8sPodNetworkEr return m } +type metricK8sPodNetworkErrorsReceive struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.pod.network.errors.receive metric with initial data. +func (m *metricK8sPodNetworkErrorsReceive) init() { + m.data.SetName("k8s.pod.network.errors.receive") + m.data.SetDescription("Pod network receive errors") + m.data.SetUnit("1") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sPodNetworkErrorsReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sPodNetworkErrorsReceive) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sPodNetworkErrorsReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sPodNetworkErrorsReceive(settings MetricSettings) metricK8sPodNetworkErrorsReceive { + m := metricK8sPodNetworkErrorsReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricK8sPodNetworkErrorsTransmit struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.pod.network.errors.transmit metric with initial data. +func (m *metricK8sPodNetworkErrorsTransmit) init() { + m.data.SetName("k8s.pod.network.errors.transmit") + m.data.SetDescription("Pod network transmission errors") + m.data.SetUnit("1") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sPodNetworkErrorsTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sPodNetworkErrorsTransmit) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sPodNetworkErrorsTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sPodNetworkErrorsTransmit(settings MetricSettings) metricK8sPodNetworkErrorsTransmit { + m := metricK8sPodNetworkErrorsTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricK8sPodNetworkIo struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -2057,6 +2407,112 @@ func newMetricK8sPodNetworkIo(settings MetricSettings) metricK8sPodNetworkIo { return m } +type metricK8sPodNetworkIoReceive struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.pod.network.io.receive metric with initial data. +func (m *metricK8sPodNetworkIoReceive) init() { + m.data.SetName("k8s.pod.network.io.receive") + m.data.SetDescription("Pod network IO received") + m.data.SetUnit("By") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sPodNetworkIoReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sPodNetworkIoReceive) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sPodNetworkIoReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sPodNetworkIoReceive(settings MetricSettings) metricK8sPodNetworkIoReceive { + m := metricK8sPodNetworkIoReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricK8sPodNetworkIoTransmit struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.pod.network.io.transmit metric with initial data. +func (m *metricK8sPodNetworkIoTransmit) init() { + m.data.SetName("k8s.pod.network.io.transmit") + m.data.SetDescription("Pod network IO transmitted") + m.data.SetUnit("By") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sPodNetworkIoTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sPodNetworkIoTransmit) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sPodNetworkIoTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sPodNetworkIoTransmit(settings MetricSettings) metricK8sPodNetworkIoTransmit { + m := metricK8sPodNetworkIoTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricK8sVolumeAvailable struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -2333,7 +2789,11 @@ type MetricsBuilder struct { metricK8sNodeMemoryUsage metricK8sNodeMemoryUsage metricK8sNodeMemoryWorkingSet metricK8sNodeMemoryWorkingSet metricK8sNodeNetworkErrors metricK8sNodeNetworkErrors + metricK8sNodeNetworkErrorsReceive metricK8sNodeNetworkErrorsReceive + metricK8sNodeNetworkErrorsTransmit metricK8sNodeNetworkErrorsTransmit metricK8sNodeNetworkIo metricK8sNodeNetworkIo + metricK8sNodeNetworkIoReceive metricK8sNodeNetworkIoReceive + metricK8sNodeNetworkIoTransmit metricK8sNodeNetworkIoTransmit metricK8sPodCPUTime metricK8sPodCPUTime metricK8sPodCPUUtilization metricK8sPodCPUUtilization metricK8sPodFilesystemAvailable metricK8sPodFilesystemAvailable @@ -2346,7 +2806,11 @@ type MetricsBuilder struct { metricK8sPodMemoryUsage metricK8sPodMemoryUsage metricK8sPodMemoryWorkingSet metricK8sPodMemoryWorkingSet metricK8sPodNetworkErrors metricK8sPodNetworkErrors + metricK8sPodNetworkErrorsReceive metricK8sPodNetworkErrorsReceive + metricK8sPodNetworkErrorsTransmit metricK8sPodNetworkErrorsTransmit metricK8sPodNetworkIo metricK8sPodNetworkIo + metricK8sPodNetworkIoReceive metricK8sPodNetworkIoReceive + metricK8sPodNetworkIoTransmit metricK8sPodNetworkIoTransmit metricK8sVolumeAvailable metricK8sVolumeAvailable metricK8sVolumeCapacity metricK8sVolumeCapacity metricK8sVolumeInodes metricK8sVolumeInodes @@ -2392,7 +2856,11 @@ func NewMetricsBuilder(settings MetricsSettings, buildInfo component.BuildInfo, metricK8sNodeMemoryUsage: newMetricK8sNodeMemoryUsage(settings.K8sNodeMemoryUsage), metricK8sNodeMemoryWorkingSet: newMetricK8sNodeMemoryWorkingSet(settings.K8sNodeMemoryWorkingSet), metricK8sNodeNetworkErrors: newMetricK8sNodeNetworkErrors(settings.K8sNodeNetworkErrors), + metricK8sNodeNetworkErrorsReceive: newMetricK8sNodeNetworkErrorsReceive(settings.K8sNodeNetworkErrorsReceive), + metricK8sNodeNetworkErrorsTransmit: newMetricK8sNodeNetworkErrorsTransmit(settings.K8sNodeNetworkErrorsTransmit), metricK8sNodeNetworkIo: newMetricK8sNodeNetworkIo(settings.K8sNodeNetworkIo), + metricK8sNodeNetworkIoReceive: newMetricK8sNodeNetworkIoReceive(settings.K8sNodeNetworkIoReceive), + metricK8sNodeNetworkIoTransmit: newMetricK8sNodeNetworkIoTransmit(settings.K8sNodeNetworkIoTransmit), metricK8sPodCPUTime: newMetricK8sPodCPUTime(settings.K8sPodCPUTime), metricK8sPodCPUUtilization: newMetricK8sPodCPUUtilization(settings.K8sPodCPUUtilization), metricK8sPodFilesystemAvailable: newMetricK8sPodFilesystemAvailable(settings.K8sPodFilesystemAvailable), @@ -2405,7 +2873,11 @@ func NewMetricsBuilder(settings MetricsSettings, buildInfo component.BuildInfo, metricK8sPodMemoryUsage: newMetricK8sPodMemoryUsage(settings.K8sPodMemoryUsage), metricK8sPodMemoryWorkingSet: newMetricK8sPodMemoryWorkingSet(settings.K8sPodMemoryWorkingSet), metricK8sPodNetworkErrors: newMetricK8sPodNetworkErrors(settings.K8sPodNetworkErrors), + metricK8sPodNetworkErrorsReceive: newMetricK8sPodNetworkErrorsReceive(settings.K8sPodNetworkErrorsReceive), + metricK8sPodNetworkErrorsTransmit: newMetricK8sPodNetworkErrorsTransmit(settings.K8sPodNetworkErrorsTransmit), metricK8sPodNetworkIo: newMetricK8sPodNetworkIo(settings.K8sPodNetworkIo), + metricK8sPodNetworkIoReceive: newMetricK8sPodNetworkIoReceive(settings.K8sPodNetworkIoReceive), + metricK8sPodNetworkIoTransmit: newMetricK8sPodNetworkIoTransmit(settings.K8sPodNetworkIoTransmit), metricK8sVolumeAvailable: newMetricK8sVolumeAvailable(settings.K8sVolumeAvailable), metricK8sVolumeCapacity: newMetricK8sVolumeCapacity(settings.K8sVolumeCapacity), metricK8sVolumeInodes: newMetricK8sVolumeInodes(settings.K8sVolumeInodes), @@ -2591,7 +3063,11 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sNodeMemoryUsage.emit(ils.Metrics()) mb.metricK8sNodeMemoryWorkingSet.emit(ils.Metrics()) mb.metricK8sNodeNetworkErrors.emit(ils.Metrics()) + mb.metricK8sNodeNetworkErrorsReceive.emit(ils.Metrics()) + mb.metricK8sNodeNetworkErrorsTransmit.emit(ils.Metrics()) mb.metricK8sNodeNetworkIo.emit(ils.Metrics()) + mb.metricK8sNodeNetworkIoReceive.emit(ils.Metrics()) + mb.metricK8sNodeNetworkIoTransmit.emit(ils.Metrics()) mb.metricK8sPodCPUTime.emit(ils.Metrics()) mb.metricK8sPodCPUUtilization.emit(ils.Metrics()) mb.metricK8sPodFilesystemAvailable.emit(ils.Metrics()) @@ -2604,7 +3080,11 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sPodMemoryUsage.emit(ils.Metrics()) mb.metricK8sPodMemoryWorkingSet.emit(ils.Metrics()) mb.metricK8sPodNetworkErrors.emit(ils.Metrics()) + mb.metricK8sPodNetworkErrorsReceive.emit(ils.Metrics()) + mb.metricK8sPodNetworkErrorsTransmit.emit(ils.Metrics()) mb.metricK8sPodNetworkIo.emit(ils.Metrics()) + mb.metricK8sPodNetworkIoReceive.emit(ils.Metrics()) + mb.metricK8sPodNetworkIoTransmit.emit(ils.Metrics()) mb.metricK8sVolumeAvailable.emit(ils.Metrics()) mb.metricK8sVolumeCapacity.emit(ils.Metrics()) mb.metricK8sVolumeInodes.emit(ils.Metrics()) @@ -2744,11 +3224,31 @@ func (mb *MetricsBuilder) RecordK8sNodeNetworkErrorsDataPoint(ts pcommon.Timesta mb.metricK8sNodeNetworkErrors.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue, directionAttributeValue.String()) } +// RecordK8sNodeNetworkErrorsReceiveDataPoint adds a data point to k8s.node.network.errors.receive metric. +func (mb *MetricsBuilder) RecordK8sNodeNetworkErrorsReceiveDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sNodeNetworkErrorsReceive.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + +// RecordK8sNodeNetworkErrorsTransmitDataPoint adds a data point to k8s.node.network.errors.transmit metric. +func (mb *MetricsBuilder) RecordK8sNodeNetworkErrorsTransmitDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sNodeNetworkErrorsTransmit.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + // RecordK8sNodeNetworkIoDataPoint adds a data point to k8s.node.network.io metric. func (mb *MetricsBuilder) RecordK8sNodeNetworkIoDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string, directionAttributeValue AttributeDirection) { mb.metricK8sNodeNetworkIo.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue, directionAttributeValue.String()) } +// RecordK8sNodeNetworkIoReceiveDataPoint adds a data point to k8s.node.network.io.receive metric. +func (mb *MetricsBuilder) RecordK8sNodeNetworkIoReceiveDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sNodeNetworkIoReceive.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + +// RecordK8sNodeNetworkIoTransmitDataPoint adds a data point to k8s.node.network.io.transmit metric. +func (mb *MetricsBuilder) RecordK8sNodeNetworkIoTransmitDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sNodeNetworkIoTransmit.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + // RecordK8sPodCPUTimeDataPoint adds a data point to k8s.pod.cpu.time metric. func (mb *MetricsBuilder) RecordK8sPodCPUTimeDataPoint(ts pcommon.Timestamp, val float64) { mb.metricK8sPodCPUTime.recordDataPoint(mb.startTime, ts, val) @@ -2809,11 +3309,31 @@ func (mb *MetricsBuilder) RecordK8sPodNetworkErrorsDataPoint(ts pcommon.Timestam mb.metricK8sPodNetworkErrors.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue, directionAttributeValue.String()) } +// RecordK8sPodNetworkErrorsReceiveDataPoint adds a data point to k8s.pod.network.errors.receive metric. +func (mb *MetricsBuilder) RecordK8sPodNetworkErrorsReceiveDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sPodNetworkErrorsReceive.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + +// RecordK8sPodNetworkErrorsTransmitDataPoint adds a data point to k8s.pod.network.errors.transmit metric. +func (mb *MetricsBuilder) RecordK8sPodNetworkErrorsTransmitDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sPodNetworkErrorsTransmit.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + // RecordK8sPodNetworkIoDataPoint adds a data point to k8s.pod.network.io metric. func (mb *MetricsBuilder) RecordK8sPodNetworkIoDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string, directionAttributeValue AttributeDirection) { mb.metricK8sPodNetworkIo.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue, directionAttributeValue.String()) } +// RecordK8sPodNetworkIoReceiveDataPoint adds a data point to k8s.pod.network.io.receive metric. +func (mb *MetricsBuilder) RecordK8sPodNetworkIoReceiveDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sPodNetworkIoReceive.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + +// RecordK8sPodNetworkIoTransmitDataPoint adds a data point to k8s.pod.network.io.transmit metric. +func (mb *MetricsBuilder) RecordK8sPodNetworkIoTransmitDataPoint(ts pcommon.Timestamp, val int64, interfaceAttributeValue string) { + mb.metricK8sPodNetworkIoTransmit.recordDataPoint(mb.startTime, ts, val, interfaceAttributeValue) +} + // RecordK8sVolumeAvailableDataPoint adds a data point to k8s.volume.available metric. func (mb *MetricsBuilder) RecordK8sVolumeAvailableDataPoint(ts pcommon.Timestamp, val int64) { mb.metricK8sVolumeAvailable.recordDataPoint(mb.startTime, ts, val) diff --git a/receiver/kubeletstatsreceiver/metadata.yaml b/receiver/kubeletstatsreceiver/metadata.yaml index 88d69aaa7e5b..799bc593d196 100644 --- a/receiver/kubeletstatsreceiver/metadata.yaml +++ b/receiver/kubeletstatsreceiver/metadata.yaml @@ -135,6 +135,7 @@ metrics: gauge: value_type: int attributes: [] + # produced when receiver.kubeletstats.emitMetricsWithDirectionAttribute feature gate is enabled k8s.node.network.io: enabled: true description: "Node network IO" @@ -144,6 +145,27 @@ metrics: monotonic: true aggregation: cumulative attributes: ["interface", "direction"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.node.network.io.transmit: + enabled: true + description: "Node network IO transmitted" + unit: By + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.node.network.io.receive: + enabled: true + description: "Node network IO received" + unit: By + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] + # produced when receiver.kubeletstats.emitMetricsWithDirectionAttribute feature gate is enabled k8s.node.network.errors: enabled: true description: "Node network errors" @@ -153,6 +175,26 @@ metrics: monotonic: true aggregation: cumulative attributes: ["interface", "direction"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.node.network.errors.transmit: + enabled: true + description: "Node network transmission errors" + unit: 1 + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.node.network.errors.receive: + enabled: true + description: "Node network receive errors" + unit: 1 + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] k8s.pod.cpu.utilization: enabled: true description: "Pod CPU utilization" @@ -232,6 +274,7 @@ metrics: gauge: value_type: int attributes: [] + # produced when receiver.kubeletstats.emitMetricsWithDirectionAttribute feature gate is enabled k8s.pod.network.io: enabled: true description: "Pod network IO" @@ -241,6 +284,27 @@ metrics: monotonic: true aggregation: cumulative attributes: ["interface", "direction"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.pod.network.io.transmit: + enabled: true + description: "Pod network IO transmitted" + unit: By + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.pod.network.io.receive: + enabled: true + description: "Pod network IO received" + unit: By + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] + # produced when receiver.kubeletstats.emitMetricsWithDirectionAttribute feature gate is enabled k8s.pod.network.errors: enabled: true description: "Pod network errors" @@ -250,6 +314,26 @@ metrics: monotonic: true aggregation: cumulative attributes: ["interface", "direction"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.pod.network.errors.transmit: + enabled: true + description: "Pod network transmission errors" + unit: 1 + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] + # produced when receiver.kubeletstats.emitMetricsWithoutDirectionAttribute feature gate is enabled + k8s.pod.network.errors.receive: + enabled: true + description: "Pod network receive errors" + unit: 1 + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: ["interface"] container.cpu.utilization: enabled: true description: "Container CPU utilization" From 9f4f03fd8ee4db0cd3ee6c9696f991b1e3a07166 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Wed, 13 Jul 2022 13:51:44 -0700 Subject: [PATCH 02/12] add feature gates for direction attributes --- receiver/kubeletstatsreceiver/scraper.go | 53 ++++++++++++++++++++---- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/receiver/kubeletstatsreceiver/scraper.go b/receiver/kubeletstatsreceiver/scraper.go index 272d11b2409d..60ad9da8edee 100644 --- a/receiver/kubeletstatsreceiver/scraper.go +++ b/receiver/kubeletstatsreceiver/scraper.go @@ -23,6 +23,7 @@ import ( "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver/scraperhelper" + "go.opentelemetry.io/collector/service/featuregate" "go.uber.org/zap" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -32,6 +33,38 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/kubeletstatsreceiver/internal/metadata" ) +const ( + emitMetricsWithDirectionAttributeFeatureGateID = "receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute" + emitMetricsWithoutDirectionAttributeFeatureGateID = "receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute" +) + +var ( + emitMetricsWithDirectionAttributeFeatureGate = featuregate.Gate{ + ID: emitMetricsWithDirectionAttributeFeatureGateID, + Enabled: true, + Description: "Some kubeletstats metrics reported are transitioning from being reported with a direction " + + "attribute to being reported with the direction included in the metric name to adhere to the " + + "OpenTelemetry specification. This feature gate controls emitting the old metrics with the direction " + + "attribute. For more details, see: " + + "https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/kubeletstatsreceiver/README.md#feature-gate-configurations", + } + + emitMetricsWithoutDirectionAttributeFeatureGate = featuregate.Gate{ + ID: emitMetricsWithoutDirectionAttributeFeatureGateID, + Enabled: false, + Description: "Some kubeletstats metrics reported are transitioning from being reported with a direction " + + "attribute to being reported with the direction included in the metric name to adhere to the " + + "OpenTelemetry specification. This feature gate controls emitting the new metrics without the direction " + + "attribute. For more details, see: " + + "https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/kubeletstatsreceiver/README.md#feature-gate-configurations", + } +) + +func init() { + featuregate.GetRegistry().MustRegister(emitMetricsWithDirectionAttributeFeatureGate) + featuregate.GetRegistry().MustRegister(emitMetricsWithoutDirectionAttributeFeatureGate) +} + type scraperOptions struct { id config.ComponentID collectionInterval time.Duration @@ -41,14 +74,16 @@ type scraperOptions struct { } type kubletScraper struct { - statsProvider *kubelet.StatsProvider - metadataProvider *kubelet.MetadataProvider - logger *zap.Logger - extraMetadataLabels []kubelet.MetadataLabel - metricGroupsToCollect map[kubelet.MetricGroup]bool - k8sAPIClient kubernetes.Interface - cachedVolumeLabels map[string][]metadata.ResourceMetricsOption - mbs *metadata.MetricsBuilders + statsProvider *kubelet.StatsProvider + metadataProvider *kubelet.MetadataProvider + logger *zap.Logger + extraMetadataLabels []kubelet.MetadataLabel + metricGroupsToCollect map[kubelet.MetricGroup]bool + k8sAPIClient kubernetes.Interface + cachedVolumeLabels map[string][]metadata.ResourceMetricsOption + mbs *metadata.MetricsBuilders + emitMetricsWithDirectionAttribute bool + emitMetricsWithoutDirectionAttribute bool } func newKubletScraper( @@ -71,6 +106,8 @@ func newKubletScraper( ContainerMetricsBuilder: metadata.NewMetricsBuilder(metricsConfig, set.BuildInfo), OtherMetricsBuilder: metadata.NewMetricsBuilder(metricsConfig, set.BuildInfo), }, + emitMetricsWithDirectionAttribute: featuregate.GetRegistry().IsEnabled(emitMetricsWithDirectionAttributeFeatureGateID), + emitMetricsWithoutDirectionAttribute: featuregate.GetRegistry().IsEnabled(emitMetricsWithoutDirectionAttributeFeatureGateID), } return scraperhelper.NewScraper(typeStr, ks.scrape) } From 29922b9648ac50710e666001f37b7ed8b033f1ca Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Fri, 15 Jul 2022 10:51:18 -0700 Subject: [PATCH 03/12] setup code paths for network metrics with direction --- .../internal/kubelet/accumulator.go | 22 ++++++++++++------- .../internal/kubelet/metrics.go | 14 +++++++----- .../internal/kubelet/metrics_test.go | 6 ++--- .../internal/kubelet/network.go | 8 +++---- .../internal/metadata/metrics.go | 6 ++--- receiver/kubeletstatsreceiver/scraper.go | 3 ++- 6 files changed, 34 insertions(+), 25 deletions(-) diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go index b82e14e5564e..933aef0dc8cf 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go @@ -44,12 +44,13 @@ var ValidMetricGroups = map[MetricGroup]bool{ } type metricDataAccumulator struct { - m []pmetric.Metrics - metadata Metadata - logger *zap.Logger - metricGroupsToCollect map[MetricGroup]bool - time time.Time - mbs *metadata.MetricsBuilders + m []pmetric.Metrics + metadata Metadata + logger *zap.Logger + metricGroupsToCollect map[MetricGroup]bool + time time.Time + mbs *metadata.MetricsBuilders + emitMetricsWithDirectionAttribute bool } func (a *metricDataAccumulator) nodeStats(s stats.NodeStats) { @@ -61,7 +62,10 @@ func (a *metricDataAccumulator) nodeStats(s stats.NodeStats) { addCPUMetrics(a.mbs.NodeMetricsBuilder, metadata.NodeCPUMetrics, s.CPU, currentTime) addMemoryMetrics(a.mbs.NodeMetricsBuilder, metadata.NodeMemoryMetrics, s.Memory, currentTime) addFilesystemMetrics(a.mbs.NodeMetricsBuilder, metadata.NodeFilesystemMetrics, s.Fs, currentTime) - addNetworkMetrics(a.mbs.NodeMetricsBuilder, metadata.NodeNetworkMetrics, s.Network, currentTime) + if a.emitMetricsWithDirectionAttribute { + addNetworkMetricsWithDirection(a.mbs.NodeMetricsBuilder, metadata.NodeNetworkMetricsWithDirection, s.Network, currentTime) + } + // todo s.Runtime.ImageFs a.m = append(a.m, a.mbs.NodeMetricsBuilder.Emit( @@ -79,7 +83,9 @@ func (a *metricDataAccumulator) podStats(s stats.PodStats) { addCPUMetrics(a.mbs.PodMetricsBuilder, metadata.PodCPUMetrics, s.CPU, currentTime) addMemoryMetrics(a.mbs.PodMetricsBuilder, metadata.PodMemoryMetrics, s.Memory, currentTime) addFilesystemMetrics(a.mbs.PodMetricsBuilder, metadata.PodFilesystemMetrics, s.EphemeralStorage, currentTime) - addNetworkMetrics(a.mbs.PodMetricsBuilder, metadata.PodNetworkMetrics, s.Network, currentTime) + if a.emitMetricsWithDirectionAttribute { + addNetworkMetricsWithDirection(a.mbs.PodMetricsBuilder, metadata.PodNetworkMetricsWithDirection, s.Network, currentTime) + } a.m = append(a.m, a.mbs.PodMetricsBuilder.Emit( metadata.WithStartTimeOverride(pcommon.NewTimestampFromTime(s.StartTime.Time)), diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go b/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go index f01b598db4b3..d505c9e0ff96 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go @@ -28,13 +28,15 @@ func MetricsData( logger *zap.Logger, summary *stats.Summary, metadata Metadata, metricGroupsToCollect map[MetricGroup]bool, - mbs *metadata.MetricsBuilders) []pmetric.Metrics { + mbs *metadata.MetricsBuilders, + emitMetricsWithDirectionAttribute bool) []pmetric.Metrics { acc := &metricDataAccumulator{ - metadata: metadata, - logger: logger, - metricGroupsToCollect: metricGroupsToCollect, - time: time.Now(), - mbs: mbs, + metadata: metadata, + logger: logger, + metricGroupsToCollect: metricGroupsToCollect, + time: time.Now(), + mbs: mbs, + emitMetricsWithDirectionAttribute: emitMetricsWithDirectionAttribute, } acc.nodeStats(summary.Node) for _, podStats := range summary.Pods { diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go b/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go index 8f8e9ab821a4..7c0a559f1dab 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go @@ -51,12 +51,12 @@ func TestMetricAccumulator(t *testing.T) { ContainerMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), OtherMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), } - requireMetricsOk(t, MetricsData(zap.NewNop(), summary, k8sMetadata, ValidMetricGroups, mbs)) + requireMetricsOk(t, MetricsData(zap.NewNop(), summary, k8sMetadata, ValidMetricGroups, mbs, true)) // Disable all groups mbs.NodeMetricsBuilder.Reset() mbs.PodMetricsBuilder.Reset() mbs.OtherMetricsBuilder.Reset() - require.Equal(t, 0, len(MetricsData(zap.NewNop(), summary, k8sMetadata, map[MetricGroup]bool{}, mbs))) + require.Equal(t, 0, len(MetricsData(zap.NewNop(), summary, k8sMetadata, map[MetricGroup]bool{}, mbs, true))) } func requireMetricsOk(t *testing.T, mds []pmetric.Metrics) { @@ -182,5 +182,5 @@ func fakeMetrics() []pmetric.Metrics { ContainerMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), OtherMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), } - return MetricsData(zap.NewNop(), summary, Metadata{}, mgs, mbs) + return MetricsData(zap.NewNop(), summary, Metadata{}, mgs, mbs, true) } diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/network.go b/receiver/kubeletstatsreceiver/internal/kubelet/network.go index 5d494ce08e85..03e8e356bd5c 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/network.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/network.go @@ -21,16 +21,16 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/kubeletstatsreceiver/internal/metadata" ) -func addNetworkMetrics(mb *metadata.MetricsBuilder, networkMetrics metadata.NetworkMetrics, s *stats.NetworkStats, currentTime pcommon.Timestamp) { +func addNetworkMetricsWithDirection(mb *metadata.MetricsBuilder, networkMetrics metadata.NetworkMetricsWithDirection, s *stats.NetworkStats, currentTime pcommon.Timestamp) { if s == nil { return } - recordNetworkDataPoint(mb, networkMetrics.IO, s, currentTime) - recordNetworkDataPoint(mb, networkMetrics.Errors, s, currentTime) + recordNetworkDataPointWithDirection(mb, networkMetrics.IO, s, currentTime) + recordNetworkDataPointWithDirection(mb, networkMetrics.Errors, s, currentTime) } -func recordNetworkDataPoint(mb *metadata.MetricsBuilder, recordDataPoint metadata.RecordIntDataPointWithDirectionFunc, s *stats.NetworkStats, currentTime pcommon.Timestamp) { +func recordNetworkDataPointWithDirection(mb *metadata.MetricsBuilder, recordDataPoint metadata.RecordIntDataPointWithDirectionFunc, s *stats.NetworkStats, currentTime pcommon.Timestamp) { if s.RxBytes == nil && s.TxBytes == nil { return } diff --git a/receiver/kubeletstatsreceiver/internal/metadata/metrics.go b/receiver/kubeletstatsreceiver/internal/metadata/metrics.go index 590e1cf44c56..3ac6558ac215 100644 --- a/receiver/kubeletstatsreceiver/internal/metadata/metrics.go +++ b/receiver/kubeletstatsreceiver/internal/metadata/metrics.go @@ -109,17 +109,17 @@ var ContainerFilesystemMetrics = FilesystemMetrics{ Usage: (*MetricsBuilder).RecordContainerFilesystemUsageDataPoint, } -type NetworkMetrics struct { +type NetworkMetricsWithDirection struct { IO RecordIntDataPointWithDirectionFunc Errors RecordIntDataPointWithDirectionFunc } -var NodeNetworkMetrics = NetworkMetrics{ +var NodeNetworkMetricsWithDirection = NetworkMetricsWithDirection{ IO: (*MetricsBuilder).RecordK8sNodeNetworkIoDataPoint, Errors: (*MetricsBuilder).RecordK8sNodeNetworkErrorsDataPoint, } -var PodNetworkMetrics = NetworkMetrics{ +var PodNetworkMetricsWithDirection = NetworkMetricsWithDirection{ IO: (*MetricsBuilder).RecordK8sPodNetworkIoDataPoint, Errors: (*MetricsBuilder).RecordK8sPodNetworkErrorsDataPoint, } diff --git a/receiver/kubeletstatsreceiver/scraper.go b/receiver/kubeletstatsreceiver/scraper.go index 60ad9da8edee..3c2c2b567f3a 100644 --- a/receiver/kubeletstatsreceiver/scraper.go +++ b/receiver/kubeletstatsreceiver/scraper.go @@ -130,7 +130,8 @@ func (r *kubletScraper) scrape(context.Context) (pmetric.Metrics, error) { } metadata := kubelet.NewMetadata(r.extraMetadataLabels, podsMetadata, r.detailedPVCLabelsSetter()) - mds := kubelet.MetricsData(r.logger, summary, metadata, r.metricGroupsToCollect, r.mbs) + // pass in direction attribute options + mds := kubelet.MetricsData(r.logger, summary, metadata, r.metricGroupsToCollect, r.mbs, r.emitMetricsWithDirectionAttribute) md := pmetric.NewMetrics() for i := range mds { mds[i].ResourceMetrics().MoveAndAppendTo(md.ResourceMetrics()) From ed92ee05fa096d7e3ccaafcdf17ef542c6fb7aa2 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Fri, 15 Jul 2022 17:26:27 -0700 Subject: [PATCH 04/12] emit network metrics without a direction attribute --- .../internal/kubelet/accumulator.go | 22 ++++--- .../internal/kubelet/metrics.go | 16 ++--- .../internal/kubelet/metrics_test.go | 60 ++++++++++++++++--- .../internal/kubelet/network.go | 18 ++++++ .../internal/metadata/metrics.go | 34 +++++++++++ receiver/kubeletstatsreceiver/scraper.go | 3 +- 6 files changed, 127 insertions(+), 26 deletions(-) diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go index 933aef0dc8cf..7ed54718eeb0 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go @@ -44,13 +44,14 @@ var ValidMetricGroups = map[MetricGroup]bool{ } type metricDataAccumulator struct { - m []pmetric.Metrics - metadata Metadata - logger *zap.Logger - metricGroupsToCollect map[MetricGroup]bool - time time.Time - mbs *metadata.MetricsBuilders - emitMetricsWithDirectionAttribute bool + m []pmetric.Metrics + metadata Metadata + logger *zap.Logger + metricGroupsToCollect map[MetricGroup]bool + time time.Time + mbs *metadata.MetricsBuilders + emitMetricsWithDirectionAttribute bool + emitMetricsWithoutDirectionAttribute bool } func (a *metricDataAccumulator) nodeStats(s stats.NodeStats) { @@ -65,7 +66,9 @@ func (a *metricDataAccumulator) nodeStats(s stats.NodeStats) { if a.emitMetricsWithDirectionAttribute { addNetworkMetricsWithDirection(a.mbs.NodeMetricsBuilder, metadata.NodeNetworkMetricsWithDirection, s.Network, currentTime) } - + if a.emitMetricsWithoutDirectionAttribute { + addNetworkMetrics(a.mbs.NodeMetricsBuilder, metadata.NodeNetworkMetrics, s.Network, currentTime) + } // todo s.Runtime.ImageFs a.m = append(a.m, a.mbs.NodeMetricsBuilder.Emit( @@ -86,6 +89,9 @@ func (a *metricDataAccumulator) podStats(s stats.PodStats) { if a.emitMetricsWithDirectionAttribute { addNetworkMetricsWithDirection(a.mbs.PodMetricsBuilder, metadata.PodNetworkMetricsWithDirection, s.Network, currentTime) } + if a.emitMetricsWithoutDirectionAttribute { + addNetworkMetrics(a.mbs.PodMetricsBuilder, metadata.PodNetworkMetrics, s.Network, currentTime) + } a.m = append(a.m, a.mbs.PodMetricsBuilder.Emit( metadata.WithStartTimeOverride(pcommon.NewTimestampFromTime(s.StartTime.Time)), diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go b/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go index d505c9e0ff96..8beeeeb515eb 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go @@ -29,14 +29,16 @@ func MetricsData( metadata Metadata, metricGroupsToCollect map[MetricGroup]bool, mbs *metadata.MetricsBuilders, - emitMetricsWithDirectionAttribute bool) []pmetric.Metrics { + emitMetricsWithDirectionAttribute, + emitMetricsWithoutDirectionAttribute bool) []pmetric.Metrics { acc := &metricDataAccumulator{ - metadata: metadata, - logger: logger, - metricGroupsToCollect: metricGroupsToCollect, - time: time.Now(), - mbs: mbs, - emitMetricsWithDirectionAttribute: emitMetricsWithDirectionAttribute, + metadata: metadata, + logger: logger, + metricGroupsToCollect: metricGroupsToCollect, + time: time.Now(), + mbs: mbs, + emitMetricsWithDirectionAttribute: emitMetricsWithDirectionAttribute, + emitMetricsWithoutDirectionAttribute: emitMetricsWithoutDirectionAttribute, } acc.nodeStats(summary.Node) for _, podStats := range summary.Pods { diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go b/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go index 7c0a559f1dab..51e0f5387843 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go @@ -51,12 +51,12 @@ func TestMetricAccumulator(t *testing.T) { ContainerMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), OtherMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), } - requireMetricsOk(t, MetricsData(zap.NewNop(), summary, k8sMetadata, ValidMetricGroups, mbs, true)) + requireMetricsOk(t, MetricsData(zap.NewNop(), summary, k8sMetadata, ValidMetricGroups, mbs, true, false)) // Disable all groups mbs.NodeMetricsBuilder.Reset() mbs.PodMetricsBuilder.Reset() mbs.OtherMetricsBuilder.Reset() - require.Equal(t, 0, len(MetricsData(zap.NewNop(), summary, k8sMetadata, map[MetricGroup]bool{}, mbs, true))) + require.Equal(t, 0, len(MetricsData(zap.NewNop(), summary, k8sMetadata, map[MetricGroup]bool{}, mbs, true, false))) } func requireMetricsOk(t *testing.T, mds []pmetric.Metrics) { @@ -112,7 +112,7 @@ func requireResourceOk(t *testing.T, resource pcommon.Resource) { } func TestWorkingSetMem(t *testing.T) { - metrics := indexedFakeMetrics() + metrics := indexedFakeMetrics(true, false) requireContains(t, metrics, "k8s.pod.memory.working_set") requireContains(t, metrics, "container.memory.working_set") @@ -122,7 +122,7 @@ func TestWorkingSetMem(t *testing.T) { } func TestPageFaults(t *testing.T) { - metrics := indexedFakeMetrics() + metrics := indexedFakeMetrics(true, false) requireContains(t, metrics, "k8s.pod.memory.page_faults") requireContains(t, metrics, "container.memory.page_faults") @@ -132,7 +132,7 @@ func TestPageFaults(t *testing.T) { } func TestMajorPageFaults(t *testing.T) { - metrics := indexedFakeMetrics() + metrics := indexedFakeMetrics(true, false) requireContains(t, metrics, "k8s.pod.memory.major_page_faults") requireContains(t, metrics, "container.memory.major_page_faults") @@ -141,13 +141,55 @@ func TestMajorPageFaults(t *testing.T) { require.Equal(t, int64(12), value) } +func TestEmitMetricsWithDirectionAttribute(t *testing.T) { + metrics := indexedFakeMetrics(true, false) + metricNamesWithDirectionAttr := []string{ + "k8s.node.network.io", + "k8s.node.network.errors", + "k8s.pod.network.io", + "k8s.pod.network.errors", + } + for _, name := range metricNamesWithDirectionAttr { + requireContains(t, metrics, name) + metric := metrics[name][0] + for i := 0; i < metric.Sum().DataPoints().Len(); i++ { + dp := metric.Sum().DataPoints().At(i) + _, found := dp.Attributes().Get("direction") + require.True(t, found, "expected direction attribute") + } + } +} + +func TestEmitMetricsWithoutDirectionAttribute(t *testing.T) { + metrics := indexedFakeMetrics(false, true) + metricNamesWithoutDirectionAttr := []string{ + "k8s.node.network.io.receive", + "k8s.node.network.io.transmit", + "k8s.node.network.errors.receive", + "k8s.node.network.errors.transmit", + "k8s.pod.network.io.receive", + "k8s.pod.network.io.transmit", + "k8s.pod.network.errors.receive", + "k8s.pod.network.errors.transmit", + } + for _, name := range metricNamesWithoutDirectionAttr { + requireContains(t, metrics, name) + metric := metrics[name][0] + for i := 0; i < metric.Sum().DataPoints().Len(); i++ { + dp := metric.Sum().DataPoints().At(i) + _, found := dp.Attributes().Get("direction") + require.False(t, found, "unexpected direction attribute") + } + } +} + func requireContains(t *testing.T, metrics map[string][]pmetric.Metric, metricName string) { _, found := metrics[metricName] require.True(t, found) } -func indexedFakeMetrics() map[string][]pmetric.Metric { - mds := fakeMetrics() +func indexedFakeMetrics(emitMetricsWithDirectionAttribute, emitMetricsWithoutDirectionAttribute bool) map[string][]pmetric.Metric { + mds := fakeMetrics(emitMetricsWithDirectionAttribute, emitMetricsWithoutDirectionAttribute) metrics := make(map[string][]pmetric.Metric) for _, md := range mds { for i := 0; i < md.ResourceMetrics().Len(); i++ { @@ -167,7 +209,7 @@ func indexedFakeMetrics() map[string][]pmetric.Metric { return metrics } -func fakeMetrics() []pmetric.Metrics { +func fakeMetrics(emitMetricsWithDirectionAttribute, emitMetricsWithoutDirectionAttribute bool) []pmetric.Metrics { rc := &fakeRestClient{} statsProvider := NewStatsProvider(rc) summary, _ := statsProvider.StatsSummary() @@ -182,5 +224,5 @@ func fakeMetrics() []pmetric.Metrics { ContainerMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), OtherMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsSettings(), componenttest.NewNopReceiverCreateSettings().BuildInfo), } - return MetricsData(zap.NewNop(), summary, Metadata{}, mgs, mbs, true) + return MetricsData(zap.NewNop(), summary, Metadata{}, mgs, mbs, emitMetricsWithDirectionAttribute, emitMetricsWithoutDirectionAttribute) } diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/network.go b/receiver/kubeletstatsreceiver/internal/kubelet/network.go index 03e8e356bd5c..cc59bb0f4de8 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/network.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/network.go @@ -21,6 +21,24 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/kubeletstatsreceiver/internal/metadata" ) +func addNetworkMetrics(mb *metadata.MetricsBuilder, networkMetrics metadata.NetworkMetrics, s *stats.NetworkStats, currentTime pcommon.Timestamp) { + if s == nil { + return + } + + recordNetworkDataPoint(mb, networkMetrics.IO, s, currentTime) + recordNetworkDataPoint(mb, networkMetrics.Errors, s, currentTime) +} + +func recordNetworkDataPoint(mb *metadata.MetricsBuilder, r metadata.NetworkMetricsRecorder, s *stats.NetworkStats, currentTime pcommon.Timestamp) { + if s.RxBytes == nil && s.TxBytes == nil { + return + } + + r.RecordReceiveDataPoint(mb, currentTime, int64(*s.RxBytes), s.Name) + r.RecordTransmitDataPoint(mb, currentTime, int64(*s.TxBytes), s.Name) +} + func addNetworkMetricsWithDirection(mb *metadata.MetricsBuilder, networkMetrics metadata.NetworkMetricsWithDirection, s *stats.NetworkStats, currentTime pcommon.Timestamp) { if s == nil { return diff --git a/receiver/kubeletstatsreceiver/internal/metadata/metrics.go b/receiver/kubeletstatsreceiver/internal/metadata/metrics.go index 3ac6558ac215..2e8adaed3f98 100644 --- a/receiver/kubeletstatsreceiver/internal/metadata/metrics.go +++ b/receiver/kubeletstatsreceiver/internal/metadata/metrics.go @@ -22,6 +22,8 @@ type RecordIntDataPointFunc func(*MetricsBuilder, pcommon.Timestamp, int64) type RecordIntDataPointWithDirectionFunc func(*MetricsBuilder, pcommon.Timestamp, int64, string, AttributeDirection) +type RecordIntDataPointWithStringAttributeFunc func(*MetricsBuilder, pcommon.Timestamp, int64, string) + type MetricsBuilders struct { NodeMetricsBuilder *MetricsBuilder PodMetricsBuilder *MetricsBuilder @@ -109,6 +111,38 @@ var ContainerFilesystemMetrics = FilesystemMetrics{ Usage: (*MetricsBuilder).RecordContainerFilesystemUsageDataPoint, } +type NetworkMetrics struct { + IO NetworkMetricsRecorder + Errors NetworkMetricsRecorder +} + +type NetworkMetricsRecorder struct { + RecordReceiveDataPoint RecordIntDataPointWithStringAttributeFunc + RecordTransmitDataPoint RecordIntDataPointWithStringAttributeFunc +} + +var NodeNetworkMetrics = NetworkMetrics{ + IO: NetworkMetricsRecorder{ + RecordReceiveDataPoint: (*MetricsBuilder).RecordK8sNodeNetworkIoReceiveDataPoint, + RecordTransmitDataPoint: (*MetricsBuilder).RecordK8sNodeNetworkIoTransmitDataPoint, + }, + Errors: NetworkMetricsRecorder{ + RecordReceiveDataPoint: (*MetricsBuilder).RecordK8sNodeNetworkErrorsReceiveDataPoint, + RecordTransmitDataPoint: (*MetricsBuilder).RecordK8sNodeNetworkErrorsTransmitDataPoint, + }, +} + +var PodNetworkMetrics = NetworkMetrics{ + IO: NetworkMetricsRecorder{ + RecordReceiveDataPoint: (*MetricsBuilder).RecordK8sPodNetworkIoReceiveDataPoint, + RecordTransmitDataPoint: (*MetricsBuilder).RecordK8sPodNetworkIoTransmitDataPoint, + }, + Errors: NetworkMetricsRecorder{ + RecordReceiveDataPoint: (*MetricsBuilder).RecordK8sPodNetworkErrorsReceiveDataPoint, + RecordTransmitDataPoint: (*MetricsBuilder).RecordK8sPodNetworkErrorsTransmitDataPoint, + }, +} + type NetworkMetricsWithDirection struct { IO RecordIntDataPointWithDirectionFunc Errors RecordIntDataPointWithDirectionFunc diff --git a/receiver/kubeletstatsreceiver/scraper.go b/receiver/kubeletstatsreceiver/scraper.go index 3c2c2b567f3a..56eaeb3f27f1 100644 --- a/receiver/kubeletstatsreceiver/scraper.go +++ b/receiver/kubeletstatsreceiver/scraper.go @@ -130,8 +130,7 @@ func (r *kubletScraper) scrape(context.Context) (pmetric.Metrics, error) { } metadata := kubelet.NewMetadata(r.extraMetadataLabels, podsMetadata, r.detailedPVCLabelsSetter()) - // pass in direction attribute options - mds := kubelet.MetricsData(r.logger, summary, metadata, r.metricGroupsToCollect, r.mbs, r.emitMetricsWithDirectionAttribute) + mds := kubelet.MetricsData(r.logger, summary, metadata, r.metricGroupsToCollect, r.mbs, r.emitMetricsWithDirectionAttribute, r.emitMetricsWithoutDirectionAttribute) md := pmetric.NewMetrics() for i := range mds { mds[i].ResourceMetrics().MoveAndAppendTo(md.ResourceMetrics()) From 8da15b0dcce76775bc26598694cf87bbafb0ad7e Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Mon, 18 Jul 2022 14:03:06 -0700 Subject: [PATCH 05/12] update readme --- receiver/kubeletstatsreceiver/README.md | 45 +++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/receiver/kubeletstatsreceiver/README.md b/receiver/kubeletstatsreceiver/README.md index 0e3d01d25942..51d532ee3068 100644 --- a/receiver/kubeletstatsreceiver/README.md +++ b/receiver/kubeletstatsreceiver/README.md @@ -187,5 +187,50 @@ The following parameters can also be specified: The full list of settings exposed for this receiver are documented [here](./config.go) with detailed sample configurations [here](./testdata/config.yaml). +## Metrics + +Details about the metrics produced by this receiver can be found in [metadata.yaml](./metadata.yaml) with further documentation in [documentation.md](./documentation.md) + +### Feature gate configurations + +#### Transition from metrics with "direction" attribute + +Some kubeletstats metrics reported are transitioning from being reported with a `direction` attribute to being reported with the +direction included in the metric name to adhere to the OpenTelemetry specification +(https://github.com/open-telemetry/opentelemetry-specification/pull/2617): + +- `k8s.node.network.io` will become: + - `k8s.node.network.io.transmit` + - `k8s.node.network.io.receive` +- `k8s.node.network.errors` will become: + - `k8s.node.network.errors.transmit` + - `k8s.node.network.errors.receive` + +The following feature gates control the transition process: + +- **receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute**: controls if the new metrics without `direction` attribute are emitted by the receiver. +- **receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute**: controls if the deprecated metrics with `direction` attribute are emitted by the receiver. + +##### Transition schedule: + +1. v0.56.0, July 2022: + +- The new metrics are available for all scrapers, but disabled by default, they can be enabled with the feature gates. +- The old metrics with `direction` attribute are deprecated with a warning. +- `receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute` is enabled by default. +- `receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute` is disabled by default. + +2. v0.58.0, August 2022: + +- The new metrics are enabled by default, deprecated metrics disabled, they can be enabled with the feature gates. +- `receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute` is disabled by default. +- `receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute` is enabled by default. + +3. v0.60.0, September 2022: + +- The feature gates are removed. +- The new metrics without `direction` attribute are always emitted. +- The deprecated metrics with `direction` attribute are no longer available. + [beta]:https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib From 24495ac1e91db7c0299a2d3c5d98e9229e1a6dc4 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Mon, 18 Jul 2022 14:09:51 -0700 Subject: [PATCH 06/12] add changelog --- unreleased/kubeletstats_direction.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 unreleased/kubeletstats_direction.yaml diff --git a/unreleased/kubeletstats_direction.yaml b/unreleased/kubeletstats_direction.yaml new file mode 100755 index 000000000000..9b847a73be46 --- /dev/null +++ b/unreleased/kubeletstats_direction.yaml @@ -0,0 +1,23 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: kubeletstatsreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Remove direction for metrics. The feature gate: receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute can be set to apply the following (#12588)" + +# One or more tracking issues related to the change +issues: [12164] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: |- + - `kubeletstats` metrics: + - `k8s.node.network.io` will become: + - `k8s.node.network.io.transmit` + - `k8s.node.network.io.receive` + - `k8s.node.network.errors` will become: + - `k8s.node.network.errors.transmit` + - `k8s.node.network.errors.receive` From 8cb8e21c691a17571941dc1139e2b36e62fa980a Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 28 Jul 2022 09:20:15 -0700 Subject: [PATCH 07/12] log warning when emitting metrics with direction attribute --- receiver/kubeletstatsreceiver/scraper.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/receiver/kubeletstatsreceiver/scraper.go b/receiver/kubeletstatsreceiver/scraper.go index 56eaeb3f27f1..9adcaa4bec5a 100644 --- a/receiver/kubeletstatsreceiver/scraper.go +++ b/receiver/kubeletstatsreceiver/scraper.go @@ -109,6 +109,15 @@ func newKubletScraper( emitMetricsWithDirectionAttribute: featuregate.GetRegistry().IsEnabled(emitMetricsWithDirectionAttributeFeatureGateID), emitMetricsWithoutDirectionAttribute: featuregate.GetRegistry().IsEnabled(emitMetricsWithoutDirectionAttributeFeatureGateID), } + if ks.emitMetricsWithDirectionAttribute { + ks.logger.Info("WARNING - Breaking Change: " + emitMetricsWithDirectionAttributeFeatureGate.Description) + ks.logger.Info("The feature gate " + emitMetricsWithDirectionAttributeFeatureGate.ID + " is enabled. This " + + "otel collector will report metrics with a direction attribute, be aware this will not be supported in the future") + } + if ks.emitMetricsWithoutDirectionAttribute { + ks.logger.Info("The " + emitMetricsWithoutDirectionAttributeFeatureGate.ID + " feature gate is enabled. This " + + "otel collector will report metrics without a direction attribute, which is good for future support") + } return scraperhelper.NewScraper(typeStr, ks.scrape) } From e0501d391428e33caf68d8bd1f2c4b93783c1b5d Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 28 Jul 2022 09:23:10 -0700 Subject: [PATCH 08/12] update release version for transition schedule --- receiver/kubeletstatsreceiver/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/receiver/kubeletstatsreceiver/README.md b/receiver/kubeletstatsreceiver/README.md index 51d532ee3068..06d4b6847871 100644 --- a/receiver/kubeletstatsreceiver/README.md +++ b/receiver/kubeletstatsreceiver/README.md @@ -213,7 +213,7 @@ The following feature gates control the transition process: ##### Transition schedule: -1. v0.56.0, July 2022: +1. v0.57.0, July 2022: - The new metrics are available for all scrapers, but disabled by default, they can be enabled with the feature gates. - The old metrics with `direction` attribute are deprecated with a warning. From f4908093c5fbc04cecb7df922265512afb85fcb0 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Mon, 8 Aug 2022 13:23:27 -0700 Subject: [PATCH 09/12] update transition schedule --- receiver/kubeletstatsreceiver/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/receiver/kubeletstatsreceiver/README.md b/receiver/kubeletstatsreceiver/README.md index 06d4b6847871..24a540506292 100644 --- a/receiver/kubeletstatsreceiver/README.md +++ b/receiver/kubeletstatsreceiver/README.md @@ -213,14 +213,14 @@ The following feature gates control the transition process: ##### Transition schedule: -1. v0.57.0, July 2022: +1. v0.58.0, Aug 2022: - The new metrics are available for all scrapers, but disabled by default, they can be enabled with the feature gates. - The old metrics with `direction` attribute are deprecated with a warning. - `receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute` is enabled by default. - `receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute` is disabled by default. -2. v0.58.0, August 2022: +2. v0.59.0, August 2022: - The new metrics are enabled by default, deprecated metrics disabled, they can be enabled with the feature gates. - `receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute` is disabled by default. From 6d1359c0b9a553d839b5db6e565644a9d2960ff9 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Tue, 9 Aug 2022 14:45:08 -0700 Subject: [PATCH 10/12] regenerate metrics from metadata --- .../internal/metadata/generated_metrics_v2.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go index 050d524549d7..32d49ad9579f 100644 --- a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go +++ b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_v2.go @@ -1411,7 +1411,7 @@ func (m *metricK8sNodeNetworkErrorsReceive) recordDataPoint(start pcommon.Timest dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -1464,7 +1464,7 @@ func (m *metricK8sNodeNetworkErrorsTransmit) recordDataPoint(start pcommon.Times dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -1571,7 +1571,7 @@ func (m *metricK8sNodeNetworkIoReceive) recordDataPoint(start pcommon.Timestamp, dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -1624,7 +1624,7 @@ func (m *metricK8sNodeNetworkIoTransmit) recordDataPoint(start pcommon.Timestamp dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -2272,7 +2272,7 @@ func (m *metricK8sPodNetworkErrorsReceive) recordDataPoint(start pcommon.Timesta dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -2325,7 +2325,7 @@ func (m *metricK8sPodNetworkErrorsTransmit) recordDataPoint(start pcommon.Timest dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -2432,7 +2432,7 @@ func (m *metricK8sPodNetworkIoReceive) recordDataPoint(start pcommon.Timestamp, dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -2485,7 +2485,7 @@ func (m *metricK8sPodNetworkIoTransmit) recordDataPoint(start pcommon.Timestamp, dp.SetStartTimestamp(start) dp.SetTimestamp(ts) dp.SetIntVal(val) - dp.Attributes().Insert("interface", pcommon.NewValueString(interfaceAttributeValue)) + dp.Attributes().InsertString("interface", interfaceAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. From 2a563f87739fb5f7a29eef7e53b90d8284ad2712 Mon Sep 17 00:00:00 2001 From: Dmitrii Anoshin Date: Wed, 10 Aug 2022 15:17:07 -0700 Subject: [PATCH 11/12] Update receiver/kubeletstatsreceiver/scraper.go --- receiver/kubeletstatsreceiver/scraper.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/receiver/kubeletstatsreceiver/scraper.go b/receiver/kubeletstatsreceiver/scraper.go index 9adcaa4bec5a..56eaeb3f27f1 100644 --- a/receiver/kubeletstatsreceiver/scraper.go +++ b/receiver/kubeletstatsreceiver/scraper.go @@ -109,15 +109,6 @@ func newKubletScraper( emitMetricsWithDirectionAttribute: featuregate.GetRegistry().IsEnabled(emitMetricsWithDirectionAttributeFeatureGateID), emitMetricsWithoutDirectionAttribute: featuregate.GetRegistry().IsEnabled(emitMetricsWithoutDirectionAttributeFeatureGateID), } - if ks.emitMetricsWithDirectionAttribute { - ks.logger.Info("WARNING - Breaking Change: " + emitMetricsWithDirectionAttributeFeatureGate.Description) - ks.logger.Info("The feature gate " + emitMetricsWithDirectionAttributeFeatureGate.ID + " is enabled. This " + - "otel collector will report metrics with a direction attribute, be aware this will not be supported in the future") - } - if ks.emitMetricsWithoutDirectionAttribute { - ks.logger.Info("The " + emitMetricsWithoutDirectionAttributeFeatureGate.ID + " feature gate is enabled. This " + - "otel collector will report metrics without a direction attribute, which is good for future support") - } return scraperhelper.NewScraper(typeStr, ks.scrape) } From 267bc02fbb7dbd9aa5f9c47d113eb8f95ed74e1d Mon Sep 17 00:00:00 2001 From: Dmitrii Anoshin Date: Thu, 11 Aug 2022 15:07:17 -0700 Subject: [PATCH 12/12] Update receiver/kubeletstatsreceiver/README.md --- receiver/kubeletstatsreceiver/README.md | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/receiver/kubeletstatsreceiver/README.md b/receiver/kubeletstatsreceiver/README.md index 24a540506292..330f6e0d971b 100644 --- a/receiver/kubeletstatsreceiver/README.md +++ b/receiver/kubeletstatsreceiver/README.md @@ -211,26 +211,5 @@ The following feature gates control the transition process: - **receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute**: controls if the new metrics without `direction` attribute are emitted by the receiver. - **receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute**: controls if the deprecated metrics with `direction` attribute are emitted by the receiver. -##### Transition schedule: - -1. v0.58.0, Aug 2022: - -- The new metrics are available for all scrapers, but disabled by default, they can be enabled with the feature gates. -- The old metrics with `direction` attribute are deprecated with a warning. -- `receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute` is enabled by default. -- `receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute` is disabled by default. - -2. v0.59.0, August 2022: - -- The new metrics are enabled by default, deprecated metrics disabled, they can be enabled with the feature gates. -- `receiver.kubeletstatsreceiver.emitMetricsWithDirectionAttribute` is disabled by default. -- `receiver.kubeletstatsreceiver.emitMetricsWithoutDirectionAttribute` is enabled by default. - -3. v0.60.0, September 2022: - -- The feature gates are removed. -- The new metrics without `direction` attribute are always emitted. -- The deprecated metrics with `direction` attribute are no longer available. - [beta]:https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib