跳转至

OpenTelemetry PHP

OpenTelemetry PHP 通过 PHP 扩展提供运行时 Hook,再由 Composer 安装的框架插桩库生成遥测数据。无需修改业务代码,即可采集受支持的 Web 框架、HTTP 客户端、数据库等调用。

本文使用 DataKit 的 OpenTelemetry 采集器接收 OTLP 数据并转发到观测云:

PHP 应用 + OpenTelemetry 扩展/插桩库 -> OTLP -> DataKit -> 观测云

前置条件

  • PHP 8.0 或更高版本;
  • Composer,以及可安装 PHP 扩展的 PECL 或系统包管理器;
  • 应用通过 Composer 加载 vendor/autoload.php
  • 已安装 DataKit,且 DataKit 已连接到目标观测云工作空间;
  • PHP 应用到 DataKit 的网络可达:OTLP/HTTP 使用 DataKit HTTP 端口 9529,OTLP/gRPC 默认使用 4317

一、开启 OpenTelemetry 采集器

进入 DataKit 安装目录下的 conf.d/opentelemetry。如果尚未创建采集器配置,复制示例文件:

cd /usr/local/datakit/conf.d/opentelemetry
sudo cp opentelemetry.conf.sample opentelemetry.conf

确认 opentelemetry.conf 至少包含以下接收配置:

[[inputs.opentelemetry]]
  # 将需要在观测云中作为标签保留的自定义属性加入白名单。
  customer_tags = ["team", "project"]

  [inputs.opentelemetry.http]
    http_status_ok = 200
    trace_api = "/otel/v1/traces"
    metric_api = "/otel/v1/metrics"
    logs_api = "/otel/v1/logs"

  [inputs.opentelemetry.grpc]
    addr = "127.0.0.1:4317"
    max_payload = 16777216

接收地址如下:

协议 数据类型 DataKit 接收地址
OTLP/HTTP + Protobuf Trace http://<DataKit-IP>:9529/otel/v1/traces
OTLP/HTTP + Protobuf Metric http://<DataKit-IP>:9529/otel/v1/metrics
OTLP/HTTP + Protobuf Log http://<DataKit-IP>:9529/otel/v1/logs
OTLP/gRPC Trace、Metric、Log http://<DataKit-IP>:4317

如果 PHP 应用与 DataKit 不在同一主机,需按实际部署调整 DataKit 监听地址、防火墙或其他网络访问控制。gRPC 可将 addr 改为应用可访问的监听地址,例如 0.0.0.0:4317。不要将 OTLP 接收端口直接暴露到公网。

重启 DataKit 并检查服务:

sudo datakit service restart
curl http://127.0.0.1:9529/v1/ping

二、应用接入 OpenTelemetry

安装 OpenTelemetry PHP 扩展

先确认 PHP CLI 使用的版本和配置文件位置:

php --version
php --ini

准备好 PHP 开发环境、PECL、编译器、makeautoconf 后,从 PECL 官方源安装扩展:

sudo pecl install opentelemetry

在 PHP 扫描的附加配置目录中创建 99-opentelemetry.ini,或把以下配置加入当前 php.ini

[opentelemetry]
extension=opentelemetry.so

重启 PHP-FPM、Apache 或其他 PHP 应用进程,然后验证扩展:

php --ri opentelemetry

只安装扩展不会自动产生 Trace,还必须安装 SDK、OTLP exporter 和与应用框架对应的插桩包。

安装 SDK 和自动插桩包

以下以 Slim 和 PSR-18 HTTP 客户端为例,在应用的 Composer 项目目录执行:

composer require \
  open-telemetry/sdk \
  open-telemetry/exporter-otlp \
  open-telemetry/opentelemetry-auto-slim \
  open-telemetry/opentelemetry-auto-psr18

如果应用中尚无可被 OTLP HTTP exporter 使用的 PSR-17 Factory 和异步 HTTP Client 实现,可补充:

composer require php-http/guzzle7-adapter nyholm/psr7

不同框架需要安装不同的 open-telemetry/opentelemetry-auto-* 包。可在 OpenTelemetry PHP 插桩包列表中选择与当前框架、数据库或客户端匹配的包。没有安装对应插桩包的组件不会自动生成 Span。

通过环境变量启动

下面以 OTLP/HTTP + Protobuf 为例,默认接入 Trace,Metric 和 Log 暂时关闭:

export OTEL_PHP_AUTOLOAD_ENABLED="true"
export OTEL_SERVICE_NAME="order-service"
export OTEL_RESOURCE_ATTRIBUTES="env=prod,version=1.0.0,team=backend"

export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="none"
export OTEL_LOGS_EXPORTER="none"

export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:9529/otel"
export OTEL_PROPAGATORS="tracecontext,baggage"

php -S 0.0.0.0:8080 -t public

