跳转至

OpenTelemetry PHP

接入前,先启用 DataKit 的 OpenTelemetry 采集器

前置条件

  • PHP 8.1、8.2、8.3 或 8.4;
  • Composer;
  • DataKit 与 PHP 应用之间端口可达。

一、零码方式注入

安装扩展

查看 PHP 版本、线程模式和扩展目录:

php -r 'printf("PHP=%s.%s MODE=%s EXT=%s\n", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_ZTS ? "ts" : "nts", ini_get("extension_dir"));'
uname -m

从 Release 页面下载与 PHP 版本、ts/nts、操作系统和 CPU 架构一致的资产。例如 PHP 8.2 NTS、Linux x86_64 使用:

php_opentelemetry-1.3.4-gtrace-8.2-nts-linux-x86_64.tar.gz

安装扩展:

tar -xzf php_opentelemetry-1.3.4-gtrace-8.2-nts-linux-x86_64.tar.gz
sudo install -m 0755 \
  php_opentelemetry-1.3.4-gtrace-8.2-nts-linux-x86_64/opentelemetry.so \
  "$(php -r 'echo ini_get("extension_dir");')/opentelemetry.so"
php --ini

在 PHP 扫描的配置目录中创建 99-opentelemetry.ini

extension=opentelemetry.so
opentelemetry.attr_hooks_enabled=On

重启 PHP-FPM、Apache 或应用进程,然后检查扩展:

php --ri opentelemetry

安装自动插桩依赖

自动插桩包需要与应用使用的框架和组件对应。以下为 Slim 和 PSR-18 示例:

composer config allow-plugins.php-http/discovery false
composer require \
  open-telemetry/sdk \
  open-telemetry/exporter-otlp \
  open-telemetry/opentelemetry-auto-slim \
  open-telemetry/opentelemetry-auto-psr18 \
  php-http/guzzle7-adapter \
  nyholm/psr7

配置上报

应用与 DataKit 在同一台主机时,使用回环地址上报:

export OTEL_PHP_AUTOLOAD_ENABLED=true
export OTEL_SERVICE_NAME=my-php-service
export OTEL_SERVICE_VERSION=1.0.0
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=prod
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=baggage,tracecontext

php -S 0.0.0.0:8080 -t public

PHP-FPM、Supervisor、systemd 或容器部署时,必须将这些变量写入对应进程的启动环境,并重启进程。

如需使用 OTLP/gRPC 4317,还需安装 PHP grpc 扩展和 Composer 传输包:

composer require open-telemetry/transport-grpc

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

验证

请求应用路由后,检查 DataKit 接收日志:

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

日志中出现 POST /otel/v1/traces 且状态码为 200,表示 Trace 已被 DataKit 接收。

二、SDK 方式

SDK 方式由业务代码创建 Span,不要求安装自动插桩扩展。

安装依赖

composer config allow-plugins.php-http/discovery false
composer require \
  open-telemetry/sdk \
  open-telemetry/exporter-otlp \
  php-http/guzzle7-adapter \
  nyholm/psr7

创建 Span

<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use OpenTelemetry\API\Trace\StatusCode;
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessorBuilder;
use OpenTelemetry\SDK\Trace\TracerProvider;

$resource = ResourceInfoFactory::defaultResource()->merge(
    ResourceInfo::create(Attributes::create([
        'service.name' => 'my-php-service',
        'service.version' => '1.0.0',
        'deployment.environment.name' => 'prod',
    ]))
);

$transport = (new OtlpHttpTransportFactory())->create(
    'http://127.0.0.1:9529/otel/v1/traces',
    'application/x-protobuf'
);
$exporter = new SpanExporter($transport);
$processor = (new BatchSpanProcessorBuilder($exporter))->build();
$tracerProvider = TracerProvider::builder()
    ->setResource($resource)
    ->addSpanProcessor($processor)
    ->build();

$tracer = $tracerProvider->getTracer('application');
$span = $tracer->spanBuilder('order.submit')->startSpan();
$scope = $span->activate();

try {
    $span->setAttribute('order.id', 'A1001');
    // 业务代码
} catch (Throwable $exception) {
    $span->recordException($exception);
    $span->setStatus(StatusCode::STATUS_ERROR, $exception->getMessage());
    throw $exception;
} finally {
    $scope->detach();
    $span->end();
    $tracerProvider->shutdown();
}

参考

文档评价

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