在使用链路追踪控制台追踪应用的链路数据之前,需要通过客户端将应用数据上报至链路追踪。本文介绍如何通过Jaeger客户端上报Python应用数据。
前提条件
获取接入点信息
- 登录ARMS控制台,在左侧导航栏选择 。
- 在应用列表页面顶部选择目标地域,然后单击目标链路追踪应用名称。
说明 语言列显示
图标的应用为接入应用监控的应用,显示-图标的应用为接入链路追踪的应用。
- 在弹出的页面中,单击左侧导航栏上方的
图标,返回上一层。
- 在左侧导航栏单击集群配置,然后在右侧页面单击接入点信息页签。
- 在页面顶部选择需要接入的地域,然后在集群信息区域打开显示Token开关。
- 在客户端采集工具区域单击需要使用的链路数据采集客户端。
在下方表格的相关信息列中,获取接入点信息。
说明- 对于ACK集群应用,建议通过ARMS OpenTelemetry Collector上报应用数据。ARMS OpenTelemetry Collector支持本地集群内的链路采样与指标无损统计,在降低链路传输、存储成本的同时,不影响监控或告警指标的准确性。更多信息,请参见ARMS OpenTelemetry Collector
- 如果应用部署于阿里云生产环境,则选择私网接入点,否则选择公网接入点。对于Zipkin,一般情况下请使用v2版接入点,v1版接入点仅限对Zipkin十分了解的高阶用户使用。
背景信息
数据是如何上报的?
- 不通过Jaeger Agent而直接上报数据的原理如下图所示。
- 通过Jaeger Agent上报数据的原理如下图所示。
注意事项
- 针对Python语言,最新v1.25版本的Jaeger仅支持通过Jaeger Agent而不支持直接使用HTTP协议上报调用链路数据。更多信息,请参见Jaeger官方文档。
- 针对Python语言,最新v1.25版本的Jaeger仅支持通过UDP协议从Jaeger Client端上报至Jaeger Agent端。由于UDP协议并不保证通信的可靠性,因此为了保证调用链路数据的可靠性,一般情况下需要将Jaeger Client端和Jaeger Agent端运行在同一个主机内。
步骤一:搭建环境
本文演示示例中对Docker、Jaeger Agent、Jaeger Client和Python的版本要求如下。
Docker和Jaeger Agent环境
Docker版本:20.10.7
Jaeger Agent版本:1.25
- 在DockerHub中执行以下命令拉取v1.25版本的Jaeger Agent镜像。
docker pull jaegertracing/jaeger-agent:1.25
- 执行以下命令运行v1.25版本的Jaeger Agent。
docker run -d --name jaeger-agent -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778/tcp jaegertracing/jaeger-agent:1.25 --reporter.type=grpc --reporter.grpc.host-port=<endpoint>(填写对应的接入点信息) --agent.tags=<auth>(填写对应的认证信息)
说明 请将<endpoint>
和<auth>
替换成控制台集群配置页面相应客户端地域的接入点信息。获取接入点信息的方法,请参见前提条件。
Python和Jaeger Client环境
Python版本:3.8.5
Jaeger Client版本:4.6.0
在Python中安装以下Python包配置Jaeger Client环境。
certifi==2021.5.30
charset-normalizer==2.0.4
idna==3.2
jaeger-client==4.6.0
opentracing==2.4.0
requests==2.26.0
six==1.16.0
threadloop==1.0.2
thrift==0.13.0
tornado==6.1
urllib3==1.26.6
步骤二:创建Tracer对象
在链路追踪控制台查看数据
参考信息
此处提供了Jaeger常见的使用方法,更多信息,请参见Jaeger官方文档。
- 创建Trace。
from jaeger_client import Config def init_jaeger_tracer(service_name='your-app-name'): config = Config(config={}, service_name=service_name) return config.initialize_tracer()
- 创建和结束Span。
# 开始无Parent的Span。 tracer.start_span('TestSpan') # 开始有Parent的Span。 tracer.start_span('ChildSpan', child_of=span) # 结束Span。 span.finish()
- 透传SpanContext。
# 将spanContext透传到下一个Span中(序列化)。 tracer.inject( span_context=span.context, format=Format.TEXT_MAP, carrier=carrier ) # 解析透传过来的spanContxt(反序列化)。 span_ctx = tracer.extract(format=Format.TEXT_MAP, carrier={})