Skip to content

Commit

Permalink
[exporter/elasticsearch] fix not exporting span events (open-telemetr…
Browse files Browse the repository at this point in the history
…y#21063)

Signed-off-by: Jared Tan <[email protected]>
  • Loading branch information
JaredTan95 committed May 20, 2023
1 parent 7e29497 commit c9eae64
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .chloggen/fix-elasticsearch-exporter-lost-span-events.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: bug_fix

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

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Fix elasticsearch exporter not exporting span events

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

# (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:
1 change: 1 addition & 0 deletions exporter/elasticsearchexporter/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
go.opentelemetry.io/collector/confmap v0.77.0
go.opentelemetry.io/collector/exporter v0.77.0
go.opentelemetry.io/collector/pdata v1.0.0-rcv0011
go.opentelemetry.io/collector/semconv v0.77.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.24.0
)
Expand Down
2 changes: 2 additions & 0 deletions exporter/elasticsearchexporter/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions exporter/elasticsearchexporter/internal/objmodel/objmodel.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
"github.com/elastic/go-structform"
"github.com/elastic/go-structform/json"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/ptrace"
)

// Document is an intermediate representation for converting open telemetry records with arbitrary attributes
Expand Down Expand Up @@ -164,6 +165,15 @@ func (doc *Document) AddAttribute(key string, attribute pcommon.Value) {
}
}

// AddEvents converts and adds span events to the document.
func (doc *Document) AddEvents(key string, events ptrace.SpanEventSlice) {
for i := 0; i < events.Len(); i++ {
e := events.At(i)
doc.AddTimestamp(flattenKey(key, e.Name()+".time"), e.Timestamp())
doc.AddAttributes(flattenKey(key, e.Name()), e.Attributes())
}
}

// Sort sorts all fields in the document by key name.
func (doc *Document) Sort() {
sort.SliceStable(doc.fields, func(i, j int) bool {
Expand Down
1 change: 1 addition & 0 deletions exporter/elasticsearchexporter/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (m *encodeModel) encodeSpan(resource pcommon.Resource, span ptrace.Span) ([
document.AddString("Link", spanLinksToString(span.Links()))
document.AddAttributes("Attributes", span.Attributes())
document.AddAttributes("Resource", resource.Attributes())
document.AddEvents("Events", span.Events())

if m.dedup {
document.Dedup()
Expand Down
59 changes: 59 additions & 0 deletions exporter/elasticsearchexporter/model_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package elasticsearchexporter

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/ptrace"
semconv "go.opentelemetry.io/collector/semconv/v1.18.0"
)

var expectedSpanBody = `{"@timestamp":"2023-04-19T03:04:05.000000006Z","Attributes.service.instance.id":"23","EndTimestamp":"2023-04-19T03:04:06.000000006Z","Events.fooEvent.evnetMockBar":"bar","Events.fooEvent.evnetMockFoo":"foo","Events.fooEvent.time":"2023-04-19T03:04:05.000000006Z","Kind":"SPAN_KIND_CLIENT","Link":"[{\"attribute\":{},\"spanID\":\"\",\"traceID\":\"01020304050607080807060504030200\"}]","Name":"client span","Resource.cloud.platform":"aws_elastic_beanstalk","Resource.cloud.provider":"aws","Resource.deployment.environment":"BETA","Resource.service.instance.id":"23","Resource.service.name":"some-service","Resource.service.version":"env-version-1234","SpanId":"1920212223242526","TraceId":"01020304050607080807060504030201","TraceStatus":0}`

func TestEncodeSpan(t *testing.T) {
model := &encodeModel{dedup: true, dedot: false}
td := mockResourceSpans()
spanByte, err := model.encodeSpan(td.ResourceSpans().At(0).Resource(), td.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0))
assert.NoError(t, err)
assert.Equal(t, expectedSpanBody, string(spanByte))
}

func mockResourceSpans() ptrace.Traces {
traces := ptrace.NewTraces()

resourceSpans := traces.ResourceSpans().AppendEmpty()
attr := resourceSpans.Resource().Attributes()
attr.PutStr("cloud.provider", "aws")
attr.PutStr("cloud.platform", "aws_elastic_beanstalk")
attr.PutStr("deployment.environment", "BETA")
attr.PutStr("service.instance.id", "23")
attr.PutStr("service.version", "env-version-1234")

resourceSpans.Resource().Attributes().PutStr(semconv.AttributeServiceName, "some-service")

tStart := time.Date(2023, 4, 19, 3, 4, 5, 6, time.UTC)
tEnd := time.Date(2023, 4, 19, 3, 4, 6, 6, time.UTC)

scopeSpans := resourceSpans.ScopeSpans().AppendEmpty()
span := scopeSpans.Spans().AppendEmpty()
span.SetName("client span")
span.SetSpanID([8]byte{0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26})
span.SetTraceID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1})
span.SetKind(ptrace.SpanKindClient)
span.SetStartTimestamp(pcommon.NewTimestampFromTime(tStart))
span.SetEndTimestamp(pcommon.NewTimestampFromTime(tEnd))
span.Attributes().PutStr("service.instance.id", "23")
span.Links().AppendEmpty().SetTraceID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 0})

event := span.Events().AppendEmpty()
event.SetName("fooEvent")
event.SetTimestamp(pcommon.NewTimestampFromTime(tStart))
event.Attributes().PutStr("evnetMockFoo", "foo")
event.Attributes().PutStr("evnetMockBar", "bar")
return traces
}

0 comments on commit c9eae64

Please sign in to comment.