首页 > 解决方案 > Stackdriver Strace 使用 python 为一个请求嵌入跟踪

问题描述

我正在使用 Stackdriver Trace 监控一些微服务的延迟,但是在将所有往返行程显示为一个请求时遇到了一些问题。

假设我有两个服务(为了简单起见)。为了从它们中获取跟踪,我需要在这两个服务中安装客户端库。现在在我做的第一个服务中说:

@app.route('/dump')
def dump():
    url = "http://db-dump/dump"
    tracer = app.config['TRACER']
    tracer.start_span(name='dump')
    result = requests.get(url)
    tracer.end_span()

    return result.content

在我的第二次服务中,我会:

@app.route('/dump')
def dump():
    conn = connect()
    tracer = app.config['TRACER']
    tracer.start_span(name='dump')
    db_content = select(conn)
    tracer.end_span()
    db_content_to_print = format(db_content)

    return render_page(db_content_to_print)

第二个服务对数据库进行查询,对结果进行 gts,然后将它们发送到第一个服务,该服务显示内容。

现在,当然我必须开始计算两个微服务的延迟,因为我想知道从第一个服务到第二个服务需要多长时间。而且我还必须开始计算第二个服务,因为我想知道从数据库中检索内容需要多长时间。

但是当我在 GCP 控制台上获得跟踪时,我看到了这个:

在此处输入图像描述

第一个跟踪来自数据库,第二个跟踪都是(从第一个服务到第二个 + 数据库)。

我想知道如何将第二个跟踪嵌入到 python 的第一个跟踪中。我一直在检查opencensuspython 的文档,我发现了这个:

类 opencensus.trace.span.Span(name, parent_span=None,...)

跨度是形成跟踪树节点的单个定时事件。每个跨度都有其名称、跨度 ID 和父 ID。父 id 指示单个分布式跟踪中各个跨度之间的因果关系。没有父 ID 的 Span 称为根 Span。与特定跟踪关联的所有跨度也共享一个公共跟踪 ID。跨度不需要是连续的,两个跨度之间可以有间隙。

所以,我想,我必须将span_id第一个请求的请求连同请求一起发送到第二个微服务?这里还有一个问题,这似乎需要用这些参数初始化跟踪器,但是我在第二个微服务上的跟踪器已经初始化了。发送请求时我无法初始化它,因为它已经无法正确计算延迟。

我需要问这个,因为要进行测试,我必须创建图像,将其上传到 docker hub,然后在 k8s 上进行测试。在这里盲目地做太多的工作。

Stackdriver 跟踪的 Python 客户端库处于 alpha 阶段,因此在 GCP 站点上也没有太多关于此的文档。

编辑

由于没有响应,我实际上尝试传递span_context信息,即:

>>> print(tracer.span_context)
SpanContext(trace_id=987b84e7efc5562ff6c21723e674cd41, span_id=910de32857b896da, trace_options=TraceOptions(enabled=True), tracestate=None)

...初始化时到第二个微服务,但它不起作用。当它开始计算第二个微服务上的跟踪时,它会自动生成新的trace_idspan_id忽略span_context第一个微服务。在这一点上,我没有想法。

编辑2

我想要的是整个跟踪(微服务 1 -> 微服务 2 -> 数据库)出现在同一跟踪下,具有不同的跨度。与此类似的东西:

一个新的

标签: pythonstackdrivergoogle-cloud-traceopencensus

解决方案


苏仁,

你能通过trace_id而不是span_id吗?这应该会在一个跟踪中向您显示所有内容。


推荐阅读