Log4j:每个请求一个日志文件

时间:2010-02-25 02:16:48

标签: java java-ee log4j batch-processing

我们有一个weblogic批处理应用程序,它同时处理来自消费者的多个请求。我们使用log4j来记录目的。现在我们为多个请求登录一个日志文件。调试给定请求的问题与日志在单个文件中的所有请求一样繁琐。

所以计划是每个请求有一个日志文件。消费者发送必须执行处理的请求ID。现在,实际上可能有多个消费者将请求ID发送到我们的应用程序。所以问题是如何根据请求分割日志文件。

我们无法开始&每次都停止生产服务器,因此排除了使用带有日期时间戳或请求ID的重写文件appender的要点。这是下面的文章中解释的: http://veerasundar.com/blog/2009/08/how-to-create-a-new-log-file-for-each-time-the-application-runs/

我也试过玩这些替代品:

http://cognitivecache.blogspot.com/2008/08/log4j-writing-to-dynamic-log-file-for.html

http://www.mail-archive.com/log4j-user@logging.apache.org/msg05099.html

此方法提供了所需的结果,但如果同时发送多个请求,则无法正常工作。由于一些并发问题,日志会随处可见。

我期待你们的帮助。提前谢谢....

4 个答案:

答案 0 :(得分:4)

以下是关于同一主题的问题: dynamically creating & destroying logging appenders

我在Log4J邮件列表上的一个帖子中跟进了这个,我讨论了这样做的事情: http://www.qos.ch/pipermail/logback-user/2009-August/001220.html

Ceci Gulcu(log4j的发明者)认为这不是一个好主意......建议使用Logback。

我们继续使用自定义文件appender完成此操作。有关详细信息,请参阅上面的讨论。

答案 1 :(得分:4)

使用logback(log4j的后继者)查看SiftingAppender发货,它旨在根据运行时条件处理appender的创建。

如果应用程序需要每个会话只创建一个日志文件,只需根据会话ID创建一个鉴别器。编写鉴别器涉及3或4行代码,因此应该相当容易。如果您需要帮助,请在logback-user邮件列表上大喊。

答案 2 :(得分:2)

Logback处理了这个问题。如果你有自由,我建议选择它。

假设你可以,你需要使用的是SiftingAppender。它允许您根据某些运行时值分隔日志文件。这意味着您可以选择多种方法来分割日志文件。

要在requestId上拆分文件,您可以执行以下操作:

<强> logback.xml

<configuration>

  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
    <discriminator>
      <key>requestId</key>
      <defaultValue>unknown</defaultValue>
    </discriminator>
    <sift>
      <appender name="FILE-${requestId}" class="ch.qos.logback.core.FileAppender">
        <file>${requestId}.log</file>
        <append>false</append>
        <layout class="ch.qos.logback.classic.PatternLayout">
          <pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
        </layout>
      </appender>
    </sift>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="SIFT" />
  </root>

</configuration>

如您所见(在discriminator元素内),您将区分用于在requestId上写日志的文件。这意味着每个请求都将转到具有匹配requestId的文件。因此,如果您有两个请求requestId=1而另一个请求requestId=2,则您将有2个日志文件:1.log(2个条目)和2.log(1个条目)。

此时您可能想知道如何设置key。这是通过将键值对放在MDC中来完成的(请注意该键与logback.xml文件中定义的键匹配):

<强> RequestProcessor.java

public class RequestProcessor {

    private static final Logger log = LoggerFactory.getLogger(RequestProcessor.java);

    public void process(Request request) {
        MDC.put("requestId", request.getId());
        log.debug("Request received: {}", request);
    }
}

这基本上是一个简单的用例。现在,每当有一个具有不同(尚未遇到)id的请求进入时,将为其创建一个新文件。

答案 3 :(得分:0)

使用filePattern

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<property name="filePattern">${date:yyyy-MM-dd-HH_mm_ss}</property>
</Properties>
<Appenders>
<File name="File" fileName="export/logs/app_${filePattern}.log" append="false">
<PatternLayout
pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
</File>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="File" />
</Root>
</Loggers>
</Configuration>