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)。例外化された場合は、キャッチされなければ「例外」としてログに出力されます。
  • 未キャッチ例外のログレベルは、コンソールでは criticalError 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_crossedaction_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