You need to enable JavaScript to run this app.
文档中心
应用性能监控全链路版

应用性能监控全链路版

复制全文
下载 pdf
接入指南
Python 应用接入
复制全文
下载 pdf
Python 应用接入
Python 应用在不同场景下有不同的接入方式,本文介绍 Python 应用通过 OpenTelemetry 接入的详细操作,接入后可以实现自动收集Trace信息、自动生成Metric指标、以及调用链检索、日志检索等功能。​
通过 OpenTelemetry 接入​
OpenTelemetry 是 CNCF 的一个可观测性项目,旨在提供可观测性领域的标准化方案,解决观测数据的数据模型、采集、处理、导出等的标准化问题,提供与三方 vendor 无关的服务。​
如果您的应用已经接入了 OpenTelemetry 的 SDK,APM 服务端可以接收 OpenTelemetry 上报的数据。接入 APM 后,您将获得RED指标生成能力、Trace 多维检索、单链路检索、拓扑生成等多项能力。​
说明​
如果您需要隔离生产和测试数据,请参见:将生产和测试数据隔离。​
使用限制​
  • 其中,APMPlus 采用 Prometheus 作为 OpenTelemetry Metrics 的存储,支持 promql 对 metrics 进行查询,具体应用请参见 自定义看板 和 报警管理。​
  • OpenTelemetry Metrics 转换为 Prometheus Metrics 时,存在一定限制:​
  • 不支持聚合方式为 delta 的数据。请不要修改 SDK 侧的默认聚合配置,保证 SDK 侧数据的聚合方式为 cumulative。​
  • 工作区拥有独立的数据上报凭证,如需使用工作区进行数据管理和数据隔离,请确保 apmplus-opentelemetry-collector 组件已经升级至 v3.1.0 及以上版本。​
注意事项​
  • Gevent 应用注意事项​
若使用 gevent 协程,需要配置环境变量 GEVENT_ENABLE=true。例如,程序中有使用如下协程时,需要设置环境变量 GEVENT_ENABLE=true。​
​
from gevent import monkey​
monkey.patch_all()​
​
  • Django 应用注意事项​
如果您的应用使用 Django 框架,在接入前需要注意如下事项:​
  • 要在 K8s 环境通过 OpenTelemetry 自动接入,需要确保 Python 版本为 3.8 及以上;​
  • OpenTelemetry 的引入,可能会导致 Django 应用不再使用默认的配置文件,需要通过环境变量重新指定配置文件:​
​
export DJANGO_SETTINGS_MODULE=mysite.settings​
​
  • 可以在项目的启动脚本中加入此设置项,或者通过 YAML 文件添加环境变量:​
​
env: ​
- name: DJANGO_SETTINGS_MODULE​
value: mysite.settings​
​
自动接入​
APM OpenTelemetry Collector 是 APM 基于 OpenTelemetry Collector 二次开发的数据采集器,遵守 Apache2.0 协议,支持采集 OpenTelemetry 监控数据,同时支持采集 Prometheus 指标、应用监控数据和 Kubernetes 资源指标。​
  1. 安装 APM OpenTelemetry Collector。​
  • 通过 VKE 集群组件中心,白屏安装 apmplus-opentelemetry-collector 组件。前往 VKE 集群界面,选择 组件管理 -> 监控,单击 apmplus-opentelemetry-collector 组件右上角...中的安装,完成 Apmplus OpenTelemetry Collector 的部署和管理。​
  • ​​​
  1. 在服务的 Kubernetes Deployment 配置中增加instrumentation.apmplus.volcengine.com/inject-python和instrumentation.apmplus.volcengine.com/workspace注解。代码示例如下:​
  • ​
    apiVersion: apps/v1​
    kind: Deployment​
    metadata:​
    name: python-flask-demo​
    labels:​
    app: python-flask-demo​
    spec:​
    replicas: 1​
    selector:​
    matchLabels:​
    app: python-flask-demo​
    template:​
    metadata:​
    labels:​
    app: python-flask-demo​
    annotations:​
    instrumentation.apmplus.volcengine.com/inject-python: 'true' # 开启 APMPlus 观测注入​
    instrumentation.apmplus.volcengine.com/workspace: default # 指定服务所属工作区​
    spec:​
    containers:​
    - name: python-flask-demo​
    image: python-flask:latest​
    imagePullPolicy: Always​
    env:​
    - name: CONTAINER_RUNTIME​
    value: "k8s"​
    ​
    ​
  1. 重新启动应用。​
Opentelemetry SDK 接入​
采用社区提供的 Opentelemetry Python SDK 手动埋点的方式上报数据,可以参考社区提供的 接入文档 和 python demo 完成 Python 项目构建。​
通过 opentelemetry-instrument 完成埋点上报​
说明​
Opentelemetry 官方文档相关介绍参考:getting-started。​
  1. 安装依赖包。​
