From 4ea075586cec88e2999633c1b8b29a1cf3690ce3 Mon Sep 17 00:00:00 2001 From: Sumit Deo <93740684+deosu@users.noreply.github.com> Date: Wed, 9 Mar 2022 22:29:07 +0530 Subject: [PATCH] [exporter/tanzuobservability]Instrumentation Library and Dropped Counts to Span Tags (#8120) * Add new span-tags. Add following span-tags: otel.dropped_events_count otel.dropped_links_count otel.dropped_attributes_co otel.span.name otel.span.version * Update CHANGELOG.md Add instrumentation Library and Dropped Counts to Span Tags. * Fix review suggestions. Misc updates. * Fix review suggestions. Misc updates. * Update CHANGELOG.md Co-authored-by: Alex Boten --- CHANGELOG.md | 1 + .../tanzuobservabilityexporter/exporter.go | 33 ++++++++++++++----- .../exporter_test.go | 29 ++++++++++++++++ .../tanzuobservabilityexporter/transformer.go | 13 ++++++++ .../transformer_test.go | 29 ++++++++++++++++ 5 files changed, 97 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b72c819de47..730479e2c18d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - `spanmetricsprocessor`: Dropping the condition to replace _ with key_ as __ label is reserved and _ is not (#8057) - `podmanreceiver`: Add container.runtime attribute to container metrics (#8262) - `dockerstatsreceiver`: Add container.runtime attribute to container metrics (#8261) +- `tanzuobservabilityexporter`: instrumentation Library and Dropped Counts to Span Tags (#8120) - `clickhouseexporter`: Implement consume log logic. (#9705) - `influxdbexporter`: Add support for cumulative, non-monotonic metrics. (#8348) - `oauth2clientauthextension`: Add support for EndpointParams (#7307) diff --git a/exporter/tanzuobservabilityexporter/exporter.go b/exporter/tanzuobservabilityexporter/exporter.go index e63660556c6f..55a30dd98f54 100644 --- a/exporter/tanzuobservabilityexporter/exporter.go +++ b/exporter/tanzuobservabilityexporter/exporter.go @@ -31,14 +31,19 @@ import ( ) const ( - defaultApplicationName = "defaultApp" - defaultServiceName = "defaultService" - labelApplication = "application" - labelError = "error" - labelEventName = "name" - labelService = "service" - labelSpanKind = "span.kind" - labelSource = "source" + defaultApplicationName = "defaultApp" + defaultServiceName = "defaultService" + labelApplication = "application" + labelError = "error" + labelEventName = "name" + labelService = "service" + labelSpanKind = "span.kind" + labelSource = "source" + labelDroppedEventsCount = "otel.dropped_events_count" + labelDroppedLinksCount = "otel.dropped_links_count" + labelDroppedAttrsCount = "otel.dropped_attributes_count" + labelOtelSpanName = "otel.span.name" + labelOtelSpanVersion = "otel.span.version" ) // spanSender Interface for sending tracing spans to Tanzu Observability @@ -103,6 +108,10 @@ func (e *tracesExporter) pushTraceData(ctx context.Context, td pdata.Traces) err for j := 0; j < rspans.InstrumentationLibrarySpans().Len(); j++ { ispans := rspans.InstrumentationLibrarySpans().At(j) transform := newTraceTransformer(resource) + + libraryName := ispans.InstrumentationLibrary().Name() + libraryVersion := ispans.InstrumentationLibrary().Version() + for k := 0; k < ispans.Spans().Len(); k++ { select { case <-ctx.Done(): @@ -114,6 +123,14 @@ func (e *tracesExporter) pushTraceData(ctx context.Context, td pdata.Traces) err continue } + if libraryName != "" { + transformedSpan.Tags[labelOtelSpanName] = libraryName + } + + if libraryVersion != "" { + transformedSpan.Tags[labelOtelSpanVersion] = libraryVersion + } + if err := e.recordSpan(transformedSpan); err != nil { errs = multierr.Append(errs, err) continue diff --git a/exporter/tanzuobservabilityexporter/exporter_test.go b/exporter/tanzuobservabilityexporter/exporter_test.go index 1855c24c4a60..7c2414913727 100644 --- a/exporter/tanzuobservabilityexporter/exporter_test.go +++ b/exporter/tanzuobservabilityexporter/exporter_test.go @@ -192,6 +192,35 @@ func validateTraces(t *testing.T, expected []*span, traces pdata.Traces) { } } +func TestExportTraceDataWithInstrumentationDetails(t *testing.T) { + minSpan := createSpan( + "root", + pdata.NewTraceID([16]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}), + pdata.NewSpanID([8]byte{9, 9, 9, 9, 9, 9, 9, 9}), + pdata.SpanID{}, + ) + traces := constructTraces([]pdata.Span{minSpan}) + + instrumentationLibrary := traces.ResourceSpans().At(0).InstrumentationLibrarySpans().At(0). + InstrumentationLibrary() + instrumentationLibrary.SetName("instrumentation_name") + instrumentationLibrary.SetVersion("v0.0.1") + + expected := []*span{{ + Name: "root", + TraceID: uuid.MustParse("01010101-0101-0101-0101-010101010101"), + SpanID: uuid.MustParse("00000000-0000-0000-0909-090909090909"), + Tags: map[string]string{ + labelApplication: "defaultApp", + labelService: "defaultService", + labelOtelSpanName: "instrumentation_name", + labelOtelSpanVersion: "v0.0.1", + }, + }} + + validateTraces(t, expected, traces) +} + func TestExportTraceDataRespectsContext(t *testing.T) { traces := constructTraces([]pdata.Span{createSpan( "root", diff --git a/exporter/tanzuobservabilityexporter/transformer.go b/exporter/tanzuobservabilityexporter/transformer.go index 5cbfc92691d8..65826b78ed22 100644 --- a/exporter/tanzuobservabilityexporter/transformer.go +++ b/exporter/tanzuobservabilityexporter/transformer.go @@ -16,6 +16,7 @@ package tanzuobservabilityexporter // import "github.com/open-telemetry/opentele import ( "errors" + "strconv" "time" "github.com/google/uuid" @@ -73,6 +74,18 @@ func (t *traceTransformer) Span(orig pdata.Span) (span, error) { tags[labelSpanKind] = spanKind(orig) + if droppedEventsCount := orig.DroppedEventsCount(); droppedEventsCount > 0 { + tags[labelDroppedEventsCount] = strconv.FormatUint(uint64(droppedEventsCount), 10) + } + + if droppedLinksCount := orig.DroppedLinksCount(); droppedLinksCount > 0 { + tags[labelDroppedLinksCount] = strconv.FormatUint(uint64(droppedLinksCount), 10) + } + + if droppedAttrsCount := orig.DroppedAttributesCount(); droppedAttrsCount > 0 { + tags[labelDroppedAttrsCount] = strconv.FormatUint(uint64(droppedAttrsCount), 10) + } + errorTags := errorTagsFromStatus(orig.Status()) for k, v := range errorTags { tags[k] = v diff --git a/exporter/tanzuobservabilityexporter/transformer_test.go b/exporter/tanzuobservabilityexporter/transformer_test.go index ecdb5cea31ce..ec0a42efda90 100644 --- a/exporter/tanzuobservabilityexporter/transformer_test.go +++ b/exporter/tanzuobservabilityexporter/transformer_test.go @@ -294,6 +294,35 @@ func TestSpanForSourceTag(t *testing.T) { assert.Equal(t, "source_from_span_attribute", actual.Tags["_source"]) } +func TestSpanForDroppedCount(t *testing.T) { + inNanos := int64(50000000) + + //TestCase: 1 count tags are not set + resAttrs := pdata.NewAttributeMap() + transform := transformerFromAttributes(resAttrs) + span := pdata.NewSpan() + span.SetSpanID(pdata.NewSpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1})) + span.SetTraceID(pdata.NewTraceID([16]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})) + span.SetStartTimestamp(pdata.Timestamp(inNanos)) + + actual, err := transform.Span(span) + require.NoError(t, err, "transforming span to wavefront format") + assert.NotContains(t, actual.Tags, "otel.dropped_events_count") + assert.NotContains(t, actual.Tags, "otel.dropped_links_count") + assert.NotContains(t, actual.Tags, "otel.dropped_attributes_count") + + //TestCase2: count tags are set + span.SetDroppedEventsCount(123) + span.SetDroppedLinksCount(456) + span.SetDroppedAttributesCount(789) + + actual, err = transform.Span(span) + require.NoError(t, err, "transforming span to wavefront format") + assert.Equal(t, "123", actual.Tags["otel.dropped_events_count"]) + assert.Equal(t, "456", actual.Tags["otel.dropped_links_count"]) + assert.Equal(t, "789", actual.Tags["otel.dropped_attributes_count"]) +} + func TestGetSourceAndResourceTags(t *testing.T) { resAttrs := pdata.NewAttributeMap() resAttrs.InsertString(labelSource, "test_source")