diff --git a/CHANGELOG.md b/CHANGELOG.md index 96f3fc4b7434..77be436f1ed3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,19 @@ ### 🚩 Deprecations 🚩 - `logzioexporter`: Announcing `custom_endpoint`, `drain_interval`, `queue_capacity`, `queue_max_length` configuration options will be deprecated in upcoming releases (#10821) +- `hostmetricsreceiver`: remove direction attribute. The feature gate: `receiver.hostmetricsreceiver.removeDirectionAttribute` can be set to apply the following (#11820) + - `system.network.dropped` will become: + - `system.network.dropped.receive` + - `system.network.dropped.transmit` + - `system.network.errors` will become: + - `system.network.errors.receive` + - `system.network.errors.transmit` + - `system.network.io` will become: + - `system.network.io.receive` + - `system.network.io.transmit` + - `system.network.packets` will become: + - `system.network.packets.receive` + - `system.network.packets.transmit` ### 🚀 New components 🚀 diff --git a/receiver/hostmetricsreceiver/README.md b/receiver/hostmetricsreceiver/README.md index 57d04160744e..4afd77cb6b7b 100644 --- a/receiver/hostmetricsreceiver/README.md +++ b/receiver/hostmetricsreceiver/README.md @@ -1,7 +1,7 @@ # Host Metrics Receiver | Status | | -| ------------------------ |-------------------| +| ------------------------ | ----------------- | | Stability | [beta] | | Supported pipeline types | metrics | | Distributions | [core], [contrib] | @@ -27,14 +27,14 @@ hostmetrics: The available scrapers are: | Scraper | Supported OSs | Description | -|------------|------------------------------|--------------------------------------------------------| +| ---------- | ---------------------------- | ------------------------------------------------------ | | cpu | All except Mac[1] | CPU utilization metrics | | disk | All except Mac[1] | Disk I/O metrics | | load | All | CPU load metrics | | filesystem | All | File System utilization metrics | | memory | All | Memory utilization metrics | | network | All | Network interface I/O metrics & TCP connection metrics | -| paging | All | Paging/Swap space utilization and I/O metrics +| paging | All | Paging/Swap space utilization and I/O metrics | | processes | Linux | Process count metrics | | process | Linux & Windows | Per process CPU, Memory, and Disk I/O metrics | @@ -130,6 +130,50 @@ service: receivers: [hostmetrics, hostmetrics/disk] ``` +### Feature gate configurations + +- `receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics` + - Description + - Some network metrics reported by the hostmetricsreceiver 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. Please update any monitoring this might affect. + - Affected Metrics + - `system.network.dropped` will become: + - `system.network.dropped.receive` + - `system.network.dropped.transmit` + - `system.network.errors` will become: + - `system.network.errors.receive` + - `system.network.errors.transmit` + - `system.network.io` will become: + - `system.network.io.receive` + - `system.network.io.transmit` + - `system.network.packets` will become: + - `system.network.packets.receive` + - `system.network.packets.transmit` + - Stages and Timeline + - Alpha (current stage) + - In this stage the feature gate is disabled by default and must be enabled by the user. This allows users to preemptively opt in and start using the bug fix by enabling the feature gate. + - Collector version: v0.55.0 + - Release Date: Early July 2022 + - Beta + - In this stage the feature gate is enabled by default and can be disabled by the user. + - Collector version: v0.57.0 + - Release Date: Early August 2022 + - Generally Available + - In this stage the feature gate is permanently enabled and the feature gate is no longer available for anyone. + - Users could experience some friction in this stage, they may have to update monitoring for the affected metrics or be blocked from upgrading the collector to versions v0.59.0 and newer. + - Collector version: v0.59.0 + - Release Date: Early September 2022 + - Usage + - Feature gate identifiers prefixed with - will disable the gate and prefixing with + or with no prefix will enable the gate. + - Start the otelcol with the feature gate enabled: + - otelcol {other_arguments} --feature-gates=receiver.k8sclusterreceiver.reportCpuMetricsAsDouble + - Start the otelcol with the feature gate disabled: + - otelcol {other_arguments} --feature-gates=-receiver.k8sclusterreceiver.reportCpuMetricsAsDouble + - More information: + - https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/11815 + - https://github.com/open-telemetry/opentelemetry-specification/pull/2617 + [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/documentation.md b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/documentation.md index 681f1adab581..7ce6bc26f6cb 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/documentation.md +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/documentation.md @@ -9,10 +9,18 @@ These are the metrics available for this scraper. | Name | Description | Unit | Type | Attributes | | ---- | ----------- | ---- | ---- | ---------- | | **system.network.connections** | The number of connections. | {connections} | Sum(Int) | | -| **system.network.dropped** | The number of packets dropped. | {packets} | Sum(Int) | | -| **system.network.errors** | The number of errors encountered. | {errors} | Sum(Int) | | -| **system.network.io** | The number of bytes transmitted and received. | By | Sum(Int) | | -| **system.network.packets** | The number of packets transferred. | {packets} | Sum(Int) | | +| **system.network.dropped** | The number of packets dropped. (Deprecated) | {packets} | Sum(Int) | | +| **system.network.dropped.receive** | The number of packets dropped on receive. | {packets} | Sum(Int) | | +| **system.network.dropped.transmit** | The number of packets dropped on transmit. | {packets} | Sum(Int) | | +| **system.network.errors** | The number of errors encountered. (Deprecated) | {errors} | Sum(Int) | | +| **system.network.errors.receive** | The number of errors encountered on receive. | {errors} | Sum(Int) | | +| **system.network.errors.transmit** | The number of errors encountered on transmit. | {errors} | Sum(Int) | | +| **system.network.io** | The number of bytes transmitted and received. (Deprecated) | By | Sum(Int) | | +| **system.network.io.receive** | The number of bytes received. | By | Sum(Int) | | +| **system.network.io.transmit** | The number of bytes transmitted. | By | Sum(Int) | | +| **system.network.packets** | The number of packets transferred. (Deprecated) | {packets} | Sum(Int) | | +| **system.network.packets.receive** | The number of packets received. | {packets} | Sum(Int) | | +| **system.network.packets.transmit** | The number of packets transmitted. | {packets} | Sum(Int) | | **Highlighted metrics** are emitted by default. Other metrics are optional and not emitted by default. Any metric can be enabled or disabled with the following scraper configuration: diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_v2.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_v2.go index 0b2759dd9e45..ef38b3e7fa11 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_v2.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_v2.go @@ -18,11 +18,19 @@ type MetricSettings struct { // MetricsSettings provides settings for hostmetricsreceiver/network metrics. type MetricsSettings struct { - SystemNetworkConnections MetricSettings `mapstructure:"system.network.connections"` - SystemNetworkDropped MetricSettings `mapstructure:"system.network.dropped"` - SystemNetworkErrors MetricSettings `mapstructure:"system.network.errors"` - SystemNetworkIo MetricSettings `mapstructure:"system.network.io"` - SystemNetworkPackets MetricSettings `mapstructure:"system.network.packets"` + SystemNetworkConnections MetricSettings `mapstructure:"system.network.connections"` + SystemNetworkDropped MetricSettings `mapstructure:"system.network.dropped"` + SystemNetworkDroppedReceive MetricSettings `mapstructure:"system.network.dropped.receive"` + SystemNetworkDroppedTransmit MetricSettings `mapstructure:"system.network.dropped.transmit"` + SystemNetworkErrors MetricSettings `mapstructure:"system.network.errors"` + SystemNetworkErrorsReceive MetricSettings `mapstructure:"system.network.errors.receive"` + SystemNetworkErrorsTransmit MetricSettings `mapstructure:"system.network.errors.transmit"` + SystemNetworkIo MetricSettings `mapstructure:"system.network.io"` + SystemNetworkIoReceive MetricSettings `mapstructure:"system.network.io.receive"` + SystemNetworkIoTransmit MetricSettings `mapstructure:"system.network.io.transmit"` + SystemNetworkPackets MetricSettings `mapstructure:"system.network.packets"` + SystemNetworkPacketsReceive MetricSettings `mapstructure:"system.network.packets.receive"` + SystemNetworkPacketsTransmit MetricSettings `mapstructure:"system.network.packets.transmit"` } func DefaultMetricsSettings() MetricsSettings { @@ -33,15 +41,39 @@ func DefaultMetricsSettings() MetricsSettings { SystemNetworkDropped: MetricSettings{ Enabled: true, }, + SystemNetworkDroppedReceive: MetricSettings{ + Enabled: true, + }, + SystemNetworkDroppedTransmit: MetricSettings{ + Enabled: true, + }, SystemNetworkErrors: MetricSettings{ Enabled: true, }, + SystemNetworkErrorsReceive: MetricSettings{ + Enabled: true, + }, + SystemNetworkErrorsTransmit: MetricSettings{ + Enabled: true, + }, SystemNetworkIo: MetricSettings{ Enabled: true, }, + SystemNetworkIoReceive: MetricSettings{ + Enabled: true, + }, + SystemNetworkIoTransmit: MetricSettings{ + Enabled: true, + }, SystemNetworkPackets: MetricSettings{ Enabled: true, }, + SystemNetworkPacketsReceive: MetricSettings{ + Enabled: true, + }, + SystemNetworkPacketsTransmit: MetricSettings{ + Enabled: true, + }, } } @@ -156,7 +188,7 @@ type metricSystemNetworkDropped struct { // init fills system.network.dropped metric with initial data. func (m *metricSystemNetworkDropped) init() { m.data.SetName("system.network.dropped") - m.data.SetDescription("The number of packets dropped.") + m.data.SetDescription("The number of packets dropped. (Deprecated)") m.data.SetUnit("{packets}") m.data.SetDataType(pmetric.MetricDataTypeSum) m.data.Sum().SetIsMonotonic(true) @@ -201,6 +233,112 @@ func newMetricSystemNetworkDropped(settings MetricSettings) metricSystemNetworkD return m } +type metricSystemNetworkDroppedReceive 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 system.network.dropped.receive metric with initial data. +func (m *metricSystemNetworkDroppedReceive) init() { + m.data.SetName("system.network.dropped.receive") + m.data.SetDescription("The number of packets dropped on receive.") + m.data.SetUnit("{packets}") + 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 *metricSystemNetworkDroppedReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkDroppedReceive) 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 *metricSystemNetworkDroppedReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkDroppedReceive(settings MetricSettings) metricSystemNetworkDroppedReceive { + m := metricSystemNetworkDroppedReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSystemNetworkDroppedTransmit 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 system.network.dropped.transmit metric with initial data. +func (m *metricSystemNetworkDroppedTransmit) init() { + m.data.SetName("system.network.dropped.transmit") + m.data.SetDescription("The number of packets dropped on transmit.") + m.data.SetUnit("{packets}") + 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 *metricSystemNetworkDroppedTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkDroppedTransmit) 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 *metricSystemNetworkDroppedTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkDroppedTransmit(settings MetricSettings) metricSystemNetworkDroppedTransmit { + m := metricSystemNetworkDroppedTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricSystemNetworkErrors struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -210,7 +348,7 @@ type metricSystemNetworkErrors struct { // init fills system.network.errors metric with initial data. func (m *metricSystemNetworkErrors) init() { m.data.SetName("system.network.errors") - m.data.SetDescription("The number of errors encountered.") + m.data.SetDescription("The number of errors encountered. (Deprecated)") m.data.SetUnit("{errors}") m.data.SetDataType(pmetric.MetricDataTypeSum) m.data.Sum().SetIsMonotonic(true) @@ -255,6 +393,112 @@ func newMetricSystemNetworkErrors(settings MetricSettings) metricSystemNetworkEr return m } +type metricSystemNetworkErrorsReceive 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 system.network.errors.receive metric with initial data. +func (m *metricSystemNetworkErrorsReceive) init() { + m.data.SetName("system.network.errors.receive") + m.data.SetDescription("The number of errors encountered on receive.") + m.data.SetUnit("{errors}") + 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 *metricSystemNetworkErrorsReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkErrorsReceive) 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 *metricSystemNetworkErrorsReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkErrorsReceive(settings MetricSettings) metricSystemNetworkErrorsReceive { + m := metricSystemNetworkErrorsReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSystemNetworkErrorsTransmit 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 system.network.errors.transmit metric with initial data. +func (m *metricSystemNetworkErrorsTransmit) init() { + m.data.SetName("system.network.errors.transmit") + m.data.SetDescription("The number of errors encountered on transmit.") + m.data.SetUnit("{errors}") + 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 *metricSystemNetworkErrorsTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkErrorsTransmit) 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 *metricSystemNetworkErrorsTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkErrorsTransmit(settings MetricSettings) metricSystemNetworkErrorsTransmit { + m := metricSystemNetworkErrorsTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricSystemNetworkIo struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -264,7 +508,7 @@ type metricSystemNetworkIo struct { // init fills system.network.io metric with initial data. func (m *metricSystemNetworkIo) init() { m.data.SetName("system.network.io") - m.data.SetDescription("The number of bytes transmitted and received.") + m.data.SetDescription("The number of bytes transmitted and received. (Deprecated)") m.data.SetUnit("By") m.data.SetDataType(pmetric.MetricDataTypeSum) m.data.Sum().SetIsMonotonic(true) @@ -309,6 +553,112 @@ func newMetricSystemNetworkIo(settings MetricSettings) metricSystemNetworkIo { return m } +type metricSystemNetworkIoReceive 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 system.network.io.receive metric with initial data. +func (m *metricSystemNetworkIoReceive) init() { + m.data.SetName("system.network.io.receive") + m.data.SetDescription("The number of bytes 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 *metricSystemNetworkIoReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkIoReceive) 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 *metricSystemNetworkIoReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkIoReceive(settings MetricSettings) metricSystemNetworkIoReceive { + m := metricSystemNetworkIoReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSystemNetworkIoTransmit 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 system.network.io.transmit metric with initial data. +func (m *metricSystemNetworkIoTransmit) init() { + m.data.SetName("system.network.io.transmit") + m.data.SetDescription("The number of bytes 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 *metricSystemNetworkIoTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkIoTransmit) 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 *metricSystemNetworkIoTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkIoTransmit(settings MetricSettings) metricSystemNetworkIoTransmit { + m := metricSystemNetworkIoTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricSystemNetworkPackets struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -318,7 +668,7 @@ type metricSystemNetworkPackets struct { // init fills system.network.packets metric with initial data. func (m *metricSystemNetworkPackets) init() { m.data.SetName("system.network.packets") - m.data.SetDescription("The number of packets transferred.") + m.data.SetDescription("The number of packets transferred. (Deprecated)") m.data.SetUnit("{packets}") m.data.SetDataType(pmetric.MetricDataTypeSum) m.data.Sum().SetIsMonotonic(true) @@ -363,19 +713,133 @@ func newMetricSystemNetworkPackets(settings MetricSettings) metricSystemNetworkP return m } +type metricSystemNetworkPacketsReceive 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 system.network.packets.receive metric with initial data. +func (m *metricSystemNetworkPacketsReceive) init() { + m.data.SetName("system.network.packets.receive") + m.data.SetDescription("The number of packets received.") + m.data.SetUnit("{packets}") + 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 *metricSystemNetworkPacketsReceive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkPacketsReceive) 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 *metricSystemNetworkPacketsReceive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkPacketsReceive(settings MetricSettings) metricSystemNetworkPacketsReceive { + m := metricSystemNetworkPacketsReceive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSystemNetworkPacketsTransmit 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 system.network.packets.transmit metric with initial data. +func (m *metricSystemNetworkPacketsTransmit) init() { + m.data.SetName("system.network.packets.transmit") + m.data.SetDescription("The number of packets transmitted.") + m.data.SetUnit("{packets}") + 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 *metricSystemNetworkPacketsTransmit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert("device", pcommon.NewValueString(deviceAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSystemNetworkPacketsTransmit) 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 *metricSystemNetworkPacketsTransmit) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSystemNetworkPacketsTransmit(settings MetricSettings) metricSystemNetworkPacketsTransmit { + m := metricSystemNetworkPacketsTransmit{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user settings. type MetricsBuilder struct { - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information - metricSystemNetworkConnections metricSystemNetworkConnections - metricSystemNetworkDropped metricSystemNetworkDropped - metricSystemNetworkErrors metricSystemNetworkErrors - metricSystemNetworkIo metricSystemNetworkIo - metricSystemNetworkPackets metricSystemNetworkPackets + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + resourceCapacity int // maximum observed number of resource attributes. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information + metricSystemNetworkConnections metricSystemNetworkConnections + metricSystemNetworkDropped metricSystemNetworkDropped + metricSystemNetworkDroppedReceive metricSystemNetworkDroppedReceive + metricSystemNetworkDroppedTransmit metricSystemNetworkDroppedTransmit + metricSystemNetworkErrors metricSystemNetworkErrors + metricSystemNetworkErrorsReceive metricSystemNetworkErrorsReceive + metricSystemNetworkErrorsTransmit metricSystemNetworkErrorsTransmit + metricSystemNetworkIo metricSystemNetworkIo + metricSystemNetworkIoReceive metricSystemNetworkIoReceive + metricSystemNetworkIoTransmit metricSystemNetworkIoTransmit + metricSystemNetworkPackets metricSystemNetworkPackets + metricSystemNetworkPacketsReceive metricSystemNetworkPacketsReceive + metricSystemNetworkPacketsTransmit metricSystemNetworkPacketsTransmit } // metricBuilderOption applies changes to default metrics builder. @@ -390,14 +854,22 @@ func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { func NewMetricsBuilder(settings MetricsSettings, buildInfo component.BuildInfo, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: buildInfo, - metricSystemNetworkConnections: newMetricSystemNetworkConnections(settings.SystemNetworkConnections), - metricSystemNetworkDropped: newMetricSystemNetworkDropped(settings.SystemNetworkDropped), - metricSystemNetworkErrors: newMetricSystemNetworkErrors(settings.SystemNetworkErrors), - metricSystemNetworkIo: newMetricSystemNetworkIo(settings.SystemNetworkIo), - metricSystemNetworkPackets: newMetricSystemNetworkPackets(settings.SystemNetworkPackets), + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: buildInfo, + metricSystemNetworkConnections: newMetricSystemNetworkConnections(settings.SystemNetworkConnections), + metricSystemNetworkDropped: newMetricSystemNetworkDropped(settings.SystemNetworkDropped), + metricSystemNetworkDroppedReceive: newMetricSystemNetworkDroppedReceive(settings.SystemNetworkDroppedReceive), + metricSystemNetworkDroppedTransmit: newMetricSystemNetworkDroppedTransmit(settings.SystemNetworkDroppedTransmit), + metricSystemNetworkErrors: newMetricSystemNetworkErrors(settings.SystemNetworkErrors), + metricSystemNetworkErrorsReceive: newMetricSystemNetworkErrorsReceive(settings.SystemNetworkErrorsReceive), + metricSystemNetworkErrorsTransmit: newMetricSystemNetworkErrorsTransmit(settings.SystemNetworkErrorsTransmit), + metricSystemNetworkIo: newMetricSystemNetworkIo(settings.SystemNetworkIo), + metricSystemNetworkIoReceive: newMetricSystemNetworkIoReceive(settings.SystemNetworkIoReceive), + metricSystemNetworkIoTransmit: newMetricSystemNetworkIoTransmit(settings.SystemNetworkIoTransmit), + metricSystemNetworkPackets: newMetricSystemNetworkPackets(settings.SystemNetworkPackets), + metricSystemNetworkPacketsReceive: newMetricSystemNetworkPacketsReceive(settings.SystemNetworkPacketsReceive), + metricSystemNetworkPacketsTransmit: newMetricSystemNetworkPacketsTransmit(settings.SystemNetworkPacketsTransmit), } for _, op := range options { op(mb) @@ -453,9 +925,17 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { ils.Metrics().EnsureCapacity(mb.metricsCapacity) mb.metricSystemNetworkConnections.emit(ils.Metrics()) mb.metricSystemNetworkDropped.emit(ils.Metrics()) + mb.metricSystemNetworkDroppedReceive.emit(ils.Metrics()) + mb.metricSystemNetworkDroppedTransmit.emit(ils.Metrics()) mb.metricSystemNetworkErrors.emit(ils.Metrics()) + mb.metricSystemNetworkErrorsReceive.emit(ils.Metrics()) + mb.metricSystemNetworkErrorsTransmit.emit(ils.Metrics()) mb.metricSystemNetworkIo.emit(ils.Metrics()) + mb.metricSystemNetworkIoReceive.emit(ils.Metrics()) + mb.metricSystemNetworkIoTransmit.emit(ils.Metrics()) mb.metricSystemNetworkPackets.emit(ils.Metrics()) + mb.metricSystemNetworkPacketsReceive.emit(ils.Metrics()) + mb.metricSystemNetworkPacketsTransmit.emit(ils.Metrics()) for _, op := range rmo { op(rm) } @@ -485,21 +965,61 @@ func (mb *MetricsBuilder) RecordSystemNetworkDroppedDataPoint(ts pcommon.Timesta mb.metricSystemNetworkDropped.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue, directionAttributeValue.String()) } +// RecordSystemNetworkDroppedReceiveDataPoint adds a data point to system.network.dropped.receive metric. +func (mb *MetricsBuilder) RecordSystemNetworkDroppedReceiveDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkDroppedReceive.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + +// RecordSystemNetworkDroppedTransmitDataPoint adds a data point to system.network.dropped.transmit metric. +func (mb *MetricsBuilder) RecordSystemNetworkDroppedTransmitDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkDroppedTransmit.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + // RecordSystemNetworkErrorsDataPoint adds a data point to system.network.errors metric. func (mb *MetricsBuilder) RecordSystemNetworkErrorsDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string, directionAttributeValue AttributeDirection) { mb.metricSystemNetworkErrors.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue, directionAttributeValue.String()) } +// RecordSystemNetworkErrorsReceiveDataPoint adds a data point to system.network.errors.receive metric. +func (mb *MetricsBuilder) RecordSystemNetworkErrorsReceiveDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkErrorsReceive.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + +// RecordSystemNetworkErrorsTransmitDataPoint adds a data point to system.network.errors.transmit metric. +func (mb *MetricsBuilder) RecordSystemNetworkErrorsTransmitDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkErrorsTransmit.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + // RecordSystemNetworkIoDataPoint adds a data point to system.network.io metric. func (mb *MetricsBuilder) RecordSystemNetworkIoDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string, directionAttributeValue AttributeDirection) { mb.metricSystemNetworkIo.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue, directionAttributeValue.String()) } +// RecordSystemNetworkIoReceiveDataPoint adds a data point to system.network.io.receive metric. +func (mb *MetricsBuilder) RecordSystemNetworkIoReceiveDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkIoReceive.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + +// RecordSystemNetworkIoTransmitDataPoint adds a data point to system.network.io.transmit metric. +func (mb *MetricsBuilder) RecordSystemNetworkIoTransmitDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkIoTransmit.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + // RecordSystemNetworkPacketsDataPoint adds a data point to system.network.packets metric. func (mb *MetricsBuilder) RecordSystemNetworkPacketsDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string, directionAttributeValue AttributeDirection) { mb.metricSystemNetworkPackets.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue, directionAttributeValue.String()) } +// RecordSystemNetworkPacketsReceiveDataPoint adds a data point to system.network.packets.receive metric. +func (mb *MetricsBuilder) RecordSystemNetworkPacketsReceiveDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkPacketsReceive.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + +// RecordSystemNetworkPacketsTransmitDataPoint adds a data point to system.network.packets.transmit metric. +func (mb *MetricsBuilder) RecordSystemNetworkPacketsTransmitDataPoint(ts pcommon.Timestamp, val int64, deviceAttributeValue string) { + mb.metricSystemNetworkPacketsTransmit.recordDataPoint(mb.startTime, ts, val, deviceAttributeValue) +} + // Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, // and metrics builder should update its startTime and reset it's internal state accordingly. func (mb *MetricsBuilder) Reset(options ...metricBuilderOption) { diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/metadata.yaml b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/metadata.yaml index 9522a8053cdb..8b5060dbffc5 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/metadata.yaml +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/metadata.yaml @@ -20,7 +20,7 @@ attributes: metrics: system.network.packets: enabled: true - description: The number of packets transferred. + description: The number of packets transferred. (Deprecated) unit: "{packets}" sum: value_type: int @@ -28,9 +28,31 @@ metrics: monotonic: true attributes: [device, direction] +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.packets.transmit: + enabled: true + description: The number of packets transmitted. + unit: "{packets}" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.packets.receive: + enabled: true + description: The number of packets received. + unit: "{packets}" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + system.network.dropped: enabled: true - description: The number of packets dropped. + description: The number of packets dropped. (Deprecated) unit: "{packets}" sum: value_type: int @@ -38,9 +60,31 @@ metrics: monotonic: true attributes: [device, direction] +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.dropped.transmit: + enabled: true + description: The number of packets dropped on transmit. + unit: "{packets}" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.dropped.receive: + enabled: true + description: The number of packets dropped on receive. + unit: "{packets}" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + system.network.errors: enabled: true - description: The number of errors encountered. + description: The number of errors encountered. (Deprecated) unit: "{errors}" sum: value_type: int @@ -48,9 +92,31 @@ metrics: monotonic: true attributes: [device, direction] +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.errors.transmit: + enabled: true + description: The number of errors encountered on transmit. + unit: "{errors}" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.errors.receive: + enabled: true + description: The number of errors encountered on receive. + unit: "{errors}" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + system.network.io: enabled: true - description: The number of bytes transmitted and received. + description: The number of bytes transmitted and received. (Deprecated) unit: "By" sum: value_type: int @@ -58,6 +124,28 @@ metrics: monotonic: true attributes: [device, direction] +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.io.transmit: + enabled: true + description: The number of bytes transmitted. + unit: "By" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + +# produced when receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics feature gate is enabled + system.network.io.receive: + enabled: true + description: The number of bytes received. + unit: "By" + sum: + value_type: int + aggregation: cumulative + monotonic: true + attributes: [device] + system.network.connections: enabled: true description: The number of connections. diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go index f769d173e790..1fa47582c9eb 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go @@ -25,6 +25,7 @@ import ( "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver/scrapererror" + "go.opentelemetry.io/collector/service/featuregate" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/processor/filterset" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata" @@ -33,6 +34,8 @@ import ( const ( networkMetricsLen = 4 connectionsMetricsLen = 1 + // ID for a temporary feature gate" + removeDirectionAttributeFeatureGateID = "receiver.hostmetricsreceiver.removeDirectionAttributeNetworkMetrics" ) // scraper for Network Metrics @@ -50,12 +53,35 @@ type scraper struct { connections func(string) ([]net.ConnectionStat, error) } +var removeDirectionAttributeFeatureGate = featuregate.Gate{ + ID: removeDirectionAttributeFeatureGateID, + Enabled: false, + Description: "Some network metrics reported by the hostmetricsreceiver 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. You can control whether the hostmetricsreceiver reports metrics with a direction " + + "attribute using the " + removeDirectionAttributeFeatureGateID + " feature gate. For more details, see: " + + "https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/hostmetricsreceiver/README.md#feature-gate-configurations", +} + +func init() { + featuregate.GetRegistry().MustRegister(removeDirectionAttributeFeatureGate) +} + // newNetworkScraper creates a set of Network related metrics func newNetworkScraper(_ context.Context, settings component.ReceiverCreateSettings, cfg *Config) (*scraper, error) { scraper := &scraper{settings: settings, config: cfg, bootTime: host.BootTime, ioCounters: net.IOCounters, connections: net.Connections} var err error + if featuregate.GetRegistry().IsEnabled(removeDirectionAttributeFeatureGateID) { + settings.Logger.Info("The " + removeDirectionAttributeFeatureGateID + " featre gate is enabled. This " + + "otel collector will report metrics without a direction attribute, which is good for future support") + } else { + settings.Logger.Info("WARNING - Breaking Change: " + removeDirectionAttributeFeatureGate.Description) + settings.Logger.Info("The feature gate " + removeDirectionAttributeFeatureGateID + " is disabled. This " + + "otel collector will report metrics with a direction attribute, be aware this will not be supported in the future") + } + if len(cfg.Include.Interfaces) > 0 { scraper.includeFS, err = filterset.CreateFilterSet(cfg.Include.Interfaces, &cfg.Include.Config) if err != nil { @@ -124,29 +150,49 @@ func (s *scraper) recordNetworkCounterMetrics() error { func (s *scraper) recordNetworkPacketsMetric(now pcommon.Timestamp, ioCountersSlice []net.IOCountersStat) { for _, ioCounters := range ioCountersSlice { - s.mb.RecordSystemNetworkPacketsDataPoint(now, int64(ioCounters.PacketsSent), ioCounters.Name, metadata.AttributeDirectionTransmit) - s.mb.RecordSystemNetworkPacketsDataPoint(now, int64(ioCounters.PacketsRecv), ioCounters.Name, metadata.AttributeDirectionReceive) + if featuregate.GetRegistry().IsEnabled(removeDirectionAttributeFeatureGateID) { + s.mb.RecordSystemNetworkPacketsTransmitDataPoint(now, int64(ioCounters.PacketsSent), ioCounters.Name) + s.mb.RecordSystemNetworkPacketsReceiveDataPoint(now, int64(ioCounters.PacketsRecv), ioCounters.Name) + } else { + s.mb.RecordSystemNetworkPacketsDataPoint(now, int64(ioCounters.PacketsSent), ioCounters.Name, metadata.AttributeDirectionTransmit) + s.mb.RecordSystemNetworkPacketsDataPoint(now, int64(ioCounters.PacketsRecv), ioCounters.Name, metadata.AttributeDirectionReceive) + } } } func (s *scraper) recordNetworkDroppedPacketsMetric(now pcommon.Timestamp, ioCountersSlice []net.IOCountersStat) { for _, ioCounters := range ioCountersSlice { - s.mb.RecordSystemNetworkDroppedDataPoint(now, int64(ioCounters.Dropout), ioCounters.Name, metadata.AttributeDirectionTransmit) - s.mb.RecordSystemNetworkDroppedDataPoint(now, int64(ioCounters.Dropin), ioCounters.Name, metadata.AttributeDirectionReceive) + if featuregate.GetRegistry().IsEnabled(removeDirectionAttributeFeatureGateID) { + s.mb.RecordSystemNetworkDroppedTransmitDataPoint(now, int64(ioCounters.Dropout), ioCounters.Name) + s.mb.RecordSystemNetworkDroppedReceiveDataPoint(now, int64(ioCounters.Dropin), ioCounters.Name) + } else { + s.mb.RecordSystemNetworkDroppedDataPoint(now, int64(ioCounters.Dropout), ioCounters.Name, metadata.AttributeDirectionTransmit) + s.mb.RecordSystemNetworkDroppedDataPoint(now, int64(ioCounters.Dropin), ioCounters.Name, metadata.AttributeDirectionReceive) + } } } func (s *scraper) recordNetworkErrorPacketsMetric(now pcommon.Timestamp, ioCountersSlice []net.IOCountersStat) { for _, ioCounters := range ioCountersSlice { - s.mb.RecordSystemNetworkErrorsDataPoint(now, int64(ioCounters.Errout), ioCounters.Name, metadata.AttributeDirectionTransmit) - s.mb.RecordSystemNetworkErrorsDataPoint(now, int64(ioCounters.Errin), ioCounters.Name, metadata.AttributeDirectionReceive) + if featuregate.GetRegistry().IsEnabled(removeDirectionAttributeFeatureGateID) { + s.mb.RecordSystemNetworkErrorsTransmitDataPoint(now, int64(ioCounters.Errout), ioCounters.Name) + s.mb.RecordSystemNetworkErrorsReceiveDataPoint(now, int64(ioCounters.Errin), ioCounters.Name) + } else { + s.mb.RecordSystemNetworkErrorsDataPoint(now, int64(ioCounters.Errout), ioCounters.Name, metadata.AttributeDirectionTransmit) + s.mb.RecordSystemNetworkErrorsDataPoint(now, int64(ioCounters.Errin), ioCounters.Name, metadata.AttributeDirectionReceive) + } } } func (s *scraper) recordNetworkIOMetric(now pcommon.Timestamp, ioCountersSlice []net.IOCountersStat) { for _, ioCounters := range ioCountersSlice { - s.mb.RecordSystemNetworkIoDataPoint(now, int64(ioCounters.BytesSent), ioCounters.Name, metadata.AttributeDirectionTransmit) - s.mb.RecordSystemNetworkIoDataPoint(now, int64(ioCounters.BytesRecv), ioCounters.Name, metadata.AttributeDirectionReceive) + if featuregate.GetRegistry().IsEnabled(removeDirectionAttributeFeatureGateID) { + s.mb.RecordSystemNetworkIoTransmitDataPoint(now, int64(ioCounters.BytesSent), ioCounters.Name) + s.mb.RecordSystemNetworkIoReceiveDataPoint(now, int64(ioCounters.BytesRecv), ioCounters.Name) + } else { + s.mb.RecordSystemNetworkIoDataPoint(now, int64(ioCounters.BytesSent), ioCounters.Name, metadata.AttributeDirectionTransmit) + s.mb.RecordSystemNetworkIoDataPoint(now, int64(ioCounters.BytesRecv), ioCounters.Name, metadata.AttributeDirectionReceive) + } } } diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go index 562558f5ce74..9b22d77b937b 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go @@ -26,6 +26,7 @@ import ( "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver/scrapererror" + "go.opentelemetry.io/collector/service/featuregate" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/processor/filterset" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal" @@ -34,17 +35,18 @@ import ( func TestScrape(t *testing.T) { type testCase struct { - name string - config Config - bootTimeFunc func() (uint64, error) - ioCountersFunc func(bool) ([]net.IOCountersStat, error) - connectionsFunc func(string) ([]net.ConnectionStat, error) - expectNetworkMetrics bool - expectedStartTime pcommon.Timestamp - newErrRegex string - initializationErr string - expectedErr string - expectedErrCount int + name string + config Config + bootTimeFunc func() (uint64, error) + ioCountersFunc func(bool) ([]net.IOCountersStat, error) + connectionsFunc func(string) ([]net.ConnectionStat, error) + expectNetworkMetrics bool + expectedStartTime pcommon.Timestamp + newErrRegex string + initializationErr string + expectedErr string + expectedErrCount int + removeDirectionAttributeFeatureGateEnabled bool } testCases := []testCase{ @@ -55,6 +57,14 @@ func TestScrape(t *testing.T) { }, expectNetworkMetrics: true, }, + { + name: "Standard with direction removed", + config: Config{ + Metrics: metadata.DefaultMetricsSettings(), + }, + expectNetworkMetrics: true, + removeDirectionAttributeFeatureGateEnabled: true, + }, { name: "Validate Start Time", config: Config{ @@ -109,6 +119,7 @@ func TestScrape(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { + featuregate.GetRegistry().Apply(map[string]bool{removeDirectionAttributeFeatureGateID: test.removeDirectionAttributeFeatureGateEnabled}) scraper, err := newNetworkScraper(context.Background(), componenttest.NewNopReceiverCreateSettings(), &test.config) if test.newErrRegex != "" { require.Error(t, err) @@ -152,7 +163,11 @@ func TestScrape(t *testing.T) { expectedMetricCount := 1 if test.expectNetworkMetrics { - expectedMetricCount += 4 + if test.removeDirectionAttributeFeatureGateEnabled { + expectedMetricCount += 8 + } else { + expectedMetricCount += 4 + } } assert.Equal(t, expectedMetricCount, md.MetricCount()) @@ -160,10 +175,21 @@ func TestScrape(t *testing.T) { idx := 0 assertNetworkConnectionsMetricValid(t, metrics.At(idx)) if test.expectNetworkMetrics { - assertNetworkIOMetricValid(t, metrics.At(idx+1), "system.network.dropped", test.expectedStartTime) - assertNetworkIOMetricValid(t, metrics.At(idx+2), "system.network.errors", test.expectedStartTime) - assertNetworkIOMetricValid(t, metrics.At(idx+3), "system.network.io", test.expectedStartTime) - assertNetworkIOMetricValid(t, metrics.At(idx+4), "system.network.packets", test.expectedStartTime) + if test.removeDirectionAttributeFeatureGateEnabled { + assertNetworkIOMetricValid(t, metrics.At(idx+1), "system.network.dropped.receive", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+2), "system.network.dropped.transmit", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+3), "system.network.errors.receive", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+4), "system.network.errors.transmit", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+5), "system.network.io.receive", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+6), "system.network.io.transmit", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+7), "system.network.packets.receive", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+8), "system.network.packets.transmit", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + } else { + assertNetworkIOMetricValid(t, metrics.At(idx+1), "system.network.dropped", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+2), "system.network.errors", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+3), "system.network.io", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + assertNetworkIOMetricValid(t, metrics.At(idx+4), "system.network.packets", test.expectedStartTime, test.removeDirectionAttributeFeatureGateEnabled) + } internal.AssertSameTimeStampForMetrics(t, metrics, 1, 5) idx += 4 } @@ -173,17 +199,20 @@ func TestScrape(t *testing.T) { } } -func assertNetworkIOMetricValid(t *testing.T, metric pmetric.Metric, expectedName string, startTime pcommon.Timestamp) { +func assertNetworkIOMetricValid(t *testing.T, metric pmetric.Metric, expectedName string, startTime pcommon.Timestamp, expectDirectionRemoved bool) { assert.Equal(t, expectedName, metric.Name()) if startTime != 0 { internal.AssertSumMetricStartTimeEquals(t, metric, startTime) } - assert.GreaterOrEqual(t, metric.Sum().DataPoints().Len(), 2) + if expectDirectionRemoved { + assert.GreaterOrEqual(t, metric.Sum().DataPoints().Len(), 1) + } else { + assert.GreaterOrEqual(t, metric.Sum().DataPoints().Len(), 2) + } internal.AssertSumMetricHasAttribute(t, metric, 0, "device") - internal.AssertSumMetricHasAttributeValue(t, metric, 0, "direction", - pcommon.NewValueString(metadata.AttributeDirectionTransmit.String())) - internal.AssertSumMetricHasAttributeValue(t, metric, 1, "direction", - pcommon.NewValueString(metadata.AttributeDirectionReceive.String())) + if !expectDirectionRemoved { + internal.AssertSumMetricHasAttribute(t, metric, 0, "direction") + } } func assertNetworkConnectionsMetricValid(t *testing.T, metric pmetric.Metric) {