OpenTelemetry SDK for PHP でメトリクスをエクスポートする際のパフォーマンス劣化について調べてみた

OpenTelemetry SDK for PHP でメトリクスをエクスポートする際のパフォーマンス劣化について調べてみた

PHPアプリケーションでOpenTelemetry SDKを使ってメトリクスをエクスポートする際、同期処理の特性によりパフォーマンス問題が発生する可能性があります。 この記事ではOpenTelemetry Laravel auto-instrumentationを利用しつつ、メトリクスをエクスポートする際のタイムアウトやリトライ関連のパラメータを調整することでパフォーマンス問題が抑えられないか検証してみました
2025.11.13

リテールアプリ共創部@大阪の岩田です。

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.

https://opentelemetry.io/docs/languages/php/exporters/#minimizing-export-delays

よくあるNginx ✕ PHP-FPMの構成のWebアプリケーションについて考えると、Opentelemetryを使わない場合は以下のようなシーケンスでユーザーからのリクエストを処理します。

php-fpmの処理シーケンス.png

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

OTEL Collectorを利用する場合のシーケンス.png

このオーバーヘッドに対する対策として、上記公式ドキュメントには以下のような記述もあります。

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()を呼び出してユーザーに対してはさっさとレスポンスを返却してからメトリクスをエクスポートすればユーザー影響を最小限に抑えられるということですね。シーケンスにすると以下のイメージです。

fastcgi_finish_requestする場合のシーケンス.png

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

やってみる

検証用の構成

検証用に以下の流れでメトリクスをエクスポートする構成を組みました。

検証用の構成.png

メトリクスをエクスポートする際の遅延を擬似的に再現するため、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関連の処理を記述します。

instrument.php
<?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にトレースデータをエクスポートしているだけなので、ユーザーリクエストへの応答を遅延させるぐらいならトレースデータの欠落を許容してさっさと処理を進めたいです。ということでエクスポート処理のタイムアウト関連設定を調整してみます。

PsrTransportFactorycreate()を呼びだす際、第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"

エクスポート処理がリトライされているようですね。

https://github.com/open-telemetry/opentelemetry-php/blob/89ca91d94236ff273b81e6cbc0c1a5ddcd40eecd/src/SDK/Common/Export/Http/PsrTransportFactory.php#L32-L42

ソースコードを見るとPsrTransportFactorycreate()を呼ぶ際の第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の場合はこういう考慮も必要ですね。オブザーバビリティを向上させるための施策がユーザー体験の悪化につながるのは本末転倒なので、メトリクスの重要性や優先度を考慮して最適な実装を心がけたいです。

参考

この記事をシェアする

FacebookHatena blogX

関連記事