java定义log4j2_关于java:Log4j2自定义包装器

我根据以下主题为log4j2记录器做了一个包装:

如何在log4j消息中添加前缀(在对象级别)

这是我有的:

导入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);

}

}

问题:

作为输出,我有一个指向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中的行。

怎么解决呢?

什么代码产生了您给我们的输出?

logger.info(" blab bla bla"); 在MyClass的方法之一中

实际上,问题在于位置信息不是您想要的。当您完成包装后,就会发生这种情况。要修复它,Log4j需要Logger类的完全限定的类名(FQCN)。手动创建执行该操作的类并不难,但是简单的方法是遵循Log4j手册中的说明,该手册位于http://logging.apache.org/log4j/2.x/manual/customloglevels.html #CustomLoggers

已投票。非常关键。

Log4j提供的用于在日志输出中添加前缀的内置机制是ThreadContext映射。这个怎么做:

码:

// usually at some entry point from where these values won't change

ThreadContext.put("user.ip", ipAdr);

ThreadContext.put("user.account", userAccount);

组态:

现在,将值放入ThreadContext后的所有日志记录都将显示所需的前缀。

定制的记录器包装器可用于实现类似的功能,但要做的工作还很多。

Log4j会记住记录器的全限定类名(FQCN),并在配置为打印位置时使用它在每个日志事件中遍历堆栈跟踪。 (请注意,使用位置记录会很慢,并且可能会影响应用程序的性能。)

定制记录器包装器的问题在于它具有与实际记录器不同的FQCN,因此Log4j找不到调用定制记录器的位置。

解决方案是提供正确的FQCN。最简单的方法是让Log4j为您生成记录器包装器。 Log4j随附Logger包装器生成器工具。该工具最初旨在支持自定义日志级别,并在此处进行了记录:https://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers

生成的记录器代码将处理FQCN,您可以将其用作进一步增强功能的基础。

我试图用ThreadContext做到这一点,但user.account从未出现在日志字符串中。可能是什么原因?顺便说一句,编译器不接受`%X {" user.account"}`。只有没有引号是可以的"%X {user.account}"

谢谢,我已经从我的答案中删除了引号。关于输出未出现,您可以仅尝试%X吗?那应该显示放置在ThreadContext中的所有键值对。另外,您是否从将user.account键值对放入ThreadContext的同一线程进行日志记录?

仅尝试%X。相同。是的,即时通讯登录了我设置ThreadContext的同一类。因此必须是同一线程。

相同的类不一定意味着相同的线程...您可以在调用logger.info("test message");之前立即通过调用ThreadContext.put("key","value");进行实验吗? (使用一些不为空或为空的固定字符串值。)

是的可以。现在-im logging [pool-2-thread-1]线程,因此它在各处显示相同的线程。

ThreadContext.put("user", username); logger.info("log after thread context");尝试过此操作-相同,上下文没有记录

猜测还必须提到ThreadPoolExecutor执行的应用程序中的所有线程

非常奇怪...请尝试ThreadContext.put("user","FIXEDVALUE"); logger.info("original value is{}", ThreadContext.get("user"));这将帮助我们确定该值在哪里消失。

logger.info("original value is:"+ ThreadContext.get("user"));正在记录" FIXEDVALUE",但未将其添加到附加程序2016-07-13 13:56:54,091 INFO [pool-2-thread-1] MyClass (MyClass.java:36) - original value is: FIXEDVALUE中,这是模式:d{yyy-MM-dd HH:mm:ss} [%t] %X{user} %-5level %logger{36} - %msg%n

啊哈!那不能是正确的布局模式:输出在线程名称之前显示INFO级别,并显示位置信息(类+行号),但是该模式首先显示线程名称,而%logger{36}则不显示位置信息。您是否更新了错误的配置文件?

那么正确的顺序是什么?如果我毕竟那样,但是在消息之前-同样的优势-从上下文中没有任何价值。 %d{yyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} %X{user} - %msg%n

不,那不是我的意思。任何命令都可以,但是显示的布局模式无法产生显示的输出,因此我认为您可能正在修改错误的log4j2.xml配置文件...您确定Log4j在布局中使用的包含%X的配置文件?

嗯是的好像我编辑错了。好瞎

谜团已揭开?! (伙计,为此我应受很多赞扬... :-D)

是的,它确实。我正在编辑文件追加器,但未编辑STDOUT:D

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值