通过OpenTelemetry上报Python应用数据

通过OpenTelemetry为应用埋点并上报链路数据至云监控2.0后,云监控2.0即可开始监控应用,您可以查看应用拓扑、调用链路、异常事务、慢事务和SQL分析等一系列监控数据。本文介绍如何使用OpenTelemetry Python Agent/SDK进行自动或手动埋点并上报数据。

重要

推荐您优先接入阿里云自研Python Agent。

相比开源实现,阿里云 Python 探针提供对常见大模型框架(llama-index、dify、langchain、openai、通义千问等)的可观测性,提供更丰富的指标、链路及持续剖析数据。详细信息,请参见手动安装Python探针

前提条件

Python 版本 ≥ 3.7。

背景信息

OpenTelemetry提供了若干自动埋点插件,支持为常见框架自动创建Span,支持的框架列表如下,完整信息请参见OpenTelemetry官方文档

说明

版本~= V.N表示≥ V.N== V.*,例如,aiohttp ~= 3.0表示aiohttp版本要求aiohttp ≥ 3.0aiohttp == 3.*

展开查看支持的Python框架

OpenTelemetry插件

支持的Package以及版本

opentelemetry-instrumentation-aio-pika

aio_pika - [7.2.0, 10.0.0)

opentelemetry-instrumentation-aiohttp-client

aiohttp ~= 3.0

opentelemetry-instrumentation-aiohttp-server

aiohttp ~= 3.0

opentelemetry-instrumentation-aiopg

aiopg - [0.13.0, 2.0.0)

opentelemetry-instrumentation-asgi

asgiref ~= 3.0

opentelemetry-instrumentation-asyncpg

asyncpg ≥ 0.12.0

opentelemetry-instrumentation-aws-lambda

aws_lambda

opentelemetry-instrumentation-boto

boto ~= 2.0

opentelemetry-instrumentation-boto3sqs

boto3 ~= 1.0

opentelemetry-instrumentation-botocore

botocore ~= 1.0

opentelemetry-instrumentation-cassandra

  • cassandra-driver ~= 3.25

  • scylla-driver ~= 3.25

opentelemetry-instrumentation-celery

celery - [4.0, 6.0)

opentelemetry-instrumentation-confluent-kafka

confluent-kafka - [1.8.2, 2.2.0]

opentelemetry-instrumentation-dbapi

dbapi

opentelemetry-instrumentation-django

django ≥ 1.10

opentelemetry-instrumentation-elasticsearch

elasticsearch ≥ 2.0

opentelemetry-instrumentation-falcon

falcon - [1.4.1, 4.0.0)

opentelemetry-instrumentation-fastapi

fastapi ~= 0.58

opentelemetry-instrumentation-flask

flask - [1.0, 3.0)

opentelemetry-instrumentation-grpc

grpcio ~= 1.27

opentelemetry-instrumentation-httpx

httpx ≥ 0.18.0

opentelemetry-instrumentation-jinja2

jinja2 - [2.7, 4.0)

opentelemetry-instrumentation-kafka-python

kafka-python ≥ 2.0

opentelemetry-instrumentation-logging

logging

opentelemetry-instrumentation-mysql

mysql-connector-python ~= 8.0

opentelemetry-instrumentation-mysqlclient

mysqlclient < 3

opentelemetry-instrumentation-pika

pika≥ 0.12.0

opentelemetry-instrumentation-psycopg2

psycopg2 ≥ 2.7.3.1

opentelemetry-instrumentation-pymemcache

pymemcache - [1.3.5, 5)

opentelemetry-instrumentation-pymongo

pymongo - [3.1, 5.0)

opentelemetry-instrumentation-pymysql

PyMySQL < 2

opentelemetry-instrumentation-pyramid

pyramid ≥ 1.7

opentelemetry-instrumentation-redis

redis ≥ 2.6

opentelemetry-instrumentation-remoulade

remoulade ≥ 0.50

opentelemetry-instrumentation-requests

requests ~= 2.0

opentelemetry-instrumentation-sqlalchemy

sqlalchemy

opentelemetry-instrumentation-sqlite3

sqlite3

opentelemetry-instrumentation-starlette

starlette ~= 0.13.0

opentelemetry-instrumentation-system-metrics

psutil ≥ 5

opentelemetry-instrumentation-tornado

tornado ≥ 5.1.1

opentelemetry-instrumentation-tortoiseorm

tortoise-orm ≥ 0.17.0

opentelemetry-instrumentation-urllib

urllib

opentelemetry-instrumentation-urllib3

urllib3 - [1.0.0, 3.0.0)

opentelemetry-instrumentation-wsgi

wsgi

步骤一:获取接入点信息

  1. 登录云监控2.0控制台,选择目标工作空间,在左侧导航栏选择接入中心 > 接入中心

  2. 服务端应用区域单击Python卡片,然后选择接入协议类型Opentelemetry

  3. 参数配置区域单击LicenseKey右侧的点击获取,然后根据需求选择埋点方式连接方式上报方式,并输入应用名称版本号部署环境

    页面下方将会根据配置参数生成相应的接入代码,代码中包含了Endpoint、LicenseKey等接入点信息。

    image

