WordPressでエラーが起きているときにwp-config.phpのWP_DEBUG定義をtrueにするとエラーがページに出力されてしまうため、実運用しているサーバではWP_DEBUGをtrueにしづらい。そこでページ内ではなく外部ファイルにエラーを出力できないものかと考えた。
WordPress内部ではエラーの出力にerror_logを使っているだけなので、出力先はphp.iniによって設定を変えることで可能である。レンタルサーバなどではphp本体の設定は変更できないのでini_setなどを使って、動的に設定を変更することになる。
実はWordPressはこの要求を設定で満たすことができて、
ini_set('display_errors', 0);
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
という設定をwp_config.phpにいれてあげればいいということがわかった。
WP_DEBUGでソースを検索したところWordPressではWP_DEBUGがtrueの場合以下のようなコードが実行される。
if ( WP_DEBUG_DISPLAY )
ini_set( 'display_errors', 1 );
if ( WP_DEBUG_LOG ) {
ini_set( 'log_errors', 1 );
ini_set( 'error_log', WP_CONTENT_DIR . '/debug.log' );
}
実はWP_DEBUG_LOGの定義をtrueにすることで WP_CONTENT_DIR . '/debug.log'、つまりwp-content/debug.logにエラーを出力する設定にできたのである。
またその前のコードを見るとWP_DEBUG_DISPLAYによって画面(ページ)にエラーを出力するかどうかが設定されているので WP_DEBUG_DISPLAY を false すればページに出力されない。
ただし、厳密にはWP_DEBUG_DISPLAY=falseでは「ページ出力を有効にする」処理(ini_set( 'display_errors', 1 ))を実行しない、ということであって明示的に無効にしてくれるわけではないので事前にini_set('display_errors', 0);を呼んでおく方が安心だろうと判断した。
しかしこの方法だと運用サーバではwp_contentに書き込み権限を加えないといけないし、wp_content/debug.logファイルは普通にテキストファイルとしてウェブサーバに公開されてしまうため好ましくない。
そこで、wp_content/debug.logではなく任意のファイルに出力することを考えてWP_DEBUG_LOGを有効にしないで、WordPressの代わりにini_setでerror_logにパスを設定することにした。
したがって最終的には以下のような設定を追加することにした。(この設定は /var/log/php_wp_error.log にWordPressのログが出力される)
ini_set('display_errors', 0);
ini_set("log_errors", 1);
ini_set("error_log", "/var/log/php_wp_error.log");
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);
WP_DEBUGを有効にするとエラーレベルが変更されてしまうので致命的なエラーを出力するだけなら、WordPressに頼らずに以下のように設定できる。(WP_DEBUGが無効であればWP_DEBUG_DISPLAYやWP_DEBUG_LOGの設定は参照されない)
ini_set('display_errors', 0);
ini_set("log_errors", 1);
ini_set("error_log", "/var/log/php_wp_error.log");
define('WP_DEBUG', false);
WP_DEBUGが有効な場合はエラーレベルが変更され無視しても実行上は問題ない警告もたくさん出力されてしまう。そうすると知らない間にログファイルが肥大化してしまうため、WP_DEBUGやWP_DEBUG_LOGを使ってログをファイルに出力するのは何かを調査したいときだけにするのが良いと思われる。