使用 Python 生成跟踪记录和指标

本文档介绍了如何修改 Python 应用以使用开源 OpenTelemetry 框架收集跟踪记录和指标数据,以及如何将结构化 JSON 日志写入标准输出。本文档还介绍了您可以安装和运行的示例 Python 应用。该应用使用 Flask Web 框架,并配置为生成指标、跟踪记录和日志。

如需详细了解插桩,请参阅以下文档:

手动和自动插桩简介

对于这种语言,OpenTelemetry 将自动插桩定义为在不更改代码的情况下从库和框架收集遥测数据的做法。不过,您必须安装模块并设置环境变量。

本文档未介绍自动插桩。如需了解该主题,请参阅适用于 Python 的自动插桩

如需了解一般信息,请参阅适用于 Python 的 OpenTelemetry 插桩

准备工作

Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs.

Enable the APIs

对应用进行插桩处理以收集跟踪记录、指标和日志

如需对应用进行插桩处理以收集跟踪记录和指标数据,并将结构化 JSON 写入标准输出,请执行以下步骤,如本文档后续部分所述:

  1. 配置 OpenTelemetry
  2. 配置结构化日志记录

配置 OpenTelemetry

此示例应用已配置为使用 OpenTelemetry Python SDK 通过 OTLP 协议导出跟踪记录和指标。默认情况下,OpenTelemetry Python SDK 使用 W3C 跟踪记录上下文格式传播跟踪记录上下文,以确保 span 在跟踪记录中具有正确的父子关系。

以下代码示例展示了用于设置 OpenTelemetry 的 Python 模块:如需查看完整示例,请点击 更多,然后选择在 GitHub 上查看

resource = Resource.create(attributes={
    # Use the PID as the service.instance.id to avoid duplicate timeseries
    # from different Gunicorn worker processes.
    SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
})

traceProvider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter())
traceProvider.add_span_processor(processor)
trace.set_tracer_provider(traceProvider)

reader = PeriodicExportingMetricReader(
    OTLPMetricExporter()
)
meterProvider = MeterProvider(metric_readers=[reader], resource=resource)
metrics.set_meter_provider(meterProvider)

Flask 应用依靠 Gunicorn 来按照 Flask 的《部署到生产环境》指南中的建议处理 HTTP 请求。Gunicorn 会启动在独立工作器进程中运行的应用的多个副本 以提高吞吐量。为确保 worker 进程的指标不会相互冲突,我们建议每个工作器进程为 service.instance.id 资源属性设置唯一的值。一种方法是在 service.instance.id 中添加进程 ID。如需了解更多信息,请参阅时序冲突

如需了解详情和配置选项,请参阅 OpenTelemetry Python 插桩

配置结构化日志记录

如需写入与跟踪记录相关联的结构化日志,请将应用配置为将 JSON 格式日志输出到标准输出,并附带包含跟踪记录信息的键。以下代码示例说明如何配置标准 logging 库以使用 python-json-logger 库输出 JSON 结构化日志,以及如何使用 opentelemetry-instrumentation-logging 软件包包含跟踪信息。

LoggingInstrumentor().instrument()

logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter(
    "%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
    rename_fields={
        "levelname": "severity",
        "asctime": "timestamp",
        "otelTraceID": "logging.googleapis.com/trace",
        "otelSpanID": "logging.googleapis.com/spanId",
        "otelTraceSampled": "logging.googleapis.com/trace_sampled",
        },
    datefmt="%Y-%m-%dT%H:%M:%SZ",
)
logHandler.setFormatter(formatter)
logging.basicConfig(
    level=logging.INFO,
    handlers=[logHandler],
)

前面的配置会从日志消息中提取活跃 span 的相关信息,然后将该信息作为属性添加到 JSON 结构化日志中。然后,您可以使用这些属性将日志与跟踪记录相关联:

  • logging.googleapis.com/trace:与日志条目关联的跟踪记录的资源名称。
  • logging.googleapis.com/spanId:与日志条目关联的跟踪记录的 span ID。
  • logging.googleapis.com/trace_sampled:此字段的值必须是 truefalse

如需详细了解这些字段,请参阅 LogEntry 结构。

运行配置为收集遥测数据的示例应用

示例应用使用不受制于供应商的格式,包括 JSON(用于日志)和 OTLP(用于指标和跟踪记录)。使用配置了 Google 导出器的 OpenTelemetry Collector 将来自应用的遥测路由到 Google Cloud。它使用 Flask 来处理 HTTP 请求,使用请求库来发出 HTTP 请求。为了为 HTTP 客户端和服务器生成指标和跟踪记录,示例应用安装了 opentelemetry-instrumentation-flaskopentelemetry-instrumentation-requests 插桩库:

logger = logging.getLogger(__name__)

app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()

