Skip to content

Commit f3fdea3

Browse files
[chore] [receiver/datadog] Add support for v1 series (#33957)
**Description:** This PR adds support for V1 series, as well as batches the metrics by resource, scope, and datapoint attributes. The batching code will also be required for future PRs which will add support for v2 series endpoints, service checks, and sketches. Follow up of #33631 and #33922. The full version of the code can be found in the `cedwards/datadog-metrics-receiver-full` branch, or in Grafana Alloy: https://github.com/grafana/alloy/tree/main/internal/etc/datadogreceiver **Link to tracking Issue:** #18278 **Testing:** Unit tests, as well as an end-to-end test, have been added. --------- Co-authored-by: Federico Torres <[email protected]>
1 parent 33c8d60 commit f3fdea3

11 files changed

+838
-7
lines changed

receiver/datadogreceiver/batcher.go

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package datadogreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/datadogreceiver"
5+
6+
import (
7+
"go.opentelemetry.io/collector/pdata/pcommon"
8+
"go.opentelemetry.io/collector/pdata/pmetric"
9+
10+
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics/identity"
11+
)
12+
13+
type Batcher struct {
14+
pmetric.Metrics
15+
16+
resourceMetrics map[identity.Resource]pmetric.ResourceMetrics
17+
scopeMetrics map[identity.Scope]pmetric.ScopeMetrics
18+
metrics map[identity.Metric]pmetric.Metric
19+
}
20+
21+
func newBatcher() Batcher {
22+
return Batcher{
23+
Metrics: pmetric.NewMetrics(),
24+
resourceMetrics: make(map[identity.Resource]pmetric.ResourceMetrics),
25+
scopeMetrics: make(map[identity.Scope]pmetric.ScopeMetrics),
26+
metrics: make(map[identity.Metric]pmetric.Metric),
27+
}
28+
}
29+
30+
// Dimensions stores the properties of the series that are needed in order
31+
// to unique identify the series. This is needed in order to batch metrics by
32+
// resource, scope, and datapoint attributes
33+
type Dimensions struct {
34+
name string
35+
metricType pmetric.MetricType
36+
resourceAttrs pcommon.Map
37+
scopeAttrs pcommon.Map
38+
dpAttrs pcommon.Map
39+
buildInfo string
40+
}
41+
42+
var metricTypeMap = map[string]pmetric.MetricType{
43+
"count": pmetric.MetricTypeSum,
44+
"gauge": pmetric.MetricTypeGauge,
45+
"rate": pmetric.MetricTypeSum,
46+
"service_check": pmetric.MetricTypeGauge,
47+
"sketch": pmetric.MetricTypeExponentialHistogram,
48+
}
49+
50+
func parseSeriesProperties(name string, metricType string, tags []string, host string, version string, stringPool *StringPool) Dimensions {
51+
resourceAttrs, scopeAttrs, dpAttrs := tagsToAttributes(tags, host, stringPool)
52+
return Dimensions{
53+
name: name,
54+
metricType: metricTypeMap[metricType],
55+
buildInfo: version,
56+
resourceAttrs: resourceAttrs,
57+
scopeAttrs: scopeAttrs,
58+
dpAttrs: dpAttrs,
59+
}
60+
}
61+
62+
func (b Batcher) Lookup(dim Dimensions) (pmetric.Metric, identity.Metric) {
63+
resource := dim.Resource()
64+
resourceID := identity.OfResource(resource)
65+
resourceMetrics, ok := b.resourceMetrics[resourceID]
66+
if !ok {
67+
resourceMetrics = b.Metrics.ResourceMetrics().AppendEmpty()
68+
resource.MoveTo(resourceMetrics.Resource())
69+
b.resourceMetrics[resourceID] = resourceMetrics
70+
}
71+
72+
scope := dim.Scope()
73+
scopeID := identity.OfScope(resourceID, scope)
74+
scopeMetrics, ok := b.scopeMetrics[scopeID]
75+
if !ok {
76+
scopeMetrics = resourceMetrics.ScopeMetrics().AppendEmpty()
77+
scope.MoveTo(scopeMetrics.Scope())
78+
b.scopeMetrics[scopeID] = scopeMetrics
79+
}
80+
81+
m := dim.Metric()
82+
metricID := identity.OfMetric(scopeID, m)
83+
metric, ok := b.metrics[metricID]
84+
if !ok {
85+
metric = scopeMetrics.Metrics().AppendEmpty()
86+
m.MoveTo(metric)
87+
b.metrics[metricID] = metric
88+
}
89+
90+
return metric, metricID
91+
}
92+
93+
func (d Dimensions) Resource() pcommon.Resource {
94+
resource := pcommon.NewResource()
95+
d.resourceAttrs.CopyTo(resource.Attributes()) // TODO(jesus.vazquez) review this copy
96+
return resource
97+
}
98+
99+
func (d Dimensions) Scope() pcommon.InstrumentationScope {
100+
scope := pcommon.NewInstrumentationScope()
101+
scope.SetName("otelcol/datadogreceiver")
102+
scope.SetVersion(d.buildInfo)
103+
d.scopeAttrs.CopyTo(scope.Attributes())
104+
return scope
105+
}
106+
107+
func (d Dimensions) Metric() pmetric.Metric {
108+
metric := pmetric.NewMetric()
109+
metric.SetName(d.name)
110+
switch d.metricType {
111+
case pmetric.MetricTypeSum:
112+
metric.SetEmptySum()
113+
case pmetric.MetricTypeGauge:
114+
metric.SetEmptyGauge()
115+
case pmetric.MetricTypeExponentialHistogram:
116+
metric.SetEmptyExponentialHistogram()
117+
}
118+
return metric
119+
}

0 commit comments

Comments
 (0)