​
pip install opentelemetry-distro opentelemetry-exporter-otlp​
opentelemetry-bootstrap -a install​
​
opentelemetry-distro 包安装了 API、SDK,以及 opentelemetry-bootstrap 和 opentelemetry-instrument 工具。​
  1. 在启动命令指定数据上报后端以及鉴权等参数。​
​
参数​
说明​
<your-service_name>​
应用服务名称。​
<apmplus_endpoint>​
对应环境的服务端地址。可前往 apmplus_endpoint/collector_endpoint 接入中心查看,获取方法参见:如何使用接入中心?。​
<collector_endpoint>​
​
<app_key>​
服务接入控制台提供的 app_key,获取方法参见:如何获取应用性能监控的认证信息 AppKey?。​
​
  • 如果指定数据直接上报至 ApmPlus 后端,示例如下:​
​
opentelemetry-instrument \​
--service_name <your-service-name> \​
--exporter_otlp_endpoint=<apmplus_endpoint> \​
--exporter_otlp_protocol=<protocol> \​
--exporter_otlp_headers=X-ByteAPM-AppKey=<app_key> \​
--python myapp.py​
​
  • 如果指定数据上报至 Collector,则无需指定 exporter_otlp_headers,示例如下:​
​
opentelemetry-instrument \​
--service_name <your-service-name> \​
--exporter_otlp_endpoint=<collector_endpoint> \​
--exporter_otlp_protocol=<protocol> \​
--python myapp.py​
​
  • 也可以通过环境变量配置这些参数,示例如下:​
​
OTEL_SERVICE_NAME=your-service-name \​
OTEL_EXPORTER_OTLP_ENDPOINT=<apmplus_endpoint>/<collector_endpoint>​
OTEL_EXPORTER_OTLP_PROTOCOL=<protocol>​
OTEL_EXPORTER_OTLP_HEADERS=X-ByteAPM-AppKey=<app_key>​
opentelemetry-instrument \​
python myapp.py​
​
通过 opentelemetry-sdk 手动埋点​
  1. 下载 API 和 SDK 包。​
​
pip install opentelemetry-api​
pip install opentelemetry-sdk​
pip install opentelemetry-exporter-otlp​
​
  1. 在代码里创建 TracerProvider, MeterProvider, LoggerProvider 并使用他们上报数据。​
Opentelemetry 官方文档相关介绍参考 Instrumentation。官方文档中的 Demo 将 metrics 和 trace 打印到 console,需要上报到 collector 的数据,除了需要换用 grpc/http exporter 外,还需要设置 endPoint、 headers 等信息。​
上报地址推荐使用 collector endpoint,参考 Demo 示例如下:​
  • TraceProvider 参考示例: ​
​
from opentelemetry import trace​
from opentelemetry.sdk.trace import TracerProvider​
from opentelemetry.sdk.trace.export import (​
BatchSpanProcessor,​
ConsoleSpanExporter,​
)​
from opentelemetry.sdk.resources import Resource​
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter​
​
# 设置 endpoint,推荐直接使用 collector endpoint​
# endpoint = "apmplus-opentelemetry-gateway-service-grpc.apmplus-opentelemetry-operator:4317"​
​
# 设置上报地址为 apmplus endpoint, 当无法安装 APM OpenTelemetry Collector 组件时使用。若通过公网接入,使用 apmplus-cn-beijing.volces.com:4317。​
endpoint = "apmplus-cn-beijing.ivolces.com:4317"​
​
# 设置 apmplus appkey, 只有上报地址为 Apmplus endpoint 时,才需要设置。​
headers = {​
"x-byteapm-appkey": "<app_key>",​
}​
​
# 设置 resource, 比如 service_name​
resource_attributes = {​
"service.name": "your-service-name",​
}​
resource = Resource.create(resource_attributes)​
​
exporter = OTLPSpanExporter(endpoint=endpoint, insecure=True, headers=headers) ​
​
provider = TracerProvider(resource=resource)​
processor = BatchSpanProcessor(exporter)​
provider.add_span_processor(processor)​
​
# Sets the global default tracer provider​
trace.set_tracer_provider(provider)​
​
# Creates a tracer from the global tracer provider​
tracer = trace.get_tracer("my.tracer.name")​
​
  • MeterProvider 参考示例: ​
