PHP 无代码插桩
要求
PHP 的自动插桩需要
- PHP 8.0 或更高版本
- OpenTelemetry PHP 扩展
- Composer 自动加载
- OpenTelemetry SDK
- 一个或多个 插桩库
- 配置
安装 OpenTelemetry 扩展
仅安装 OpenTelemetry 扩展本身不会生成跟踪。
可以通过 pecl、pickle、PIE 或 php-extension-installer(Docker 特定)安装该扩展。对于某些 Linux 包管理器,也提供了该扩展的打包版本。
Linux 包
RPM 和 APK 包由以下提供:
- Remi repository - RPM
- Alpine Linux - APK(目前在 testing 分支中)
#this example is for CentOS 7. The PHP version can be changed by
#enabling remi-<version>, eg "yum config-manager --enable remi-php83"
yum update -y
yum install -y epel-release yum-utils
yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager --enable remi-php81
yum install -y php php-pecl-opentelemetry
php --ri opentelemetry
#At the time of writing, PHP 8.1 was the default PHP version. You may need to
#change "php81" if the default changes. You can alternatively choose a PHP
#version with "apk add php<version>", eg "apk add php83".
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
apk add php php81-pecl-opentelemetry@testing
php --ri opentelemetry
PECL
设置开发环境。从源代码安装需要 proper 开发环境和一些依赖项。
sudo apt-get install gcc make autoconfbrew install gcc make autoconf构建/安装扩展。设置好环境后,您可以安装扩展:
pecl install opentelemetryphp pickle.phar install opentelemetryinstall-php-extensions opentelemetry将扩展添加到您的
php.ini文件中[opentelemetry] extension=opentelemetry.so验证扩展是否已安装并启用
php -m | grep opentelemetry
安装 SDK 和插桩库
现在扩展已安装,请安装 OpenTelemetry SDK 和一个或多个插桩库。
自动插桩功能适用于许多常用的 PHP 库。完整列表请参阅 Packagist 上的插桩库。
假设您的应用程序使用 Slim Framework 和一个 PSR-18 HTTP 客户端,并且我们将使用 OTLP 协议导出跟踪。
然后,您将安装 SDK、一个导出器以及 Slim Framework 和 PSR-18 的自动插桩包。
composer require \
open-telemetry/sdk \
open-telemetry/exporter-otlp \
open-telemetry/opentelemetry-auto-slim \
open-telemetry/opentelemetry-auto-psr18
配置
当与 OpenTelemetry SDK 结合使用时,您可以使用环境变量或 php.ini 文件来配置自动插桩。
环境配置
OTEL_PHP_AUTOLOAD_ENABLED=true \
OTEL_SERVICE_NAME=your-service-name \
OTEL_TRACES_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318 \
OTEL_PROPAGATORS=baggage,tracecontext \
php myapp.php
php.ini 配置
将以下内容添加到 php.ini 或 PHP 将处理的另一个 ini 文件中:
OTEL_PHP_AUTOLOAD_ENABLED="true"
OTEL_SERVICE_NAME=your-service-name
OTEL_TRACES_EXPORTER=otlp
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318
OTEL_PROPAGATORS=baggage,tracecontext
运行您的应用程序
在安装和配置完以上所有内容后,像往常一样启动您的应用程序。
您在 OpenTelemetry Collector 中看到的导出的跟踪取决于您安装的插桩库以及应用程序内部执行的代码路径。在前面的示例中,使用 Slim Framework 和 PSR-18 插桩库,您应该会看到类似以下的 span:
- 代表 HTTP 事务的根 span
- 代表已执行操作的 span
- PSR-18 客户端发送的每个 HTTP 事务的 span
请注意,PSR-18 客户端插桩会将 分布式跟踪 标头附加到传出的 HTTP 请求中。
工作原理
如果您只想快速上手,并且有适合您应用程序的插桩库,可以跳过此部分。
该扩展允许将观察者函数注册为针对类和方法的 PHP 代码,并在观察到的方法运行之前和之后执行这些函数。
如果您的框架或应用程序没有插桩库,您可以编写自己的。以下示例提供了一些要进行插桩的代码,然后说明如何使用 OpenTelemetry 扩展来跟踪该代码的执行。
<?php
use OpenTelemetry\API\Instrumentation\CachedInstrumentation;
use OpenTelemetry\API\Trace\Span;
use OpenTelemetry\API\Trace\StatusCode;
use OpenTelemetry\Context\Context;
require 'vendor/autoload.php';
/* The class to be instrumented */
class DemoClass
{
public function run(): void
{
echo 'Hello, world';
}
}
/* The auto-instrumentation code */
OpenTelemetry\Instrumentation\hook(
class: DemoClass::class,
function: 'run',
pre: static function (DemoClass $demo, array $params, string $class, string $function, ?string $filename, ?int $lineno) {
static $instrumentation;
$instrumentation ??= new CachedInstrumentation('example');
$span = $instrumentation->tracer()->spanBuilder('democlass-run')->startSpan();
Context::storage()->attach($span->storeInContext(Context::getCurrent()));
},
post: static function (DemoClass $demo, array $params, $returnValue, ?Throwable $exception) {
$scope = Context::storage()->scope();
$scope->detach();
$span = Span::fromContext($scope->context());
if ($exception) {
$span->recordException($exception);
$span->setStatus(StatusCode::STATUS_ERROR);
}
$span->end();
}
);
/* Run the instrumented code, which will generate a trace */
$demo = new DemoClass();
$demo->run();
前面的示例定义了 DemoClass,然后在其 run 方法上注册了 pre 和 post 钩子函数。钩子函数在每次执行 DemoClass::run() 方法之前和之后运行。pre 函数启动并激活一个 span,而 post 函数则结束它。
如果 DemoClass::run() 抛出异常,post 函数会在不影响异常传播的情况下记录该异常。
下一步
在为您的应用程序或服务配置好自动插桩后,您可能希望添加 手动插桩 来收集自定义遥测数据。
更多示例,请参阅 opentelemetry-php-contrib/examples。