OpenTelemetry PHP自动化仪表化

自动化仪表化是在不修改源代码的情况下向用户应用程序添加跟踪能力的过程。有几种技术可以实现这一点,但它们大致都通过在编译时、链接时、运行时注入额外的代码,或者在eBPF的情况下通过扩展操作系统来工作。本博文介绍了OpenTelemetry PHP自动化仪表化所使用的方法。

先决条件

要使用PHP自动化仪表化,您需要准备以下三样东西:

  • PHP 8.0或更高版本。PHP自动化仪表化使用了PHP 8.0引入的Observability API。
  • Composer
  • 机器上必须有一个C编译器

关于PHP 8.0 Observability API的背景

Observability API允许您在原始代码之前和之后注册和执行额外的代码(函数),而不会对其他区域引入额外的性能损耗。在PHP 8.0之前,添加跟踪功能的最常见技术是修改zend_execute_ex函数(一种猴子补丁技术)。然而,这可能会导致性能问题、运行时堆栈溢出以及通常情况下不可取的应用程序开销。过去考虑的另一种方法是插入AST并在编译时修改它,但没有已知的生产就绪的轨迹使用这种技术。

从自动化仪表化角度看Observability API

在本文撰写时,可观测性APIc扩展使用,并公开了一个具有以下接口的函数:

function hook(
    ?string $class,
    string $function,
    ?\Closure $pre = null,
    ?\Closure $post = null,
): bool {}

用户应用程序可以使用此函数在观察的函数之前和之后添加附加功能。下面的代码片段展示了如何对helloWorld函数进行仪表化:

function helloWorld() {
  echo 'helloWorld';
}

\OpenTelemetry\Instrumentation\hook(null, 'helloWorld',
    static function (?string $class, array $params, ?string $classname, string $functionname, ?string $filename, ?int $lineno)
    {
      echo 'before';
    },
    static function (mixed $object, array $params, mixed $return, ?Throwable $exception)
    {
      echo 'after';
    }
);

同样地,我们为部分重要的接口/库/框架实现了跟踪支持,这些都是Contrib仓库的一部分。每个自动化仪表化包都使用上述hook函数来注册和提供跟踪功能。还有一件未提及的事情是用于创建跟踪和其他必要组件的API SDK。这是opentelemetry-php的职责main,它是所有事物的基础。

php-rel

如何使用

所有必要的自动化仪表化组件都可以手动安装,不过我们花费时间降低了使用门槛,并创建了一个可以替您完成此任务的安装程序。本节将展示如何自动化仪表化一个从头开始创建的简单PHP laravel 应用程序。

第一步是创建一个演示应用程序。这里我们使用流行的Laravel框架:

composer create-project laravel/laravel example-app

接下来,安装opentelemetry-instrumentation-installer

cd example-app
composer require open-telemetry/opentelemetry-instrumentation-installer

OpenTelemetry仪表化安装程序有两种模式:

  • 基本模式(安装版本最新的组件)
  • 高级模式(让用户有更多控制权)

安装完成后,以basicadvanced开关运行install-otel-instrumentation命令,如下所示。

./vendor/bin/install-otel-instrumentation basic

最后一步是使用run-with-otel-instrumentation命令运行应用程序:

./vendor/bin/run-with-otel-instrumentation php -S localhost:8080 -t public public/index.php

run-with-otel-instrumentation并不是通过手动设置环境变量和正常运行应用程序无法实现的魔术操作。它是一个方便的工具,可以快速测试针对具有工作默认配置的应用程序的OpenTelemetry。

./vendor/bin/run-with-otel-instrumentation php -S localhost:8080 -t public public/index.php

现在,当您访问http://localhost:8080时,您应该在Jaeger中看到以下结果。

laravel-auto

当前状态和下一步计划

我们已经准备就绪,具备了以下所有必要的组件:

  • 作为基础并实现了opentelemetry规范的API和SDK。
  • 作为自动化仪表化基础的C扩展。
  • 大部分重要和流行的库和框架的自动化仪表化支持(正在进行中)。
  • 可帮助用户和开发人员降低使用门槛的开发工具。
  • 文档

我们的目标之一是增加这项工作的认知度,并吸引更多人参与其中,帮助我们改进它、增加覆盖范围和修复错误。

请尝试并给我们反馈。如果遇到任何问题,可以打开一个issue。有问题?请随时在CNCF的#otel-php Slack频道与我们联系,或参加我们的SIG会议,可以在OTel public calendar中找到。