Skip to main content

Code-based OpenTelemetry auto-instrumentation for Python

Project description

fastx-opentelemetry

OpenTelemetry 自动增强 SDK 封装,支持零代码代码两种接入方式。自动发现并加载所有已安装的 instrumentation 库。

特性

  • 零代码接入fastx-otel-py-instrument python app.py 一行命令完成全部增强,无需修改应用代码
  • 代码接入fastx_opentelemetry.init(service_name="my-app") 完成全部配置
  • 自动发现增强 — 自动检测并加载所有已安装的 opentelemetry-instrumentation-*
  • 智能建议 — 检测已安装但未增强的库,提示安装对应 instrumentation 包
  • 上下游服务串联 — 自动传播 Baggage 中的服务调用链(parent.service.name / parent.service.names / current.service.name
  • Baggage → Span 属性 — 自动将 Baggage 条目复制为 Span 属性,无需手动操作
  • 内置采样器 — 提供 RulesBasedSampler(按规则采样)和 RateLimitingSampler(限流采样)
  • 自动资源检测 — 自动采集 hostname、IP、PID、instance ID 以及云平台属性(cloud.platformcloud.region 等)
  • 环境变量兼容 — 完全兼容 OpenTelemetry 标准环境变量
  • 信号级端点 — 自动为 traces/metrics/logs 拼接 /v1/traces/v1/metrics/v1/logs 路径

安装

# 基础安装
pip install fastx-opentelemetry

# 带 OTLP gRPC 导出器
pip install fastx-opentelemetry[otlp-grpc]

# 带 OTLP HTTP 导出器
pip install fastx-opentelemetry[otlp-http]

# 全部安装
pip install fastx-opentelemetry[all]

方式一:零代码接入(推荐)

通过 fastx-otel-py-instrument 命令直接启动应用,无需修改任何代码。适用于已有项目快速接入、容器化部署等场景。

基本用法

# 直接用命令启动应用
fastx-otel-py-instrument python app.py

# 指定服务名和采集器地址
fastx-otel-py-instrument --service-name my-app --endpoint http://collector:4318 python app.py

# 传递应用参数
fastx-otel-py-instrument --service-name my-app python app.py --host 0.0.0.0 --port 8080

命令行参数

fastx-otel-py-instrument [选项] <命令> [参数...]
参数 说明 对应环境变量
--service-name NAME 服务名称 OTEL_SERVICE_NAME
--endpoint URL OTLP Collector 地址 OTEL_EXPORTER_OTLP_ENDPOINT
--protocol PROTO 传输协议:http/protobuf(默认)或 grpc OTEL_EXPORTER_OTLP_PROTOCOL
--compression MODE 压缩方式:gzip(默认)、deflate OTEL_EXPORTER_OTLP_COMPRESSION
--headers KV 请求头,逗号分隔的 key=value OTEL_EXPORTER_OTLP_HEADERS
--disabled-instrumentations LIST 禁用的增强,逗号分隔,* 禁用全部 OTEL_PYTHON_DISABLED_INSTRUMENTATIONS
--log-level LEVEL 日志级别:debuginfo(默认)、warningerror

工作原理

  1. CLI 解析参数,设置对应的环境变量
  2. fastx_opentelemetry 包目录加入 PYTHONPATH
  3. 通过 os.execv 替换为目标进程
  4. Python 启动时自动执行 sitecustomize.py,调用 fastx_opentelemetry.init() 完成初始化
  5. 应用代码在完整的 OpenTelemetry 环境中运行

使用示例

Flask 应用(无需改代码):

fastx-otel-py-instrument \
  --service-name my-flask-app \
  --endpoint http://collector:4318 \
  python app.py

Django 应用:

fastx-otel-py-instrument \
  --service-name my-django-app \
  --endpoint http://collector:4318 \
  python manage.py runserver 0.0.0.0:8000

FastAPI 应用:

fastx-otel-py-instrument \
  --service-name my-fastapi-app \
  --endpoint http://collector:4318 \
  uvicorn main:app --host 0.0.0.0 --port 8000

Docker 容器:

FROM python:3.11-slim
RUN pip install fastx-opentelemetry[all]
COPY . /app
WORKDIR /app
CMD ["fastx-otel-py-instrument", "--service-name", "my-app", "--endpoint", "http://collector:4318", "python", "app.py"]

环境变量方式配置

所有 CLI 参数都可以通过环境变量设置,适合容器化部署:

export OTEL_SERVICE_NAME=my-app
export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

fastx-otel-py-instrument python app.py

方式二:代码接入

在 Python 代码中调用 fastx_opentelemetry.init() 完成初始化。适合需要精细控制配置的场景。

最简用法

import fastx_opentelemetry

fastx_opentelemetry.init()

配合环境变量:

export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318
export OTEL_SERVICE_NAME=my-app
python my_app.py

Flask 应用

import fastx_opentelemetry

# 必须在创建 Flask app 之前初始化
fastx_opentelemetry.init(service_name="my-flask-app")

from flask import Flask
app = Flask(__name__)

@app.route("/hello")
def hello():
    return {"message": "Hello, World!"}

Django 应用

settings.py 中添加:

import fastx_opentelemetry
fastx_opentelemetry.init(service_name="my-django-app")

FastAPI 应用

import fastx_opentelemetry

fastx_opentelemetry.init(service_name="my-fastapi-app")

from fastapi import FastAPI
app = FastAPI()

@app.get("/hello")
async def hello():
    return {"message": "Hello, World!"}

自定义采样器

import fastx_opentelemetry
from fastx_opentelemetry import RulesBasedSampler, SamplingRule, RateLimitingSampler
from opentelemetry.sdk.trace.sampling import ALWAYS_ON, ALWAYS_OFF, TraceIdRatioBased

sampler = RulesBasedSampler(
    rules=[
        SamplingRule(match_name="/health.*", sampler=ALWAYS_ON),
        SamplingRule(match_name="/static/.*", sampler=ALWAYS_OFF),
        SamplingRule(match_name="/api/.*", sampler=TraceIdRatioBased(0.1)),
    ],
    default_sampler=RateLimitingSampler(max_spans_per_second=50),
)

fastx_opentelemetry.init(
    service_name="my-app",
    sampler=sampler,
)

完整配置

import fastx_opentelemetry
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor

console_processor = SimpleSpanProcessor(ConsoleSpanExporter())

loaded = fastx_opentelemetry.init(
    service_name="my-app",
    endpoint="http://collector:4317",  # 自动拼接 /v1/traces, /v1/metrics, /v1/logs
    protocol="grpc",
    compression="gzip",
    headers={"Authorization": "Bearer token123"},
    extra_resource_attributes={
        "deployment.environment": "production",
        "service.version": "1.2.3",
    },
    span_processors=[console_processor],
    disabled_instrumentations=["sqlite3"],
)

print(f"Loaded instrumentors: {loaded}")

禁用特定增强

fastx_opentelemetry.init(
    service_name="my-app",
    disabled_instrumentations=["sqlite3", "urllib"],
)

或通过环境变量:

export OTEL_PYTHON_DISABLED_INSTRUMENTATIONS=sqlite3,urllib

禁用所有增强(仅初始化 SDK,不加载任何 instrumentor):

fastx_opentelemetry.init(
    service_name="my-app",
    disabled_instrumentations=["*"],
)

上下游服务串联

FastxBaggagePropagatorFastxSpanProcessorinit() 时自动启用,无需额外配置。它们实现了与 Go 端 fastx_otel.go 一致的 Baggage 传播逻辑:

  • FastxBaggagePropagator — 包装 W3C Baggage 传播器,提取时自动转换服务链:
    • current.service.name 移入 parent.service.name
    • current.service.name 追加到 parent.service.names(以 ++ 分隔,去重)
    • current.service.name 设置为本地服务名
  • FastxSpanProcessor — 在 Span 开始时,自动将所有 Baggage 条目复制为 Span 属性

这意味着在微服务调用链中,每个服务的 Span 都会携带完整的上游服务链信息,便于在后端(如 Jaeger、Grafana)中追踪调用路径。

环境变量

变量 说明 默认值
FASTX_PYTHON_INSTRUMENTATION_ENABLED 全局开关,false 时跳过全部初始化 true
OTEL_SERVICE_NAME 服务名称 unknown_service
OTEL_EXPORTER_OTLP_ENDPOINT OTLP Collector 地址(自动拼接信号路径)
OTEL_EXPORTER_OTLP_PROTOCOL 传输协议 http/protobufgrpc http/protobuf
OTEL_EXPORTER_OTLP_COMPRESSION 压缩方式 gzip/deflate gzip
OTEL_EXPORTER_OTLP_TRACES_HEADERS 导出器请求头
OTEL_TRACES_SAMPLER 采样器名称 parentbased_always_on
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS 禁用的增强列表(逗号分隔,* 禁用全部)
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED 是否启用日志自动增强 true
IP_ADDR 自动检测为 host.ip 资源属性 本地非回环 IP
CLOUD_TYPE 自动检测为 cloud.platform 资源属性
REGION_CODE 自动检测为 cloud.region 资源属性
AZ_CODE 自动检测为 cloud.availability 资源属性
env_cd 自动检测为 deployment.environment.name 资源属性

安装增强库

fastx-opentelemetry 会自动检测已安装的库并加载对应的 instrumentation。你需要手动安装需要的 instrumentation 包:

# Web 框架
pip install opentelemetry-instrumentation-flask
pip install opentelemetry-instrumentation-django
pip install opentelemetry-instrumentation-fastapi

# HTTP 客户端
pip install opentelemetry-instrumentation-requests
pip install opentelemetry-instrumentation-httpx
pip install opentelemetry-instrumentation-urllib

# 数据库
pip install opentelemetry-instrumentation-sqlalchemy
pip install opentelemetry-instrumentation-psycopg2
pip install opentelemetry-instrumentation-redis
pip install opentelemetry-instrumentation-pymongo

# 消息队列
pip install opentelemetry-instrumentation-celery
pip install opentelemetry-instrumentation-kafka-python

检查已安装的增强库:

pip list | grep opentelemetry-instrumentation

API 参考

fastx_opentelemetry.init(**kwargs)

初始化 OpenTelemetry SDK 并加载所有已安装的 instrumentor。

参数:

参数 类型 说明
service_name str | None 服务名称,回退到 OTEL_SERVICE_NAME
endpoint str | None OTLP Collector 地址(自动拼接信号路径)
protocol str | None http/protobufgrpc
compression str | None gzipdeflate
headers dict | None OTLP 导出器请求头
extra_resource_attributes dict | None 额外的资源属性
span_processors list | None 自定义 SpanProcessor 列表
sampler Sampler | None 自定义采样器实例
disabled_instrumentations list | None 禁用的 instrumentor 名称列表,"*" 禁用全部

返回值: list[str] — 成功加载的 instrumentor 名称列表。

fastx_opentelemetry.list_available_instrumentors()

返回所有已安装的 instrumentor 名称列表。

fastx_opentelemetry.suggest_missing_instrumentations(loaded)

检查已安装但未增强的库,返回建议安装的 instrumentation 包名列表。

采样器

RulesBasedSampler(rules, default_sampler=None)

按规则匹配 span 名称或属性,委托给不同的采样器。

SamplingRule(sampler, match_name=None, match_attributes=None)

单条采样规则。match_name 为正则表达式匹配 span 名称,match_attributes 为属性键值对匹配。

RateLimitingSampler(max_spans_per_second)

基于令牌桶算法的限流采样器,限制每秒采样的 span 数量。

Baggage 传播与 Span 处理

FastxBaggagePropagator

包装 W3C Baggage 传播器,在 extract 时自动转换服务调用链。init() 时自动设置为全局传播器。

FastxSpanProcessor

在 Span on_start 时将所有 Baggage 条目复制为 Span 属性。init() 时自动添加到 TracerProvider。

本地开发

# 安装依赖
pip install -e ".[all]"

# 运行示例(零代码方式)
fastx-otel-py-instrument --service-name my-app --endpoint http://127.0.0.1:4318 python examples/app.py

# 运行示例(代码方式)
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
export OTEL_SERVICE_NAME=my-app
python examples/app.py

日志打印trace_id

都要安装:

pip install opentelemetry-instrumentation-logging

无代码增强方式

配置环境变量

export OTEL_PYTHON_LOG_CORRELATION=true
export OTEL_PYTHON_LOG_FORMAT=" %(msg)s [trace_id=%(otelTraceID)s]"

代码方式

方式1:环境变量启用

export OTEL_PYTHON_LOG_CORRELATION=true

import logging
logging.basicConfig(level=logging.INFO, format=' [trace_id=%(otelTraceID)s] %(message)s')

方式2:代码中启用。

import logging
from opentelemetry.instrumentation.logging import LoggingInstrumentor
# set_logging_format=True 会自动调用 logging.basicConfig 设置带 trace_id 的格式
# 注意一定放在logging.basicConfig之前才行
LoggingInstrumentor().instrument(set_logging_format=True)

logging.basicConfig(level=logging.INFO, format=' [trace_id=%(otelTraceID)s] %(message)s')

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastx_opentelemetry-0.2.1.tar.gz (27.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastx_opentelemetry-0.2.1-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file fastx_opentelemetry-0.2.1.tar.gz.

File metadata

  • Download URL: fastx_opentelemetry-0.2.1.tar.gz
  • Upload date:
  • Size: 27.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for fastx_opentelemetry-0.2.1.tar.gz
Algorithm Hash digest
SHA256 211313a9ae4446d78e82f48cf7c42612c0e65a1bba957df62e6c2f7ca784cc3f
MD5 4e492ad61c6aab4395f2f122f6e7e9ca
BLAKE2b-256 071387b3e4b74d839cf7f5541a585ed4277ebae8da0a4653c980aabf196754a7

See more details on using hashes here.

File details

Details for the file fastx_opentelemetry-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for fastx_opentelemetry-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 22c65b89a4007cb24cb751ae52fda97ffe155dc72b20dc10ca18530cb78cbc8a
MD5 c172ee27a2ddcde61ca84a4cb1f7b8ef
BLAKE2b-256 7e9fe229c37a202ed488efcbc052c10bc9876c2b444cf1c83f29f5c6ed8a9443

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page