マルチスレッドアプリケーションでのアクティビティのログ記録

StackOverflow https://stackoverflow.com/questions/83117

  •  01-07-2019
  •  | 
  •  

質問

Javaで階層化されたアプリケーションを持っています。これには、さまざまなポイントから呼び出されるマルチスレッドデータアクセスレイヤーがあります。この層への 1 回の呼び出しで、DB へのリクエストを並列化するために複数のスレッドが生成される可能性があります。

私が探しているのは、さまざまなスレッドで構成される「アクティビティ」を定義できるログ ツールです。したがって、データ アクセス層の同じメソッドは、呼び出し元に応じて異なる出力をログに記録する必要があります。さまざまな出力をグループ化して、操作の総コストを要約する機能も重要です。

アプリケーションは Java ですが、言語に制限はありません。私に必要なのは、最終的に実装するための設計ガイドラインです。現在 log4j を使用していますが、この動作を得ることができません。

役に立ちましたか?

解決

もご覧ください。 ネストされた診断コンテキスト log4jの機能。呼び出し元ごとに異なるコンテキストをロガーにプッシュするとうまくいく場合があります。

他のヒント

ロガーを渡すことができるはずなので、タスク データの「共通」に基づいてロガーを作成します。ユーザー名など次に、このロガーをパラメータとして必要なすべてのメソッドに渡します。こうすることで、log4j 構成ファイルにさまざまなフィルターやルールを設定できるようになります。または、ロガー名に基づいて出力ファイルをスクレイピングします。

編集:log4j の MDC クラスと NDC クラスも確認してください。そこにコンテキスト データを追加できます。

log4j では、「%t」パターンでスレッド名をログに記録できます。見る log4j パターン レイアウト.

私の (Web) アプリケーションの 1 つでは、ログ情報を StringBuilder にキャプチャする ThreadLocal ロガーを使用しています。トレース パラメーターが設定されている場合、ロガー オブジェクトは HttpServlet#service メソッドで初期化されます (設定されていない場合は、非常に高速な null ロガーが存在します)。結果の出力は、要求元のページに HTML コメントとしてダンプされるか、1 つのセグメントでログ ファイルに書き込まれます。

Java5 (以降) では、次のように呼び出すことができます。

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

必要な深さまでスタック トレースを検査し、それに応じてログを記録します。

Java 1.4 では、同じ情報を取得できます。

StackTraceElement[] stackTrace = new Exception().getStackTrace();

ロガーオブジェクトをスレッドに関連付けたいと思います。各スレッドの log4j ロガー インスタンスを保持する ThreadLocal 変数が役立つ場合があります。

http://java.sun.com/javase/6/docs/api/java/lang/ThreadLocal.html

現在の「アクティビティ」を識別する何らかの構造をデータ アクセス層に渡す必要があります。意味のある "Activity" クラスがすでにあるかもしれません。Logger インスタンスを次のように使用することもできます。 サニーが提案した または、アクティビティのコンテキストを追跡するために 3 番目の構造を使用することもできます。

いずれにせよ、「アクティビティ」は複数のスレッドにわたって処理されるため、他の現在の回答のほとんどが示唆しているように、現在の「アクティビティ」を追跡するためにスレッドローカルストレージを使用することはできません。明示的に渡す必要があります。

log4j の上に小さなファサードを作成し、次のようなメソッドでインターフェイスを拡張することをお勧めします。

void debug(Activity activity, String message);

そしてアクティビティコンテキストをデータアクセス層からこれに渡します。

現在のアクティビティをデータ アクセス層に渡せるようにするには、データ アクセス層に何らかの変更を加える必要がありますが、それを行う最善の方法は、現在のインターフェイスに大きく依存します。Workspace パターンを使用する場合、Workspace クラスに setActivity() メソッドを追加するだけで済みますが、他のインターフェイス パターンでは、すべてのメソッドに Activity パラメータを追加する必要がある場合があります。

何らかの理由でデータ アクセス レイヤーを変更できない、または変更したくない場合は、データ アクセス レイヤーを呼び出す前にアクティビティ コンテキストをスレッド ローカル ストレージに保存し、サブスレッドを生成するか、サブスレッドをエンキューする直前にそれを取得することもできます。データ アクセス層のジョブ。それは実行可能な解決策ですが、その方法で情報を伝達するのは少し危険でしょうか。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top