複数のサービスを備えた大規模なエンタープライズ アプリケーションのロギングを実装したいと考えています。重要な設計上の制約は、「すべてをログに記録する」アプローチを実装するロギングの実装です。できるだけ高速にするための最初のアイデアは、クラスター内のノードごとに 1 つのログ ファイルに記録することです。追加のサービスを使用すると、ノードでログがフェッチされてクリアされ、コンテンツを分析するためにストリーミングできる中央ログ サービスに送られます。
システムはJBoss 7.1に基づいており、ロガーはCDIを介して次のように動作する必要があります:
@Inject
private MyLogger logger;
...
logger.info("Info message");
...
ロガーを作成するための slf4j では、インスタンス化するロガーのクラスが必要です (また、ロギングにも必要です)。したがって、インジェクションは次のようなプロデューサー クラス内で生成できます。
@Produces
public MyLogger create(InjectionPoint ip) {
return new MyLogger(ip.getBean().getBeanClass());
}
MyLogger 内で、実際のロガーは次の方法で作成されます。
public MyLogger(Class<?> clazz) {
super();
logger = LoggerFactory.getLogger(clazz);
}
MyLogger は、trace、debug、info、warn、error などの一般的なメソッドを実装する slf4j ロガーへの単純なデリゲートです。デリゲートは、マーカーをサポートするように拡張することもできます。ここまでは、すべて順調です。
この質問の最後の問題とポイントは、スレッドごとではなく、セッション/ユーザーごとにサポートされるように MDC (マップされた診断コンテキスト) を実装する方法です... slf4j の MDC はスレッドごとにしか機能しないため、私は間違っています。情報をいくつかの場所に個別に設定することもできます。
アイデアは、独自の MDC ステートフル Bean を実装することでした。この Bean は、ユーザー ログイン、アプリケーション状態変更 Bean、処理情報などの他のステートフル Bean によって個別に満たすことができます。この Bean は次のようになります。
@Stateful
public class MappedDiagnosticContext {
private final Map<String, String> contextInformation = new HashMap<String, String>();
public void addConextInformation(String type, String value) {
contextInformation.put(type, value);
}
public void removeConextInformation(String type) {
contextInformation.remove(type);
}
public Map<String, String> getContextMap() {
return contextInformation;
}
}
今必要なのは、MyLogger がステートフル Bean にアクセスして、MyLogger 内で次のようなことを行うことです。
...
@EJB
private MappedDiagnosticContext mappedDiagnosticContext;
...
public final void info(String infoMessage) {
MDC.setContextMap(mappedDiagnosticContext.getContextMap());
logger.info(infoMessage);
MDC.clear();
}
...
プロデューサ クラスで getLogger(clazz) が使用されているため、EJB 注入は明らかに機能しません。質問は次のとおりです。
使ってもいいですか
@EJB プライベート MappedDiagnosticContext マップされたDiagnosticContext;
正しい状態のステートフル Bean を取得するプロデューサー クラスで? プロデューサークラスはどのように扱われますか? シングルトンとして?このシナリオを簡単にテストすることはできないので、質問の方が早いかもしれません。;-)
自分の情報を取得する別の方法はありますか? 現在は確認できません。プロデューサー メソッドで正しいステートフル Bean にアクセスする機会はありますか? はいの場合、どのように?
私が必要とする機能をすでに備えているフリー/オープンソースのライブラリはありますか?
答えが気になります。前もって感謝します!