该应用有两个端点:

  • /multi 端点由 multi 函数处理。该应用中的负载生成器会向 /multi 端点发出请求。此端点收到请求时,它会向本地服务器上的 /single 端点发送 3 到 7 个请求。

    @app.route('/multi')
    def multi():
        """Handle an http request by making 3-7 http requests to the /single endpoint."""
        subRequests = randint(3, 7)
        logger.info("handle /multi request", extra={'subRequests': subRequests})
        for _ in range(subRequests):
            requests.get(url_for('single', _external=True))
        return 'ok'
  • /single 端点由 single 函数处理。当此端点收到请求时,它会休眠一小段延迟时间,然后以字符串进行响应。

    @app.route('/single')
    def single():
        """Handle an http request by sleeping for 100-200 ms, and write the number of seconds slept as the response."""
        duration = uniform(0.1, 0.2)
        time.sleep(duration)
        return f'slept {duration} seconds'

下载并部署应用

如需运行示例,请执行以下操作:

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 克隆代码库:

    git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-python
    
  3. 转到示例目录:

    cd opentelemetry-operations-python/samples/instrumentation-quickstart
    
  4. 构建并运行示例:

    docker compose up --abort-on-container-exit
    

    如果您未在 Cloud Shell 上运行,请使用指向凭据文件的 GOOGLE_APPLICATION_CREDENTIALS 环境变量运行应用。应用默认凭据提供了一个凭据文件 ($HOME/.config/gcloud/application_default_credentials.json)。

    # Set environment variables
    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json"
    export USERID="$(id -u)"
    
    # Run
    docker compose -f docker-compose.yaml -f docker-compose.creds.yaml up --abort-on-container-exit
    

查看指标

示例应用中的 OpenTelemetry 插桩生成 Prometheus 指标,您可以使用 Metrics Explorer 查看这些指标:

  • Prometheus/http_server_duration_milliseconds/histogram 会记录服务器请求的持续时间,并将结果存储在直方图中。

  • Prometheus/http_client_duration_milliseconds/histogram 会记录客户端请求的持续时间,并将结果存储在直方图中。

如需查看示例应用生成的指标,请执行以下操作:
  1. 在 Google Cloud 控制台中,转到 Metrics Explorer 页面:

    进入 Metrics Explorer

    如果您使用搜索栏查找此页面,请选择子标题为监控的结果。

  2. 指标元素中,展开选择指标菜单,在过滤栏中输入 http_server,然后使用子菜单选择一个特定资源类型和指标:
    1. 活跃资源菜单中,选择 Prometheus 目标
    2. 活跃指标类别菜单中,选择 HTTP
    3. 活跃指标菜单中,选择指标。
    4. 点击应用
  3. 配置数据的查看方式。

    如果指标的测量结果是累积的,则 Metrics Explorer 会自动按校准时间段对测量数据进行归一化,从而使图表显示速率。如需了解详情,请参阅种类、类型和转换

    测量整数或双精度值时(例如使用两个 counter 指标),Metrics Explorer 会自动对所有时序求和。如需查看 /multi/single HTTP 路由的数据,请将聚合条目的第一个菜单设置为

    如需详细了解如何配置图表,请参阅使用 Metrics Explorer 时选择指标

查看跟踪记录

如需查看跟踪记录数据,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到 Trace 探索器页面:

    转到 Trace 探索器

    您也可以使用搜索栏查找此页面。

  2. 在散点图中,选择 URI 为 /multi 的跟踪记录。
  3. 跟踪记录详情面板的甘特图中,选择标记为 /multi 的 span。

    此时会打开一个面板,其中显示 HTTP 请求的相关信息。这些详细信息包括方法、状态代码、字节数以及调用方的用户代理。

  4. 如需查看与此跟踪记录关联的日志,请选择日志和事件标签页。

    该标签页会显示各个日志。如需查看日志条目的详细信息,请展开日志条目。您还可以点击查看日志,并使用 Logs Explorer 查看日志。

如需详细了解如何使用 Cloud Trace 探索器,请参阅查找和探索跟踪记录

查看日志

在 Logs Explorer 中,您可以检查日志,还可以查看关联的跟踪记录(如果存在)。

  1. 在 Google Cloud 控制台中,转到 Logs Explorer 页面。

    前往 Logs Explorer

    如果您使用搜索栏查找此页面,请选择子标题为 Logging 的结果。

  2. 找到具有 handle /multi request 说明的日志。

    如需查看日志的详细信息,请展开日志条目。

  3. 点击包含“处理/多请求”消息的日志条目中的 跟踪记录,然后选择查看跟踪记录详情

    跟踪记录详情面板随即会打开并显示所选跟踪记录。

如需详细了解如何使用 Logs Explorer,请参阅使用 Logs Explorer 查看日志

后续步骤