Skip to content

Commit

Permalink
exporter/datadogexporter: add containers.* metrics mapping (open-tele…
Browse files Browse the repository at this point in the history
…metry#22150)

* exporter/datadogexporter: add containers.* metrics mapping

* Update exporter/datadogexporter/internal/metrics/system.go

Co-authored-by: Pablo Baeyens <[email protected]>

* Update exporter/datadogexporter/internal/metrics/system_deprecated.go

Co-authored-by: Pablo Baeyens <[email protected]>

---------

Co-authored-by: Pablo Baeyens <[email protected]>
  • Loading branch information
gbbr and mx-psi committed May 22, 2023
1 parent b8fc1de commit 9e2210e
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .chloggen/gbbr_container-metrics.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: exporter/datadog

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Map Docker stats receiver metrics to Datadog container metrics.

# One or more tracking issues related to the change
issues: [22149]

# (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: This change enables the use of the Containers (Overview) dashboard.
71 changes: 71 additions & 0 deletions exporter/datadogexporter/internal/metrics/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ const (
// Warning: this is not a deep copy. Only some fields are fully copied, others remain shared. This is intentional.
// Do not alter the returned metric (or the source one) after copying.
func copySystemMetric(src datadogV2.MetricSeries, name string, div float64) datadogV2.MetricSeries {
return copySystemMetricWithUnit(src, name, div, "")
}

// copySystemMetricWithUnit is equivalent to copySystemMetric, but allows changing the unit.
func copySystemMetricWithUnit(src datadogV2.MetricSeries, name string, div float64, unit string) datadogV2.MetricSeries {
cp := src
cp.Metric = name
// No need to set cp.Interval if cp.Type is gauge.
Expand All @@ -32,6 +37,9 @@ func copySystemMetric(src datadogV2.MetricSeries, name string, div float64) data
// division by 0 or 1 should not have an impact
return cp
}
if unit != "" {
cp.Unit = &unit
}
cp.Points = make([]datadogV2.MetricPoint, len(src.Points))
for i, dp := range src.Points {
cp.Points[i].Timestamp = dp.Timestamp
Expand Down Expand Up @@ -119,3 +127,66 @@ func PrepareSystemMetrics(ms []datadogV2.MetricSeries) []datadogV2.MetricSeries
}
return series
}

// PrepareContainerMetrics converts OTEL container.* metrics to Datadog container
// metrics.
func PrepareContainerMetrics(ms []datadogV2.MetricSeries) []datadogV2.MetricSeries {
series := ms
for _, m := range ms {
if !strings.HasPrefix(m.Metric, "container.") {
// not what we're looking for
continue
}
switch m.Metric {
case "container.cpu.usage.total":
series = append(series, copySystemMetricWithUnit(m, "container.cpu.usage", 1, "nanocore"))
case "container.cpu.usage.usermode":
series = append(series, copySystemMetricWithUnit(m, "container.cpu.user", 1, "nanocore"))
case "container.cpu.usage.system":
series = append(series, copySystemMetricWithUnit(m, "container.cpu.system", 1, "nanocore"))
case "container.cpu.throttling_data.throttled_time":
series = append(series, copySystemMetric(m, "container.cpu.throttled", 1))
case "container.cpu.throttling_data.throttled_periods":
series = append(series, copySystemMetric(m, "container.cpu.throttled.periods", 1))
case "container.memory.usage.total":
series = append(series, copySystemMetric(m, "container.memory.usage", 1))
case "container.memory.active_anon":
series = append(series, copySystemMetric(m, "container.memory.kernel", 1))
case "container.memory.hierarchical_memory_limit":
series = append(series, copySystemMetric(m, "container.memory.limit", 1))
case "container.memory.usage.limit":
series = append(series, copySystemMetric(m, "container.memory.soft_limit", 1))
case "container.memory.total_cache":
series = append(series, copySystemMetric(m, "container.memory.cache", 1))
case "container.memory.total_swap":
series = append(series, copySystemMetric(m, "container.memory.swap", 1))
case "container.blockio.io_service_bytes_recursive":
for _, tag := range m.Tags {
switch tag {
case "operation:write":
series = append(series, copySystemMetric(m, "container.io.write", 1))
case "operation:read":
series = append(series, copySystemMetric(m, "container.io.read", 1))
}
}
case "container.blockio.io_serviced_recursive":
for _, tag := range m.Tags {
switch tag {
case "operation:write":
series = append(series, copySystemMetric(m, "container.io.write.operations", 1))
case "operation:read":
series = append(series, copySystemMetric(m, "container.io.read.operations", 1))
}
}
case "container.network.io.usage.tx_bytes":
series = append(series, copySystemMetric(m, "container.net.sent", 1))
case "container.network.io.usage.tx_packets":
series = append(series, copySystemMetric(m, "container.net.sent.packets", 1))
case "container.network.io.usage.rx_bytes":
series = append(series, copySystemMetric(m, "container.net.rcvd", 1))
case "container.network.io.usage.rx_packets":
series = append(series, copySystemMetric(m, "container.net.rcvd.packets", 1))
}
}
return series
}
70 changes: 70 additions & 0 deletions exporter/datadogexporter/internal/metrics/system_deprecated.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import (
// Warning: this is not a deep copy. Only some fields are fully copied, others remain shared. This is intentional.
// Do not alter the returned metric (or the source one) after copying.
func copyZorkianSystemMetric(src zorkian.Metric, name string, div float64) zorkian.Metric {
return copyZorkianSystemMetricWithUnit(src, name, div, "")
}

func copyZorkianSystemMetricWithUnit(src zorkian.Metric, name string, div float64, unit string) zorkian.Metric {
cp := src
cp.Metric = &name
i := 1
Expand All @@ -25,6 +29,9 @@ func copyZorkianSystemMetric(src zorkian.Metric, name string, div float64) zorki
// division by 0 or 1 should not have an impact
return cp
}
if unit != "" {
cp.Unit = &unit
}
cp.Points = make([]zorkian.DataPoint, len(src.Points))
for i, dp := range src.Points {
cp.Points[i][0] = dp[0]
Expand Down Expand Up @@ -112,3 +119,66 @@ func PrepareZorkianSystemMetrics(ms []zorkian.Metric) []zorkian.Metric {
}
return series
}

// PrepareZorkianContainerMetrics converts OTEL container.* metrics to Datadog container
// metrics.
func PrepareZorkianContainerMetrics(ms []zorkian.Metric) []zorkian.Metric {
series := ms
for _, m := range ms {
if !strings.HasPrefix(*m.Metric, "container.") {
// not what we're looking for
continue
}
switch *m.Metric {
case "container.cpu.usage.total":
series = append(series, copyZorkianSystemMetricWithUnit(m, "container.cpu.usage", 1, "nanocore"))
case "container.cpu.usage.usermode":
series = append(series, copyZorkianSystemMetricWithUnit(m, "container.cpu.user", 1, "nanocore"))
case "container.cpu.usage.system":
series = append(series, copyZorkianSystemMetricWithUnit(m, "container.cpu.system", 1, "nanocore"))
case "container.cpu.throttling_data.throttled_time":
series = append(series, copyZorkianSystemMetric(m, "container.cpu.throttled", 1))
case "container.cpu.throttling_data.throttled_periods":
series = append(series, copyZorkianSystemMetric(m, "container.cpu.throttled.periods", 1))
case "container.memory.usage.total":
series = append(series, copyZorkianSystemMetric(m, "container.memory.usage", 1))
case "container.memory.active_anon":
series = append(series, copyZorkianSystemMetric(m, "container.memory.kernel", 1))
case "container.memory.hierarchical_memory_limit":
series = append(series, copyZorkianSystemMetric(m, "container.memory.limit", 1))
case "container.memory.usage.limit":
series = append(series, copyZorkianSystemMetric(m, "container.memory.soft_limit", 1))
case "container.memory.total_cache":
series = append(series, copyZorkianSystemMetric(m, "container.memory.cache", 1))
case "container.memory.total_swap":
series = append(series, copyZorkianSystemMetric(m, "container.memory.swap", 1))
case "container.blockio.io_service_bytes_recursive":
for _, tag := range m.Tags {
switch tag {
case "operation:write":
series = append(series, copyZorkianSystemMetric(m, "container.io.write", 1))
case "operation:read":
series = append(series, copyZorkianSystemMetric(m, "container.io.read", 1))
}
}
case "container.blockio.io_serviced_recursive":
for _, tag := range m.Tags {
switch tag {
case "operation:write":
series = append(series, copyZorkianSystemMetric(m, "container.io.write.operations", 1))
case "operation:read":
series = append(series, copyZorkianSystemMetric(m, "container.io.read.operations", 1))
}
}
case "container.network.io.usage.tx_bytes":
series = append(series, copyZorkianSystemMetric(m, "container.net.sent", 1))
case "container.network.io.usage.tx_packets":
series = append(series, copyZorkianSystemMetric(m, "container.net.sent.packets", 1))
case "container.network.io.usage.rx_bytes":
series = append(series, copyZorkianSystemMetric(m, "container.net.rcvd", 1))
case "container.network.io.usage.rx_packets":
series = append(series, copyZorkianSystemMetric(m, "container.net.rcvd.packets", 1))
}
}
return series
}
2 changes: 2 additions & 0 deletions exporter/datadogexporter/metrics_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func (exp *metricsExporter) PushMetricsData(ctx context.Context, md pmetric.Metr
var ms []datadogV2.MetricSeries
ms, sl, sp = consumer.(*metrics.Consumer).All(exp.getPushTime(), exp.params.BuildInfo, tags)
ms = metrics.PrepareSystemMetrics(ms)
ms = metrics.PrepareContainerMetrics(ms)

err = nil
if len(ms) > 0 {
Expand All @@ -220,6 +221,7 @@ func (exp *metricsExporter) PushMetricsData(ctx context.Context, md pmetric.Metr
var ms []zorkian.Metric
ms, sl, sp = consumer.(*metrics.ZorkianConsumer).All(exp.getPushTime(), exp.params.BuildInfo, tags)
ms = metrics.PrepareZorkianSystemMetrics(ms)
ms = metrics.PrepareZorkianContainerMetrics(ms)

err = nil
if len(ms) > 0 {
Expand Down

0 comments on commit 9e2210e

Please sign in to comment.