Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Log4j2自定义包装器_Java_Logging_Log4j_Log4j2 - Fatal编程技术网

Java Log4j2自定义包装器

Java 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;

基于此主题,我为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 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