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 不仅仅是 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?如果是,如何?

  • 是否有一个免费/开源库已经具有我需要的功能?

我很好奇答案。提前致谢!

4

0 回答 0