Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.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 如何定制log4j输出_Java_Logging_Log4j_Slf4j - Fatal编程技术网

Java 如何定制log4j输出

Java 如何定制log4j输出,java,logging,log4j,slf4j,Java,Logging,Log4j,Slf4j,我希望log4j在打印日志时吐出自定义模式。以下是场景: log4j.properties中的当前log4j配置: log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} - %p <%t> - %m%n log4j.appender.stdout.layout=org.apache.log4j.pa

我希望log4j在打印日志时吐出自定义模式。以下是场景:

log4j.properties中的当前log4j配置:

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} - %p <%t> - %m%n
log4j.appender.stdout.layout=org.apache.log4j.patternalyout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE}-%p-%m%n
log语句看起来像这样

08:48:03,092 - INFO <main> - some message
08:48:03092-信息-一些消息
但是,我想添加自定义模式(或者任何让我可以自定义的模式),以便为打印的每个日志语句都包括loginId帐户

期望输出:

08:48:03,092 - INFO <main> <abcuser:12345> - some message 
08:48:03092-信息-一些消息
我正在使用带有log4j绑定的slf4j


我怎样才能做到这一点?请帮忙

您可以实现自己的模式布局,并定义新字符以映射帐户、登录等


您可以找到教程

一种替代方法是使用或

例如,您可以将用户信息添加到MDC映射:

public class Controller { 
   public void someControllerMethod(){
      MDC.put("user", SecurityContext.getCurrentUser().getName());
      try{
        //do your work here
      }finally{
         MDC.clear();
      }
   }
}
然后,您可以在中配置MDC值的使用:

%d{ABSOLUTE} - %p <%t> %X{user} - %m%n
%d{ABSOLUTE}-%p%X{user}-%m%n
这将保证您将在日志输出中看到用户名:

08:48:03,092 - INFO <main> <obiwan> - some message 
08:48:03092-信息-一些消息
--编辑--

要回答您的问题:

MDC是一种类似于映射的结构,每个线程都有一个实例。因此,它很可能在幕后使用变量

您的服务器中的线程数量有限,因此,我怀疑这会在内存方面花费很多。由于它是每线程结构,因此仅在第一次使用线程时才假定创建对象的成本。但无论如何,这可能是微不足道的。我想你应该小心不要在这个结构里面放太大的东西,当你不再需要它的时候一定要把它清理干净

清除MDC结构的重要性与对
ThreadLocal
变量调用
remove
方法的重要性相同。如果您没有调用clear,那么变量将保持连接到线程,如果您使用的是线程池,那么您可能会从之前使用的线程中得到无效的MDC值。因此,理想情况下,在代码中有一个点,您可以注册变量用于日志记录,在代码中有一个位置,您知道您不再需要它,您可以像我一样删除它或清除整个结构

此外,根据您在结构中放置的内容,如果不清除它,可能会阻止对不必要对象的垃圾收集。所以,底线是,最好在你知道你不再需要它的那一刻,清除它或移除你不需要的东西


理想情况下,您应该只在这里放置真正简单的对象,如字符串或基本值,这样可以避免类似的麻烦。

好的,有一个问题。我把这个东西作为一个样本项目进行了测试,它很有效。。但在我的实际应用中。。在应用程序启动(或引导)期间,将读取log4j属性。。它抛出了一个ClassNotFoundException,因为还没有创建MyPatternLayout。我们如何处理这种情况?可能是类加载器的问题。如果您将MyPatternLayout编译的类放在应用程序服务器的公共类加载器目录中会更好吗?好的,这是一个类路径问题。现在,我仍然不明白的是。请帮帮我。下面是我的应用程序启动并获取用户请求时发生的一系列步骤:1。在应用程序启动时,将创建MyPatternLayout的实例。但是,此时没有要设置的loginid。(还没有用户请求)2。当第一个请求进入服务层时,我如何将userid(它是请求的一部分)作为日志事件传递给MyPatternConverter?3.它的演出成功率有多高?4.有没有更好的方法来处理这个案子?我也试过MDC的方法。。它成功了。这个选项看起来简单多了!谢谢然而,我很想知道——MDC有多贵?我是说。。通常,设置自定义日志属性是一件坏事吗?另外,是否必须调用MDC.clear()?@aravindatta我已经扩展了我的答案以解决您的问题。