Go语言 使用trace_id和span_id将span链接到父span

anauzrmj  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(107)

我有一个启动父跨接的过程。然后调用一个导出函数将span_id和trace_id保存在一个JSON文件中。

tracer := otel.GetTracerProvider().Tracer("")
_, span := tracer.Start(ctx, "parent span name")
exportSpanContextToJSON(span)
...
defer span.End()

go进程最终运行一个python脚本。我需要在python进程中启动spans,它们都是go的父span的子进程。
Python脚本并不那么简单。
我正在示例化一个创建跟踪程序的类MainStreamEngine。它有一个名为new_stream的函数,该函数创建ChildStream的示例,该示例从MainStreamEngine获取内容。它看起来像这样:

class MainStreamEngine:
    def __init__(self):
        resource = Resource(attributes={
            "service.name": "python_service"
        })
        trace.set_tracer_provider(TracerProvider(resource=resource))
        self.tracer = trace.get_tracer(__name__)
        otlp_exporter = OTLPSpanExporter(
            endpoint="http://localhost:4317", insecure=True)
        span_processor = BatchSpanProcessor(otlp_exporter)
        trace.get_tracer_provider().add_span_processor(span_processor)
        self.span_context = trace.SpanContext(
            is_remote=True,
            span_id=int(span_ctx_from_json["spanId"], 16)),
            trace_id=int(span_ctx_from_json["traceId"], 16))

    def new_stream(self):
        stream = ChildStream(self.tracer, self.span_context)

class ChildStream:
    def __init__(self, tracer, span_context):
        self.tracer = tracer
        ctx = trace.set_span_in_context(trace.NonRecordingSpan(span_context))
        self.tracing_span = tracer.start_span(self.name, ctx)

    def close(self):
        self.tracing_span.close()

问题是python进程中的span是用它们自己的trace_id创建的,而不是在go进程的trace_id下创建的(我还需要它们是go中创建的span的子span)。

sqxo8psd

sqxo8psd1#

在您的示例中,您正在MainStreamEngineChildStream之间使用 explicit span上下文传递。目前尚不清楚如何在ChildStream中向下游传递span上下文,但由于调用了tracer.start_span来创建span,因此还需要通过向下游传递tracing_span(或更具体地说,tracing_span.get_span_context())来确保所有直接的下游span也使用 explicit span上下文传递。
如果您的任何直接下游span是使用 implicit span上下文传递创建的,则它们不会知道来自ChildStream的span,因为它从未被设置为 current span。如果你想使用 implicit span上下文传递,你需要使用tracer.start_as_current_span来启动ChildStream中的span。
此外,如果你想使用 implicit span上下文传递,你可以在MainStreamEngine.__init__中使用context.attach(ctx),然后在创建ChildStream时不需要传递self.span_context。有关示例,请参阅本手册中手动设置范围上下文的最后几行。
最后,如果你想简化Go和Python之间的上下文传播,并且想避免编写JSON文件,我有一个小的Python模块,它为Python进程的生命周期创建一个span,如果设置了TRACEPARENT环境变量(如果有的话),则将其链接到父span(遵循非正式模式mentioned here)。让我知道如果这可能是有用的,我可以清理代码和分享它。

相关问题