方法名称在 Java 的 log4j 记录器中打印不正确

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22233965/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:30:01  来源:igfitidea点击:

method name not printing correctly in log4j logger in Java

javalogginglog4jmethod-names

提问by eagertoLearn

My log happens in getParam()method. but it is logged as mainmethod. And I have three objects, but I do not see any information as to which object is logging. I want that information too.

我的日志发生在getParam()方法中。但它被记录为main方法。我有三个对象,但我没有看到关于哪个对象正在记录的任何信息。我也想要那个信息。

Here is the output:

这是输出:

INFO  [main]: info
INFO  [main]: debug
INFO  [main]: trace

here is the code:

这是代码:

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

class Log4jTest {

    private static Logger log=Logger.getLogger(Log4jTest.class);
    private String param;

    public Log4jTest(String param){
        this.param=param;
    }

    public String getParam(){
        log.info(param);
        return param;
    }

}

public class Log4j_testing {
    public static void main(String[] args) throws FileNotFoundException{
        Log4jTest l1= new Log4jTest("info");
        l1.getParam();
        Log4jTest l2= new Log4jTest("debug");
        l2.getParam();
        Log4jTest l3= new Log4jTest("trace");
        l3.getParam();
    }
}

my log4j.properties:

我的 log4j.properties:

log4j.rootLogger=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.stdout.layout.ConversionPattern=%-5p [%t]: %m%n

On a different note: if I have the above commented line uncommented and the last line commented out, I get

换个说法:如果我将上面的注释行取消注释,最后一行注释掉,我得到

11:19:41,586  INFO Log4jTest:19 - info
11:19:41,589  INFO Log4jTest:19 - debug
11:19:41,589  INFO Log4jTest:19 - trace

It gives the correct line number(19) that is being logged, but not the correct method.

它给出了正在记录的正确行号(19),但不是正确的方法。

回答by Peter Keller

Add %Mto your pattern. However, as it is stated in the JavaDoc: "Generating caller location information is extremely slow and should be avoided unless execution speed is not an issue. "

添加%M到您的模式。但是,正如JavaDoc中所述:“生成调用者位置信息的速度非常慢,除非执行速度不是问题,否则应该避免。”

回答by ubiquibacon

The doc for PatteryLayouttells us that %Mwill provide the method name where the logging request was made, but I have not ever been able to get it to work and ended up putting the method name in the log message.

PatteryLayout的文档告诉我们,%M它将提供发出日志记录请求的方法名称,但我一直无法让它工作并最终将方法名称放入日志消息中。

回答by lmiguelmh

There are some cases when some patterns are ignoredor never logged (%C, %F, %l, %L, %M). This is true when using asynchronous loggers and asynchronous appenders. Here is what the user guide for Log4j 2.xhas to said about this (see page 217-218):

在某些情况下,某些模式被忽略或从不记录 ( %C, %F, %l, %L, %M)。使用异步记录器和异步追加器时确实如此。以下是Log4j 2.x用户指南对此的说明(参见第 217-218 页):

If one of the layouts is configured with a location-related attribute like HTML locationInfo, or one of the patterns %C or %class, %F or %file, %l or %location, %L or %line, %M or %method, Log4j will take a snapshot of the stack, and walk the stack trace to find the location information.

This is an expensive operation: 1.3 - 5 times slower for synchronous loggers. Synchronous loggers wait as long as possible before they take this stack snapshot. If no location is required, the snapshot will never be taken.

However, asynchronous loggers need to make this decision before passing the log message to another thread; the location information will be lost after that point. The performance impact of taking a stack trace snapshot is even higher for asynchronous loggers: logging with location is 30-100 times slower than without location. For this reason, asynchronous loggers and asynchronous appenders do not include location information by default.

You can override the default behaviour in your logger or asynchronous appender configuration by specifying includeLocation="true".

如果布局之一配置了与位置相关的属性,如 HTML locationInfo,或模式之一 %C 或 %class、%F 或 %file、%l 或 %location、%L 或 %line、%M 或 %方法,Log4j 会对堆栈进行快照,并遍历堆栈跟踪以查找位置信息。

这是一个昂贵的操作:同步记录器慢 1.3 - 5 倍。同步记录器在获取此堆栈快照之前等待尽可能长的时间。如果不需要位置,则永远不会拍摄快照。

但是,异步记录器需要在将日志消息传递给另一个线程之前做出这个决定;在那之后位置信息将丢失。对于异步记录器,获取堆栈跟踪快照的性能影响甚至更高:使用位置记录比没有位置记录慢 30-100 倍。出于这个原因,异步记录器和异步附加器默认不包含位置信息。

您可以通过指定来覆盖记录器或异步 appender 配置中的默认行为includeLocation="true"