步骤二:设置依赖库

自动埋点(推荐)

  1. 下载并安装所需包。

    pip install opentelemetry-distro opentelemetry-exporter-otlp
    
    opentelemetry-bootstrap -a install
    说明

    opentelemetry-bootstrap -a install 命令会扫描当前 Python 环境的 site-packages 文件夹,如果有 OpenTelemetry 支持自动埋点的框架,会自动下载框架对应的 OpenTelemetry 插件。 例如已经安装过 django,那么该命令会自动下载 opentelemetry-instrumentation-django 包。

  2. 配置以下环境变量,然后启动应用程序。

    export OTEL_SERVICE_NAME=<service name>
    export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
    export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=<traces.endpoint>
    export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=<metrics.endpoint>
    export OTEL_EXPORTER_OTLP_HEADERS="x-arms-license-key=<license-key>,x-arms-project=<arms-project>,x-cms-workspace=<workspace>"
    export OTEL_RESOURCE_ATTRIBUTES=service.name=<service name>,acs.cms.workspace=<workspace>,service.version=<service version>,deployment.environment=<environment>
    opentelemetry-instrument <your_run_command>

    步骤一获取到的接入点信息替换到以上代码中,并将 <your_run_command> 替换为需要 Python 应用的启动命令,<your_run_command> 可以是:

    • 普通应用:python app.py

    • Flask应用:flask run -p 8000

    • Django应用:python manage.py runserver --noreload

    • uWGSI应用:uwsgi --http :8000 --module app.wsgi

    • Gunicorn应用:gunicorn app:app --bind=127.0.0.1:8000gunicorn app:app --workers 2 --worker-class uvicorn.workers.UvicornWorker --bind 127.0.0.1:8000(多worker模式)

    • Uvicorn应用:uvicorn app:app --host localhost --port 8000

    说明

    使用自动埋点时,请勿启用热更新配置,如--reload或者reload=True,否则将使OpenTelemetry自动埋点失效。 Django开发环境默认启用热加载,使用OpenTelemetry自动埋点需要显式指定--noreload参数。 OpenTelemetry自动埋点暂不支持Uvicorn应用多worker模式。

手动埋点

  1. 下载所需包。

    pip install opentelemetry-api
    pip install opentelemetry-sdk
    pip install opentelemetry-exporter-otlp
  2. 创建 Python Demo 应用。

    创建 main.py 文件,并添加如下内容:

    from opentelemetry import trace, baggage
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as OTLPSpanHttpExporter
    from opentelemetry.sdk.resources import DEPLOYMENT_ENVIRONMENT, HOST_NAME, Resource, SERVICE_NAME, SERVICE_VERSION
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    
    def inner_method():
        tracer = trace.get_tracer(__name__)
        with tracer.start_as_current_span("child_span") as child_span:
            print("hello world")
    
    def outer_method():
        tracer = trace.get_tracer(__name__)
        with tracer.start_as_current_span("parent_span") as parent_span:
            inner_method()
    
    # 初始化 OpenTelemetry
    def init_opentelemetry():
        # 设置服务名、主机名
        resource = Resource(attributes={
            SERVICE_NAME: "<service name>",  # 应用名。
            SERVICE_VERSION: "<service version>",  # 版本号。
            DEPLOYMENT_ENVIRONMENT: "<environment>", # 部署环境。
            HOST_NAME: "${hostName}", # 请将 ${hostName} 替换为主机名
            "acs.cms.workspace": "<workspace>"  # 请将 <workspace> 替换为您的workspace名称。
        })
        
        headers = {
            "x-arms-license-key": "<license-key>",  # 请将 <license-key> 替换为步骤一中获取的接入点信息。
            "x-arms-project": "<arms-project>",  # 请将 <arms-project> 替换为步骤一中获取的接入点信息。
            "x-cms-workspace": "<workspace>"  # 请将 <workspace> 替换为您的workspace名称。
        }
        
        # 使用HTTP协议上报
        span_processor = BatchSpanProcessor(OTLPSpanHttpExporter(
            endpoint="<endpoint>",  # 请将<endpoint>替换为步骤一中获取的接入点信息。
            headers=headers
        ))
        
        trace_provider = TracerProvider(resource=resource, active_span_processor=span_processor)
        trace.set_tracer_provider(trace_provider)
    
    if __name__ == '__main__':
        init_opentelemetry()
        outer_method()
  3. 启动应用程序.

    python main.py

查看监控数据

  1. 登录云监控2.0控制台,选择目标工作空间,在左侧导航栏选择应用中心 > 运维监控 > 应用监控

  2. 应用列表页面单击目标应用名称,然后查看对应的监控详情。更多信息,请参见应用监控