​
​
from opentelemetry import metrics​
from opentelemetry.sdk.metrics import MeterProvider​
from opentelemetry.sdk.metrics.export import (​
ConsoleMetricExporter,​
PeriodicExportingMetricReader,​
)​
from opentelemetry.sdk.resources import Resource​
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter​
​
# 设置 endpoint,推荐直接使用 collector endpoint​
# endpoint = "apmplus-opentelemetry-gateway-service-grpc.apmplus-opentelemetry-operator:4317"​
​
# 设置上报地址为 apmplus endpoint, 当无法安装 APM OpenTelemetry Collector 组件时使用。若通过公网接入,使用 apmplus-cn-beijing.volces.com:4317。​
endpoint = "apmplus-cn-beijing.ivolces.com:4317"​
# 设置 apmplus appkey, 只有上报地址为 Apmplus endpoint 时,才需要设置​
headers = {​
"x-byteapm-appkey": "<app_key>",​
}​
​
# 设置 resource, 比如 service_name​
resource_attributes = {​
"service.name": "your-service-name",​
}​
resource = Resource.create(resource_attributes)​
​
exporter = OTLPMetricExporter(endpoint=endpoint, headers=headers)​
metric_reader = PeriodicExportingMetricReader(exporter)​
provider = MeterProvider(metric_readers=[metric_reader], resource=resource)​
​
# Sets the global default meter provider​
metrics.set_meter_provider(provider)​
​
# Creates a meter from the global meter provider​
meter = metrics.get_meter("my.meter.name")​
​
  • LoggerProvider 参考示例: ​
对于日志的上报,除了需要初始化 LoggerProvider, 建议使用 opentelemetry LoggingInstrumentor 对 logging 库进行插装,从而将 log 与 trace 关联起来。​
  1. 安装 LoggingInstrumentor​
​
pip install opentelemetry-instrumentation-logging​
​
  1. 初始化 LoggerProvider 并添加 LoggingInstrumentor​
