2012-01-24 11 views
8

私はすべての致命的なエラーを記録したい、タイムアウトしてもE_ERRORSのものも記録したい。私はset_error_handlerとシャットダウン関数を使用しますが、最後のものではスタックトレースを持つことができません。それを持つ方法はありますか?PHP:生産における致命的なエラーのログスタックトレース

運用環境でのみ発生するバグを解決するために、運用サーバーに致命的なエラーを記録したいと考えています。私は知っている、devのサーバー上でxdebugは十分でなければならないが、そうではありません。 xdebugを最低限有効にしてxdebugを使うこともできますし、スタックトレースをエラーログに追加するためのバージョンを削除することもできますか?

このコードは、1つのエラーが発生した場合、タイムアウトしてもエラー情報を表示します。 「FATAL」、すなわちトレースは、通常のチャネルを介して生成することができない、スクリプトの実行を意味すぐを停止するため

<?php 
function shutdown() 
{ 
    $a=error_get_last(); 
    if($a!==null) print_r($a); 
} 
register_shutdown_function('shutdown'); 

答えて

7

あなたは致命的なエラーのスタックトレースを取得することはありません。だから、あなたが例外をスローするカスタムエラーハンドラを設定している場合、それはPHP manualあたりとして致命的なエラーのために呼び出されることはありません。

次のエラーの種類は、ユーザーで扱うことができない 定義関数:E_ERRORを、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、 E_COMPILE_ERROR、をE_COMPILE_WARNING、とはset_error_handler()が呼び出され ファイルで育っE_STRICTのほとんど。致命的なエラー(本番環境ではオプションではありませんにdisplay_errorsを回すの短い、)で何が起こったかについての情報を取得するために

最も簡単な方法は、手動でシャットダウンハンドラでエラー情報を自分で構築することです。また、プロダクションサーバーでxdebugを使用しません...これは開発環境のデバッグ用であり、本番環境では不要なオーバーヘッドを追加します。あなたはPHP-FPMを使用することができますタイムアウトの最大実行を引くために

function shutdown() 
{ 
    if (! $err = error_get_last()) { 
    return; 
    } 

    $fatals = array(
    E_USER_ERROR  => 'Fatal Error', 
    E_ERROR   => 'Fatal Error', 
    E_PARSE   => 'Parse Error', 
    E_CORE_ERROR  => 'Core Error', 
    E_CORE_WARNING => 'Core Warning', 
    E_COMPILE_ERROR => 'Compile Error', 
    E_COMPILE_WARNING => 'Compile Warning' 
); 

    if (isset($fatals[$err['type']])) { 
    $msg = $fatals[$err['type']] . ': ' . $err['message'] . ' in '; 
    $msg.= $err['file'] . ' on line ' . $err['line']; 
    error_log($msg); 
    } 
} 
+0

注意'$ fatals'配列がありますが、実際にはカスタムエラーハンドラで正常に処理できます。 – rdlowrey

+0

私は、xdebugのような致命的なエラーをスタックトレースに取り込むだけのPHPモジュールを考えていましたが、より軽いです。私の探求は、生産上の致命的なエラーについてより多くの情報を持って、それらを修正する手助けをする方法です。 –

+0

@CédricGirardああ、私は参照してください。私は、致命的なエラーの大部分は、開発段階で取り除くことができるタイプのものだと思います。残りは異常な状態です(メモリが不足している、リクエストの途中でサーバーがスマートになっているなど)。これらの場合、私は常に、上記の方法がロギングに十分な情報を提供していることに気付きました。私はそれが致命的なエラー(私はそうすべきだと思う)で動作するかどうかを調べるためにテストしていませんが、['debug_print_backtrace'](http://www.php.net/manual/en/function。トレース・インフォメーション – rdlowrey

1

とフルスタックトレースをログに記録しますslowlog + request_slowlog_timeoutを設定します。

だから、あなたのシャットダウンハンドラを変更しますが、このような何かを行うことができます。

3

あなたがHHVMを使用している場合は、それが致命的なエラーに(スタックトレースで)エラーハンドラを呼び出す持っているあなたのphp.ini

hhvm.error_handling.call_user_handler_on_fatals = 1 

を設定することができます。 (more info

プロファイラーを使用することもオプションです。 XHProfを使用し、致命的なハンドラでxhprof_disable()を呼び出すと、スタックトレースに似たものが表示されることがあります。 (NOアイデアは、これは実際に動作しない場合。)

+0

HHVMオプションとリンクはまさに​​私が探していたものです。 –

0

これは私の作品(条件付きの内側に、それは、開発環境でのみ動作しますので):私は** E_USER_ERROR **中に投げた

if (function_exists('xdebug_break')) { 
    register_shutdown_function(function() { 
     if ($last_error = error_get_last()) { 
      xdebug_break(); 
     } 
    }); 
} 
関連する問題