kokizzu/jeager1

Stackoverflow suffering

Closed this issue · 3 comments

I saw your question, took me basically all day to figure this out lmao. The go.opentelemetry.io/otel/trace@v1.11.1/trace.go file has the definitions for the context right, you can call MarshalJSON and have it spit something that looks useful but here's the thing. There is no equivalent unmarshalling function and the output is a string while the internal format is a fixed length byte array...

So to get it to work just dump the trace and span IDs into whatever format you like:

// Attach telemetry headers
headers := nats.Header{}
headers.Set(otelTraceID, span.SpanContext().TraceID().String())
headers.Set(otelSpanID, span.SpanContext().SpanID().String())

Then on the receive side you have to rebuild it manually into a SpanContext:

func getParentContext(msg *nats.Msg) (spanContext trace.SpanContext, err error) {
	var traceID trace.TraceID
	traceID, err = trace.TraceIDFromHex(msg.Header.Get(otelTraceID))
	if err != nil {
		return spanContext, err
	}
	var spanID trace.SpanID
	spanID, err = trace.SpanIDFromHex(msg.Header.Get(otelSpanID))
	if err != nil {
		return spanContext, err
	}
	var spanContextConfig trace.SpanContextConfig
	spanContextConfig.TraceID = traceID
	spanContextConfig.SpanID = spanID
	spanContextConfig.TraceFlags = 01
	spanContextConfig.Remote = true
	spanContext = trace.NewSpanContext(spanContextConfig)
	return spanContext, nil
}

Then actually use it:

remoteCtx, err := getParentContext(msg)
if err != nil {
	logrus.Fatal(err)
}

_, span := otel.Tracer(fqpn).Start(trace.ContextWithRemoteSpanContext(context.Background(), remoteCtx), msg.Subject)
defer span.End()

:trollface:

thanks a lot :3

works perfectly :3 awesome man

image