我想为具有多个服务的大型企业应用程序实现日志记录。一个重要的设计约束是实现“记录所有内容”方法的日志记录。为了尽可能快,第一个想法是将集群中的每个节点记录到单个日志文件中。通过附加服务,日志在节点上被提取并清除到中央日志服务,在那里它们可以流式传输以分析内容。
该系统将基于 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 不仅仅是 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 mappedDiagnosticContext;
在生产者类中获得正确状态的有状态bean?生产者阶级如何对待?作为单身人士?我不能这么容易地测试这种情况,所以问题可能会更快。;-)
有没有其他方法可以让我的信息到位,我目前看不到?我是否有机会在生产者方法中访问正确的有状态 bean?如果是,如何?
是否有一个免费/开源库已经具有我需要的功能?
我很好奇答案。提前致谢!