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-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 計装インストーラーには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 で以下のような結果が表示されるはずです。

laravel-auto

現在のステータスと今後のステップ

必要なコンポーネントはすべて揃っています。

  • OpenTelemetry 仕様の基盤および実装としての API と SDK。
  • 自動計装の基盤としての C 拡張。
  • 最も重要で人気のあるライブラリやフレームワークに対する自動計装サポート(WIP)。
  • 任意のコードを計装することに関心のあるユーザーや開発者の障壁を下げるための開発ツール。
  • ドキュメント

私たちの目標の1つは、この取り組みの認知度を高め、改善、カバレッジの拡大、バグ修正を支援してくれるより多くの人々を巻き込むことです。

ぜひ試してフィードバックをお寄せください。 問題が発生した場合は、イシューを開くことができます。 質問がありましたら、CNCF の #otel-php Slack チャンネルでお気軽にお問い合わせいただくか、OTel 公開カレンダーで確認できる SIG ミーティングにご参加ください。