每个动态日志记录类别的可插入appender?

时间:2013-08-07 18:19:49

标签: java logging dynamic log4j slf4j

我正在使用SLF4J和Log4J后端。

我有独立的Java服务,它从队列中获取“任务”并在单独的线程中执行任务(Akka Actors,如果这很重要)。我想将日志消息发送到每个任务日志文件(因此每个任务都开始登录到它自己唯一的日志文件)。

我的要求是:

  • 使用日志消息隐式传递任务ID
  • 选择要按该ID记录的文件
  • 在任务结束时删除ID,因此后续任务不会意外地记录到错误的文件

到目前为止看起来我必须创建自己的日志追加器,它将通过某些标准“识别”任务(这是一个很大的问题,因为我没有看到如何轻松地将任务ID传递给记录器,并且可以不依赖ThreadLocal,因为某些任务可能会启动线程池/ fork-join,因此继承线程上下文会很复杂)

您知道任何可能对我有用的现有日志记录实现吗?可能是Log4J的一些扩展?

1 个答案:

答案 0 :(得分:2)

Log4J有一个不太广为人知的功能可以帮助您完成任务。自己的appender方法似乎是正确的,并且可靠地传递ID,您可以使用映射诊断上下文(MDC)。在任何已知任务ID的地方,您可以将任务ID放入MDC:

MDC.put("id", id);

在自定义appender中,只需将其取回:

Object id = MDC.get("id");

与简单的ThreadLocal存储相比,MDC的主要优点是一种“线程继承”。子线程自动继承其父级的映射诊断上下文的副本:

    MDC.put("id", "1");
    new Thread(){
        @Override
        public void run() {
            System.out.println(MDC.get("id"));  // prints 1
        }
    }.start();

在自定义appender中有一个任务ID,您可以轻松地将输出转发到适当的文件。 SLF4J也提供MDC,但它的行为取决于底层实现。