web-dev-qa-db-ja.com

マルチスレッドシステムのロガーに最適な作成パターン?

これは私の過去の質問のフォローアップ質問です: マルチスレッドアプリケーションでのロガーの同時実行パターン

他の人が示唆したように、私はこの質問を個別に出しています。

最後の質問からの学びとして。マルチスレッド環境では、ロガーをスレッドセーフにし、おそらく非同期にする必要があります(バックグラウンドスレッドが書き込みを要求している間にメッセージがキューに入れられ、要求しているオブジェクトスレッドが解放されます)。ロガーはsignletonにすることも、上記を一般化したグループごとのロガーにすることもできます。

ここで発生する問題は、どのようにロガーをオブジェクトに割り当てる必要があるかということです。私が考えることができる2つのオプションがあります:

1。ロガーを要求するオブジェクト:

各オブジェクトはget_logger()などのグローバルAPIを呼び出す必要がありますか?このようなAPIは、「the」シングルトンまたはグループロガーを返します。ただし、これには、ロガーを実装するためのアプリケーション環境に関する想定が含まれていると感じています。同じオブジェクトを他のアプリケーションで使用する必要がある場合-この新しいアプリケーションでも、このようなメソッドを実装する必要があります。

2。いくつかの既知のAPIを介してロガーを割り当てます他の代替アプローチは、Appの独自の構造に基づいてアプリケーションによって実装される一種の仮想クラスを作成し、コンストラクターでオブジェクトを割り当てることです。

これはより一般的な方法です。残念ながら、非常に多くのオブジェクトが存在する場合、ロガーオブジェクトを各レベルに渡すオブジェクトのツリーはかなり厄介です。

私の質問はこれを行うより良い方法はありますか?上記のいずれかを選択する必要がある場合、どのアプローチを選択しますか、またその理由は何ですか?

その他の質問は、それらの構成方法について未解決のままです。

  1. (モジュール名として)ログメッセージの印刷に使用されるようにオブジェクトの名前またはIDを割り当てる方法

  2. これらのオブジェクトは、適切なプロパティ(ログレベルなどのパラメーターなど)をどのようにして見つけるか

最初のアプローチでは、中央APIはこのすべての種類を処理する必要があります。 2番目のアプローチでは、追加の作業が必要です。

したがって、そのような環境でロガーを効果的に書く方法について、実際の人の経験から理解したいと思います。

6
Dipan Mehta

これは簡潔に答えるのは簡単な質問ではありません。

まず、選択するアプローチは、非常に具体的な目標と制約によって異なります。オブジェクトメッセージまたはアクティビティをどの程度ログに記録しますか?また、固有のアクティビティ(オブジェクトの重要な統合責任であるものか、それとも二次的な、本当に良い簿記アクティビティか)をログに記録していますか?

ロギングが本質的かつ広範に行われている状況もありますが、多くの場合、それは二次的な問題です(簿記活動)。これは、追跡している各オブジェクトにロガーを強く結合したくないことを示唆しています。

検討する1つのアプローチは、アプリケーションのグローバルメッセージキュー、またはエンタープライズサービスバスに沿ったものです。あなたが提案した2番目の選択肢よりも1番目の選択肢に近いもの。

ロガーで追跡する各オブジェクトは、オブジェクトまたはアクティビティ固有のメッセージを生成します。各メッセージは、識別のためにログに記録する各オブジェクトに関心のある共通プロパティをサポートする共通メッセージインターフェイスを実装します。各オブジェクトまたはアクティビティ固有のメッセージで、特定の詳細を定義し、そのメッセージ構造に追加します。最後に、メッセージをアプリケーションのメッセージリスナーキューに送信します。受信確認が必要な場合は、送信者に渡してください。そうすれば続行できます。一般に、閉じた単一ホストシステムでは、メッセージ受信の明示的な確認は必要ありません。

アプリケーションスコープのメッセージプロセッサ(アプリケーション内でグローバルに使用可能)では、メッセージハンドラを「登録」します。これは、必要に応じて「遅延」で実行することも、「ブートストラップ」の一部として起動時に事前に実行することもできます。おそらく、受信したメッセージを処理する汎用ハンドラーが含まれます。その共通ロガーメッセージのハンドラーがある場合があります。そのメッセージに関連して他のアクティビティーを発生させる必要がある場合は、特定のロガーメッセージのいくつかまたはすべてのハンドラーを持つこともあります。いずれにしても、メッセージプロセッサはメッセージを順次デキューし、登録されたメッセージハンドラでメッセージを処理し、適切に破棄してから、次のメッセージを取得します。

マルチスレッドアプリケーションでのアプリケーションスコープのメッセージプロセッサの影響の一部は、メッセージの順序に対する唯一の保証は、メッセージがメッセージキューに入る順序が特定のログに表示される順序で大きな役割を果たすことです。

メッセージの順序をより確定的にするための戦略がありますが、すべての場合に完璧なものはありません。 1つの方法は、グローバルメッセージシーケンサーを追加し、すべてのメッセージを作成するときにシーケンサーから「get_next」を追加してから、インデックス付きキューに挿入し、シーケンス内の次のメッセージが到着するまでデキューするのを待ちます。これにも影響があり、特にメッセージが失われたり破棄されたりすると、メッセージキューがブロックされます。

3
JustinC