OpenTelemetry SDK for PHP でメトリクスをエクスポートする際のパフォーマンス劣化について調べてみた
リテールアプリ共創部@大阪の岩田です。
OTEL SDKを利用したメトリクスのエクスポートはオブザーバビリティを確保するために有益な技術です。しかし、アプリケーションの本来やりたいこととは別にメトリクスを送信する処理が発生する関係上、パフォーマンスへの悪影響も考慮する必要があります。
特にPHPにおいてはランタイムの特性から他の言語よりも注意が必要になるため、考慮事項や設定を調整すべき点などをご紹介します。
環境
今回検証に利用した環境は以下の通りです。
- PHP: 8.4.7
- 各種ライブラリ
- laravel/framework: v12.22.0
- open-telemetry/api: 1.4.0
- open-telemetry/exporter-otlp: 1.2.0
- open-telemetry/opentelemetry-auto-laravel: 1.2.0
- open-telemetry/sdk: 1.6.0
- OpenTelemetry auto-instrumentation extension: 1.1.3
背景
PHPでOpentelemetryのSDKを利用する際の注意事項として公式ドキュメントに以下の記載があります。
Most PHP runtimes are synchronous and blocking. Sending telemetry data can delay HTTP responses being received by your users.
よくあるNginx ✕ PHP-FPMの構成のWebアプリケーションについて考えると、Opentelemetryを使わない場合は以下のようなシーケンスでユーザーからのリクエストを処理します。

前述のドキュメントの記載に沿って考えると、OpentelemetryのSDKを使ってメトリクスをエクスポートする場合のシーケンスは以下のようになり、メトリクスをエクスポートする処理の分オーバーヘッドが発生することになります。

このオーバーヘッドに対する対策として、上記公式ドキュメントには以下のような記述もあります。
If you are using fastcgi, you could issue a call to fastcgi_finish_request() after sending a user response, which means that delays in sending >telemetry data will not hold up request processing.
fastcgi_finish_request()を呼び出してユーザーに対してはさっさとレスポンスを返却してからメトリクスをエクスポートすればユーザー影響を最小限に抑えられるということですね。シーケンスにすると以下のイメージです。

ここまでの内容を踏まえ、単純にLaravel ✕ OpenTelemetry Laravel auto-instrumentationを使った場合にメトリクスのエクスポートによるパフォーマンス劣化が発生しないか気になったので検証してみました。
やってみる
検証用の構成
検証用に以下の流れでメトリクスをエクスポートする構成を組みました。

