我正在尝试在wicket中的onBeginRequest()
的RequestCycle()
中记录一些值。
但是这些值未记录在调试文件中。我将值放在RequestCycleListeners()
的MDC中。
以下是代码:
getRequestCycleListeners().add(new AbstractRequestCycleListener()
{
public void onBeginRequest(RequestCycle cycle)
{
if( cycle.getRequest().getContainerRequest() instanceof HttpServletRequest )
{
HttpServletRequest containerRequest =
(HttpServletRequest)cycle.getRequest().getContainerRequest();
MDC.put("serverName", containerRequest.getServerName());
MDC.put("sessionId", containerRequest.getSession().getId());
LOGGER.debug("logging from RequestCycleListeners() !!!");
WebClientInfo webClientInfo = new WebClientInfo(RequestCycle.get());
System.out.println(webClientInfo.getUserAgent());
System.out.println("webClientInfo.getProperties().getBrowserVersionMajor() " +containerRequest.getRemoteAddr());
}
};
我期望在调试文件中记录“serverName”,“sessionId”。
我在扩展
listener
的类中添加了这个WebApplication
。我正在使用log4j.xml,
DEBUG appender
如下所示:<appender name="DEBUG" class="org.apache.log4j.rolling.RollingFileAppender">
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{ISO8601} %t %5p] %m -- %X{serverName} -- %X{sessionId} -- %X{portNumber}%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="WARN"/>
</filter>
</appender>
我们在root标签中定义作用域:
<root>
<priority value="INFO" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG" />
<appender-ref ref="ERROR" />
</root>
最佳答案
通常,只有在通过配置将MDC key 包括在日志记录模式中时,MDC值才会输出到日志。由于slf4j只是一个外观,因此您需要在slf4j下具有特定于框架的支持和配置才能使用MDC。阅读关于here的slf4j的注释。
因此,举例来说,如果您将log4j用作slf4j下的impl,则需要使用log4j config(ConversionPattern),例如:
%d %-5p [%c] [%X{serverName} %X{sessionId}] %m%n
其中
%X{serverName} %X{sessionId}
是从MDC中提取值的相关部分。Here是不带sl4j的使用log4j的一个很好的示例。请参阅log4j javadoc here中有关
X
转换字符的注释。请注意,用于登录的模式语法是相同的。请参阅logback here的详细信息。
还要注意,MDC的最佳实践(在后台使用
ThreadLocal
)是在上下文不在范围内时清除上下文(删除在 map 中输入的值)。这通常意味着在remove
块中调用clear
或finally
,例如:try {
//...
MDC.put("key1", value1);
MDC.put("key2", value2);
//...
} finally {
//this
MDC.remove("key1");
MDC.remove("key2");
//or this
MDC.clear();
}
如果保存MDC的线程属于一个池以供以后重用,则这尤其重要。您当然不希望无意间记录无效的上下文值,因为这只会引起困惑。
编辑
您的log4j配置似乎有些奇怪,原因如下:
RollingFileAppender
未定义文件root
记录器将记录到3个不同的附加程序,其中一个名为DEBUG
,但是它被配置为仅记录INFO
级别和更高级别(基于priority
标记),因此调试语句不会被记录除非您有一些未单独配置的特定类别,这些类别没有显示,否则我想您的
LOGGER.debug
语句都不会被记录,无论您尝试使用MDC如何。