OpenTelemetry PHP サービスオブザーバビリティ実践ガイド¶
はじめに¶
本稿では、GuanceCloud/opentelemetry-php-instrumentation をベースに PHP サービスを Guance に接続し、ログ、PHP-FPM メトリクス、プロファイリングを補完することで、すぐに導入可能な可観測性ソリューションを構築する方法を解説します。
このソリューションは、PHP-FPM、CLI Worker、Supervisor、コンテナ内の PHP プロセスなど、一般的なデプロイ環境に適しています。トレースデータは、まず DataKit 4317 ポート経由の OTLP gRPC で送信することを推奨します。結合テストやトラブルシューティングの段階では、一時的に 9529/otel の HTTP OTLP 方式に切り替えて、トレースが確立されていることを確認できます。
環境情報¶
- システム環境:Linux
- 開発言語:PHP 8.2
- デプロイ方式:PHP-FPM / CLI
- APM 拡張:
GuanceCloud/opentelemetry-php-instrumentation 1.3.1-gtrace - コレクター:DataKit
実現目標¶
- アプリケーショントレースの接続
- アプリケーションログの接続
- PHP-FPM メトリクスの接続
- プロファイリングの接続(オプション)
接続ソリューション¶
GuanceCloud Fork に関する説明¶
本稿で解説する接続方式は、GuanceCloud/opentelemetry-php-instrumentation に基づいています。これは OpenTelemetry 公式リポジトリからフォークされた拡張リポジトリです。
ここで明確にすべき境界が 2 つあります。
- 拡張の入手元としては、
GuanceCloudフォークのリリースアセットを使用できます。 composer requireでインストールするopen-telemetry/sdk、open-telemetry/exporter-otlp、open-telemetry/opentelemetry-auto-*は引き続き公式の PHP パッケージです。
つまり、現在のフォークの変更は主に PHP 拡張層に限定されており、PHP SDK、exporter、auto instrumentation のエコシステム全体がフォークされているわけではありません。
コンポーネント一覧¶
OpenTelemetry PHP を導入するには、少なくとも以下のコンポーネントが必要です。
- DataKit:トレース、ログ、メトリクス、プロファイルデータを受信
- PHP
opentelemetry拡張:自動インストルメンテーション機能を提供 - OpenTelemetry PHP SDK:データの構築とエクスポートを担当
- OTLP Exporter:
gRPCまたはHTTP経由で DataKit にデータを送信 - 対応するフレームワークまたはコンポーネントのインストルメンテーションライブラリ:Laravel、Slim、Symfony、PDO、Guzzle などの自動インストルメンテーションを担当
opentelemetry 拡張をインストールするだけでは不十分で、プロジェクト内に SDK + exporter + 対応する自動インストルメンテーションパッケージ をインストールする必要があります。そうしないと、拡張が読み込まれても、完全なトレースデータを生成できません。
準備¶
DataKit のインストール¶
ホストに DataKit をインストールし、127.0.0.1:4317 または 127.0.0.1:9529 にアクセスできることを確認します。
OpenTelemetry コレクターの有効化¶
DataKit のインストールディレクトリに移動し、サンプル設定をコピーして DataKit を再起動します。
mkdir -p /usr/local/datakit/conf.d/opentelemetry
cp /usr/local/datakit/conf.d/samples/opentelemetry.conf.sample \
/usr/local/datakit/conf.d/opentelemetry/opentelemetry.conf
systemctl restart datakit
DataKit が正常に動作していることを確認します。
Warning
アプリケーションが http://127.0.0.1:9529/otel/v1/traces に送信して 404 が返る場合、通常は PHP 側の問題ではなく、DataKit の opentelemetry 入力が実際に有効になっていないことが原因です。まず opentelemetry.conf が存在し、DataKit の再起動後に反映されているかを確認してください。
トレースの接続¶
1. OTEL 拡張のインストールと有効化¶
OpenTelemetry 公式のゼロコードドキュメントに従い、最も簡単な方法は、最初からコンパイルを行うのではなく、「システムパッケージ」または「イメージインストール」を優先することです。
推奨される順序は以下の通りです。
- Linux パッケージマネージャーによるインストール
- Docker イメージによるインストール
- ホストに
peclが既にある場合はpeclを使用 - 最後にソースコードからのコンパイルを検討
Warning
Linux ホストに必ず pecl があると仮定しないでください。例えば、本稿で検証に使用したホスト(2026-07-30 時点)では、phpize は存在するが pecl は存在しない状態でした。
また、yum install php-pecl-opentelemetry や pecl install opentelemetry でインストールされるのは、通常、公式の upstream 拡張であり、GuanceCloud フォークの gtrace バージョンではないことに注意してください。1.3.1-gtrace を検証または導入する場合は、インストール元を GuanceCloud フォークのリリースアセットまたは社内のビルド成果物に変更する必要があります。
ディストリビューションにパッケージが用意されている場合は、そちらを優先してインストールしてください。
CentOS/RHEL 系のシステムでは、公式が推奨する Remi リポジトリ方式が利用できます。
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
Alpine では、APK パッケージを直接インストールできます。
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
apk add php php81-pecl-opentelemetry@testing
php --ri opentelemetry
Docker 公式 PHP イメージの場合:
ホストに既に pecl がインストールされている場合は、直接実行できます。
ホストに pecl がない場合は、以下のいずれかの方法を優先してください。
- プラットフォーム側で PHP バージョンに適合した
opentelemetry.soを直接提供する - システムパッケージマネージャーを使用してインストールする
- コンテナイメージ内で
install-php-extensionsを使用してインストールする
GuanceCloud フォークの場合、現在のエンタープライズ導入では以下の方法が推奨されます。
- Windows:リリースに含まれている zip アセットを直接使用する
- Linux:CI で対応する PHP マイナーバージョンの
opentelemetry.soをビルドし、運用チームや成果物リポジトリから一元的に配布する
これにより、インストールされる拡張が確実に gtrace バージョンであり、公式の upstream 拡張ではないことが保証されます。
Windows:
GuanceCloud/opentelemetry-php-instrumentationの Release ページから、現在の PHP マイナーバージョン、ts/nts、コンパイラに一致する zip パッケージをダウンロードします。php_opentelemetry.dllを PHP のext/ディレクトリに配置します。php.iniで拡張を有効にします。
どの方法を選択する場合でも、拡張パッケージを選択する際には、以下の条件を厳密に一致させる必要があります。
- PHP マイナーバージョン(例:
8.1/8.2/8.3/8.4) ts/nts- プラットフォームとコンパイラ
- 対象の実行方式に対応する PHP バイナリ
php.ini で拡張を有効にします。
拡張が読み込まれていることを確認します。
2. SDK と自動インストルメンテーション依存関係のインストール¶
公式ドキュメントの重要なポイントは、拡張自体をインストールするだけではトレースは生成されないことです。プロジェクト内に SDK + exporter + instrumentation libraries をインストールする必要があります。
Slim + PSR-18 を例にとると、最小限の依存関係は以下の通りです。
composer config allow-plugins.php-http/discovery false
composer require \
open-telemetry/sdk \
open-telemetry/exporter-otlp \
php-http/guzzle7-adapter \
nyholm/psr7
アプリケーションが Slim ではなく、他のフレームワークやコンポーネントを使用している場合は、実際の技術スタックに応じて対応する自動インストルメンテーションパッケージをインストールしてください。一般的な例は以下の通りです。
# PSR-18 HTTP Client
composer require open-telemetry/opentelemetry-auto-psr18
# Slim
composer require open-telemetry/opentelemetry-auto-slim
# Laravel
composer require open-telemetry/opentelemetry-auto-laravel
# Symfony
composer require open-telemetry/opentelemetry-auto-symfony
# PDO
composer require open-telemetry/opentelemetry-auto-pdo
# Guzzle
composer require open-telemetry/opentelemetry-auto-guzzle
最小限の原則は以下の通りです。
- 拡張がインストールされていること
sdkがインストールされていることexporter-otlpがインストールされていること- 現在のフレームワークとミドルウェアに一致する
auto-*パッケージがインストールされていること
これらが不足していると、不完全または空のトレースデータしか得られません。
3. トレース送信パラメータの設定¶
OTLP gRPC を使用して、ローカルの DataKit の 4317 ポートに直接接続することを推奨します。
OTEL_PHP_AUTOLOAD_ENABLED=true \
OTEL_SERVICE_NAME=my-php-service \
OTEL_SERVICE_VERSION=1.3.1-gtrace \
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=prod \
OTEL_TRACES_EXPORTER=otlp \
OTEL_METRICS_EXPORTER=none \
OTEL_LOGS_EXPORTER=none \
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317 \
OTEL_PROPAGATORS=baggage,tracecontext
トラブルシューティングの際は、HTTP OTLP に切り替えることもできます。
PHP-FPM、Apache、Supervisor、systemd、またはコンテナで PHP を起動する場合は、これらの環境変数を現在のシェルセッションだけでなく、プロセスの起動環境に設定してください。
推奨される最小構成は以下の通りです。
OTEL_PHP_AUTOLOAD_ENABLED=true
OTEL_SERVICE_NAME=my-php-service
OTEL_SERVICE_VERSION=1.3.1-gtrace
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=none
OTEL_LOGS_EXPORTER=none
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317
環境を区別する必要がある場合は、以下を追加します。
4. ビジネスロジックへのインストルメンテーション追加¶
フレームワークの自動インストルメンテーションは、一般的なエントリポイントのみをカバーします。注文、支払い、外部API呼び出し、バッチ処理などの重要なビジネスロジックには、WithSpan を使用してインストルメンテーションを追加することを推奨します。
<?php
declare(strict_types=1);
use OpenTelemetry\API\Instrumentation\SpanAttribute;
use OpenTelemetry\API\Instrumentation\WithSpan;
#[WithSpan('order.submit')]
function submitOrder(#[SpanAttribute] string $orderNo): void
{
// ビジネスロジック
}
ログの接続¶
アプリケーションは JSON 形式のログを出力し、service、env、version を明示的に書き込むことを推奨します。ログとトレースを連携させる必要がある場合は、現在の trace_id と span_id を合わせて出力します。
use OpenTelemetry\API\Trace\Span;
$context = Span::getCurrent()->getContext();
$traceId = $context->isValid() ? $context->getTraceId() : '';
$spanId = $context->isValid() ? $context->getSpanId() : '';
DataKit 側で logging コレクターを有効にします。設定例は以下の通りです。
[[inputs.logging]]
logfiles = ["/var/log/php-app/*.log"]
source = "php"
service = "my-php-service"
pipeline = "php-json.p"
ログフィールドには、少なくとも以下を含めることを推奨します。
messagestatusserviceenvversiontrace_idspan_id
PHP-FPM メトリクスの接続¶
アプリケーションが PHP-FPM で動作している場合は、phpfpm コレクターも有効にすることを推奨します。
www.confでステータスページを有効にします。
-
Nginx または Apache で
/statusを公開します。 -
DataKit で
phpfpmコレクターを有効にします。
これにより、以下の項目を同時に監視できます。
- アクティブプロセス数
- アイドルプロセス数
- 接続キューの長さ
- スローリクエスト数
- プロセスあたりのリクエスト処理時間とメモリ消費
プロファイリングの接続(オプション)¶
トレースに加えて、CPU、メモリ割り当て、ホットスポット関数を特定する必要がある場合は、PHP プロファイリングを個別に有効にできます。
現在のより確実な方法は以下の通りです。
- DataKit で
profileコレクターを有効にします。 - PHP に
dd-trace-phpをインストールし、プロファイリングを有効にします。 - PHP プロセスに以下の環境変数を設定します。
DD_PROFILING_ENABLED=true
DD_SERVICE=my-php-service
DD_ENV=prod
DD_VERSION=1.3.1-gtrace
DD_AGENT_HOST=127.0.0.1
DD_TRACE_AGENT_PORT=9529
プロファイリングはトレースの補完的な機能であり、必要に応じて有効にし、すべてのサービスでデフォルトで有効にする必要はありません。
最小限の接続手順¶
まずトレースを動作させ、その後他の観測データを段階的に追加することを目標とする場合は、以下の順序で接続することを推奨します。
- DataKit の
opentelemetry入力を有効にする - PHP
opentelemetry拡張をインストールして有効にする - プロジェクト内に
sdk + exporter-otlp + 対応する auto-*依存関係をインストールする OTEL_*プロセス環境変数を設定する- 実際のリクエストを1回実行し、トレースが Guance に到達したことを確認する
- その後、ログ収集、PHP-FPM メトリクス、プロファイリングを追加する
これにより、トレースの結合テスト手順を最小限に抑え、最初から多くのコンポーネントを同時に処理する必要がなくなります。
現在のフォークの不足点¶
OpenTelemetry 公式のゼロコードエクスペリエンスに完全に準拠する場合、現在の GuanceCloud フォークにはいくつかの明らかなギャップがあります。
- Linux 用の事前ビルド済みバイナリアセットが用意されておらず、Linux 側のインストールパスがまだ十分に短くない
- 独立して識別可能なパッケージ配布チャネルがなく、
pecl install opentelemetryは upstream にインストールされ、gtraceにはインストールされない - リリースアセットと公式ドキュメントの「システムパッケージインストール」パスが完全に統合されておらず、ドキュメントは公式のインストールコマンドをそのままコピーできない
- 「拡張はフォークから提供されるが、SDK と auto instrumentation の依存関係は引き続き公式の Composer パッケージから提供される」ことを個別に説明する必要がある
今後、接続体験をさらに最適化する場合、優先順位は以下のようになります。
- Linux 向けに、一般的な PHP マイナーバージョンの事前ビルド済み拡張アセットを追加する
- PHP バージョン、
ts/nts、拡張ディレクトリを自動的に識別するインストールスクリプトを提供する - リリースページに、「どの PHP バージョン/実行モードに対応しているか」を明確に示すアセット説明を固定で提供する
- フォークの README で、「upstream インストールパス」と「GuanceCloud gtrace インストールパス」を明確に区別する
実践効果¶
上記の接続を完了すると、通常、以下の観測機能が得られます。
- アプリケーションパフォーマンスモニタリング(APM)で、PHP サービスのエントリポイントリクエスト、データベース呼び出し、ダウンストリーム HTTP 呼び出しなどのトレース情報を確認できる
- ログを
service/env/versionでフィルタリングし、trace_idに基づいて同じリクエストをトレースバックできる - インフラストラクチャまたはカスタムビューで、PHP-FPM のアクティブプロセス、キューイング、スローリクエストなどの実行状態を監視できる
- プロファイリングビューで、CPU ホットスポット、メモリ割り当てホットスポット、スロー関数を特定できる
ベストプラクティス¶
- リソース属性を統一する:少なくとも
service.name、service.version、deployment.environmentを固定する - リリース命名を統一する:拡張バージョン、アプリケーションバージョン、リリースタグは可能な限り一致させ、バージョンのトレースバックを容易にする
4317/gRPCを優先して使用する:本番環境ではOTLP gRPCを優先し、9529/otelは結合テストやトラブルシューティングに適している- 既存のインストール方法を優先する:イメージへの事前インストール、ビルド済み成果物の配布、または
peclが利用可能な環境でのPECLインストールを優先し、ソースコードからのコンパイルを主な推奨パスとしない - プロセスレベルの環境変数を使用する:
OTEL_*をログインシェルだけで設定するのではなく、php-fpm、systemd、コンテナ、または起動スクリプトに書き込む - 属性のカーディナリティを制御する:電話番号、注文番号の全集、生の SQL、長すぎる URL などをスパン属性に大量に書き込まない
- 重要なビジネスロジックには手動でインストルメンテーションを追加する:自動インストルメンテーションでカバーできないビジネスロジックには、
WithSpanを使用して正確に補完する - ログにトレースフィールドを保持する:
trace_id/span_idを統一して出力しないと、ログとトレースを安定して連携できない - 最初に DataKit 入力を確認する:トレースが到達しない場合、
opentelemetry、logging、phpfpm、profileコレクターが有効になっているかを最初に確認する