当社のいくつかのアプリケーションでは、カスタムロガーを使用しています。かなり堅牢ですが、将来的にはNLogなどに置き換える可能性があります。ロガーのタスクの1つは、アプリケーションで発生した例外をログに記録することです。
私がいつも持っていた1つの懸念は、例外処理ロガー内がサイレントエラーを許可することです。つまり、ログが特定の例外に対して(ロガーのエラーが原因で)書き込まれていない場合、どのように処理し、(どういうわけか)ロガー自体に例外をログに記録する?
WriteLog関数が例外をスローするとします。何回か、または例外がスローされなくなるまで、関数を呼び出そうとする必要がありますか?スローされた例外をロガーで書き込もうとする必要がありますか(これにより、例外が発生する可能性があります。)私は幸運にも、私たちが最初にカスタムロガーを実装していたときを除いて、この状況に遭遇しないようにしています。一方、ロガーがアプリケーションの例外をログに記録できなかったかどうかは、現時点では知ることができません(独自の例外のため)。
私はオンラインおよびいくつかのSEサイトで検索を試みましたが、すべての投稿がロガーのエラー(ただし、例外の可能性とログの記録方法ではない)またはロガー外の例外を扱っているため、これまでのところ効果がありません。
ロガー自体の中で例外が発生した場合は、ロガーを使用してそれ自体の例外をログに記録しないでください。その理由は次のとおりです。
無限ループに陥る可能性があります。ロガー内に、テストされていない(そして例外を生成する)条件付きブランチがあると想像してください。条件が満たされると、さらに報告された例外は同じブランチによって処理されると想像してください。これは、ブランチが実行された瞬間から、無限ループに入っていることを意味します。
一時的なループに陥り、毎秒数千の例外を生成する場合があります。例外をリモートサーバーに報告するとします。サーバーに問題があると別の例外が発生し、接続が戻るまで別の例外が発生します。
代わりに、例外をログに記録するより安全な方法にフォールバックする必要があります。たとえば、ロガーが例外をリモートサーバーに送信する場合、代わりにロガー内の例外をsyslog
に送信します。ロガーがWindowsイベントに例外を記録し、このアクションが失敗した場合、失敗の例外を単純なテキストファイルに保存します。
それができたら、次の質問は、それらの例外が発生したことをどのようにして知るのかです。何千ものサーバーで何十ものアプリケーションが実行されている場合、それらを定期的にSSHでローカルにログに記録しているかどうかを確認することはできません。 。
1つの方法は、これらの「例外ログ」をチェックし、他の例外が格納されている場所にプッシュするcronジョブを作成することです(最終的にロガーを使用しますが、無限ループまたは一時ループに注意してください)。
ロギングがアプリケーションにとって重要である場合、ロギングが失敗した場合はアプリケーションを停止する必要があります。
重要でない場合は、ある程度防御的であるため、セカンダリソースにログ/アラートを記録するログ障害を処理するセカンダリコンポーネントを使用できます。しかし、それでも完全な証拠ではありません。セカンダリロガーがプライマリロガーを監視しているときに障害が発生した場合、どうなるかを考慮する必要があります。
ローカルファイルにログを記録することをお勧めします。失敗した場合は、そのエラーをイベントログに記録し、電子メールアラートを生成し、データベースに保存するなどです。利用可能なログフレームワークを使用すると、マシンが実行されない限り、これは間違いなく機能します。ディスク容量不足またはその他のまれな状態。
理想的には、サイレントで失敗する方がアプリケーションの複雑さが軽減されるため、より良い方法です。
さらに重要なことは、ロギングの失敗を処理するには、サードパーティからのログを監視する必要があります。時間の経過とともに、ヘルスアプリケーションがログに記録しているイベントの数を識別できるはずです。イベントが少ないかまったくイベントのログが記録されなくなった場合は、監視を通じて、問題が発生していることを確認し、サードパーティのメカニズムを通じてアラートを送信することができます。