-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Closed
Description
When decoding OTLP data encoded as JSON, the Span.Flags field is not decoded.
$ cat go.mod
module testing/flag
go 1.23.1
require (
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/collector/pdata v1.16.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
google.golang.org/grpc v1.66.2 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
package main
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/ptrace"
)
var (
pSpanA = func() ptrace.Span {
s := ptrace.NewSpan()
s.SetTraceID(pcommon.TraceID([16]byte{0x1}))
s.SetSpanID(pcommon.SpanID([8]byte{0x2}))
s.SetFlags(1)
return s
}()
pScope = func() pcommon.InstrumentationScope {
s := pcommon.NewInstrumentationScope()
s.SetName("test")
s.SetVersion("v0.0.1")
return s
}()
pScopeSpans = func() ptrace.ScopeSpans {
s := ptrace.NewScopeSpans()
pSpanA.CopyTo(s.Spans().AppendEmpty())
pScope.CopyTo(s.Scope())
return s
}()
pResSpans = func() ptrace.ResourceSpans {
rs := ptrace.NewResourceSpans()
pScopeSpans.CopyTo(rs.ScopeSpans().AppendEmpty())
return rs
}()
pTraces = func() ptrace.Traces {
traces := ptrace.NewTraces()
pResSpans.CopyTo(traces.ResourceSpans().AppendEmpty())
return traces
}()
)
func TestDecode(t *testing.T) {
var enc ptrace.JSONMarshaler
b, err := enc.MarshalTraces(pTraces)
require.NoError(t, err)
t.Log(string(b))
assert.Equal(t, data, b)
}
// {
// "resourceSpans": [
// {
// "resource": {},
// "scopeSpans": [
// {
// "scope": {
// "name": "test",
// "version": "v0.0.1"
// },
// "spans": [
// {
// "traceId": "01000000000000000000000000000000",
// "spanId": "0200000000000000",
// "flags": 1,
// }
// ]
// }
// ]
// }
// ]
// }
var data = []byte(`{"resourceSpans":[{"resource":{},"scopeSpans":[{"scope":{"name":"test","version":"v0.0.1"},"spans":[{"traceId":"01000000000000000000000000000000","spanId":"0200000000000000","parentSpanId":"","flags":1,"status":{}}]}]}]}`)
func TestEncode(t *testing.T) {
var dec ptrace.JSONUnmarshaler
got, err := dec.UnmarshalTraces(data)
require.NoError(t, err)
assert.Equal(t, pTraces, got)
}$ go test -v .
=== RUN TestDecode
bug_test.go:53: {"resourceSpans":[{"resource":{},"scopeSpans":[{"scope":{"name":"test","version":"v0.0.1"},"spans":[{"traceId":"01000000000000000000000000000000","spanId":"0200000000000000","parentSpanId":"","flags":1,"status":{}}]}]}]}
--- PASS: TestDecode (0.00s)
=== RUN TestEncode
bug_test.go:85:
Error Trace: /home/tyler/go/src/testing/flag/bug_test.go:85
Error: Not equal:
expected: ptrace.Traces{orig:(*v1.ExportTraceServiceRequest)(0xc000012b28), state:(*internal.State)(0xc000015758)}
actual : ptrace.Traces{orig:(*v1.ExportTraceServiceRequest)(0xc000012de0), state:(*internal.State)(0xc000015f88)}
Diff:
--- Expected
+++ Actual
@@ -29,3 +29,3 @@
},
- Flags: (uint32) 1,
+ Flags: (uint32) 0,
Name: (string) "",
Test: TestEncode
--- FAIL: TestEncode (0.00s)
FAIL
FAIL testing/flag 0.005s
FAIL
It looks to be a missing case statement here:
opentelemetry-collector/pdata/ptrace/json.go
Lines 98 to 151 in 9811830
| func (dest Span) unmarshalJsoniter(iter *jsoniter.Iterator) { | |
| iter.ReadObjectCB(func(iter *jsoniter.Iterator, f string) bool { | |
| switch f { | |
| case "traceId", "trace_id": | |
| if err := dest.orig.TraceId.UnmarshalJSON([]byte(iter.ReadString())); err != nil { | |
| iter.ReportError("readSpan.traceId", fmt.Sprintf("parse trace_id:%v", err)) | |
| } | |
| case "spanId", "span_id": | |
| if err := dest.orig.SpanId.UnmarshalJSON([]byte(iter.ReadString())); err != nil { | |
| iter.ReportError("readSpan.spanId", fmt.Sprintf("parse span_id:%v", err)) | |
| } | |
| case "traceState", "trace_state": | |
| dest.TraceState().FromRaw(iter.ReadString()) | |
| case "parentSpanId", "parent_span_id": | |
| if err := dest.orig.ParentSpanId.UnmarshalJSON([]byte(iter.ReadString())); err != nil { | |
| iter.ReportError("readSpan.parentSpanId", fmt.Sprintf("parse parent_span_id:%v", err)) | |
| } | |
| case "name": | |
| dest.orig.Name = iter.ReadString() | |
| case "kind": | |
| dest.orig.Kind = otlptrace.Span_SpanKind(json.ReadEnumValue(iter, otlptrace.Span_SpanKind_value)) | |
| case "startTimeUnixNano", "start_time_unix_nano": | |
| dest.orig.StartTimeUnixNano = json.ReadUint64(iter) | |
| case "endTimeUnixNano", "end_time_unix_nano": | |
| dest.orig.EndTimeUnixNano = json.ReadUint64(iter) | |
| case "attributes": | |
| iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { | |
| dest.orig.Attributes = append(dest.orig.Attributes, json.ReadAttribute(iter)) | |
| return true | |
| }) | |
| case "droppedAttributesCount", "dropped_attributes_count": | |
| dest.orig.DroppedAttributesCount = json.ReadUint32(iter) | |
| case "events": | |
| iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { | |
| dest.Events().AppendEmpty().unmarshalJsoniter(iter) | |
| return true | |
| }) | |
| case "droppedEventsCount", "dropped_events_count": | |
| dest.orig.DroppedEventsCount = json.ReadUint32(iter) | |
| case "links": | |
| iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { | |
| dest.Links().AppendEmpty().unmarshalJsoniter(iter) | |
| return true | |
| }) | |
| case "droppedLinksCount", "dropped_links_count": | |
| dest.orig.DroppedLinksCount = json.ReadUint32(iter) | |
| case "status": | |
| dest.Status().unmarshalJsoniter(iter) | |
| default: | |
| iter.Skip() | |
| } | |
| return true | |
| }) | |
| } |
Metadata
Metadata
Assignees
Labels
No labels