手动从golang提取OpenTelemetry上下文到字符串?



我正在构建一个简单的客户端服务器应用程序,我想通过客户端执行跟踪到调用第二个服务器微服务的服务器微服务。

简单地说,它并不比CLI ->ServiceA→ServiceB .

我所面临的挑战是如何序列化上下文-我看过的大多数文档似乎都做了某种形式的自动HTTP头注入(例如https://opentelemetry.lightstep.com/core-concepts/context-propagation/),但我没有访问权限。我需要序列化(我认为)客户端中trace/span的上下文,并将其推送到服务器,在那里我将对其进行补充。(请注意,我希望这能更简单,但我想不出来)。

对象看起来像这样(叫做"job"):

    args := &types.SubmitArgs{
        SerializedOtelContext: serializedOtelContext,
    }
    job := &types.Job{}
    tracer := otel.GetTracerProvider().Tracer("myservice.org")
    _, span := tracer.Start(ctx, "Submitting Job to RPC")
    err := system.JsonRpcMethod(rpcHost, rpcPort, "Submit", args, job)
要提交给JsonRpcMethod的函数在这里:
func JsonRpcMethod(
    host string,
    port int,
    method string,
    req, res interface{},
) error {
    client, err := rpc.DialHTTP("tcp", fmt.Sprintf("%s:%d", host, port))
    if err != nil {
        return fmt.Errorf("Error in dialing. %s", err)
    }
    return client.Call(fmt.Sprintf("JobServer.%s", method), req, res)
}

接收它的函数在这里:

func (server *JobServer) Submit(args *types.SubmitArgs, reply *types.Job) error {
    //nolint
    job, err := server.RequesterNode.Scheduler.SubmitJob(args.Spec, args.Deal)
    if err != nil {
        return err
    }
    *reply = *job
    return nil
}

我的问题是我如何,在接收函数("提交"从发送方提取跟踪/跨度?

下面是一个演示用法的小程序。希望这能说清楚。

package main
import (
    "context"
    "fmt"
    "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
    "go.opentelemetry.io/otel/propagation"
    sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func main() {
    // common init
    // You may also want to set them as globals
    exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint())
    bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod
    tp := sdktrace.NewTracerProvider(
        sdktrace.WithSampler(sdktrace.AlwaysSample()),
        sdktrace.WithSpanProcessor(bsp),
    )
    propgator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
    ctx, span := tp.Tracer("foo").Start(context.Background(), "parent-span-name")
    defer span.End()
    // Serialize the context into carrier
    carrier := propagation.MapCarrier{}
    propgator.Inject(ctx, carrier)
    // This carrier is sent accros the process
    fmt.Println(carrier)
    // Extract the context and start new span as child
    // In your receiving function
    parentCtx := propgator.Extract(context.Background(), carrier)
    _, childSpan := tp.Tracer("foo").Start(parentCtx, "child-span-name")
    childSpan.AddEvent("some-dummy-event")
    childSpan.End()
}

最新更新