OpenTelemetry Python¶
OpenTelemetry Python Agent 通过运行时 monkey patch 为受支持的 Python 库和框架注入遥测能力。使用 opentelemetry-instrument 启动应用,无需修改业务代码即可采集 Web 请求、HTTP 客户端、数据库、消息队列等调用。
本文使用 DataKit 的 OpenTelemetry 采集器接收 OTLP 数据并转发到观测云:
前置条件¶
- Python 3.10 或更高版本;
pip和可用的 Python 虚拟环境;- 已安装 DataKit,且 DataKit 已连接到目标观测云工作空间;
- Python 应用到 DataKit 的网络可达:OTLP/HTTP 使用 DataKit HTTP 端口
9529,OTLP/gRPC 默认使用4317。
一、开启 OpenTelemetry 采集器¶
进入 DataKit 安装目录下的 conf.d/opentelemetry。如果尚未创建采集器配置,复制示例文件:
确认 opentelemetry.conf 至少包含以下接收配置:
[[inputs.opentelemetry]]
# 将需要在观测云中作为标签保留的自定义属性加入白名单。
customer_tags = ["team", "project"]
[inputs.opentelemetry.http]
http_status_ok = 200
trace_api = "/otel/v1/traces"
metric_api = "/otel/v1/metrics"
logs_api = "/otel/v1/logs"
[inputs.opentelemetry.grpc]
addr = "127.0.0.1:4317"
max_payload = 16777216
接收地址如下:
| 协议 | 数据类型 | DataKit 接收地址 |
|---|---|---|
| OTLP/HTTP + Protobuf | Trace | http://<DataKit-IP>:9529/otel/v1/traces |
| OTLP/HTTP + Protobuf | Metric | http://<DataKit-IP>:9529/otel/v1/metrics |
| OTLP/HTTP + Protobuf | Log | http://<DataKit-IP>:9529/otel/v1/logs |
| OTLP/gRPC | Trace、Metric、Log | http://<DataKit-IP>:4317 |
如果 Python 应用与 DataKit 不在同一主机,需按实际部署调整 DataKit 监听地址、防火墙或其他网络访问控制。gRPC 可将 addr 改为应用可访问的监听地址,例如 0.0.0.0:4317。不要将 OTLP 接收端口直接暴露到公网。
重启 DataKit 并检查服务:
二、应用接入 OpenTelemetry¶
创建虚拟环境¶
OpenTelemetry Agent、应用及插桩包必须安装在同一个 Python 环境中。建议为应用使用独立虚拟环境:
先安装应用自身依赖,例如:
安装 Agent、Exporter 和插桩包¶
从 Python Package Index 官方包源安装 OpenTelemetry Distro 和 OTLP exporter:
python -m pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
opentelemetry-distro 提供 SDK、opentelemetry-bootstrap 和 opentelemetry-instrument。opentelemetry-bootstrap -a install 会检查当前环境已安装的应用依赖,并安装匹配的插桩包。例如环境中存在 Flask 时,会安装 opentelemetry-instrumentation-flask。
必须先安装应用依赖,再运行 bootstrap。应用新增或升级框架、数据库驱动、HTTP 客户端等依赖后,建议重新执行:
如需先查看将要安装的插桩包而不执行安装,可运行:
配置并启动应用¶
下面以 OTLP/HTTP + Protobuf 为例,默认接入 Trace,Metric 和 Log 暂时关闭:
export OTEL_SERVICE_NAME="order-service"
export OTEL_RESOURCE_ATTRIBUTES="env=prod,version=1.0.0,team=backend"
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="none"
export OTEL_LOGS_EXPORTER="none"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:9529/otel"
export OTEL_PROPAGATORS="tracecontext,baggage"
export OTEL_PYTHON_LOG_AUTO_INSTRUMENTATION="false"
opentelemetry-instrument python app.py
OTEL_EXPORTER_OTLP_ENDPOINT 是基础地址。OTLP/HTTP exporter 会根据数据类型自动追加 /v1/traces、/v1/metrics 或 /v1/logs,最终对应 DataKit 的 /otel/v1/* 路由。
必须使用 opentelemetry-instrument 启动实际应用进程。仅设置环境变量后直接执行 python app.py 不会启用零代码自动插桩。
常见启动方式¶
Flask 开发服务:
Gunicorn:
Gunicorn 等预派生服务器使用多个 worker 时,自动插桩和 Metric 导出可能受到进程 fork 行为影响。建议先用单 worker 验证;生产环境需要多进程时,应结合所用框架和信号类型评估官方的预派生部署方案。
Django 开发服务:
生产环境使用 Supervisor、systemd 或其他进程管理器时,应把环境变量和 opentelemetry-instrument 写入实际启动命令,然后重启应用。
使用 OTLP/gRPC¶
安装的 opentelemetry-exporter-otlp 已包含 OTLP exporter。改用 gRPC 时替换协议和 endpoint:
export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4317"
gRPC endpoint 不能追加 /v1/traces 等 HTTP 路径。
三、数据上报参数¶
Python Agent 支持命令行参数和环境变量。命令行参数名转为环境变量时,需要转成大写并增加 OTEL_ 前缀,例如 --service_name 对应 OTEL_SERVICE_NAME。同一参数同时通过命令行和环境变量设置时,命令行参数优先。
基础参数¶
| 环境变量 | 说明 | 建议值或示例 |
|---|---|---|
OTEL_SERVICE_NAME |
设置 service.name;未设置时服务无法被稳定识别。 |
order-service,生产环境必须显式设置。 |
OTEL_RESOURCE_ATTRIBUTES |
资源属性,格式为逗号分隔的 key=value。 |
env=prod,version=1.0.0,team=backend |
OTEL_TRACES_EXPORTER |
Trace 导出器。 | 上报到 DataKit 时设为 otlp;关闭时设为 none。 |
OTEL_METRICS_EXPORTER |
Metric 导出器。 | 需要上报指标时设为 otlp,否则设为 none。 |
OTEL_LOGS_EXPORTER |
Log 导出器。 | 需要上报日志时设为 otlp,否则设为 none。 |
OTEL_PROPAGATORS |
跨服务上下文传播格式。 | 默认 tracecontext,baggage;全链路应保持兼容。 |
OTEL_SDK_DISABLED |
禁用 OpenTelemetry SDK。 | 默认 false;应急关闭时设为 true。 |
service.name 用于观测云中的服务归属;建议同时设置 env 和 version,用于按环境和版本筛选。其他自定义资源属性需要加入 DataKit customer_tags 白名单后才会作为标签保留,属性名中的 . 会转换为 _。
Python 自动插桩参数¶
| 环境变量 | 说明 | 默认值或示例 |
|---|---|---|
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS |
禁用指定插桩,多个 entry point 名称用逗号分隔。 | redis,kafka,grpc_client |
OTEL_PYTHON_EXCLUDED_URLS |
所有支持的 Web 插桩共同排除的 URL 正则表达式。 | healthz,readyz |
OTEL_PYTHON_<LIBRARY>_EXCLUDED_URLS |
只对指定库排除 URL,其中 <LIBRARY> 使用大写库名。 |
OTEL_PYTHON_FLASK_EXCLUDED_URLS=healthz |
OTEL_PYTHON_LOG_CORRELATION |
向 Python 日志记录注入 Trace 上下文。 | 默认 false;需要日志关联时设为 true。 |
OTEL_PYTHON_LOG_AUTO_INSTRUMENTATION |
自动配置 OpenTelemetry Logging Handler。 | 当前版本默认 true;不通过 OTLP 上报日志时建议设为 false。 |
OTEL_PYTHON_LOG_LEVEL |
Python 自动插桩日志级别。 | info、warning、error、debug。 |
OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH |
在初始化 SDK 前调用 gevent monkey patch。 | gevent 应用可设为 patch_all。 |
OTLP 参数¶
| 环境变量 | 说明 | 建议值或示例 |
|---|---|---|
OTEL_EXPORTER_OTLP_PROTOCOL |
所有信号的 OTLP 协议。 | DataKit 支持 http/protobuf 或 grpc。 |
OTEL_EXPORTER_OTLP_ENDPOINT |
所有信号共用的基础地址。 | HTTP:http://datakit-host:9529/otel;gRPC:http://datakit-host:4317。 |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
仅 Trace 使用的地址,优先于共用地址。 | http://datakit-host:9529/otel/v1/traces |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT |
仅 Metric 使用的地址,优先于共用地址。 | http://datakit-host:9529/otel/v1/metrics |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT |
仅 Log 使用的地址,优先于共用地址。 | http://datakit-host:9529/otel/v1/logs |
OTEL_EXPORTER_OTLP_HEADERS |
所有 OTLP 请求携带的请求头,多个值用逗号分隔。 | x-tenant=tenant-a;需与 DataKit expected_headers 一致。 |
OTEL_EXPORTER_OTLP_COMPRESSION |
OTLP 请求压缩方式。 | 跨主机上报可设为 gzip。 |
OTEL_EXPORTER_OTLP_TIMEOUT |
单次导出超时,单位秒。 | 10 |
DataKit 的 OTLP/HTTP 采集仅支持 Protobuf,请使用 http/protobuf,不要使用 http/json。统一 endpoint 与某类数据的 endpoint 同时存在时,某类数据的配置优先。
采样和批量上报参数¶
| 环境变量 | 说明 | 默认值或示例 |
|---|---|---|
OTEL_TRACES_SAMPLER |
Trace 头部采样器。 | 默认 parentbased_always_on;按比例采样使用 parentbased_traceidratio。 |
OTEL_TRACES_SAMPLER_ARG |
采样器参数。 | 0.1 表示根 Trace 采样 10%。 |
OTEL_BSP_SCHEDULE_DELAY |
Span 批量导出间隔,单位毫秒。 | 默认 5000。 |
OTEL_BSP_MAX_QUEUE_SIZE |
待导出的 Span 队列上限。 | 默认 2048。 |
OTEL_BSP_MAX_EXPORT_BATCH_SIZE |
每批最多导出的 Span 数。 | 默认 512。 |
OTEL_BSP_EXPORT_TIMEOUT |
Span 批量导出超时,单位毫秒。 | 默认 30000。 |
OTEL_METRIC_EXPORT_INTERVAL |
Metric 导出间隔,单位毫秒。 | 默认 60000。 |
生产环境应根据流量和数据预算设置采样率。应用侧头部采样与 DataKit 侧采样同时开启时,最终保留率会叠加降低,应统一规划采样位置。
验证接入¶
请求一个经过已安装插桩库的应用路由,然后在 DataKit 主机检查接收日志:
出现 /otel/v1/traces 的 POST 请求且响应码为 200,表示 DataKit 已接收 Trace。然后进入观测云的「应用性能监测 > 链路」按 service:order-service 查询。
如果没有数据,依次检查:应用和 OpenTelemetry 是否安装在同一虚拟环境、是否在安装应用依赖后执行了 opentelemetry-bootstrap -a install、是否通过 opentelemetry-instrument 启动、实际代码路径是否命中受支持的插桩库,以及 OTLP endpoint 是否可达。