// Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 package ptrace // import "go.opentelemetry.io/collector/pdata/ptrace" import ( "bytes" "fmt" jsoniter "github.com/json-iterator/go" "go.opentelemetry.io/collector/pdata/internal" otlptrace "go.opentelemetry.io/collector/pdata/internal/data/protogen/trace/v1" "go.opentelemetry.io/collector/pdata/internal/json" "go.opentelemetry.io/collector/pdata/internal/otlp" ) type JSONMarshaler struct{} func (*JSONMarshaler) MarshalTraces(td Traces) ([]byte, error) { buf := bytes.Buffer{} pb := internal.TracesToProto(internal.Traces(td)) err := json.Marshal(&buf, &pb) return buf.Bytes(), err } type JSONUnmarshaler struct{} func (*JSONUnmarshaler) UnmarshalTraces(buf []byte) (Traces, error) { iter := jsoniter.ConfigFastest.BorrowIterator(buf) defer jsoniter.ConfigFastest.ReturnIterator(iter) td := NewTraces() td.unmarshalJsoniter(iter) if iter.Error != nil { return Traces{}, iter.Error } otlp.MigrateTraces(td.getOrig().ResourceSpans) return td, nil } func (ms Traces) unmarshalJsoniter(iter *jsoniter.Iterator) { iter.ReadObjectCB(func(iter *jsoniter.Iterator, f string) bool { switch f { case "resourceSpans", "resource_spans": iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { ms.ResourceSpans().AppendEmpty().unmarshalJsoniter(iter) return true }) default: iter.Skip() } return true }) } func (ms ResourceSpans) unmarshalJsoniter(iter *jsoniter.Iterator) { iter.ReadObjectCB(func(iter *jsoniter.Iterator, f string) bool { switch f { case "resource": json.ReadResource(iter, internal.GetOrigResource(internal.Resource(ms.Resource()))) case "scopeSpans", "scope_spans": iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { ms.ScopeSpans().AppendEmpty().unmarshalJsoniter(iter) return true }) case "schemaUrl", "schema_url": ms.orig.SchemaUrl = iter.ReadString() default: iter.Skip() } return true }) } func (ms ScopeSpans) unmarshalJsoniter(iter *jsoniter.Iterator) { iter.ReadObjectCB(func(iter *jsoniter.Iterator, f string) bool { switch f { case "scope": json.ReadScope(iter, &ms.orig.Scope) case "spans": iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { ms.Spans().AppendEmpty().unmarshalJsoniter(iter) return true }) case "schemaUrl", "schema_url": ms.orig.SchemaUrl = iter.ReadString() default: iter.Skip() } return true }) } 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 }) } func (dest Status) unmarshalJsoniter(iter *jsoniter.Iterator) { iter.ReadObjectCB(func(iter *jsoniter.Iterator, f string) bool { switch f { case "message": dest.orig.Message = iter.ReadString() case "code": dest.orig.Code = otlptrace.Status_StatusCode(json.ReadEnumValue(iter, otlptrace.Status_StatusCode_value)) default: iter.Skip() } return true }) } func (dest SpanLink) 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("readSpanLink", fmt.Sprintf("parse trace_id:%v", err)) } case "spanId", "span_id": if err := dest.orig.SpanId.UnmarshalJSON([]byte(iter.ReadString())); err != nil { iter.ReportError("readSpanLink", fmt.Sprintf("parse span_id:%v", err)) } case "traceState", "trace_state": dest.orig.TraceState = iter.ReadString() 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) default: iter.Skip() } return true }) } func (dest SpanEvent) unmarshalJsoniter(iter *jsoniter.Iterator) { iter.ReadObjectCB(func(iter *jsoniter.Iterator, f string) bool { switch f { case "timeUnixNano", "time_unix_nano": dest.orig.TimeUnixNano = json.ReadUint64(iter) case "name": dest.orig.Name = iter.ReadString() 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) default: iter.Skip() } return true }) }