コンテンツにスキップ

OpenTelemetry PHP サービスオブザーバビリティ実践ガイド


はじめに

本稿では、GuanceCloud/opentelemetry-php-instrumentation をベースに PHP サービスを Guance に接続し、ログ、PHP-FPM メトリクス、プロファイリングを補完することで、すぐに導入可能な可観測性ソリューションを構築する方法を解説します。

このソリューションは、PHP-FPMCLI WorkerSupervisor、コンテナ内の PHP プロセスなど、一般的なデプロイ環境に適しています。トレースデータは、まず DataKit 4317 ポート経由の OTLP gRPC で送信することを推奨します。結合テストやトラブルシューティングの段階では、一時的に 9529/otelHTTP 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/sdkopen-telemetry/exporter-otlpopen-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 が正常に動作していることを確認します。

curl http://127.0.0.1:9529/v1/ping
ss -lntp | grep -E '4317|9529'
Warning

アプリケーションが http://127.0.0.1:9529/otel/v1/traces に送信して 404 が返る場合、通常は PHP 側の問題ではなく、DataKit の opentelemetry 入力が実際に有効になっていないことが原因です。まず opentelemetry.conf が存在し、DataKit の再起動後に反映されているかを確認してください。

トレースの接続

1. OTEL 拡張のインストールと有効化

OpenTelemetry 公式のゼロコードドキュメントに従い、最も簡単な方法は、最初からコンパイルを行うのではなく、「システムパッケージ」または「イメージインストール」を優先することです。

推奨される順序は以下の通りです。

  1. Linux パッケージマネージャーによるインストール
  2. Docker イメージによるインストール
  3. ホストに pecl が既にある場合は pecl を使用
  4. 最後にソースコードからのコンパイルを検討
Warning

Linux ホストに必ず pecl があると仮定しないでください。例えば、本稿で検証に使用したホスト(2026-07-30 時点)では、phpize は存在するが pecl は存在しない状態でした。

また、yum install php-pecl-opentelemetrypecl 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 イメージの場合:

install-php-extensions opentelemetry

ホストに既に pecl がインストールされている場合は、直接実行できます。

pecl install opentelemetry

ホストに 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 で拡張を有効にします。

[opentelemetry]
extension=opentelemetry.so
opentelemetry.attr_hooks_enabled = On

拡張が読み込まれていることを確認します。

php --ri opentelemetry

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 に切り替えることもできます。

OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:9529/otel

PHP-FPMApacheSupervisorsystemd、またはコンテナで 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

環境を区別する必要がある場合は、以下を追加します。

OTEL_RESOURCE_ATTRIBUTES=deployment.environment=prod

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 形式のログを出力し、serviceenvversion を明示的に書き込むことを推奨します。ログとトレースを連携させる必要がある場合は、現在の trace_idspan_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"

ログフィールドには、少なくとも以下を含めることを推奨します。

  • message
  • status
  • service
  • env
  • version
  • trace_id
  • span_id

PHP-FPM メトリクスの接続

アプリケーションが PHP-FPM で動作している場合は、phpfpm コレクターも有効にすることを推奨します。

  1. www.conf でステータスページを有効にします。
pm.status_path = /status
  1. Nginx または Apache で /status を公開します。

  2. DataKit で phpfpm コレクターを有効にします。

[[inputs.phpfpm]]
  status_url = "http://127.0.0.1/status"
  use_fastcgi = false

これにより、以下の項目を同時に監視できます。

  • アクティブプロセス数
  • アイドルプロセス数
  • 接続キューの長さ
  • スローリクエスト数
  • プロセスあたりのリクエスト処理時間とメモリ消費

プロファイリングの接続(オプション)

トレースに加えて、CPU、メモリ割り当て、ホットスポット関数を特定する必要がある場合は、PHP プロファイリングを個別に有効にできます。

現在のより確実な方法は以下の通りです。

  1. DataKit で profile コレクターを有効にします。
  2. PHP に dd-trace-php をインストールし、プロファイリングを有効にします。
  3. 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

プロファイリングはトレースの補完的な機能であり、必要に応じて有効にし、すべてのサービスでデフォルトで有効にする必要はありません。

最小限の接続手順

