You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-09-16 09:26:25 +02:00
Add MarshalJSON for core.Value (#281)
- fix #280, where stdout export will not print Attributes value from MessageEvents. - add unit test for it.
This commit is contained in:
committed by
Liz Fong-Jones
parent
d25fae7c10
commit
881e51f708
@@ -17,6 +17,7 @@ package core
|
||||
//go:generate stringer -type=ValueType
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
@@ -325,3 +326,14 @@ func (v *Value) Emit() string {
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of the Value.
|
||||
func (v *Value) MarshalJSON() ([]byte, error) {
|
||||
var jsonVal struct {
|
||||
Type string
|
||||
Value interface{}
|
||||
}
|
||||
jsonVal.Type = v.Type().String()
|
||||
jsonVal.Value = v.AsInterface()
|
||||
return json.Marshal(jsonVal)
|
||||
}
|
||||
|
@@ -19,12 +19,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
|
||||
"go.opentelemetry.io/otel/api/core"
|
||||
apitrace "go.opentelemetry.io/otel/api/trace"
|
||||
"go.opentelemetry.io/otel/sdk/export"
|
||||
)
|
||||
|
||||
@@ -48,72 +43,15 @@ func NewExporter(o Options) (*Exporter, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
type jsonValue struct {
|
||||
Type string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type jsonKeyValue struct {
|
||||
Key core.Key
|
||||
Value jsonValue
|
||||
}
|
||||
|
||||
type jsonSpanData struct {
|
||||
SpanContext core.SpanContext
|
||||
ParentSpanID core.SpanID
|
||||
SpanKind apitrace.SpanKind
|
||||
Name string
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
Attributes []jsonKeyValue
|
||||
MessageEvents []export.Event
|
||||
Links []apitrace.Link
|
||||
Status codes.Code
|
||||
HasRemoteParent bool
|
||||
DroppedAttributeCount int
|
||||
DroppedMessageEventCount int
|
||||
DroppedLinkCount int
|
||||
ChildSpanCount int
|
||||
}
|
||||
|
||||
func marshalSpanData(data *export.SpanData, pretty bool) ([]byte, error) {
|
||||
jsd := jsonSpanData{
|
||||
SpanContext: data.SpanContext,
|
||||
ParentSpanID: data.ParentSpanID,
|
||||
SpanKind: data.SpanKind,
|
||||
Name: data.Name,
|
||||
StartTime: data.StartTime,
|
||||
EndTime: data.EndTime,
|
||||
Attributes: toJSONAttributes(data.Attributes),
|
||||
MessageEvents: data.MessageEvents,
|
||||
Links: data.Links,
|
||||
Status: data.Status,
|
||||
HasRemoteParent: data.HasRemoteParent,
|
||||
DroppedAttributeCount: data.DroppedAttributeCount,
|
||||
DroppedMessageEventCount: data.DroppedMessageEventCount,
|
||||
DroppedLinkCount: data.DroppedLinkCount,
|
||||
ChildSpanCount: data.ChildSpanCount,
|
||||
}
|
||||
|
||||
if pretty {
|
||||
return json.MarshalIndent(jsd, "", "\t")
|
||||
}
|
||||
return json.Marshal(jsd)
|
||||
}
|
||||
|
||||
func toJSONAttributes(attributes []core.KeyValue) []jsonKeyValue {
|
||||
jsonAttrs := make([]jsonKeyValue, len(attributes))
|
||||
for i := 0; i < len(attributes); i++ {
|
||||
jsonAttrs[i].Key = attributes[i].Key
|
||||
jsonAttrs[i].Value.Type = attributes[i].Value.Type().String()
|
||||
jsonAttrs[i].Value.Value = attributes[i].Value.AsInterface()
|
||||
}
|
||||
return jsonAttrs
|
||||
}
|
||||
|
||||
// ExportSpan writes a SpanData in json format to stdout.
|
||||
func (e *Exporter) ExportSpan(ctx context.Context, data *export.SpanData) {
|
||||
jsonSpan, err := marshalSpanData(data, e.pretty)
|
||||
var jsonSpan []byte
|
||||
var err error
|
||||
if e.pretty {
|
||||
jsonSpan, err = json.MarshalIndent(data, "", "\t")
|
||||
} else {
|
||||
jsonSpan, err = json.Marshal(data)
|
||||
}
|
||||
if err != nil {
|
||||
// ignore writer failures for now
|
||||
_, _ = e.outputWriter.Write([]byte("Error converting spanData to json: " + err.Error()))
|
||||
|
@@ -58,6 +58,10 @@ func TestExporter_ExportSpan(t *testing.T) {
|
||||
key.String("key", keyValue),
|
||||
key.Float64("double", doubleValue),
|
||||
},
|
||||
MessageEvents: []export.Event{
|
||||
{Message: "foo", Attributes: []core.KeyValue{key.String("key", keyValue)}, Time: now},
|
||||
{Message: "bar", Attributes: []core.KeyValue{key.Float64("double", doubleValue)}, Time: now},
|
||||
},
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
Status: codes.Unknown,
|
||||
}
|
||||
@@ -84,7 +88,28 @@ func TestExporter_ExportSpan(t *testing.T) {
|
||||
`"Value":{"Type":"FLOAT64","Value":123.456}` +
|
||||
`}` +
|
||||
`],` +
|
||||
`"MessageEvents":null,` +
|
||||
`"MessageEvents":[` +
|
||||
`{` +
|
||||
`"Message":"foo",` +
|
||||
`"Attributes":[` +
|
||||
`{` +
|
||||
`"Key":"key",` +
|
||||
`"Value":{"Type":"STRING","Value":"value"}` +
|
||||
`}` +
|
||||
`],` +
|
||||
`"Time":` + string(expectedSerializedNow) +
|
||||
`},` +
|
||||
`{` +
|
||||
`"Message":"bar",` +
|
||||
`"Attributes":[` +
|
||||
`{` +
|
||||
`"Key":"double",` +
|
||||
`"Value":{"Type":"FLOAT64","Value":123.456}` +
|
||||
`}` +
|
||||
`],` +
|
||||
`"Time":` + string(expectedSerializedNow) +
|
||||
`}` +
|
||||
`],` +
|
||||
`"Links":null,` +
|
||||
`"Status":2,` +
|
||||
`"HasRemoteParent":false,` +
|
||||
|
Reference in New Issue
Block a user