From 7235ad381f11d63ee52537c8113fb741d19f6a92 Mon Sep 17 00:00:00 2001 From: "Mengyi Zhou (bjrara)" Date: Fri, 17 May 2024 11:37:04 -0700 Subject: [PATCH 1/5] Update ApplicationSignals log group name and adjust AWS service name --- exporter/awsemfexporter/config_test.go | 26 +++++++-------- exporter/awsemfexporter/datapoint.go | 23 +++++-------- exporter/awsemfexporter/datapoint_test.go | 33 ++++++++----------- exporter/awsemfexporter/emf_exporter.go | 4 +-- .../awsemfexporter/grouped_metric_test.go | 22 +++++-------- .../awsemfexporter/metric_translator_test.go | 15 --------- .../internal/translator/segment.go | 8 +++-- .../internal/translator/segment_test.go | 30 ++++++++++++++++- internal/aws/cwlogs/cwlog_client_test.go | 11 +++++-- 9 files changed, 91 insertions(+), 81 deletions(-) diff --git a/exporter/awsemfexporter/config_test.go b/exporter/awsemfexporter/config_test.go index 99dba3d90510..bd7e7710a542 100644 --- a/exporter/awsemfexporter/config_test.go +++ b/exporter/awsemfexporter/config_test.go @@ -271,7 +271,7 @@ func TestNoDimensionRollupFeatureGate(t *testing.T) { _ = featuregate.GlobalRegistry().Set("awsemf.nodimrollupdefault", false) } -func TestIsAppSignalsEnabled(t *testing.T) { +func TestIsApplicationSignalsEnabled(t *testing.T) { tests := []struct { name string metricNameSpace string @@ -279,27 +279,27 @@ func TestIsAppSignalsEnabled(t *testing.T) { expectedResult bool }{ { - "validAppSignalsEMF", - "AppSignals", - "/aws/appsignals/eks", + "validApplicationSignalsEMF", + "ApplicationSignals", + "/aws/application-signals/data", true, }, { - "invalidAppSignalsLogsGroup", - "AppSignals", - "/nonaws/appsignals/eks", + "invalidApplicationSignalsLogsGroup", + "ApplicationSignals", + "/nonaws/application-signals/eks", false, }, { - "invalidAppSignalsMetricNamespace", - "NonAppSignals", - "/aws/appsignals/eks", + "invalidApplicationSignalsMetricNamespace", + "NonApplicationSignals", + "/aws/application-signals/data", false, }, { - "invalidAppSignalsEMF", - "NonAppSignals", - "/nonaws/appsignals/eks", + "invalidApplicationSignalsEMF", + "NonApplicationSignals", + "/nonaws/application-signals/eks", false, }, { diff --git a/exporter/awsemfexporter/datapoint.go b/exporter/awsemfexporter/datapoint.go index 1104a9e59e41..d5ddac4343d8 100644 --- a/exporter/awsemfexporter/datapoint.go +++ b/exporter/awsemfexporter/datapoint.go @@ -110,9 +110,9 @@ type summaryMetricEntry struct { } // CalculateDeltaDatapoints retrieves the NumberDataPoint at the given index and performs rate/delta calculation if necessary. -func (dps numberDataPointSlice) CalculateDeltaDatapoints(i int, instrumentationScopeName string, _ bool, calculators *emfCalculators) ([]dataPoint, bool) { +func (dps numberDataPointSlice) CalculateDeltaDatapoints(i int, _ string, _ bool, calculators *emfCalculators) ([]dataPoint, bool) { metric := dps.NumberDataPointSlice.At(i) - labels := createLabels(metric.Attributes(), instrumentationScopeName) + labels := createLabels(metric.Attributes()) timestampMs := unixNanoToMilliseconds(metric.Timestamp()) var metricVal float64 @@ -161,9 +161,9 @@ func (dps numberDataPointSlice) IsStaleNaNInf(i int) (bool, pcommon.Map) { } // CalculateDeltaDatapoints retrieves the HistogramDataPoint at the given index. -func (dps histogramDataPointSlice) CalculateDeltaDatapoints(i int, instrumentationScopeName string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { +func (dps histogramDataPointSlice) CalculateDeltaDatapoints(i int, _ string, _ bool, calculators *emfCalculators) ([]dataPoint, bool) { metric := dps.HistogramDataPointSlice.At(i) - labels := createLabels(metric.Attributes(), instrumentationScopeName) + labels := createLabels(metric.Attributes()) timestamp := unixNanoToMilliseconds(metric.Timestamp()) return []dataPoint{{ @@ -193,7 +193,7 @@ func (dps histogramDataPointSlice) IsStaleNaNInf(i int) (bool, pcommon.Map) { } // CalculateDeltaDatapoints retrieves the ExponentialHistogramDataPoint at the given index. -func (dps exponentialHistogramDataPointSlice) CalculateDeltaDatapoints(idx int, instrumentationScopeName string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { +func (dps exponentialHistogramDataPointSlice) CalculateDeltaDatapoints(idx int, _ string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { metric := dps.ExponentialHistogramDataPointSlice.At(idx) scale := metric.Scale() @@ -269,7 +269,7 @@ func (dps exponentialHistogramDataPointSlice) CalculateDeltaDatapoints(idx int, Max: metric.Max(), Min: metric.Min(), }, - labels: createLabels(metric.Attributes(), instrumentationScopeName), + labels: createLabels(metric.Attributes()), timestampMs: unixNanoToMilliseconds(metric.Timestamp()), }}, true } @@ -292,9 +292,9 @@ func (dps exponentialHistogramDataPointSlice) IsStaleNaNInf(i int) (bool, pcommo } // CalculateDeltaDatapoints retrieves the SummaryDataPoint at the given index and perform calculation with sum and count while retain the quantile value. -func (dps summaryDataPointSlice) CalculateDeltaDatapoints(i int, instrumentationScopeName string, detailedMetrics bool, calculators *emfCalculators) ([]dataPoint, bool) { +func (dps summaryDataPointSlice) CalculateDeltaDatapoints(i int, _ string, detailedMetrics bool, calculators *emfCalculators) ([]dataPoint, bool) { metric := dps.SummaryDataPointSlice.At(i) - labels := createLabels(metric.Attributes(), instrumentationScopeName) + labels := createLabels(metric.Attributes()) timestampMs := unixNanoToMilliseconds(metric.Timestamp()) sum := metric.Sum() @@ -371,18 +371,13 @@ func (dps summaryDataPointSlice) IsStaleNaNInf(i int) (bool, pcommon.Map) { // createLabels converts OTel AttributesMap attributes to a map // and optionally adds in the OTel instrumentation library name -func createLabels(attributes pcommon.Map, instrLibName string) map[string]string { +func createLabels(attributes pcommon.Map) map[string]string { labels := make(map[string]string, attributes.Len()+1) attributes.Range(func(k string, v pcommon.Value) bool { labels[k] = v.AsString() return true }) - // Add OTel instrumentation lib name as an additional label if it is defined - if instrLibName != "" { - labels[oTellibDimensionKey] = instrLibName - } - return labels } diff --git a/exporter/awsemfexporter/datapoint_test.go b/exporter/awsemfexporter/datapoint_test.go index 597f1d4b091c..f8d8e55c9408 100644 --- a/exporter/awsemfexporter/datapoint_test.go +++ b/exporter/awsemfexporter/datapoint_test.go @@ -442,7 +442,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "double", value: 0.4, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, expectedRetained: retainInitialValueOfDeltaMetric, }, @@ -454,7 +454,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "double", value: 0.4, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, expectedRetained: true, }, @@ -466,7 +466,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "double", value: 0.5, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, expectedRetained: true, }, @@ -479,7 +479,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "int", value: float64(-17), - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, expectedRetained: retainInitialValueOfDeltaMetric, }, @@ -491,7 +491,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "int", value: float64(18), - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, expectedRetained: true, }, @@ -503,7 +503,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "int", value: float64(10), - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, expectedRetained: true, }, @@ -567,7 +567,7 @@ func TestCalculateDeltaDatapoints_HistogramDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricStats{Sum: 17.13, Count: 17, Min: 10, Max: 30}, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, }, { @@ -584,7 +584,7 @@ func TestCalculateDeltaDatapoints_HistogramDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricStats{Sum: 17.13, Count: 17, Min: 0, Max: 0}, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, }, { @@ -602,7 +602,7 @@ func TestCalculateDeltaDatapoints_HistogramDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricStats{Sum: 17.13, Count: 17, Min: 0, Max: 0}, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, }, } @@ -817,7 +817,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{}, Counts: []float64{}, Sum: 17.13, Count: 17, Min: 10, Max: 30}, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, }, { @@ -834,7 +834,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{}, Counts: []float64{}, Sum: 17.13, Count: 17, Min: 0, Max: 0}, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, }, { @@ -851,7 +851,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{1.5, 3, 6, 0, -1.5, -3, -6}, Counts: []float64{1, 2, 3, 4, 1, 2, 3}}, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, + labels: map[string]string{"label1": "value1"}, }, }, { @@ -872,7 +872,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{0.625, 2.5, 10, 0, -0.625, -2.5, -10}, Counts: []float64{1, 2, 3, 4, 1, 2, 3}}, - labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1", "label2": "value2"}, + labels: map[string]string{"label1": "value1", "label2": "value2"}, }, }, } @@ -1382,12 +1382,7 @@ func TestCreateLabels(t *testing.T) { "c": "C", })) - labels := createLabels(labelsMap, "") - assert.Equal(t, expectedLabels, labels) - - // With isntrumentation library name - labels = createLabels(labelsMap, "cloudwatch-otel") - expectedLabels[oTellibDimensionKey] = "cloudwatch-otel" + labels := createLabels(labelsMap) assert.Equal(t, expectedLabels, labels) } diff --git a/exporter/awsemfexporter/emf_exporter.go b/exporter/awsemfexporter/emf_exporter.go index 7b5bda9d8176..67eb53b3356d 100644 --- a/exporter/awsemfexporter/emf_exporter.go +++ b/exporter/awsemfexporter/emf_exporter.go @@ -29,8 +29,8 @@ const ( outputDestinationStdout = "stdout" // AppSignals EMF config - appSignalsMetricNamespace = "AppSignals" - appSignalsLogGroupNamePrefix = "/aws/appsignals/" + appSignalsMetricNamespace = "ApplicationSignals" + appSignalsLogGroupNamePrefix = "/aws/application-signals/" ) type emfExporter struct { diff --git a/exporter/awsemfexporter/grouped_metric_test.go b/exporter/awsemfexporter/grouped_metric_test.go index 47bee6e50fea..ac8d1f02b5a0 100644 --- a/exporter/awsemfexporter/grouped_metric_test.go +++ b/exporter/awsemfexporter/grouped_metric_test.go @@ -39,7 +39,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Double gauge", metric: generateTestGaugeMetric("foo", doubleValueType), expectedMetricType: pmetric.MetricTypeGauge, - expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, + expectedLabels: map[string]string{"label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: 0.1, @@ -51,7 +51,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Int sum", metric: generateTestSumMetric("foo", intValueType), expectedMetricType: pmetric.MetricTypeSum, - expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, + expectedLabels: map[string]string{"label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: float64(1), @@ -63,7 +63,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Histogram", metric: generateTestHistogramMetric("foo"), expectedMetricType: pmetric.MetricTypeHistogram, - expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, + expectedLabels: map[string]string{"label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: &cWMetricStats{ @@ -78,7 +78,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Summary", metric: generateTestSummaryMetric("foo"), expectedMetricType: pmetric.MetricTypeSummary, - expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, + expectedLabels: map[string]string{"label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: &cWMetricStats{ @@ -120,7 +120,7 @@ func TestAddToGroupedMetric(t *testing.T) { for _, v := range groupedMetrics { assert.Equal(t, len(tc.expectedMetricInfo), len(v.metrics)) assert.Equal(t, tc.expectedMetricInfo, v.metrics) - assert.Equal(t, 2, len(v.labels)) + assert.Equal(t, 1, len(v.labels)) assert.Equal(t, generateTestMetricMetadata(namespace, timestamp, logGroup, logStreamName, instrumentationLibName, tc.expectedMetricType), v.metadata) assert.Equal(t, tc.expectedLabels, v.labels) } @@ -182,8 +182,7 @@ func TestAddToGroupedMetric(t *testing.T) { assert.Fail(t, fmt.Sprintf("Unhandled metric %s not expected", metricName)) } expectedLabels := map[string]string{ - oTellibDimensionKey: "cloudwatch-otel", - "label1": "value1", + "label1": "value1", } assert.Equal(t, expectedLabels, group.labels) } @@ -254,8 +253,7 @@ func TestAddToGroupedMetric(t *testing.T) { assert.Fail(t, fmt.Sprintf("Unhandled metric %s not expected", metricName)) } expectedLabels := map[string]string{ - oTellibDimensionKey: "cloudwatch-otel", - "label1": "value1", + "label1": "value1", } assert.Equal(t, expectedLabels, group.labels) } @@ -303,8 +301,7 @@ func TestAddToGroupedMetric(t *testing.T) { } assert.Equal(t, expectedMetrics, group.metrics) expectedLabels := map[string]string{ - oTellibDimensionKey: "cloudwatch-otel", - "label1": "value1", + "label1": "value1", } assert.Equal(t, expectedLabels, group.labels) @@ -351,8 +348,7 @@ func TestAddToGroupedMetric(t *testing.T) { assert.Equal(t, 1, len(groupedMetrics)) labels := map[string]string{ - oTellibDimensionKey: instrumentationLibName, - "label1": "value1", + "label1": "value1", } // Test output warning logs expectedLogs := []observer.LoggedEntry{ diff --git a/exporter/awsemfexporter/metric_translator_test.go b/exporter/awsemfexporter/metric_translator_test.go index 1ac411048e6d..94a2412bbc2f 100644 --- a/exporter/awsemfexporter/metric_translator_test.go +++ b/exporter/awsemfexporter/metric_translator_test.go @@ -259,7 +259,6 @@ func TestTranslateOtToGroupedMetric(t *testing.T) { translator := newMetricTranslator(*config) defer require.NoError(t, translator.Shutdown()) - noInstrLibMetric := createTestResourceMetrics() instrLibMetric := createTestResourceMetrics() ilm := instrLibMetric.ScopeMetrics().At(0) ilm.Scope().SetName("cloudwatch-lib") @@ -308,20 +307,6 @@ func TestTranslateOtToGroupedMetric(t *testing.T) { { "w/ instrumentation library and namespace", instrLibMetric, - map[string]string{ - (oTellibDimensionKey): "cloudwatch-lib", - "isItAnError": "false", - "spanName": "testSpan", - }, - map[string]string{ - (oTellibDimensionKey): "cloudwatch-lib", - "spanName": "testSpan", - }, - "myServiceNS/myServiceName", - }, - { - "w/o instrumentation library, w/ namespace", - noInstrLibMetric, map[string]string{ "isItAnError": "false", "spanName": "testSpan", diff --git a/exporter/awsxrayexporter/internal/translator/segment.go b/exporter/awsxrayexporter/internal/translator/segment.go index 9460f1ce5c67..9bb8582d14c6 100644 --- a/exporter/awsxrayexporter/internal/translator/segment.go +++ b/exporter/awsxrayexporter/internal/translator/segment.go @@ -770,8 +770,12 @@ func fixAnnotationKey(key string) string { } func trimAwsSdkPrefix(name string, span ptrace.Span) string { - if isAwsSdkSpan(span) && strings.HasPrefix(name, "AWS.SDK.") { - return strings.TrimPrefix(name, "AWS.SDK.") + if isAwsSdkSpan(span) { + if strings.HasPrefix(name, "AWS.SDK.") { + return strings.TrimPrefix(name, "AWS.SDK.") + } else if strings.HasPrefix(name, "AWS::") { + return strings.TrimPrefix(name, "AWS::") + } } return name } diff --git a/exporter/awsxrayexporter/internal/translator/segment_test.go b/exporter/awsxrayexporter/internal/translator/segment_test.go index 8426e2e976ac..8b33edec28eb 100644 --- a/exporter/awsxrayexporter/internal/translator/segment_test.go +++ b/exporter/awsxrayexporter/internal/translator/segment_test.go @@ -1093,7 +1093,7 @@ func TestClientSpanWithAwsRemoteServiceName(t *testing.T) { assert.False(t, strings.Contains(jsonStr, "user")) } -func TestAwsSdkSpanWithAwsRemoteServiceName(t *testing.T) { +func TestAwsSdkSpanWithDeprecatedAwsRemoteServiceName(t *testing.T) { spanName := "DynamoDB.PutItem" parentSpanID := newSegmentID() user := "testingT" @@ -1121,6 +1121,34 @@ func TestAwsSdkSpanWithAwsRemoteServiceName(t *testing.T) { assert.False(t, strings.Contains(jsonStr, "user")) } +func TestAwsSdkSpanWithAwsRemoteServiceName(t *testing.T) { + spanName := "DynamoDB.PutItem" + parentSpanID := newSegmentID() + user := "testingT" + attributes := make(map[string]any) + attributes[conventions.AttributeRPCSystem] = "aws-api" + attributes[conventions.AttributeHTTPMethod] = "POST" + attributes[conventions.AttributeHTTPScheme] = "https" + attributes[conventions.AttributeRPCService] = "DynamoDb" + attributes[awsRemoteService] = "AWS::DynamoDB" + + resource := constructDefaultResource() + span := constructClientSpan(parentSpanID, spanName, 0, "OK", attributes) + + segment, _ := MakeSegment(span, resource, nil, false, nil, false) + assert.Equal(t, "DynamoDB", *segment.Name) + assert.Equal(t, "subsegment", *segment.Type) + + jsonStr, err := MakeSegmentDocumentString(span, resource, nil, false, nil, false) + + assert.NotNil(t, jsonStr) + assert.Nil(t, err) + assert.True(t, strings.Contains(jsonStr, "DynamoDb")) + assert.False(t, strings.Contains(jsonStr, "DynamoDb.PutItem")) + assert.False(t, strings.Contains(jsonStr, user)) + assert.False(t, strings.Contains(jsonStr, "user")) +} + func TestProducerSpanWithAwsRemoteServiceName(t *testing.T) { spanName := "ABC.payment" parentSpanID := newSegmentID() diff --git a/internal/aws/cwlogs/cwlog_client_test.go b/internal/aws/cwlogs/cwlog_client_test.go index 36c5f30004d9..2832251e47e4 100644 --- a/internal/aws/cwlogs/cwlog_client_test.go +++ b/internal/aws/cwlogs/cwlog_client_test.go @@ -600,14 +600,14 @@ func TestUserAgent(t *testing.T) { { "validAppSignalsLogGroupAndAgentString", component.BuildInfo{Command: "opentelemetry-collector-contrib", Version: "1.0"}, - "/aws/appsignals", + "/aws/application-signals", []ClientOption{WithUserAgentExtras("AppSignals")}, fmt.Sprintf("opentelemetry-collector-contrib/1.0 (%s; AppSignals)", expectedComponentName), }, { "multipleAgentStringExtras", component.BuildInfo{Command: "opentelemetry-collector-contrib", Version: "1.0"}, - "/aws/appsignals", + "/aws/application-signals", []ClientOption{WithUserAgentExtras("abcde", "vwxyz", "12345")}, fmt.Sprintf("opentelemetry-collector-contrib/1.0 (%s; abcde; vwxyz; 12345)", expectedComponentName), }, @@ -618,6 +618,13 @@ func TestUserAgent(t *testing.T) { []ClientOption{WithUserAgentExtras("extra0", "extra1", "extra2")}, fmt.Sprintf("opentelemetry-collector-contrib/1.0 (%s; extra0; extra1; extra2; ContainerInsights)", expectedComponentName), }, + { + "validAppSignalsEMFEnabled", + component.BuildInfo{Command: "opentelemetry-collector-contrib", Version: "1.0"}, + "/aws/application-signals", + []ClientOption{WithUserAgentExtras("AppSignals")}, + fmt.Sprintf("opentelemetry-collector-contrib/1.0 (%s; AppSignals)", expectedComponentName), + }, } testSession, _ := session.NewSession() From 432c9af0338a26b9ca42e0ce21e52e3762bfa9c5 Mon Sep 17 00:00:00 2001 From: jjllee Date: Thu, 27 Jun 2024 14:26:04 -0700 Subject: [PATCH 2/5] add entry for .chloggen --- ...ppsignals-and-awssdk-name-adjustments.yaml | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .chloggen/appsignals-and-awssdk-name-adjustments.yaml diff --git a/.chloggen/appsignals-and-awssdk-name-adjustments.yaml b/.chloggen/appsignals-and-awssdk-name-adjustments.yaml new file mode 100644 index 000000000000..9fea0fb00569 --- /dev/null +++ b/.chloggen/appsignals-and-awssdk-name-adjustments.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: awsemfexporter + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: AWS EMF Exporter to update ApplicationSignals log group name and namespace, and adjust AWS service name + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [33798] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] From 9505f06d4013267961364ac54e0ec1b5614b8df7 Mon Sep 17 00:00:00 2001 From: jjllee Date: Thu, 27 Jun 2024 14:32:45 -0700 Subject: [PATCH 3/5] fix lint error --- exporter/awsemfexporter/datapoint.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/awsemfexporter/datapoint.go b/exporter/awsemfexporter/datapoint.go index d5ddac4343d8..6f13fe2d6ff2 100644 --- a/exporter/awsemfexporter/datapoint.go +++ b/exporter/awsemfexporter/datapoint.go @@ -161,7 +161,7 @@ func (dps numberDataPointSlice) IsStaleNaNInf(i int) (bool, pcommon.Map) { } // CalculateDeltaDatapoints retrieves the HistogramDataPoint at the given index. -func (dps histogramDataPointSlice) CalculateDeltaDatapoints(i int, _ string, _ bool, calculators *emfCalculators) ([]dataPoint, bool) { +func (dps histogramDataPointSlice) CalculateDeltaDatapoints(i int, _ string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { metric := dps.HistogramDataPointSlice.At(i) labels := createLabels(metric.Attributes()) timestamp := unixNanoToMilliseconds(metric.Timestamp()) From 4867b42771009f0485ec9b90735a79a3f7762985 Mon Sep 17 00:00:00 2001 From: jjllee Date: Fri, 28 Jun 2024 14:18:59 -0700 Subject: [PATCH 4/5] update .chloggen entry --- .chloggen/appsignals-and-awssdk-name-adjustments.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.chloggen/appsignals-and-awssdk-name-adjustments.yaml b/.chloggen/appsignals-and-awssdk-name-adjustments.yaml index 9fea0fb00569..c0c64e9954bb 100644 --- a/.chloggen/appsignals-and-awssdk-name-adjustments.yaml +++ b/.chloggen/appsignals-and-awssdk-name-adjustments.yaml @@ -7,7 +7,7 @@ change_type: enhancement component: awsemfexporter # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: AWS EMF Exporter to update ApplicationSignals log group name and namespace, and adjust AWS service name +note: AWS EMF Exporter to update ApplicationSignals log group name and namespace, adjust AWS service name, and remove OTelLib label from EMF log # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [33798] From f08ff9ba711a44f04e72e36d8f3dc98f593e459f Mon Sep 17 00:00:00 2001 From: jjllee Date: Fri, 28 Jun 2024 16:19:41 -0700 Subject: [PATCH 5/5] restore logic that adds OTelLib label in EMF log --- ...ppsignals-and-awssdk-name-adjustments.yaml | 2 +- exporter/awsemfexporter/datapoint.go | 23 ++++++++----- exporter/awsemfexporter/datapoint_test.go | 33 +++++++++++-------- .../awsemfexporter/grouped_metric_test.go | 22 ++++++++----- .../awsemfexporter/metric_translator_test.go | 15 +++++++++ 5 files changed, 62 insertions(+), 33 deletions(-) diff --git a/.chloggen/appsignals-and-awssdk-name-adjustments.yaml b/.chloggen/appsignals-and-awssdk-name-adjustments.yaml index c0c64e9954bb..536df16f4d56 100644 --- a/.chloggen/appsignals-and-awssdk-name-adjustments.yaml +++ b/.chloggen/appsignals-and-awssdk-name-adjustments.yaml @@ -7,7 +7,7 @@ change_type: enhancement component: awsemfexporter # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: AWS EMF Exporter to update ApplicationSignals log group name and namespace, adjust AWS service name, and remove OTelLib label from EMF log +note: AWS EMF Exporter to update ApplicationSignals log group name and namespace, and adjust AWS service name prefix logic in spans # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [33798] diff --git a/exporter/awsemfexporter/datapoint.go b/exporter/awsemfexporter/datapoint.go index 6f13fe2d6ff2..1104a9e59e41 100644 --- a/exporter/awsemfexporter/datapoint.go +++ b/exporter/awsemfexporter/datapoint.go @@ -110,9 +110,9 @@ type summaryMetricEntry struct { } // CalculateDeltaDatapoints retrieves the NumberDataPoint at the given index and performs rate/delta calculation if necessary. -func (dps numberDataPointSlice) CalculateDeltaDatapoints(i int, _ string, _ bool, calculators *emfCalculators) ([]dataPoint, bool) { +func (dps numberDataPointSlice) CalculateDeltaDatapoints(i int, instrumentationScopeName string, _ bool, calculators *emfCalculators) ([]dataPoint, bool) { metric := dps.NumberDataPointSlice.At(i) - labels := createLabels(metric.Attributes()) + labels := createLabels(metric.Attributes(), instrumentationScopeName) timestampMs := unixNanoToMilliseconds(metric.Timestamp()) var metricVal float64 @@ -161,9 +161,9 @@ func (dps numberDataPointSlice) IsStaleNaNInf(i int) (bool, pcommon.Map) { } // CalculateDeltaDatapoints retrieves the HistogramDataPoint at the given index. -func (dps histogramDataPointSlice) CalculateDeltaDatapoints(i int, _ string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { +func (dps histogramDataPointSlice) CalculateDeltaDatapoints(i int, instrumentationScopeName string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { metric := dps.HistogramDataPointSlice.At(i) - labels := createLabels(metric.Attributes()) + labels := createLabels(metric.Attributes(), instrumentationScopeName) timestamp := unixNanoToMilliseconds(metric.Timestamp()) return []dataPoint{{ @@ -193,7 +193,7 @@ func (dps histogramDataPointSlice) IsStaleNaNInf(i int) (bool, pcommon.Map) { } // CalculateDeltaDatapoints retrieves the ExponentialHistogramDataPoint at the given index. -func (dps exponentialHistogramDataPointSlice) CalculateDeltaDatapoints(idx int, _ string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { +func (dps exponentialHistogramDataPointSlice) CalculateDeltaDatapoints(idx int, instrumentationScopeName string, _ bool, _ *emfCalculators) ([]dataPoint, bool) { metric := dps.ExponentialHistogramDataPointSlice.At(idx) scale := metric.Scale() @@ -269,7 +269,7 @@ func (dps exponentialHistogramDataPointSlice) CalculateDeltaDatapoints(idx int, Max: metric.Max(), Min: metric.Min(), }, - labels: createLabels(metric.Attributes()), + labels: createLabels(metric.Attributes(), instrumentationScopeName), timestampMs: unixNanoToMilliseconds(metric.Timestamp()), }}, true } @@ -292,9 +292,9 @@ func (dps exponentialHistogramDataPointSlice) IsStaleNaNInf(i int) (bool, pcommo } // CalculateDeltaDatapoints retrieves the SummaryDataPoint at the given index and perform calculation with sum and count while retain the quantile value. -func (dps summaryDataPointSlice) CalculateDeltaDatapoints(i int, _ string, detailedMetrics bool, calculators *emfCalculators) ([]dataPoint, bool) { +func (dps summaryDataPointSlice) CalculateDeltaDatapoints(i int, instrumentationScopeName string, detailedMetrics bool, calculators *emfCalculators) ([]dataPoint, bool) { metric := dps.SummaryDataPointSlice.At(i) - labels := createLabels(metric.Attributes()) + labels := createLabels(metric.Attributes(), instrumentationScopeName) timestampMs := unixNanoToMilliseconds(metric.Timestamp()) sum := metric.Sum() @@ -371,13 +371,18 @@ func (dps summaryDataPointSlice) IsStaleNaNInf(i int) (bool, pcommon.Map) { // createLabels converts OTel AttributesMap attributes to a map // and optionally adds in the OTel instrumentation library name -func createLabels(attributes pcommon.Map) map[string]string { +func createLabels(attributes pcommon.Map, instrLibName string) map[string]string { labels := make(map[string]string, attributes.Len()+1) attributes.Range(func(k string, v pcommon.Value) bool { labels[k] = v.AsString() return true }) + // Add OTel instrumentation lib name as an additional label if it is defined + if instrLibName != "" { + labels[oTellibDimensionKey] = instrLibName + } + return labels } diff --git a/exporter/awsemfexporter/datapoint_test.go b/exporter/awsemfexporter/datapoint_test.go index f8d8e55c9408..597f1d4b091c 100644 --- a/exporter/awsemfexporter/datapoint_test.go +++ b/exporter/awsemfexporter/datapoint_test.go @@ -442,7 +442,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "double", value: 0.4, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, expectedRetained: retainInitialValueOfDeltaMetric, }, @@ -454,7 +454,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "double", value: 0.4, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, expectedRetained: true, }, @@ -466,7 +466,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "double", value: 0.5, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, expectedRetained: true, }, @@ -479,7 +479,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "int", value: float64(-17), - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, expectedRetained: retainInitialValueOfDeltaMetric, }, @@ -491,7 +491,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "int", value: float64(18), - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, expectedRetained: true, }, @@ -503,7 +503,7 @@ func TestCalculateDeltaDatapoints_NumberDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "int", value: float64(10), - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, expectedRetained: true, }, @@ -567,7 +567,7 @@ func TestCalculateDeltaDatapoints_HistogramDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricStats{Sum: 17.13, Count: 17, Min: 10, Max: 30}, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, }, { @@ -584,7 +584,7 @@ func TestCalculateDeltaDatapoints_HistogramDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricStats{Sum: 17.13, Count: 17, Min: 0, Max: 0}, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, }, { @@ -602,7 +602,7 @@ func TestCalculateDeltaDatapoints_HistogramDataPointSlice(t *testing.T) { expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricStats{Sum: 17.13, Count: 17, Min: 0, Max: 0}, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, }, } @@ -817,7 +817,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{}, Counts: []float64{}, Sum: 17.13, Count: 17, Min: 10, Max: 30}, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, }, { @@ -834,7 +834,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{}, Counts: []float64{}, Sum: 17.13, Count: 17, Min: 0, Max: 0}, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, }, { @@ -851,7 +851,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{1.5, 3, 6, 0, -1.5, -3, -6}, Counts: []float64{1, 2, 3, 4, 1, 2, 3}}, - labels: map[string]string{"label1": "value1"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1"}, }, }, { @@ -872,7 +872,7 @@ func TestCalculateDeltaDatapoints_ExponentialHistogramDataPointSlice(t *testing. expectedDatapoint: dataPoint{ name: "foo", value: &cWMetricHistogram{Values: []float64{0.625, 2.5, 10, 0, -0.625, -2.5, -10}, Counts: []float64{1, 2, 3, 4, 1, 2, 3}}, - labels: map[string]string{"label1": "value1", "label2": "value2"}, + labels: map[string]string{oTellibDimensionKey: instrLibName, "label1": "value1", "label2": "value2"}, }, }, } @@ -1382,7 +1382,12 @@ func TestCreateLabels(t *testing.T) { "c": "C", })) - labels := createLabels(labelsMap) + labels := createLabels(labelsMap, "") + assert.Equal(t, expectedLabels, labels) + + // With isntrumentation library name + labels = createLabels(labelsMap, "cloudwatch-otel") + expectedLabels[oTellibDimensionKey] = "cloudwatch-otel" assert.Equal(t, expectedLabels, labels) } diff --git a/exporter/awsemfexporter/grouped_metric_test.go b/exporter/awsemfexporter/grouped_metric_test.go index ac8d1f02b5a0..47bee6e50fea 100644 --- a/exporter/awsemfexporter/grouped_metric_test.go +++ b/exporter/awsemfexporter/grouped_metric_test.go @@ -39,7 +39,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Double gauge", metric: generateTestGaugeMetric("foo", doubleValueType), expectedMetricType: pmetric.MetricTypeGauge, - expectedLabels: map[string]string{"label1": "value1"}, + expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: 0.1, @@ -51,7 +51,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Int sum", metric: generateTestSumMetric("foo", intValueType), expectedMetricType: pmetric.MetricTypeSum, - expectedLabels: map[string]string{"label1": "value1"}, + expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: float64(1), @@ -63,7 +63,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Histogram", metric: generateTestHistogramMetric("foo"), expectedMetricType: pmetric.MetricTypeHistogram, - expectedLabels: map[string]string{"label1": "value1"}, + expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: &cWMetricStats{ @@ -78,7 +78,7 @@ func TestAddToGroupedMetric(t *testing.T) { name: "Summary", metric: generateTestSummaryMetric("foo"), expectedMetricType: pmetric.MetricTypeSummary, - expectedLabels: map[string]string{"label1": "value1"}, + expectedLabels: map[string]string{oTellibDimensionKey: instrumentationLibName, "label1": "value1"}, expectedMetricInfo: map[string]*metricInfo{ "foo": { value: &cWMetricStats{ @@ -120,7 +120,7 @@ func TestAddToGroupedMetric(t *testing.T) { for _, v := range groupedMetrics { assert.Equal(t, len(tc.expectedMetricInfo), len(v.metrics)) assert.Equal(t, tc.expectedMetricInfo, v.metrics) - assert.Equal(t, 1, len(v.labels)) + assert.Equal(t, 2, len(v.labels)) assert.Equal(t, generateTestMetricMetadata(namespace, timestamp, logGroup, logStreamName, instrumentationLibName, tc.expectedMetricType), v.metadata) assert.Equal(t, tc.expectedLabels, v.labels) } @@ -182,7 +182,8 @@ func TestAddToGroupedMetric(t *testing.T) { assert.Fail(t, fmt.Sprintf("Unhandled metric %s not expected", metricName)) } expectedLabels := map[string]string{ - "label1": "value1", + oTellibDimensionKey: "cloudwatch-otel", + "label1": "value1", } assert.Equal(t, expectedLabels, group.labels) } @@ -253,7 +254,8 @@ func TestAddToGroupedMetric(t *testing.T) { assert.Fail(t, fmt.Sprintf("Unhandled metric %s not expected", metricName)) } expectedLabels := map[string]string{ - "label1": "value1", + oTellibDimensionKey: "cloudwatch-otel", + "label1": "value1", } assert.Equal(t, expectedLabels, group.labels) } @@ -301,7 +303,8 @@ func TestAddToGroupedMetric(t *testing.T) { } assert.Equal(t, expectedMetrics, group.metrics) expectedLabels := map[string]string{ - "label1": "value1", + oTellibDimensionKey: "cloudwatch-otel", + "label1": "value1", } assert.Equal(t, expectedLabels, group.labels) @@ -348,7 +351,8 @@ func TestAddToGroupedMetric(t *testing.T) { assert.Equal(t, 1, len(groupedMetrics)) labels := map[string]string{ - "label1": "value1", + oTellibDimensionKey: instrumentationLibName, + "label1": "value1", } // Test output warning logs expectedLogs := []observer.LoggedEntry{ diff --git a/exporter/awsemfexporter/metric_translator_test.go b/exporter/awsemfexporter/metric_translator_test.go index 94a2412bbc2f..1ac411048e6d 100644 --- a/exporter/awsemfexporter/metric_translator_test.go +++ b/exporter/awsemfexporter/metric_translator_test.go @@ -259,6 +259,7 @@ func TestTranslateOtToGroupedMetric(t *testing.T) { translator := newMetricTranslator(*config) defer require.NoError(t, translator.Shutdown()) + noInstrLibMetric := createTestResourceMetrics() instrLibMetric := createTestResourceMetrics() ilm := instrLibMetric.ScopeMetrics().At(0) ilm.Scope().SetName("cloudwatch-lib") @@ -307,6 +308,20 @@ func TestTranslateOtToGroupedMetric(t *testing.T) { { "w/ instrumentation library and namespace", instrLibMetric, + map[string]string{ + (oTellibDimensionKey): "cloudwatch-lib", + "isItAnError": "false", + "spanName": "testSpan", + }, + map[string]string{ + (oTellibDimensionKey): "cloudwatch-lib", + "spanName": "testSpan", + }, + "myServiceNS/myServiceName", + }, + { + "w/o instrumentation library, w/ namespace", + noInstrLibMetric, map[string]string{ "isItAnError": "false", "spanName": "testSpan",