メトリクスをエクスポートする際の遅延を擬似的に再現するため、OTEL Collectorの前段にNginxを配置してLuaモジュールによる5秒のSleepを挟んでからOTEL Collectorにリバースプロキシします。これによりPHP-FPMからはメトリクスデータのエクスポートに5秒以上の時間を要しているように見えます。
Nginxの設定ファイルはこんな感じです。
location / {
access_by_lua_block {
ngx.sleep(5)
}
proxy_pass http://<OTEL Collector>:4318;
}
検証用コード
Laravelアプリケーションのソースコードは以下の通りです。
まずinstrument.phpというファイルにOTEL関連の処理を記述します。
<?php
require_once __DIR__.'/vendor/autoload.php';
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Sdk;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;
use OpenTelemetry\SemConv\ResourceAttributes;
$resource = ResourceInfo::create(Attributes::create([
ResourceAttributes::SERVICE_NAME => 'laravel-app',
ResourceAttributes::SERVICE_VERSION => env('OTEL_SERVICE_VERSION', '0.1'),
ResourceAttributes::DEPLOYMENT_ENVIRONMENT_NAME => env('APP_ENV', 'development'),
]));
$spanExporter = new SpanExporter(
(new PsrTransportFactory())->create( 'http://host.docker.internal:4319/v1/traces', 'application/json')
);
$tracerProvider = TracerProvider::builder()
->addSpanProcessor(
BatchSpanProcessor::builder($spanExporter)->build()
)
->setResource($resource)
->build();
Sdk::builder()
->setTracerProvider($tracerProvider)
->setPropagator(TraceContextPropagator::getInstance())
->setAutoShutdown(true)
->buildAndRegisterGlobal();
あとはこのファイルをbootstrap/app.phpからrequire_once()した上で、Hello World的な処理を実行する簡単なルートを定義すれば準備完了です。
まずは普通にcurlでアクセスしてみる
準備ができたのでcurlでテスト用のエンドポイントにアクセスしてみます。
time curl -s -o /dev/null http://localhost/api/hello
結果は以下の通りでした。
real 0m0.154s
user 0m0.013s
sys 0m0.021s
特にfastcgi_finish_request()を呼び出すコードは書いていないのですが、この結果を見る限りユーザーへのレスポンスを返却してからOTEL Collectorにメトリクスをエクスポートしているようですね。リバースプロキシとして利用したNginxのアクセスログやOTEL Collectorのデバッグログを見てもcurlコマンド実行の約5秒後にメトリクスがエクスポートされていると確認できました。OpenTelemetry Laravel auto-instrumentation側でユーザーへの影響が出ないようにうまく実装してくれているんでしょう!
この結果を見ると単純なパターンではメトリクスをエクスポートすることによるパフォーマンスの遅延は無視して良さそうですね。
PHP-FPMのプロセス数を1に制限してみる
単純なパターンでは特に問題が発生しませんでしたが、実際のワークロードはそう簡単な話ではありません。ユーザーに対するレスポンスはさっさと返却してくれましたがメトリクスのエクスポートに5秒以上所要しているのは事実です。この5秒間PHP-FPMのプロセスは同期処理を実行しているはずなので、アクセスが集中した場合にパフォーマンスの問題が顕在化しないかが気になります。
ということでPHP-FPMの設定を変更し、pm = staticかつpm.max_children = 1としました。これでPHP-FPMのプロセスは1つのみに制限されます。
続いてabコマンドで10リクエストを直列実行してみます。
ab -n 10 -c 1 http://localhost/api/hello
結果は以下の通りでした。
This is ApacheBench, Version 2.3 <$Revision: 1913912 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: nginx
Server Hostname: localhost
Server Port: 80
Document Path: /api/hello
Document Length: 2 bytes
Concurrency Level: 1
Time taken for tests: 46.463 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 2280 bytes
HTML transferred: 20 bytes
Requests per second: 0.22 [#/sec] (mean)
Time per request: 4646.276 [ms] (mean)
Time per request: 4646.276 [ms] (mean, across all concurrent requests)
Transfer rate: 0.05 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 118 4646 1591.0 5145 5176
Waiting: 118 4646 1591.0 5145 5176
Total: 119 4646 1591.0 5145 5176
Percentage of the requests served within a certain time (ms)
50% 5145
66% 5154
75% 5172
80% 5174
90% 5176
95% 5176
98% 5176
99% 5176
100% 5176 (longest request)
実行完了まで合計46秒程度かかっています。これは2~10回目のリクエストに関して直前のリクエストのメトリクス送信が完了するまで約5秒待たされていることが原因でしょう。これは望ましくないです。
abコマンドの-cオプションを5に変更して再度実行、並行してPHP-FPMのステータスページにアクセスしてみると以下の結果が返却されました。
pool: www
process manager: static
start time: 13/Nov/2025:02:33:36 +0000
start since: 15125
accepted conn: 56
listen queue: 5
max listen queue: 6
listen queue len: 4096
idle processes: 0
active processes: 1
total processes: 1
max active processes: 1
max children reached: 0
slow requests: 0
memory peak: 10485760
listen queueが5になっています。PHP-FPMのプロセスが1つしか起動していないため5つのリクエストがPHP-FPMのプロセスが空くのを待たされていることが分かります。
PHP-FPMのプロセス数を増やしてみる
メトリクスのエクスポート処理が遅延するとPHP-FPMのプロセス不足を引き起こし、雪だるま式に後続リクエストのレスポンスタイムが悪化することが分かりました。今度はPHP-FPMのプロセスを増やしてみましょう。
設定を以下のように変更しPHP-FPMを再起動します。
pm = dynamic
pm.max_children = 10
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 5
その後再度ab -n 10 -c 1 ... で10リクエストを送信し、結果を確認します。今度は以下の結果でした。
This is ApacheBench, Version 2.3 <$Revision: 1913912 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: nginx
Server Hostname: localhost
Server Port: 80
Document Path: /api/hello
Document Length: 2 bytes
Concurrency Level: 1
Time taken for tests: 6.609 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 2280 bytes
HTML transferred: 20 bytes
Requests per second: 1.51 [#/sec] (mean)
Time per request: 660.948 [ms] (mean)
Time per request: 660.948 [ms] (mean, across all concurrent requests)
Transfer rate: 0.34 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 30 661 453.2 989 1059
Waiting: 30 661 453.2 989 1059
Total: 30 661 453.2 990 1060
Percentage of the requests served within a certain time (ms)
50% 990
66% 998
75% 1002
80% 1013
90% 1060
95% 1060
98% 1060
99% 1060
100% 1060 (longest request)
トータル約6.6秒で完了しています。PHP-FPMのログは以下の通りで、プロセスの不足に応じて新たなプロセスが生成されていることが分かります。
172.18.0.5 - 13/Nov/2025:06:53:07 +0000 "GET /index.php" 200
172.18.0.5 - 13/Nov/2025:06:53:07 +0000 "GET /index.php" 200
172.18.0.5 - 13/Nov/2025:06:53:08 +0000 "GET /index.php" 200
172.18.0.5 - 13/Nov/2025:06:53:09 +0000 "GET /index.php" 200
[13-Nov-2025 06:53:10] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, and 4 total children
172.18.0.5 - 13/Nov/2025:06:53:10 +0000 "GET /index.php" 200
[13-Nov-2025 06:53:11] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 0 idle, and 5 total children
172.18.0.5 - 13/Nov/2025:06:53:11 +0000 "GET /index.php" 200
[13-Nov-2025 06:53:12] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 6 total children
172.18.0.5 - 13/Nov/2025:06:53:12 +0000 "GET /index.php" 200
172.18.0.5 - 13/Nov/2025:06:53:12 +0000 "GET /index.php" 200
172.18.0.5 - 13/Nov/2025:06:53:12 +0000 "GET /index.php" 200
[13-Nov-2025 06:53:13] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 7 total children
172.18.0.5 - 13/Nov/2025:06:53:13 +0000 "GET /index.php" 200
メトリクスエクスポート処理のタイムアウト値を調整してみる
PHP-FPMのプロセスを増やせばエクスポート処理の遅延にも対応できそうです。しかし、プロセスを無限に増やすわけにはいかないため、どこかでプロセス数の上限に達してPHP -FPMのListenキューが「詰まる」ことが想定されます。
扱うメトリクスの特性にもよりますが、今回のソースコードはOTEL Collectorにトレースデータをエクスポートしているだけなので、ユーザーリクエストへの応答を遅延させるぐらいならトレースデータの欠落を許容してさっさと処理を進めたいです。ということでエクスポート処理のタイムアウト関連設定を調整してみます。
PsrTransportFactoryのcreate()を呼びだす際、第5引数でエクスポート処理のタイムアウト値が秒単位で指定できるので、これを0.1に指定してみます。
< (new PsrTransportFactory())->create(env('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'http://otel-collector:4318/v1/traces'), 'application/json')
---
> (new PsrTransportFactory())->create( 'http://host.docker.internal:4319/v1/traces', 'application/json', [], null, 0.1)
準備ができたので再度PHP-FPMの設定をpm = staticかつpm.max_children = 1に変更し、ab -c 1 -n 10で直列に10リクエストを発行してみます。結果は以下の通りです。
This is ApacheBench, Version 2.3 <$Revision: 1913912 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: nginx
Server Hostname: localhost
Server Port: 80
Document Path: /api/hello
Document Length: 2 bytes
Concurrency Level: 1
Time taken for tests: 9.504 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 2280 bytes
HTML transferred: 20 bytes
Requests per second: 1.05 [#/sec] (mean)
Time per request: 950.419 [ms] (mean)
Time per request: 950.419 [ms] (mean, across all concurrent requests)
Transfer rate: 0.23 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 331 950 223.3 1030 1088
Waiting: 331 950 223.3 1030 1088
Total: 331 950 223.3 1030 1088
Percentage of the requests served within a certain time (ms)
50% 1030
66% 1042
75% 1062
80% 1075
90% 1088
95% 1088
98% 1088
99% 1088
100% 1088 (longest request)
今度は約9.5秒で完了です。5秒のSleepを実行するためにはさんだNginxのログを見てみると、10リクエストに対して30行のログが出力されていました。
172.17.0.1 - - [13/Nov/2025:07:08:29 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:29 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:29 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:29 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:30 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:30 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:30 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:30 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:30 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:31 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:31 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:31 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:34 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:34 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:34 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:34 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:35 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:35 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:35 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:36 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:36 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:36 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:36 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:37 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:37 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:37 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:38 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:38 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:38 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:38 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:08:39 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
エクスポート処理がリトライされているようですね。
ソースコードを見るとPsrTransportFactoryのcreate()を呼ぶ際の第6引数でリトライ回数が指定できるようなので、これも0に変更してしまいます。
2c2
< (new PsrTransportFactory())->create( 'http://host.docker.internal:4319/v1/traces', 'application/json', [], null, 0.1)
---
> (new PsrTransportFactory())->create( 'http://host.docker.internal:4319/v1/traces', 'application/json', [], null, 0.1, 0, 0)
ここまで修正して再度abコマンドでテストすると...
This is ApacheBench, Version 2.3 <$Revision: 1913912 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: nginx
Server Hostname: localhost
Server Port: 80
Document Path: /api/hello
Document Length: 2 bytes
Concurrency Level: 1
Time taken for tests: 1.406 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 2280 bytes
HTML transferred: 20 bytes
Requests per second: 7.11 [#/sec] (mean)
Time per request: 140.639 [ms] (mean)
Time per request: 140.639 [ms] (mean, across all concurrent requests)
Transfer rate: 1.58 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 108 140 12.2 143 156
Waiting: 108 140 12.2 143 156
Total: 108 141 12.2 143 156
Percentage of the requests served within a certain time (ms)
50% 143
66% 143
75% 144
80% 145
90% 156
95% 156
98% 156
99% 156
100% 156 (longest request)
今度は1.4秒で終了しました!
タイムアウト値が100msなので期待通りの挙動になってそうですね。
Sleep用のNginxのログは以下の通りでした。
172.17.0.1 - - [13/Nov/2025:07:20:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:32 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
172.17.0.1 - - [13/Nov/2025:07:20:33 +0000] "POST /v1/traces HTTP/1.1" 499 0 "-" "GuzzleHttp/7"
今度は10行しかログが出力されておらずリトライしていないことが分かります。これでOTEL Collectorに起因してレスポンスが悪化するのを最小限に抑えられるようになりました!
まとめ
Node.jsなどでは雑に作ってもメトリクスのエクスポートが大きな遅延につながることは無いと思いますが、PHPの場合はこういう考慮も必要ですね。オブザーバビリティを向上させるための施策がユーザー体験の悪化につながるのは本末転倒なので、メトリクスの重要性や優先度を考慮して最適な実装を心がけたいです。