​
import logging​
​
from opentelemetry._logs import get_logger, set_logger_provider​
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter​
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler​
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor​
from opentelemetry.sdk.resources import Resource​
from opentelemetry.instrumentation.logging import LoggingInstrumentor​
​
# 设置 endpoint,推荐直接使用 collector endpoint​
# endpoint = "apmplus-opentelemetry-gateway-service-grpc.apmplus-opentelemetry-operator:4317"​
​
# 设置上报地址为 apmplus endpoint, 当无法安装 APM OpenTelemetry Collector 组件时使用。若通过公网接入,使用 apmplus-cn-beijing.volces.com:4317。​
endpoint = "apmplus-cn-beijing.ivolces.com:4317"​
# 设置 apmplus appkey, 只有上报地址为 Apmplus endpoint 时,才需要设置​
headers = {​
"x-byteapm-appkey": "<app_key>",​
}​
​
# 设置 resource, 比如 service_name​
resource_attributes = {​
"service.name": "your-service-name",​
}​
resource = Resource.create(resource_attributes)​
​
exporter = OTLPLogExporter(endpoint=endpoint, insecure=True, headers=headers)​
provider = LoggerProvider(resource=resource)​
processor = BatchLogRecordProcessor(exporter)​
provider.add_log_record_processor(processor)​
​
# Sets the global default logger provider​
set_logger_provider(provider)​
​
# Attach OTLP handler to root logger​
handler = LoggingHandler(level=logging.INFO, logger_provider=provider)​
logging.basicConfig(handlers=[handler], level=logging.INFO)​
# instrument logging​
LoggingInstrumentor().instrument(set_logging_format=True)​
​
# log​
logging.info("This is an OpenTelemetry log record!")​
​
​
自动注入支持的框架​
​
Supported Packages​
Version​
volcenginesdkarkruntime(火山引擎方舟智能体 SDK)​
>= 0.0.1​
openai​
>= 0.27.0​
langchain​
>= 0.0.346​
mcp​
>=1.6.0, <=1.8.0​
aio_pika​
>= 7.2.0, < 10.0.0​
aiohttp​
~= 3.0​
aiopg​
>= 0.13.0, < 2.0.0​
asgiref​
~= 3.0​
asyncio​
all​
asyncpg​
>= 0.12.0​
aws_lambda​
all​
boto​
~=2.0​
boto3 ​
~= 1.0​
botocore​
~= 1.0​
cassandra-driver​
~= 3.25​
scylla-driver​
~= 3.25​
celery​
>= 4.0, < 6.0​
click​
>= 8.1.3, < 9.0.0​
confluent-kafka ​
>= 1.8.2, <= 2.4.0​
dbapi​
all​
django ​
>= 1.10​
elasticsearch ​
>= 6.0​
falcon​
>= 1.4.1, < 4.0.0​
fastapi​
~= 0.58​
flask ​
>= 1.0​
grpcio​
>= 1.42.0​
httpx ​
>= 0.18.0​
jinja2 ​
>= 2.7, < 4.0​
kafka-python​
>= 2.0, < 3.0​
kafka-python-ng ​
>= 2.0, < 3.0​
logging​
all​
mysql-connector-python ​
>= 8.0, < 10.0​
mysqlclient ​
< 3​
pika​
>= 0.12.0​
psycopg ​
>= 3.1.0​
psycopg2 ​
>= 2.7.3.1​
pymemcache ​
>= 1.3.5, < 5​
pymongo​
>= 3.1, < 5.0​
PyMySQL​
< 2​
pyramid​
>= 1.7​
redis​
>= 2.6​
remoulade​
>= 0.50​
requests​
~= 2.0​
sqlalchemy​
>= 1.0.0, < 2.1.0​
sqlite3​
all​
starlette ​
~= 0.13.0​
psutil ​
>= 5​
threading​
all​
tornado ​
>= 5.1.1​
tortoise-orm ​
>= 0.17.0​
urllib​
all​
urllib3 ​
>= 1.0.0, < 3.0.0​
wsgi​
all​
​
Python 日志接入及注意事项​
Python 应用的日志采集依赖 Opentelemetry,完成上述 OpenTelemetry 接入 Python 应用的全部流程,即可自动采集和上报日志信息。​
工作原理​
Opentelemetry Python 日志通过 logging 库插桩方式实现,通过 Log 信息增强和添加对应上报 handler,将日志上报到 APMPlus 后端并关联 Trace 和 Span 等信息。因此,只有通过 logging 库打印的日志,才能采集并发送到 APMPlus,控制台等其他方式无法采集日志信息。​
Python 应用中的一条日志,从诞生到通过 OpenTelemetry 发送再到上报 APMPlus 后端的完整流程如下:​
​​​
注意事项​
采集 Python 应用日志时,需要注意以下情况。​
Log level 配置​
Python logging 库存在 Log level 配置,默认为 WARNING。 当记录日志小于 level 配置时,实际不会进行日志打印操作,同样也不会上报到 APMPlus 服务端。因此,如需采集 INFO、DEBUG 等日志,必须通过 logging.basicConfig 手动设置 Log level,示例代码如下:​
​
import logging​
logging.basicConfig(level=logging.INFO)​
​
propagate 参数配置​
为了更好区分日志,业务通常不会直接使用 logging 进行日志记录,而是使用 logging.getLogger(name) 创建 logger,再通过 logger 进行日志记录。而 Opentelemetry logging 基于 root logger 进行埋点。因此,当使用 logger 进行日志记录,并且设置了 propagate = False 时,logger 记录的日志不会传播到 root logger, 也无法被 opentelemetry 采集上报。​
每个通过 logging.getLogger(name) 创建的 logger 实例均存在 propagate 属性,默认为 True,工作原理如下。​
  • propagate = True (默认): 当 logger 处理完一条日志后,将进行 propagate 标志检查,若为 True,这条日志记录将继续向上传递给父 logger (parent logger)。此过程一直持续到 root logger。​
  • propagate = False: 当 logger 处理完一条日志后,将停止向上传播。其父 logger 及更高层级的祖先 logger 将完全不感知这条日志的存在。​
异步日志记录​
日志记录需要关联日志所在的请求 Trace,因此,在 Opentelemetry LoggingInstrumentor 中会对 Log 信息进行增强,将获取日志打印时的上下文信息并存放在 Log 信息中。但当实际业务中采用异步方式记录日志时,可能丢失上下文信息,此时,日志无法关联到 Trace,将导致 APMPlus 日志页面的 TraceId 信息显示为空。​
排查方式​
当日志采集时发现并没有日志数据采集时,排除注意事项中提及的情况后,可通过主动添加相应日志的方式进行问题排查。示例如下:​
  • 在 logging basicConfig 设置后和打印日志前添加以下代码,将可以打印出 logging 库的 handler 和 level 信息。​
​
print(f"logging handlers: {logging.root.handlers}")​
print(f"logging level: {logging.root.level}")​
​
此时,若 LoggingInstrumentor 生效,则输出信息的 logging.root.handlers 中会包含以下 handler。​
​
<LoggingHandler (NOTSET)>​
​
  • 若使用 logger 打印日志,可使用以下代码打印日志。​
​
print(f"logger propagate: {your_logger.propagate}")​
print(f"logger level: {your_logger.level}")​
​
此时,若 LoggingInstrumentor 生效,则输出信息的 logging.root.handlers 中会包含以下 handler。​
​
<LoggingHandler (NOTSET)>​
​
​
最近更新时间:2026.06.09 14:58:55
这个页面对您有帮助吗?
有用
有用
无用
无用