キャッチオールまたは基本例外クラスで例外を記録する方が賢明ですか?


15

私はかなり大きなWebアプリをリファクタリングしています。主な問題の1つは、一貫性のないエラー処理であり、私は賢明な戦略を考え出そうとしています。set_error_handlerを介し、基本的にErrorExceptionsの PHPエラーを変換するカスタムエラーハンドラーと、Exceptionから直接継承するカスタムベース例外クラスを作成しました。

実稼働環境ではset_exception_handlerを介して汎用の例外catch-allを使用しており、例外ログ*をミックスに追加しようとしています。私のジレンマは、基本例外クラスまたはキャッチオールで実際のロギングを行う場所です。

私はそれをキャッチオールに記録するいくつかの理由を考えました:

  • 基本例外クラスの適切な子に変換する必要があるコードには、かなりの数の例外があります。それが起こるまで、すべての例外がログに記録されるわけではありません。
  • キャッチオールでそれを行う方が自然な感じがします。ベース例外クラスはそれ以上のことをすべきではありません。(それは単一の責任原則のことかもしれませんが、見当違いの感覚かもしれません)

基本例外クラスにログインする1つの理由:

  • 現在、キャッチオールは本番環境でのみ使用されています。他の環境(開発、テスト)で導入するのは簡単ですが、エラーは環境ごとに処理が異なるため、本番環境では404/503エラーページに変換されるため、いくつかの調整が必要になります。

例外をログに記録する場所について、受け入れられるプラクティスはありますか?

*ロギングには最初はテキストファイルへの書き込みが含まれますが、特定の種類の例外のメールを送信するように進化する場合があります。


@unholysamplerの答えに促されたいくつかの説明:

私は2 * 10 ^ 6のslocコードベースに直面しており、多くのサードパーティのものを制御できません。また、PHPの前日例外を制御するコードの一部もあります。また、最近のくだらないコードもいくつかあります。私たちは、思考をやめ、ハッキングされなければならなかった激しいプレッシャーから長期間回復しています。

すべての矛盾に対処し、適切なエラー処理アプローチを導入するために積極的にリファクタリングを行っていますが、それには時間がかかります。エラーが適切に処理されるようになるまで、どうすればいいのか興味があります。おそらく、ある時点で賢明な例外戦略について別の質問をするでしょう。

ロギングの背後にある主な動機は、本番環境で何か悪いことが起こったときに電話でメールを受け取ることです。データダンプが巨大になるかどうかは気にしません。データダンプが大きくなると、古いジョブを時々削除するcronジョブが必要になります。

回答:


11

つまり、例外の存在をログに記録する必要があるのは、例外を処理しているときだけです。

例外をスローするのは、コードが正しく処理できない状態になっているためです。例外をスローすることにより、発生したエラーに関するプログラムへの特定のメッセージを表します。適切に処理できる時点になるまで、例外をキャッチしないでください。

メインアプリケーションの一部として記述するコードは、スローされる可能性のある例外のタイプと、いつスローされる可能性があるかを認識している必要があります。例外で生産的なことができない場合は、キャッチしないでください。処理されるまで例外をログに記録しないでください。処理コードのみが、プログラムフローのコンテキストにおける例外の意味とそれに対応する方法を知っています。ここにログメッセージを書き込むことは理にかなっています。ロギングフレームワークを使用する場合、メッセージのログレベルを設定し、潜在的にそれらをフィルタリングできます。これは、発生する可能性のある例外には有効ですが、重大ではなく、きれいに回復できます。

あなたの例外は、コードがい死をクラッシュさせないようにする最後の努力です。ここまで進んだ場合は、可能な状態とエラー情報をすべて記録します。次に、すべてが停止する前にプログラムがクラッシュしていることをユーザーにうまく伝えるために最善を尽くします。あなたの目標は、このコードを実行させないことです。

基本クラスへのロギングの埋め込みは、上記のガイドラインに従っていません。基本クラスは、コードの状態について何も知りません。(スタックトレースは、解析に基づいて決定を行うコードを記述しないため、カウントされません。)基本クラスは、重大度または例外の処理方法を示すために何も実行できません。簡単な例外があり、きれいに処理して回復できるたびに、巨大なデータダンプとスタックトレースが必要になることはありません。


私はあなたの答えによって促される質問にいくつかの明確化を追加しました。私が集めたものから、あなたがキャッチオールにログインすることを提案する質問の実際的な面で?
ヤンニス

1
@YannisRizos:はい、最初のステップとしてキャッチオールを実装する必要があります。キャッチオールについて私が言ったことは、コードフローの通常の部分としてそれを使用しないようにすることでした。未処理の例外ハンドラを実装することは、コードが何か悪いことをするたびに多くの情報を取得できるため重要です。
unholysampler

「これが置き換えられない限り、ログに記録されるべきものがたくさんある」という概念を便利に処理できるロギングフレームワークはありませんか?例外を検出した各レイヤーは、前のデータに取って代わることができますが、スタックの巻き戻し中に新しい例外がスローされた場合、最後のログレポートは置き換えられず、記録されます。このようなパターンをサポートするフレームワークはありませんか?
-supercat

3

言語/ランタイムで例外の原因を簡単に判断できない場合は、スロー時にログに記録する場合があります。C ++および一部のJSエンジンは、キャッチした時点では例外のファイル+行または呼び出しスタックを公開しませんが、この情報は例外を構築する時点で利用可能です。

私たちの解決策は、ランタイム構成を使用して、これらの問題を診断するときに安価なスタックとともに例外のタイプを記録できるメカニズムを提供することでした。


間違いなく、スローでのロギングのために良いケースだ1 ... PHPは、私はおそらく、他の道を行くよので、かかわらずキャッチでフルスタックトレースを提供してい...
ヤニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.