Home  >  Article  >  Backend Development  >  Get trace_id from OTEL trace instrumented with golang otelmux

Get trace_id from OTEL trace instrumented with golang otelmux

WBOY
WBOYforward
2024-02-11 12:51:07603browse

从使用 golang otelmux 检测的 OTEL 跟踪获取trace_id

php Xiaobian Yuzai will introduce to you the method of obtaining trace_id using OTEL tracking detected by golang otelmux. OTEL (OpenTelemetry) is an open source observation tool that helps developers monitor and debug distributed applications. By using golang otelmux, we can easily integrate OTEL tracing functionality in the application and obtain the trace_id to better analyze and optimize the application's performance. Next, we will introduce in detail how to use golang otelmux for OTEL tracing and how to obtain trace_id.

Question content

In my golang application, I use otelmux middleware and ddotel tracker provider to detect OTEL tracking middleware File:

package tracing

import (
    "github.com/gorilla/mux"
    "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
    ddotel "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentelemetry"
    "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
)

// Middleware returns a tracing middleware that will add a span for each request.
func Middleware(t *TraceProvider) mux.MiddlewareFunc {
    sampler := tracer.NewRateSampler(0.1)
    provider := ddotel.NewTracerProvider(
        tracer.WithSampler(sampler), 
        tracer.WithRuntimeMetrics(),
    )
    return otelmux.Middleware("my-service", otelmux.WithTracerProvider(provider))
}

Whenever a trace is attached to a request (taking into account the sampling rate), I want to extract the trace ID from the root span so that I can inject it into the logging API in order to correlate the logs from that request with those from the same request tracking.

So far I haven't found a way to get the tracking ID directly from the request context.

How to extract the tracking ID?

Solution

Thanks to @hamed-n for commenting on the best solution:

There is a function in the trace package that extracts the trace ID from the span context: "go.opentelemetry.io/otel/trace":

func GetTraceID(ctx context.Context) string {
    spanCtx := trace.SpanContextFromContext(ctx)
    if spanCtx.HasTraceID() {
        traceID := spanCtx.TraceID()
        return traceID.String()
    }
    return ""
}

In my case, since the provider I'm using is DataDog, I have to convert the tracking ID to uint64 big endian:

func GetTraceID(ctx context.Context) string {
    spanCtx := trace.SpanContextFromContext(ctx)
    if spanCtx.HasTraceID() {
        // Since datadog trace provider (ddtrace) uses big endian uint64 for the trace ID, we must first to first convert it back to uint64.
        traceID := spanCtx.TraceID()
        traceIDRaw := [16]byte(traceID)
        traceIDUint64 := byteArrToUint64(traceIDRaw[8:])
        traceIDStr := strconv.FormatUint(traceIDUint64, 10)
        return traceIDStr
    }
    return ""
}

func byteArrToUint64(buf []byte) uint64 {
    var x uint64
    for i, b := range buf {
        x = x<<8 + uint64(b)
        if i == 7 {
            return x
        }
    }
    return x
}

The above is the detailed content of Get trace_id from OTEL trace instrumented with golang otelmux. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete