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-pythoninstrumentation.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
这个页面对您有帮助吗?
有用
有用
无用
无用