OTEL_EXPORTER_OTLP_ENDPOINT 是基础地址。OTLP/HTTP exporter 会根据数据类型自动追加 /v1/traces/v1/metrics/v1/logs,最终对应 DataKit 的 /otel/v1/* 路由。

PHP-FPM、Apache、Supervisor 或 systemd 不一定继承当前终端的环境变量。应将变量写入实际服务进程的启动环境,或使用下一节的 PHP 配置方式,然后重启服务。

通过 PHP 配置启用

也可以将以下内容加入 PHP-FPM 或 Apache 实际加载的 php.ini 或附加 INI 文件:

OTEL_PHP_AUTOLOAD_ENABLED="true"
OTEL_SERVICE_NAME="order-service"
OTEL_RESOURCE_ATTRIBUTES="env=prod,version=1.0.0,team=backend"
OTEL_TRACES_EXPORTER="otlp"
OTEL_METRICS_EXPORTER="none"
OTEL_LOGS_EXPORTER="none"
OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:9529/otel"
OTEL_PROPAGATORS="tracecontext,baggage"

PHP CLI 和 PHP-FPM 可能加载不同的配置文件。使用 php --ini 只能确认 CLI 配置;接入 Web 应用时,还需确认 PHP-FPM 或 Apache 对应 SAPI 已加载扩展和以上配置。

使用 OTLP/gRPC

PHP 使用 OTLP/gRPC 还需要 grpc PHP 扩展和 Composer transport 包:

sudo pecl install grpc
composer require open-telemetry/transport-grpc

export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4317"

gRPC endpoint 不能追加 /v1/traces 等 HTTP 路径。

三、数据上报参数

基础参数

环境变量 说明 建议值或示例
OTEL_SERVICE_NAME 设置 service.name;未设置时服务无法被稳定识别。 order-service,生产环境必须显式设置。
OTEL_RESOURCE_ATTRIBUTES 资源属性,格式为逗号分隔的 key=value env=prod,version=1.0.0,team=backend
OTEL_TRACES_EXPORTER Trace 导出器。 上报到 DataKit 时设为 otlp;关闭时设为 none
OTEL_METRICS_EXPORTER Metric 导出器。 需要上报指标时设为 otlp,否则设为 none
OTEL_LOGS_EXPORTER Log 导出器。 需要上报日志时设为 otlp,否则设为 none
OTEL_PROPAGATORS 跨服务上下文传播格式。 默认 tracecontext,baggage;全链路应保持兼容。
OTEL_SDK_DISABLED 禁用 OpenTelemetry SDK。 默认 false;应急关闭时设为 true

service.name 用于观测云中的服务归属;建议同时设置 envversion,用于按环境和版本筛选。其他自定义资源属性需要加入 DataKit customer_tags 白名单后才会作为标签保留,属性名中的 . 会转换为 _

PHP 自动插桩参数

环境变量 说明 默认值或示例
OTEL_PHP_AUTOLOAD_ENABLED 启用 SDK 和自动插桩的 Composer 自动加载。 默认 false;零代码接入必须设为 true
OTEL_PHP_DISABLED_INSTRUMENTATIONS 禁用指定的已安装插桩,多个名称用逗号分隔;也可使用 all psr15,psr18
OTEL_PHP_EXCLUDED_URLS 不加载 SDK 的请求 URL 正则表达式,多个表达式用逗号分隔。 healthz,readyz
OTEL_PHP_LOG_DESTINATION OpenTelemetry PHP 内部错误和告警的输出位置。 stderrerror_lognone 等。
OTEL_PHP_FIBERS_ENABLED 启用 Fiber 上下文存储;非 CLI SAPI 还需额外预加载配置。 默认 false

OTLP 参数

环境变量 说明 建议值或示例
OTEL_EXPORTER_OTLP_PROTOCOL 所有信号的 OTLP 协议。 DataKit 支持 http/protobufgrpc
OTEL_EXPORTER_OTLP_ENDPOINT 所有信号共用的基础地址。 HTTP:http://datakit-host:9529/otel;gRPC:http://datakit-host:4317
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT 仅 Trace 使用的地址,优先于共用地址。 http://datakit-host:9529/otel/v1/traces
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT 仅 Metric 使用的地址,优先于共用地址。 http://datakit-host:9529/otel/v1/metrics
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT 仅 Log 使用的地址,优先于共用地址。 http://datakit-host:9529/otel/v1/logs
OTEL_EXPORTER_OTLP_HEADERS 所有 OTLP 请求携带的请求头,多个值用逗号分隔。 x-tenant=tenant-a;需与 DataKit expected_headers 一致。
OTEL_EXPORTER_OTLP_COMPRESSION OTLP 请求压缩方式。 安装 zlib 扩展后可设为 gzip
OTEL_EXPORTER_OTLP_TIMEOUT 单次导出超时,单位毫秒。 10000

DataKit 的 OTLP/HTTP 采集仅支持 Protobuf,请使用 http/protobuf,不要使用 http/json。统一 endpoint 与某类数据的 endpoint 同时存在时,某类数据的配置优先。

采样参数

环境变量 说明 默认值或示例
OTEL_TRACES_SAMPLER Trace 头部采样器。 默认 parentbased_always_on;按比例采样使用 parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG 采样器参数。 0.1 表示根 Trace 采样 10%。

生产环境应根据流量和数据预算设置采样率。应用侧头部采样与 DataKit 侧采样同时开启时,最终保留率会叠加降低,应统一规划采样位置。

验证接入

请求一个已安装自动插桩包的应用路由,然后在 DataKit 主机检查接收日志:

curl http://127.0.0.1:8080/
sudo tail -f /usr/local/datakit/log/gin.log | grep '/otel/v1/'

出现 /otel/v1/tracesPOST 请求且响应码为 200,表示 DataKit 已接收 Trace。然后进入观测云的「应用性能监测 > 链路」按 service:order-service 查询。

如果没有数据,依次检查:PHP Web SAPI 是否加载 opentelemetry 扩展、应用是否加载 Composer autoloader、OTEL_PHP_AUTOLOAD_ENABLED 是否为 true、是否安装了与实际代码路径匹配的自动插桩包,以及 OTLP endpoint 是否可达。

参考

文档评价

文档内容是否对您有帮助? ×