OpenTelemetry PHP 自動計装
Blog posts are not updated after publication. This post is more than a year old, so its content may be outdated, and some links may be invalid. Cross-verify any information before relying on it.
自動計装は、ユーザーアプリケーションのソースコードを変更せずにトレーシング機能を追加するプロセスです。 そのためのテクニックはいくつかありますが、いずれもコンパイル時、リンク時、実行時に追加コードを元のコードに注入するか、eBPF の場合はオペレーティングシステムを拡張することで、多かれ少なかれ同じ仕組みで動作します。 このブログ記事では、OpenTelemetry PHP 自動計装で使用されている手法を紹介します。
前提条件
PHP 自動計装を使用するには、次の3つが必要です。
- 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
この記事の執筆時点で、Observability API は C 拡張によって使用されており、以下のインターフェイスを持つ1つの関数を公開しています。
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 リポジトリの一部である最も重要な interfaces/libraries/frameworks のいくつかに対してトレーシングサポートを実装しました。
各 auto-instrumentation パッケージは、上述の hook 関数を使用してトレーシング機能を登録し提供します。
まだ言及していないものとして、トレースやその他の必要なコンポーネントを作成するために使用される API SDK があります。
これは opentelemetry-php の main リポジトリの責務であり、すべての基盤となっています。

使い方
自動計装に必要なすべてのコンポーネントは手動でインストールできますが、参入障壁を下げるために時間を投資し、それをかわりに行ってくれるインストーラーを作成しました。
このセクションでは、ゼロから作成したシンプルな PHP laravel アプリケーションを自動計装する方法を示します。
最初のステップは、デモアプリケーションを作成することです。 ここでは人気のある Laravel フレームワークを使用します。
composer create-project laravel/laravel example-app
次に、opentelemetry-instrumentation-installer をインストールします。
cd example-app
composer require open-telemetry/opentelemetry-instrumentation-installer
OpenTelemetry 計装インストーラーには2つのモードがあります。
- basic(最新バージョンですべてをインストール)
- advanced(ユーザーに制御を委ねる)
インストール後、以下のように basic または advanced スイッチを指定して 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 で以下のような結果が表示されるはずです。

現在のステータスと今後のステップ
必要なコンポーネントはすべて揃っています。
- OpenTelemetry 仕様の基盤および実装としての API と SDK。
- 自動計装の基盤としての C 拡張。
- 最も重要で人気のあるライブラリやフレームワークに対する自動計装サポート(WIP)。
- 任意のコードを計装することに関心のあるユーザーや開発者の障壁を下げるための開発ツール。
- ドキュメント
私たちの目標の1つは、この取り組みの認知度を高め、改善、カバレッジの拡大、バグ修正を支援してくれるより多くの人々を巻き込むことです。
ぜひ試してフィードバックをお寄せください。 問題が発生した場合は、イシューを開くことができます。 質問がありましたら、CNCF の #otel-php Slack チャンネルでお気軽にお問い合わせいただくか、OTel 公開カレンダーで確認できる SIG ミーティングにご参加ください。