Java Log4j2自定义包装器
基于此主题,我为log4j2 logger制作了一个包装器: 以下是我所拥有的: 导入org.apache.log4j.LoggerJava Log4j2自定义包装器,java,logging,log4j,log4j2,Java,Logging,Log4j,Log4j2,基于此主题,我为log4j2 logger制作了一个包装器: 以下是我所拥有的: 导入org.apache.log4j.Logger public class LogWrapper { private Logger log; private String prefix; public LogWrapper(Logger log, String prefix) { this.log = log; this.prefix = prefix;
public class LogWrapper
{
private Logger log;
private String prefix;
public LogWrapper(Logger log, String prefix) {
this.log = log;
this.prefix = prefix;
}
public void info(String msg)
{
log.error(prefix + "| " + msg);
}
public void error(String msg)
{
log.error(prefix + "| " + msg);
}
}
用法:
public class MyClass {
private final LogWrapper logger;
public MyClass(String username) {
logger = new LogWrapper(Logger.getLogger(MyClass.class.getName()), username);
}
}
问题:
public class MyClass {
private final LogWrapper logger;
public MyClass(String username) {
logger = new LogWrapper(Logger.getLogger(MyClass.class.getName()), username);
}
}
作为输出,我有一个到LogWrapper
类的链接
2016-07-12 21:15:17,543 ERROR [pool-3-thread-1] global.LogWrapper (LogWrapper.java:17) - blab bla bla
'LogWrapper.java:17'
它不指向调用记录器的MyClass
中的行
如何解决它?Log4j提供的在日志输出中添加前缀的内置机制是ThreadContext映射。如何做到这一点: 代码: 配置:
<PatternLayout pattern="%d %p %c{1.} [%t] %X{user.ip} %X{user.account} %m%n"/>
现在,将值放入ThreadContext之后的任何日志记录都将显示所需的前缀
自定义记录器包装器可以用来实现类似的功能,但工作量要大得多
Log4j记住记录器的完全限定类名(FQCN),并在配置为打印位置时,使用它来遍历每个日志事件的堆栈跟踪。(请注意,使用location进行日志记录的速度很慢,可能会影响应用程序的性能。)
自定义记录器包装的问题在于,它的FQCN与实际记录器不同,因此Log4j无法找到调用自定义记录器的位置
解决方案是提供正确的FQCN。最简单的方法是让Log4j为您生成记录器包装器。Log4j附带一个记录器包装生成器工具。此工具最初用于支持自定义日志级别,并记录在此处:
生成的记录器代码将处理FQCN,您可以将其用作进一步增强的基础 实际上,问题在于位置信息不是您想要的。当您创建一个包装器时就会发生这种情况。要修复它,Log4j需要记录器类的完全限定类名(FQCN)。手动创建一个这样做的类并不难,但简单的方法是按照Log4j手册中的说明进行操作,该手册位于什么代码生成了您提供给我们的输出?logger.info(“blab bla bla”);在
MyClass
的其中一个方法中,我尝试使用ThreadContext执行此操作,但是user.account
从未出现在日志字符串中。原因是什么?顺便说一句,编译器不接受“%X{”user.account“}”。只有不带引号才可以“%X{user.account}”谢谢,我已经从我的答案中删除了引号。关于输出不显示,您可以尝试仅使用%X吗?应该显示放置在ThreadContext中的所有键值对。另外,您是否从将user.account
键值对放入ThreadContext的同一线程登录?仅使用%X
进行了尝试。一样。是的,我正在登录设置ThreadContext
的同一个类。所以必须是相同的线程。相同的类不一定意味着相同的线程。。。您可以通过调用ThreadContext.put(“key”、“value”)代码>在调用logger.info(“测试消息”)之前代码>?(使用一些不为空的固定字符串值。)是的。我正在编辑一个文件追加器,但不是标准输出:D