web-dev-qa-db-ja.com

多層アーキテクチャ:エラー​​ロギング\処理を実装する必要がありますか?

私は現在、多層アーキテクチャを持つ大規模なサブシステムをリファクタリングしており、効果的なエラーロギングと処理の戦略を設計するのに苦労しています。

私のアーキテクチャが次の3つの層で構成されているとしましょう。

  • パブリックインターフェイス(つまり、MVCコントローラー)
  • ドメイン層
  • データアクセス層

私の混乱の原因は、エラーロギング\処理を実装する必要がある場所です。

  1. 最も簡単な解決策は、トップレベルでログを実装することです(つまり、パブリックインターフェイス\ MVCコントローラー)。ただし、これは別のレイヤーを介して例外をバブリングし、ログに記録することを意味するため、間違っていると感じます。ソースで例外を記録するのではなく。

  2. 例外をそのソースでログに記録することは、私が最も多くの情報を持っているため、明らかに最良の解決策です。これに関する私の問題は、すべての例外をキャッチせずにすべての例外をソースでキャッチできないことです。ドメイン/パブリックインターフェイスレイヤーでは、これにより、下のレイヤーによってすでにキャッチ、ログ、および再スローされた例外がキャッチされます。 。

  3. もう1つの可能な戦略は、#1と#2の組み合わせです。これにより、スローされる可能性が最も高いレイヤーで特定の例外をキャッチし(I.Eキャッチ、ログ、およびデータアクセスレイヤーでのSqlExceptionsの再スロー)、その後、キャッチされなかった例外をトップレベルでログに記録します。ただし、これにより、すべての例外をトップレベルでキャッチして再ログする必要があります。これは、すでにログに記録されているエラーと処理されていないエラーを区別できないためです。

さて、これはほとんどのソフトウェアアプリケーションの問題であるため、例外がソースでキャッチされ、一度ログに記録されるこの問題の標準的な解決策が必要です。しかし、私はこれを自分で行う方法がわかりません。

この質問のタイトルは「 多層アプリケーションでのログの例外」 'とよく似ていますが、その投稿の回答は詳細が欠けており、私の質問に答えるには不十分です。

17
KidCode

あなたの質問に:

最も簡単な解決策は、トップレベルでロギングを実装することです

例外バブルを最上位まで上げることは、完全に正しい、もっともらしいアプローチです。上位層のメソッドはいずれも、失敗後に何らかのプロセスを続行しようとはしませんが、通常は成功しません。また、十分な設備の整った例外には、ロギングに必要なすべての情報が含まれています。また、例外について何もしないことで、コードをクリーンに保ち、失敗ではなくメインタスクに集中することができます。

例外をそのソースでログに記録することは、私が最も多くの情報を持っているため、明らかに最良の解決策です。

それは半分正しいです。はい、最も役立つ情報はそこで入手できます。ただし、すぐにログを記録するのではなく、これらすべてを例外オブジェクトに含めることをお勧めします(まだ存在しない場合)。低いレベルでログを記録する場合でも、例外をスローして、ジョブを完了しなかったことを発信者に伝える必要があります。これは、同じイベントの複数のログで終了します。

例外

私の主なガイドラインは、例外をキャッチしてログに記録することです。また、以下のすべてのレイヤーは、必要なすべての障害情報が最上位に転送されることを確認する必要があります。シングルプロセスアプリケーション内(例: Javaでは、これは主に、トップレベルの外部でまったく試行/キャッチまたはログ記録しないことを意味します。

場合によっては、元の例外では利用できないコンテキストログを例外ログに含めたいことがあります。例外がスローされたときに実行されたSQLステートメントとパラメーター次に、元の例外をキャッチし、元の例外とコンテキストを含む新しい例外を再スローできます。

もちろん、実際の生活は時々干渉します:

  • Javaでは、いくつかの固定メソッドシグネチャに従うために、例外をキャッチして別の例外タイプにラップする必要がある場合があります。ただし、例外を再スローする場合は、再スローされた例外に、後でロギングするために必要なすべての情報が含まれていることを確認してください。

  • プロセス間境界を越えている場合、技術的にはスタックトレースを含む完全な例外オブジェクトを転送できないことがよくあります。そしてもちろん、接続が失われる可能性があります。したがって、ここでサービスが例外をログに記録し、回線を介してクライアントにできるだけ多くの障害情報を送信するように最善を尽くす必要があるポイントです。サービスは、失敗の応答を受信するか、接続が切断された場合にタイムアウトすることにより、クライアントが失敗の通知を確実に受け取るようにする必要があります。これにより、通常は同じエラーが2回ログに記録されます。1回はサービス内(詳細)で、もう1回はクライアントのトップレベルで記録されます。

ロギング

例外のログだけでなく、一般的なログに関する文章も追加します。

例外的な状況に加えて、アプリケーションの重要なアクティビティもログに記録する必要があります。したがって、ロギングフレームワークを使用します。

ログレベルに注意してください(デバッグ情報と重大なエラーに異なるフラグが付いていないログを読み取るのは面倒です!)。一般的なログレベルは次のとおりです。

  • エラー:一部の機能が回復不能に失敗しました。これは必ずしもプログラム全体がクラッシュしたことを意味するわけではありませんが、一部のタスクを完了できませんでした。通常、失敗を説明する例外オブジェクトがあります。
  • 警告:奇妙なことが発生しましたが、タスクが失敗することはありませんでした(奇妙な構成が検出された、一時的な接続の故障により再試行が発生したなど)
  • 情報:重要なプログラムアクションをローカルシステム管理者に伝えたい場合(その設定とソフトウェアバージョンでサービスを開始し、データベースにデータファイルをインポートし、ユーザーがシステムにログインすると、アイデアが得られます...)。
  • デバッグ:問題をデバッグしているときに開発者が見たいもの(ただし、これまたはその特定のバグの場合に本当に何が必要かを事前に知ることはできません-予見できれば、バグを修正します) )。常に便利なことの1つは、外部インターフェイスのアクティビティをログに記録することです。

本番環境では、ログレベルをINFOに設定します。結果はシステム管理者にとって有用なはずなので、何が起こっているのかを理解できます。ログ内のすべてのエラーと警告の半分について、支援またはバグ修正についてあなたに電話することを期待します。

DEBUGレベルは、実際のデバッグセッション中にのみ有効にします。

ログエントリを適切なカテゴリにグループ化し(たとえば、エントリを生成するコードの完全修飾クラス名によって)、プログラムの特定の部分のデバッグログをオンにできるようにします。

18
Ralf Kleberhoff