public class SessionLogger {
private final String sessionId;
public SessionLogger(String sessionId) {
this.sessionId = sessionId;
}
public void info(Log log, String message, Object... args) {
log.info(formatMessage(message, args));
}
public void error(Log log, String message, Throwable t, Object... args) {
log.error(formatMessage(message, args), t);
}
private String formatMessage(String message, Object... args) {
for (int i = 0; i < args.length; i++) {
message = message.replaceFirst("\\{\\}", args[i].toString());
}
return String.format("SessionId [%s]: %s", sessionId, message);
}
}
我想要做的是将Logger实例传递给SessionLogger类,我希望看到类名,Logger初始化。
public class A {
private static final Log log = LogFactory.getLog(A.class)
public void doIt() {
sessionLogger.info(log, "hello world");
}
}
我希望在日志消息中看到A类而不是SessionLogger:
2013-10-07 00:29:27,328 INFO [main] (SessionLogger.java:17) - SessionId [123]: Hello world
我在classpath中有commons-logging.jar和log4j-1.2.16.jar。 Logger是org.apache.commons.logging.Log
的一个实例更新
刚刚发布它是预期的行为,导致Logger
记录代码行,其中调用了log方法。所以它应该以某种方式以另一种方式完成
答案 0 :(得分:1)
我认为解决方案是编写本文中提供的自定义Log4j模式布局:http://fw-geekycoder.blogspot.com/2010/07/creating-log4j-custom-patternlayout.html
然后您将不需要SessionLogger,这将显着简化您的代码。
布局:
public class MyPatternLayout extends PatternLayout {
@Override
protected PatternParser createPatternParser(String pattern) {
return new MyPatternParser(pattern);
}
}
模式解析器:
public class MyPatternParser extends PatternParser {
private static final char USERNAME_CHAR = 'S';
public MyPatternParser(String pattern) {
super(pattern);
}
@Override
protected void finalizeConverter(char c) {
switch (c) {
case USERNAME_CHAR:
currentLiteral.setLength(0);
addConverter(new MyPatternConverter());
break;
default:
super.finalizeConverter(c);
}
}
}
模式转换器:
public class MyPatternConverter extends PatternConverter {
@Override
protected String convert(LoggingEvent event) {
// Retrieve SessionID
return "123";
}
}
Log4j配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="MyPatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p (%F:%L) - Session ID:%S %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
答案 1 :(得分:1)
在看了一下你想要实现的目标后,我相信使用MDC而不是做那件棘手的SessionLogger,可能是一个更合理的选择。
在MDC中设置会话ID(取决于您的应用程序设计。对于Web应用程序,使用servlet过滤器进行MDC设置工作是合理的),并让每个人都像往常一样简单地使用记录器。通过使用适当的模式,您可以将会话ID放在结果日志消息中。
不确定MDC是否在Apache Commons Logging中公开,但它在SLF4J或Log4J中可用。
好奇,有没有理由使用ACL(已知有很多问题)。考虑转换到近年来更广泛采用的SLF4J。