まずトレースを動作させ、その後他の観測データを段階的に追加することを目標とする場合は、以下の順序で接続することを推奨します。

  1. DataKit の opentelemetry 入力を有効にする
  2. PHP opentelemetry 拡張をインストールして有効にする
  3. プロジェクト内に sdk + exporter-otlp + 対応する auto-* 依存関係をインストールする
  4. OTEL_* プロセス環境変数を設定する
  5. 実際のリクエストを1回実行し、トレースが Guance に到達したことを確認する
  6. その後、ログ収集、PHP-FPM メトリクス、プロファイリングを追加する

これにより、トレースの結合テスト手順を最小限に抑え、最初から多くのコンポーネントを同時に処理する必要がなくなります。

現在のフォークの不足点

OpenTelemetry 公式のゼロコードエクスペリエンスに完全に準拠する場合、現在の GuanceCloud フォークにはいくつかの明らかなギャップがあります。

  • Linux 用の事前ビルド済みバイナリアセットが用意されておらず、Linux 側のインストールパスがまだ十分に短くない
  • 独立して識別可能なパッケージ配布チャネルがなく、pecl install opentelemetry は upstream にインストールされ、gtrace にはインストールされない
  • リリースアセットと公式ドキュメントの「システムパッケージインストール」パスが完全に統合されておらず、ドキュメントは公式のインストールコマンドをそのままコピーできない
  • 「拡張はフォークから提供されるが、SDK と auto instrumentation の依存関係は引き続き公式の Composer パッケージから提供される」ことを個別に説明する必要がある

今後、接続体験をさらに最適化する場合、優先順位は以下のようになります。

  1. Linux 向けに、一般的な PHP マイナーバージョンの事前ビルド済み拡張アセットを追加する
  2. PHP バージョン、ts/nts、拡張ディレクトリを自動的に識別するインストールスクリプトを提供する
  3. リリースページに、「どの PHP バージョン/実行モードに対応しているか」を明確に示すアセット説明を固定で提供する
  4. フォークの README で、「upstream インストールパス」と「GuanceCloud gtrace インストールパス」を明確に区別する

実践効果

上記の接続を完了すると、通常、以下の観測機能が得られます。

  • アプリケーションパフォーマンスモニタリング(APM)で、PHP サービスのエントリポイントリクエスト、データベース呼び出し、ダウンストリーム HTTP 呼び出しなどのトレース情報を確認できる
  • ログを service/env/version でフィルタリングし、trace_id に基づいて同じリクエストをトレースバックできる
  • インフラストラクチャまたはカスタムビューで、PHP-FPM のアクティブプロセス、キューイング、スローリクエストなどの実行状態を監視できる
  • プロファイリングビューで、CPU ホットスポット、メモリ割り当てホットスポット、スロー関数を特定できる

ベストプラクティス

  • リソース属性を統一する:少なくとも service.nameservice.versiondeployment.environment を固定する
  • リリース命名を統一する:拡張バージョン、アプリケーションバージョン、リリースタグは可能な限り一致させ、バージョンのトレースバックを容易にする
  • 4317/gRPC を優先して使用する:本番環境では OTLP gRPC を優先し、9529/otel は結合テストやトラブルシューティングに適している
  • 既存のインストール方法を優先する:イメージへの事前インストール、ビルド済み成果物の配布、または pecl が利用可能な環境での PECL インストールを優先し、ソースコードからのコンパイルを主な推奨パスとしない
  • プロセスレベルの環境変数を使用する:OTEL_* をログインシェルだけで設定するのではなく、php-fpmsystemd、コンテナ、または起動スクリプトに書き込む
  • 属性のカーディナリティを制御する:電話番号、注文番号の全集、生の SQL、長すぎる URL などをスパン属性に大量に書き込まない
  • 重要なビジネスロジックには手動でインストルメンテーションを追加する:自動インストルメンテーションでカバーできないビジネスロジックには、WithSpan を使用して正確に補完する
  • ログにトレースフィールドを保持する:trace_id/span_id を統一して出力しないと、ログとトレースを安定して連携できない
  • 最初に DataKit 入力を確認する:トレースが到達しない場合、opentelemetryloggingphpfpmprofile コレクターが有効になっているかを最初に確認する

参考資料

フィードバック

このページは役に立ちましたか?