每个请求在一个文件中记录不同的日志框架

时间:2016-04-17 11:24:10

标签: java hadoop logging log4j slf4j

我有一个包含很多类的java jaxrs Web服务器。每个类使用不同的日志框架。他们中的大多数使用slf4j,其中一些使用org.apache.commons.logging。我也在我的程序中使用hadoop 1.2.0,它使用log4j进行日志记录。

我想为每个请求(每个请求运行的线程)和服务器的不同日志文件提供不同的日志文件。 我为此目标使用了MDC和siftingappender,但只使用了线程日志中编写的slf4j日志文件。用不同的日志文件写的hadoop日志和用服务器日志文件写的apache.commons.logging日志。 我该怎么做才能将每​​个请求的日志保存在一个文件中。

请考虑因为课程数量众多,我不想将所有日志文件更改为log4j。我也无法改变hadoop日志框架,因为它是一个jar文件。

有人能帮助我吗? (如果我的英语不好,我道歉。)

1 个答案:

答案 0 :(得分:0)

我找到了集成所有日志框架以使用slf4j的解决方案。我将log4j-over-slf4j.jar和jcl-over-slf4j.jar添加到我的库中。所以log4j和org.apache.commons.logging根据this使用slf4j配置进行日志记录。

但它不是sifficeint,我还有一个问题! Hadoop作业日志没有在其请求线程日志文件中写入。事实上,我的新问题是:" Hadoop工作不具备固有的MDC日志值!"。我通过为每个新请求创建新的logback.xml来解决它,使用JoranConfigurator.doConfigure()将其设置为新的配置文件。

这是我的logback.xml

    

<appender name="FILE" class="ch.qos.logback.classic.sift.SiftingAppender">

    <!-- This is MDC value -->
    <!-- We will assign a value to 'logFileName' via Java code -->
    <discriminator>
        <key>logFileName</key>
        <defaultValue>server</defaultValue>
    </discriminator>

    <sift>

      <!-- A standard RollingFileAppender, the log file is based on 'logFileName' at runtime  -->
      <appender name="FILE-${logFileName}"
        class="ch.qos.logback.core.FileAppender">
        <file>${USER_HOME}/${logFileName}.log</file>

        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>
                %d{ISO8601} %level %X{logName} : %logger{30} - %msg%n
            </Pattern>
        </encoder>

      </appender>

    </sift>
</appender>

<root level="info">
    <appender-ref ref="FILE" />
</root>

我的程序复制此文件并将logFileName默认值更改为我想要的String。然后使用此代码将新文件设置为配置。

    // assume SLF4J is bound to logback in the current environment
    LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();

    try {
      JoranConfigurator configurator = new JoranConfigurator();
      configurator.setContext(context);
      // Call context.reset() to clear any previous configuration, e.g. default 
      // configuration. For multi-step configuration, omit calling context.reset().
      context.reset(); 
      configurator.doConfigure(newPath+"/logback.xml");
    } catch (JoranException je) {
      // StatusPrinter will handle this
    }
    StatusPrinter.printInCaseOfErrorsOrWarnings(context);