OpenTelemetry を使用してアプリケーションをインストルメントし、トレースデータを Managed Service for OpenTelemetry にレポートすると、Managed Service for OpenTelemetry はアプリケーションの監視を開始します。アプリケーショントポロジー、トレース、異常トランザクション、低速トランザクション、SQL 分析など、アプリケーションのモニタリングデータを表示できます。このトピックでは、PHP 用 OpenTelemetry SDK を使用して PHP アプリケーションを自動または手動でインストルメントし、PHP アプリケーションのトレースデータをレポートする方法について説明します。
前提条件
背景情報
PHP 用 OpenTelemetry SDK を使用すると、異なるバージョンの PHP を使用して PHP アプリケーションを自動または手動でインストルメントできます。
PHP アプリケーションを自動的にインストルメントするには、PHP 8.0 以降を使用します。
PHP アプリケーションを手動でインストルメントするには、PHP 7.4 以降を使用します。
PHP 用 OpenTelemetry SDK は、複数のフレームワークに基づく自動インストルメンテーションをサポートしています。詳細については、「レジストリ」をご参照ください。
サンプルコード
サンプルコードは、php-demo からダウンロードできます。
OpenTelemetry PHP 拡張機能を使用してアプリケーションを自動的にインストルメントし、トレースデータをレポートする
このセクションでは、Slim フレームワークに基づいてサイコロをシミュレートする PHP アプリケーションを作成する方法について説明します。また、OpenTelemetry を使用してアプリケーションを自動的にインストルメントし、非侵入型でアプリケーションのトレースデータをレポートする方法についても説明します。このプロセス中に、OpenTelemetry はトレースデータとスパンデータを自動的に生成します。
OpenTelemetry は、Slim を含む複数のフレームワークに基づく自動インストルメンテーションをサポートしています。詳細については、「レジストリ」をご参照ください。
前提条件
PHP 8.0 以降、Composer、および PHP Extension Community Library (PECL) がインストールされていること。
手順
サイコロアプリケーションを作成します。
アプリケーションを初期化します。
mkdir <project-name> && cd <project-name> composer init \ --no-interaction \ --stability beta \ --require slim/slim:"^4" \ --require slim/psr7:"^1" composer update
アプリケーションコードを記述します。
<project-name> フォルダに index.php ファイルを作成し、次のコードを追加します。
次のサンプルコードは、サイコロを振り、1 ~ 6 の範囲の乱数を返すサイコロゲームをシミュレートします。
<?php use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; require __DIR__ . '/vendor/autoload.php'; $app = AppFactory::create(); $app->get('/rolldice', function (Request $request, Response $response) { $result = random_int(1,6); $response->getBody()->write(strval($result)); return $response; }); $app->run();
アプリケーションコードを記述した後、
php -S localhost:8080
コマンドを実行してアプリケーションを実行します。ブラウザでhttp://localhost:8080/rolldice
にアクセスします。
OpenTelemetry PHP 拡張機能をビルドします。
OpenTelemetry PHP 拡張機能のビルドに必要なツールをダウンロードします。
macOS
brew install gcc make autoconf
Linux(apt コマンド)
sudo apt-get install gcc make autoconf
PECL を使用して OpenTelemetry PHP 拡張機能をビルドします。
pecl install opentelemetry
成功応答の最後の数行は、次の出力のようになります。
Build process completed successfully Installing '/opt/homebrew/Cellar/php/8.2.8/pecl/20220829/opentelemetry.so' install ok: channel://pecl.php.net/opentelemetry-1.0.0beta6 Extension opentelemetry enabled in php.ini
オプション。OpenTelemetry PHP 拡張機能を有効にします。
前のステップで
Extension opentelemetry enabled in php.ini
メッセージが返された場合は、このステップをスキップします。次のコードを php.ini ファイルに追加します。
[opentelemetry] extension=opentelemetry.so
OpenTelemetry PHP 拡張機能がビルドされ、有効になっていることを確認します。
方法 1:
php -m | grep opentelemetry
予期される出力:
opentelemetry
方法 2
php --ri opentelemetry
予期される出力:
opentelemetry opentelemetry support => enabled extension version => 1.0.0beta6
PHP 用 OpenTelemetry SDK がサイコロアプリケーションで自動インストルメンテーションを実行するために必要な追加の依存関係を追加します。
# この操作には長い時間がかかります。コンソールに大量の情報が表示されます。 pecl install grpc composer config allow-plugins.php-http/discovery false composer require \ open-telemetry/sdk \ open-telemetry/opentelemetry-auto-slim \ open-telemetry/exporter-otlp \ php-http/guzzle7-adapter \ open-telemetry/transport-grpc
open-telemetry/sdk:PHP 用 OpenTelemetry SDK のパッケージ。
open-telemetry/opentelemetry-auto-slim:Slim フレームワークに基づく PHP 用 OpenTelemetry SDK の自動インストルメンテーションプラグイン。
open-telemetry/exporter-otlp:PHP 用 OpenTelemetry SDK が OpenTelemetry Protocol (OTLP) 経由でデータをレポートするために必要な依存関係。
アプリケーションを実行します。
次のコマンドを実行します。
env OTEL_PHP_AUTOLOAD_ENABLED=true \ OTEL_SERVICE_NAME=<your-service-name> \ OTEL_TRACES_EXPORTER=otlp \ OTEL_METRICS_EXPORTER=none \ OTEL_LOGS_EXPORTER=none \ OTEL_EXPORTER_OTLP_PROTOCOL=grpc \ OTEL_EXPORTER_OTLP_ENDPOINT=<endpoint> \ OTEL_EXPORTER_OTLP_HEADERS=Authentication=<token> \ OTEL_PROPAGATORS=baggage,tracecontext \ php -S localhost:8080
<your-service-name>:アプリケーションの名前。例:
php-demo
。<endpoint>:「前提条件」セクションで取得した gRPC エンドポイント。例:
http://tracing-analysis-dc-hz.aliyuncs.com:8090
。<token>:「前提条件」セクションで取得した認証トークン。
ブラウザで次の URL にアクセスします。
http://localhost:8080/rolldice
このページにアクセスするたびに、OpenTelemetry はトレースデータを自動的に生成し、Managed Service for OpenTelemetry にレポートします。
トレースデータを表示します。
Managed Service for OpenTelemetry コンソール にログインします。[アプリケーション] ページで、アプリケーションを見つけて名前をクリックします。アプリケーションの詳細ページで、アプリケーションのトレースデータを表示します。
PHP 用 OpenTelemery SDK を使用してアプリケーションを手動でインストルメントし、トレースデータをレポートする
このセクションでは、Slim フレームワークに基づいてサイコロをシミュレートする PHP アプリケーションを作成する方法について説明します。また、PHP 用 OpenTelemetry SDK を使用してアプリケーションを手動でインストルメントし、カスタム設定に基づいてアプリケーションのトレースデータをレポートする方法についても説明します。このプロセス中に、コードでスパンを作成し、スパンの属性、イベント、およびステータスを設定できます。
自動インストルメンテーションがビジネス要件を満たせない場合、またはビジネス要件に基づいて手動でインストルメンテーションを追加する場合は、アプリケーションを手動でインストルメントしてデータをレポートできます。
前提条件
PHP 7.4 以降、Composer、および PECL がインストールされていること。
手順
サイコロアプリケーションを作成します。
アプリケーションを初期化します。
mkdir <project-name> && cd <project-name> composer init \ --no-interaction \ --stability beta \ --require slim/slim:"^4" \ --require slim/psr7:"^1" composer update
アプリケーションコードを記述します。
<project-name> フォルダに index.php ファイルを作成し、次のコードを追加します。
次のサンプルコードは、サイコロを振り、1 ~ 6 の範囲の乱数を返すサイコロゲームをシミュレートします。
<?php use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; require __DIR__ . '/vendor/autoload.php'; $app = AppFactory::create(); $app->get('/rolldice', function (Request $request, Response $response) { $result = random_int(1,6); $response->getBody()->write(strval($result)); return $response; }); $app->run();
アプリケーションコードを記述した後、
php -S localhost:8080
コマンドを実行してアプリケーションを実行します。ブラウザでhttp://localhost:8080/rolldice
にアクセスします。
PHP 用 OpenTelemetry SDK の依存関係を追加します。
gRPC
トレースデータをレポートするための PHP HTTP クライアントライブラリをダウンロードします。
composer require guzzlehttp/guzzle
PHP 用 OpenTelemetry SDK のパッケージをダウンロードします。
composer require \ open-telemetry/sdk \ open-telemetry/exporter-otlp
gRPC 経由でデータをレポートするために必要な依存関係をダウンロードします。
pecl install grpc # gRPC がすでにダウンロードおよびインストールされている場合は、このステップをスキップします。 composer require open-telemetry/transport-grpc
HTTP
トレースデータをレポートするための PHP HTTP クライアントライブラリをダウンロードします。
composer require guzzlehttp/guzzle
PHP 用 OpenTelemetry SDK のパッケージをダウンロードします。
composer require \ open-telemetry/sdk \ open-telemetry/exporter-otlp
OpenTelemetry 初期化コードを記述します。
index.php ファイルと同じディレクトリに opentelemetry_util.php ファイルを作成します。
次のコードを opentelemetry_util.php ファイルに追加します。
gRPC
<?php use OpenTelemetry\API\Common\Instrumentation\Globals; use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator; use OpenTelemetry\Contrib\Otlp\SpanExporter; use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory; use OpenTelemetry\SDK\Resource\ResourceInfo; use OpenTelemetry\SDK\Resource\ResourceInfoFactory; use OpenTelemetry\SDK\Sdk; use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler; use OpenTelemetry\SDK\Trace\Sampler\ParentBased; use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessorBuilder; use OpenTelemetry\SDK\Trace\TracerProvider; use OpenTelemetry\SemConv\ResourceAttributes; use OpenTelemetry\Contrib\Grpc\GrpcTransportFactory; use OpenTelemetry\Contrib\Otlp\OtlpUtil; use OpenTelemetry\API\Signals; // PHP アプリケーションの初期化中に OpenTelemetry を初期化します。 function initOpenTelemetry() { // 1. OpenTelemetry リソースに関する情報を指定します。 $resource = ResourceInfoFactory::emptyResource()->merge(ResourceInfo::create(Attributes::create([ ResourceAttributes::SERVICE_NAME => '<your-service-name>', # 必須。アプリケーションの名前。 ResourceAttributes::HOST_NAME => '<your-host-name>' # オプション。ホスト名。 ]))); // 2. スパンデータをコンソールにエクスポートする SpanExporter を作成します。 // $spanExporter = new SpanExporter( // (new StreamTransportFactory())->create('php://stdout', 'application/json') // ); // 2. gRPC 経由でスパンデータをレポートする SpanExporter を作成します。 $headers = [ 'Authentication' => "<your-token>", ]; $transport = (new GrpcTransportFactory())->create('<grpc-endpoint>' . OtlpUtil::method(Signals::TRACE), 'application/x-protobuf', $headers); $spanExporter = new SpanExporter($transport); // 3. トレーサーを作成するためにグローバル TracerProvider を追加します。 $tracerProvider = TracerProvider::builder() ->addSpanProcessor( (new BatchSpanProcessorBuilder($spanExporter))->build() ) ->setResource($resource) ->setSampler(new ParentBased(new AlwaysOnSampler())) ->build(); Sdk::builder() ->setTracerProvider($tracerProvider) ->setPropagator(TraceContextPropagator::getInstance()) ->setAutoShutdown(true) // PHP アプリケーションの終了時に TracerProvider を自動的にシャットダウンするかどうかを指定します。これにより、すべてのトレースデータがレポートされます。 ->buildAndRegisterGlobal(); // TracerProvider をグローバルに追加します。 } ?>
<your-service-name>:アプリケーションの名前
<your-host-name>:ホスト名
<your-token>:gRPC 経由でデータをレポートするために使用される認証トークン
<grpc-endpoint>:gRPC 経由でデータをレポートするために使用されるエンドポイント
HTTP
<?php use OpenTelemetry\API\Common\Instrumentation\Globals; use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator; use OpenTelemetry\Contrib\Otlp\SpanExporter; use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory; use OpenTelemetry\SDK\Resource\ResourceInfo; use OpenTelemetry\SDK\Resource\ResourceInfoFactory; use OpenTelemetry\SDK\Sdk; use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler; use OpenTelemetry\SDK\Trace\Sampler\ParentBased; use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessorBuilder; use OpenTelemetry\SDK\Trace\TracerProvider; use OpenTelemetry\SemConv\ResourceAttributes; use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory; use OpenTelemetry\SDK\Common\Export\TransportFactoryInterface; // PHP アプリケーションの初期化中に OpenTelemetry を初期化します。 function initOpenTelemetry() { // 1. OpenTelemetry リソースに関する情報を指定します。 $resource = ResourceInfoFactory::emptyResource()->merge(ResourceInfo::create(Attributes::create([ ResourceAttributes::SERVICE_NAME => '<your-service-name>', # 必須。アプリケーションの名前。 ResourceAttributes::HOST_NAME => '<your-host-name>' # オプション。ホスト名。 ]))); // 2. (オプション)スパンデータをコンソールにエクスポートする SpanExporter を作成します。 // $spanExporter = new SpanExporter( // (new StreamTransportFactory())->create('php://stdout', 'application/json') // ); // 2. HTTP 経由でスパンデータをレポートする SpanExporter を作成します。 $transport = (new OtlpHttpTransportFactory())->create('<http-endpoint>','application/x-protobuf'); $spanExporter = new SpanExporter($transport); // 3. トレーサーを作成するためにグローバル TracerProvider を追加します。 $tracerProvider = TracerProvider::builder() ->addSpanProcessor( (new BatchSpanProcessorBuilder($spanExporter))->build() ) ->setResource($resource) ->setSampler(new ParentBased(new AlwaysOnSampler())) ->build(); Sdk::builder() ->setTracerProvider($tracerProvider) ->setPropagator(TraceContextPropagator::getInstance()) ->setAutoShutdown(true) // PHP アプリケーションの終了時に TracerProvider を自動的にシャットダウンするかどうかを指定します。これにより、すべてのトレースデータがレポートされます。 ->buildAndRegisterGlobal(); // TracerProvider をグローバルに追加します。 } ?>
<your-service-name>:アプリケーションの名前
<your-host-name>:ホスト名
<http-endpoint>:HTTP 経由でデータをレポートするために使用されるエンドポイント
アプリケーションコードを変更し、OpenTelemetry API を使用してスパンを作成します。
index.php ファイルに必要なパッケージをインポートします。
<?php use OpenTelemetry\API\Common\Instrumentation\Globals; use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Trace\TracerProvider; require __DIR__ . '/opentelemetry_util.php';
initOpenTelemetry メソッドを呼び出して OpenTelemetry を初期化します。この操作は、PHP アプリケーションの初期化中に実行する必要があります。
// OpenTelemetry を初期化します。アプリケーション名、トレースデータのエクスポートモード、トレースデータのレポートに使用するエンドポイントを指定し、グローバル TracerProvider を作成します。 initOpenTelemetry();
rolldice 操作を呼び出すときにスパンを作成します。
/** * 1. 操作の説明:サイコロを振り、1 ~ 6 の範囲の乱数を返すサイコロゲームをシミュレートします。 * スパンを作成し、スパンの属性、イベント、および属性を持つイベントを設定します。 */ $app->get('/rolldice', function (Request $request, Response $response) { // トレーサーを取得します。 $tracer = \OpenTelemetry\API\Globals::tracerProvider()->getTracer('my-tracer'); // スパンを作成します。 $span = $tracer->spanBuilder("/rolldice")->startSpan(); // スパンの属性を設定します。 $span->setAttribute("http.method", "GET"); // スパンのイベントを設定します。 $span->addEvent("Init"); // 属性を持つイベントを設定します。 $eventAttributes = Attributes::create([ "key1" => "value", "key2" => 3.14159, ]); // ビジネスコード。 $result = random_int(1,6); $response->getBody()->write(strval($result)); $span->addEvent("End"); // スパンを破棄します。 $span->end(); return $response; });
ネストされたスパンを作成します。
2 つのサイコロを振り、1 ~ 6 の範囲の乱数を返すサイコロゲームをシミュレートする rolltwodices 操作を作成します。
次のサンプルコードは、ネストされたスパンを作成する方法の例を示しています。
$app->get('/rolltwodices', function (Request $request, Response $response) { // トレーサーを取得します。 $tracer = \OpenTelemetry\API\Globals::tracerProvider()->getTracer('my-tracer'); // スパンを作成します。 $parentSpan = $tracer->spanBuilder("/rolltwodices/parent")->startSpan(); $scope = $parentSpan->activate(); $value1 = random_int(1,6); $childSpan = $tracer->spanBuilder("/rolltwodices/parent/child")->startSpan(); // ビジネスコード。 $value2 = random_int(1,6); $result = "dice1: " . $value1 . ", dice2: " . $value2; // スパンを破棄します。 $childSpan->end(); $parentSpan->end(); $scope->detach(); $response->getBody()->write(strval($result)); return $response; });
スパンを使用して、コードで発生した例外を記録します。
操作で例外が発生した場合をシミュレートする error 操作を作成します。
次のサンプルコードは、スパンを使用してコードで発生した例外を記録する方法の例を示しています。
$app->get('/error', function (Request $request, Response $response) { // トレーサーを取得します。 $tracer = \OpenTelemetry\API\Globals::tracerProvider()->getTracer('my-tracer'); // スパンを作成します。 $span3 = $tracer->spanBuilder("/error")->startSpan(); try { // コードで例外が発生した場合をシミュレートします。 throw new \Exception('exception!'); } catch (\Throwable $t) { // スパンの状態をエラーに設定します。 $span3->setStatus(\OpenTelemetry\API\Trace\StatusCode::STATUS_ERROR, "exception in span3!"); // スタック例外のトレースを記録します。 $span3->recordException($t, ['exception.escaped' => true]); } finally { $span3->end(); $response->getBody()->write("error"); return $response; } });
アプリケーションを実行します。
次のコマンドを実行します。
php -S localhost:8080
ブラウザで次の URL にアクセスします。
http://localhost:8080/rolldice http://localhost:8080/rolltwodices http://localhost:8080/error
ページにアクセスするたびに、OpenTelemetry はトレースデータを生成し、Managed Service for OpenTelemetry にレポートします。
トレースデータを表示します。
Managed Service for OpenTelemetry コンソール にログインします。[アプリケーション] ページで、アプリケーションを見つけて名前をクリックします。アプリケーションの詳細ページで、アプリケーションのトレースデータを表示します。