Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[datadogexporter] Fix missing resource attributes default mapping when resource_attributes_as_tags: false #6359

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ func (t *Translator) MapMetrics(ctx context.Context, md pdata.Metrics, consumer
var additionalTags []string
if t.cfg.InstrumentationLibraryMetadataAsTags {
additionalTags = append(attributeTags, instrumentationlibrary.TagsFromInstrumentationLibraryMetadata(ilm.InstrumentationLibrary())...)
} else {
additionalTags = attributeTags
mx-psi marked this conversation as resolved.
Show resolved Hide resolved
}

for k := 0; k < metricsArray.Len(); k++ {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package translator

import (
"context"
"fmt"
"math"
"testing"
"time"
Expand All @@ -26,6 +27,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/model/pdata"
conventions "go.opentelemetry.io/collector/model/semconv/v1.5.0"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest/observer"
Expand Down Expand Up @@ -106,12 +108,16 @@ func (t testProvider) Hostname(context.Context) (string, error) {
return string(t), nil
}

func newTranslator(t *testing.T, logger *zap.Logger) *Translator {
tr, err := New(
logger,
func newTranslator(t *testing.T, logger *zap.Logger, opts ...Option) *Translator {
options := append([]Option{
WithFallbackHostnameProvider(testProvider("fallbackHostname")),
WithHistogramMode(HistogramModeDistributions),
WithNumberMode(NumberModeCumulativeToDelta),
}, opts...)

tr, err := New(
logger,
options...,
)

require.NoError(t, err)
Expand Down Expand Up @@ -934,16 +940,22 @@ const (
testHostname = "res-hostname"
)

func createTestMetrics() pdata.Metrics {
func createTestMetrics(additionalAttributes map[string]string, name, version string) pdata.Metrics {
md := pdata.NewMetrics()
rms := md.ResourceMetrics()
rm := rms.AppendEmpty()

attrs := rm.Resource().Attributes()
attrs.InsertString(attributes.AttributeDatadogHostname, testHostname)
for attr, val := range additionalAttributes {
attrs.InsertString(attr, val)
}
ilms := rm.InstrumentationLibraryMetrics()

metricsArray := ilms.AppendEmpty().Metrics()
ilm := ilms.AppendEmpty()
ilm.InstrumentationLibrary().SetName(name)
ilm.InstrumentationLibrary().SetVersion(version)
metricsArray := ilm.Metrics()
metricsArray.AppendEmpty() // first one is TypeNone to test that it's ignored

// IntGauge
Expand Down Expand Up @@ -1096,64 +1108,203 @@ func createTestMetrics() pdata.Metrics {
return md
}

func newGaugeWithHostname(name string, val float64) metric {
m := newGauge(name, 0, val, []string{})
func newGaugeWithHostname(name string, val float64, tags []string) metric {
m := newGauge(name, 0, val, tags)
m.host = testHostname
return m
}

func newCountWithHostname(name string, val float64, seconds uint64) metric {
m := newCount(name, seconds*1e9, val, []string{})
func newCountWithHostname(name string, val float64, seconds uint64, tags []string) metric {
m := newCount(name, seconds*1e9, val, tags)
m.host = testHostname
return m
}

func newSketchWithHostname(name string, summary summary.Summary, seconds uint64) sketch {
s := newSketch(name, seconds, summary, []string{})
func newSketchWithHostname(name string, summary summary.Summary, tags []string) sketch {
s := newSketch(name, 0, summary, tags)
s.host = testHostname
return s
}

func TestMapMetrics(t *testing.T) {
md := createTestMetrics()
attrs := map[string]string{
conventions.AttributeDeploymentEnvironment: "dev",
"custom_attribute": "custom_value",
}
// When ResourceAttributesAsTags is true, attributes are
// converted into labels by the resourcetotelemetry helper,
// so MapMetrics doesn't do any conversion.
// When ResourceAttributesAsTags is false, attributes
// defined in internal/attributes get converted to tags.
// Other tags do not get converted.
attrTags := []string{
"env:dev",
}

core, observed := observer.New(zapcore.DebugLevel)
testLogger := zap.New(core)
ctx := context.Background()
consumer := &mockFullConsumer{}
tr := newTranslator(t, testLogger)
err := tr.MapMetrics(ctx, md, consumer)
require.NoError(t, err)
ilName := "instrumentation_library"
ilVersion := "1.0.0"
ilTags := []string{
fmt.Sprintf("instrumentation_library:%s", ilName),
fmt.Sprintf("instrumentation_library_version:%s", ilVersion),
}

assert.ElementsMatch(t, consumer.metrics, []metric{
newGaugeWithHostname("int.gauge", 1),
newGaugeWithHostname("double.gauge", math.Pi),
newCountWithHostname("int.delta.sum", 2, 0),
newCountWithHostname("double.delta.sum", math.E, 0),
newCountWithHostname("int.delta.monotonic.sum", 2, 0),
newCountWithHostname("double.delta.monotonic.sum", math.E, 0),
newCountWithHostname("summary.sum", 10_000, 2),
newCountWithHostname("summary.count", 100, 2),
newGaugeWithHostname("int.cumulative.sum", 4),
newGaugeWithHostname("double.cumulative.sum", 4),
newCountWithHostname("int.cumulative.monotonic.sum", 3, 2),
newCountWithHostname("double.cumulative.monotonic.sum", math.Pi, 2),
})
tests := []struct {
name string
resourceAttributesAsTags bool
instrumentationLibraryMetadataAsTags bool
expectedMetrics []metric
expectedSketches []sketch
expectedUnknownMetricType int
expectedUnsupportedAggregationTemporality int
}{
{
name: "ResourceAttributesAsTags: false, InstrumentationLibraryMetadataAsTags: false",
resourceAttributesAsTags: false,
instrumentationLibraryMetadataAsTags: false,
expectedMetrics: []metric{
newGaugeWithHostname("int.gauge", 1, attrTags),
newGaugeWithHostname("double.gauge", math.Pi, attrTags),
newCountWithHostname("int.delta.sum", 2, 0, attrTags),
newCountWithHostname("double.delta.sum", math.E, 0, attrTags),
newCountWithHostname("int.delta.monotonic.sum", 2, 0, attrTags),
newCountWithHostname("double.delta.monotonic.sum", math.E, 0, attrTags),
newCountWithHostname("summary.sum", 10_000, 2, attrTags),
newCountWithHostname("summary.count", 100, 2, attrTags),
newGaugeWithHostname("int.cumulative.sum", 4, attrTags),
newGaugeWithHostname("double.cumulative.sum", 4, attrTags),
newCountWithHostname("int.cumulative.monotonic.sum", 3, 2, attrTags),
newCountWithHostname("double.cumulative.monotonic.sum", math.Pi, 2, attrTags),
},
expectedSketches: []sketch{
newSketchWithHostname("double.histogram", summary.Summary{
Min: 0,
Max: 0,
Sum: 0,
Avg: 0,
Cnt: 20,
}, attrTags),
},
expectedUnknownMetricType: 1,
expectedUnsupportedAggregationTemporality: 2,
},
{
name: "ResourceAttributesAsTags: true, InstrumentationLibraryMetadataAsTags: false",
resourceAttributesAsTags: true,
instrumentationLibraryMetadataAsTags: false,
expectedMetrics: []metric{
newGaugeWithHostname("int.gauge", 1, []string{}),
newGaugeWithHostname("double.gauge", math.Pi, []string{}),
newCountWithHostname("int.delta.sum", 2, 0, []string{}),
newCountWithHostname("double.delta.sum", math.E, 0, []string{}),
newCountWithHostname("int.delta.monotonic.sum", 2, 0, []string{}),
newCountWithHostname("double.delta.monotonic.sum", math.E, 0, []string{}),
newCountWithHostname("summary.sum", 10_000, 2, []string{}),
newCountWithHostname("summary.count", 100, 2, []string{}),
newGaugeWithHostname("int.cumulative.sum", 4, []string{}),
newGaugeWithHostname("double.cumulative.sum", 4, []string{}),
newCountWithHostname("int.cumulative.monotonic.sum", 3, 2, []string{}),
newCountWithHostname("double.cumulative.monotonic.sum", math.Pi, 2, []string{}),
},
expectedSketches: []sketch{
newSketchWithHostname("double.histogram", summary.Summary{
Min: 0,
Max: 0,
Sum: 0,
Avg: 0,
Cnt: 20,
}, []string{}),
},
expectedUnknownMetricType: 1,
expectedUnsupportedAggregationTemporality: 2,
},
{
name: "ResourceAttributesAsTags: false, InstrumentationLibraryMetadataAsTags: true",
resourceAttributesAsTags: false,
instrumentationLibraryMetadataAsTags: true,
expectedMetrics: []metric{
newGaugeWithHostname("int.gauge", 1, append(attrTags, ilTags...)),
newGaugeWithHostname("double.gauge", math.Pi, append(attrTags, ilTags...)),
newCountWithHostname("int.delta.sum", 2, 0, append(attrTags, ilTags...)),
newCountWithHostname("double.delta.sum", math.E, 0, append(attrTags, ilTags...)),
newCountWithHostname("int.delta.monotonic.sum", 2, 0, append(attrTags, ilTags...)),
newCountWithHostname("double.delta.monotonic.sum", math.E, 0, append(attrTags, ilTags...)),
newCountWithHostname("summary.sum", 10_000, 2, append(attrTags, ilTags...)),
newCountWithHostname("summary.count", 100, 2, append(attrTags, ilTags...)),
newGaugeWithHostname("int.cumulative.sum", 4, append(attrTags, ilTags...)),
newGaugeWithHostname("double.cumulative.sum", 4, append(attrTags, ilTags...)),
newCountWithHostname("int.cumulative.monotonic.sum", 3, 2, append(attrTags, ilTags...)),
newCountWithHostname("double.cumulative.monotonic.sum", math.Pi, 2, append(attrTags, ilTags...)),
},
expectedSketches: []sketch{
newSketchWithHostname("double.histogram", summary.Summary{
Min: 0,
Max: 0,
Sum: 0,
Avg: 0,
Cnt: 20,
}, append(attrTags, ilTags...)),
},
expectedUnknownMetricType: 1,
expectedUnsupportedAggregationTemporality: 2,
},
{
name: "ResourceAttributesAsTags: true, InstrumentationLibraryMetadataAsTags: true",
resourceAttributesAsTags: true,
instrumentationLibraryMetadataAsTags: true,
expectedMetrics: []metric{
newGaugeWithHostname("int.gauge", 1, ilTags),
newGaugeWithHostname("double.gauge", math.Pi, ilTags),
newCountWithHostname("int.delta.sum", 2, 0, ilTags),
newCountWithHostname("double.delta.sum", math.E, 0, ilTags),
newCountWithHostname("int.delta.monotonic.sum", 2, 0, ilTags),
newCountWithHostname("double.delta.monotonic.sum", math.E, 0, ilTags),
newCountWithHostname("summary.sum", 10_000, 2, ilTags),
newCountWithHostname("summary.count", 100, 2, ilTags),
newGaugeWithHostname("int.cumulative.sum", 4, ilTags),
newGaugeWithHostname("double.cumulative.sum", 4, ilTags),
newCountWithHostname("int.cumulative.monotonic.sum", 3, 2, ilTags),
newCountWithHostname("double.cumulative.monotonic.sum", math.Pi, 2, ilTags),
},
expectedSketches: []sketch{
newSketchWithHostname("double.histogram", summary.Summary{
Min: 0,
Max: 0,
Sum: 0,
Avg: 0,
Cnt: 20,
}, ilTags),
},
expectedUnknownMetricType: 1,
expectedUnsupportedAggregationTemporality: 2,
},
}

assert.ElementsMatch(t, consumer.sketches, []sketch{
newSketchWithHostname("double.histogram", summary.Summary{
Min: 0,
Max: 0,
Sum: 0,
Avg: 0,
Cnt: 20,
}, 0),
})
for _, testInstance := range tests {
t.Run(testInstance.name, func(t *testing.T) {
md := createTestMetrics(attrs, ilName, ilVersion)

// One metric type was unknown or unsupported
assert.Equal(t, observed.FilterMessage("Unknown or unsupported metric type").Len(), 1)
// Two metric aggregation temporality was unknown or unsupported
assert.Equal(t, observed.FilterMessage("Unknown or unsupported aggregation temporality").Len(), 2)
core, observed := observer.New(zapcore.DebugLevel)
testLogger := zap.New(core)
ctx := context.Background()
consumer := &mockFullConsumer{}

options := []Option{}
if testInstance.resourceAttributesAsTags {
options = append(options, WithResourceAttributesAsTags())
}
if testInstance.instrumentationLibraryMetadataAsTags {
options = append(options, WithInstrumentationLibraryMetadataAsTags())
}
tr := newTranslator(t, testLogger, options...)
err := tr.MapMetrics(ctx, md, consumer)
require.NoError(t, err)

assert.ElementsMatch(t, consumer.metrics, testInstance.expectedMetrics)
assert.ElementsMatch(t, consumer.sketches, testInstance.expectedSketches)
assert.Equal(t, observed.FilterMessage("Unknown or unsupported metric type").Len(), testInstance.expectedUnknownMetricType)
assert.Equal(t, observed.FilterMessage("Unknown or unsupported aggregation temporality").Len(), testInstance.expectedUnsupportedAggregationTemporality)
})
}
}

func createNaNMetrics() pdata.Metrics {
Expand Down Expand Up @@ -1259,7 +1410,7 @@ func TestNaNMetrics(t *testing.T) {
require.NoError(t, err)

assert.ElementsMatch(t, consumer.metrics, []metric{
newCountWithHostname("nan.summary.count", 100, 2),
newCountWithHostname("nan.summary.count", 100, 2, []string{}),
})

assert.ElementsMatch(t, consumer.sketches, []sketch{
Expand All @@ -1269,7 +1420,7 @@ func TestNaNMetrics(t *testing.T) {
Sum: 0,
Avg: 0,
Cnt: 20,
}, 0),
}, []string{}),
})

// One metric type was unknown or unsupported
Expand Down