每个请求在一个文件中记录不同的日志框架
logging of different log frameworks in one file per request
我有一个 java jaxrs 网络服务器,其中有很多 classes。每个 class 使用不同的日志框架。大部分使用slf4j,部分使用org.apache.commons.logging。此外,我在使用 log4j 进行日志记录的程序中使用 hadoop 1.2.0。
我希望每个请求有不同的日志文件(每个请求 运行 的线程)和服务器的不同日志文件。
我为此目标使用了 MDC 和 siftingappender,但只有 slf4j 日志文件写入线程日志。 hadoop 日志写在不同的日志文件中,apache.commons.logging 日志写在服务器日志文件中。
我应该怎么做才能将每个请求的日志保存在一个文件中。
请考虑我不想将所有日志文件更改为 log4j,因为 classes 很多。我也不能更改 hadoop 日志框架,因为它是一个 jar 文件。
有人可以帮助我吗?
(如果我的英语不好,我深表歉意。)
我找到了集成所有日志框架的解决方案,使用slf4j。我将 log4j-over-slf4j.jar 和 jcl-over-slf4j.jar 添加到我的库中。所以 log4j 和 org.apache.commons.logging 根据 this.
使用 slf4j 配置进行日志记录
但这还不够,我还遇到了问题! Hadoop 作业日志未写入其请求线程日志文件。事实上,我的新问题是:"Hadoop jobs don't inherent MDC log values!"。我通过为每个新请求创建新的 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 默认值更改为我想要的字符串。然后使用此代码将新文件设置为配置。
// 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);
我有一个 java jaxrs 网络服务器,其中有很多 classes。每个 class 使用不同的日志框架。大部分使用slf4j,部分使用org.apache.commons.logging。此外,我在使用 log4j 进行日志记录的程序中使用 hadoop 1.2.0。
我希望每个请求有不同的日志文件(每个请求 运行 的线程)和服务器的不同日志文件。 我为此目标使用了 MDC 和 siftingappender,但只有 slf4j 日志文件写入线程日志。 hadoop 日志写在不同的日志文件中,apache.commons.logging 日志写在服务器日志文件中。 我应该怎么做才能将每个请求的日志保存在一个文件中。
请考虑我不想将所有日志文件更改为 log4j,因为 classes 很多。我也不能更改 hadoop 日志框架,因为它是一个 jar 文件。
有人可以帮助我吗? (如果我的英语不好,我深表歉意。)
我找到了集成所有日志框架的解决方案,使用slf4j。我将 log4j-over-slf4j.jar 和 jcl-over-slf4j.jar 添加到我的库中。所以 log4j 和 org.apache.commons.logging 根据 this.
使用 slf4j 配置进行日志记录但这还不够,我还遇到了问题! Hadoop 作业日志未写入其请求线程日志文件。事实上,我的新问题是:"Hadoop jobs don't inherent MDC log values!"。我通过为每个新请求创建新的 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 默认值更改为我想要的字符串。然后使用此代码将新文件设置为配置。
// 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);