Stackdriver Strace 使用 python 为一个请求嵌入跟踪
Posted
技术标签:
【中文标题】Stackdriver Strace 使用 python 为一个请求嵌入跟踪【英文标题】:Stackdriver Strace embedded traces for one request with python 【发布时间】:2020-03-24 03:29:37 【问题描述】:我正在使用 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 中将第二个跟踪嵌入到第一个跟踪中。我一直在检查 opencensus
的 python 文档,我发现了这个:
class opencensus.trace.span.Span(name, parent_span=None,...)
跨度是形成跟踪节点的单个定时事件 树。每个跨度都有其名称、跨度 ID 和父 ID。父母身份 表示单个跨度之间的因果关系 单个分布式跟踪。没有父 ID 的 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_id
和span_id
,并忽略第一个微服务的span_context
。在这一点上我没有想法。
EDIT2
我想要的是整个跟踪(微服务 1 -> 微服务 2 -> 数据库)出现在同一跟踪下,具有不同的跨度。类似的东西:
【问题讨论】:
你好,Suren,如果我理解正确,请告诉我第一个跟踪来自数据库,第二个跟踪是两者(从第一个服务到第二个 + 数据库) i> 意味着您想要的是从第一个服务到第二个服务到数据库到第一个服务全部在一个跟踪中,这样您就可以看到获得答案所需的全部时间。我对吗?如果没有,请详细说明,以便我提供帮助。谢谢! taht 是正确的。第一个来自数据库,第二个如果从第一个服务到第二个,从第二个到数据库。它们出现在不同的痕迹中。我想要的是它们出现在相同的跟踪中,但具有不同的跨度。我在帖子中添加了一张新图片(EDIT2) 【参考方案1】:我终于完成了。看起来,我不得不将trace_id
传递给第二个微服务。不是 span_id。但是我现在有一个不同的问题,我会提出另一个问题。
所以,总而言之,我解决了将跟踪放在不同跨度中的问题。现在他们在同一个:
问题是第一个跟踪仍然包含第二个。如果我有第三个,第一个将同时包含它们,第二个将包含第三个,因为我无法阻止第二个微服务的第一个跨度。当我尝试时,我收到以下错误。
WARNING:root:No active span, cannot do end_span.
我尝试的是在到达那里后立即结束第二个微服务的第一个跨度,但我收到了这个错误。我只是要发布另一个答案,因为我无法通过此屏幕。
【讨论】:
【参考方案2】:苏伦,
你能通过 trace_id
而不是 span_id
吗?这应该会在一个跟踪中显示所有内容。
【讨论】:
没错。我发布了答案,但不确定我做对了,所以删除它以进行更多调查。但是,如果您确认是这样,我会继续这样做。谢谢。以上是关于Stackdriver Strace 使用 python 为一个请求嵌入跟踪的主要内容,如果未能解决你的问题,请参考以下文章
使用 Google Container Engine (GKE) 和 Stackdriver 监控和提醒 Pod 状态或重启
使用 Python 查询 GCP Stackdriver 日志