PHP エラーと Monolog レベルの対応 | Symfony7
PHP エラーと Monolog レベルの対応
対象: Symfony 7.4 / MonologBundle(
symfony/error-handlerのソースで確認)
例外化の仕組みは Symfony のエラー処理 を参照してください。
PHP 側の設定
公式 Docker イメージ(php:8.4-fpm など)は、php.ini-development / php.ini-production を配置するだけで、既定では php.ini を有効にしません。そのため PHP の組み込み既定値が使われます。
| 設定 | 値(php.ini なしの場合) |
|---|---|
display_errors |
1(組み込み既定) |
log_errors |
1(組み込み既定) |
error_log |
未設定 |
error_reporting |
E_ALL |
[!NOTE] イメージ内の
error_log = /proc/self/fd/2は、php-fpm の設定(php-fpm.d/zz-docker.confの[global])であり、PHP のerror_log(php.ini)とは別物です。
実際の値は次のコマンドで確認できます。
docker run --rm php:8.4-fpm php -i | grep -E "^(display_errors|log_errors|error_log|error_reporting|Loaded Configuration File)"
error_reporting は Symfony が起動時に上書きします(E_ALL から Deprecated 系を除外)。詳細は Symfony のエラー処理 を参照してください。
Symfony のログレベル対応
PHP エラーを Monolog のレベルに変換するのは Monolog ではなく、Symfony の ErrorHandler です(ErrorHandler::$loggers の既定値)。
| PHP エラー定数 | 既定のログレベル |
|---|---|
E_DEPRECATED, E_USER_DEPRECATED |
info |
E_NOTICE, E_USER_NOTICE |
error |
E_WARNING, E_USER_WARNING, E_CORE_WARNING, E_COMPILE_WARNING |
error |
E_USER_ERROR, E_RECOVERABLE_ERROR |
critical |
E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR(Fatal 系) |
critical |
[!IMPORTANT]
- この表は、例外化されずにログだけ出力されるエラーに適用されます(例:
APP_DEBUG=falseの Warning・Notice)。例外化された場合は、キャッチされなければ「例外」としてログに出力されます。- 未キャッチ例外のログレベルは、コンソールでは
critical(Error thrown while running command ...)です。HTTP ではframework.exceptionsの設定や#[WithLogLevel]属性で決まります。- 変換表は
framework.php_errors.logに「E_*定数 => ログレベル」の配列を指定して変更できます。- PHP エラーのログは、既定でチャンネル
phpに出力されます。Deprecated 系は、deprecationチャンネルが定義されていればそちらに出力されます。
Monolog のハンドラー設定
ハンドラーごとに、処理するレベルとチャンネルを config/packages/monolog.yaml で指定します。以下は MonologBundle のレシピ(symfony/recipes)の構成です。
monolog.yaml
```yaml monolog: channels: - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists when@dev: monolog: handlers: main: type: stream path: "%kernel.logs_dir%/%kernel.environment%.log" level: debug channels: ["!event"] console: type: console process_psr_3_messages: false channels: ["!event", "!doctrine", "!console"] when@prod: monolog: handlers: main: type: fingers_crossed action_level: error handler: nested excluded_http_codes: [404, 405] channels: ["!deprecation"] buffer_size: 50 # How many messages should be saved? Prevent memory leaks nested: type: stream path: php://stderr level: debug formatter: monolog.formatter.json console: type: console process_psr_3_messages: false channels: ["!event", "!doctrine"] deprecation: type: stream channels: [deprecation] path: php://stderr formatter: monolog.formatter.json ```[!NOTE]
fingers_crossedはaction_level(ここではerror)以上のログが出たときに、それ以前にバッファしたログも含めてnestedに出力します。- 同じ出力先(例:
php://stderr)に、レベル違いのハンドラーを複数定義すると、該当するログが二重に出力されます。ハンドラーを分ける場合は、channelsで対象を分けてください。APP_DEBUG=falseの Warning・Notice はerrorレベルなので、上記のaction_level: errorにより出力対象になります。
確認方法
bin/console debug:config framework php_errors
bin/console debug:config monolog