Log4j getAllAppenders() 返回 null 枚举

Lah*_*ima 4 java log4j2

我正在尝试获取 log4j 日志文件的文件名。我尝试了以下答案中给出的解决方案。

/sf/answers/308097121/

Enumeration e = Logger.getRootLogger().getAllAppenders();
while ( e.hasMoreElements() ){
  Appender app = (Appender)e.nextElement();
  if ( app instanceof FileAppender ){
    System.out.println("File: " + ((FileAppender)app).getFile());
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,Logger.getRootLogger().getAllAppenders()返回一个空枚举。rootLogger(我按照答案中提到的小心使用)

以下是我的log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
    <Properties>
        <!-- This will be used if LOG_FILE_NAME env variable is not set  -->
        <Property name="LOG_FILE_NAME">my_app_log</Property>
    </Properties>
    <Appenders>
        <RollingFile name="RollingFile-${web:contextPath}"
                     fileName="${sys:catalina.base}/logs/${env:LOG_FILE_NAME}.log" immediateFlush="true"
                     filePattern="${sys:catalina.base}/logs/${env:LOG_FILE_NAME}.log.%d{yyyy_MM_dd.HH_mm_ss}">
            <PatternLayout pattern="%d{yyyyMMdd-HHmmss.SSS}|%-5p|%t| %-100m (%c{1})%n"/>
            <Policies>
                <OnStartupTriggeringPolicy/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="DEBUG" includeLocation="false">
            <AppenderRef ref="RollingFile-${web:contextPath}"/>
        </Root>
    </Loggers>
</Configuration>
Run Code Online (Sandbox Code Playgroud)

知道为什么吗?

raj*_*uGT 5

我刚刚对forgrep的整个源代码进行了研究,发现只有一个地方它得到了实现。apache-log4j-2.3-srcgetAllAppenders

在类别.java中

@SuppressWarnings("rawtypes")
public Enumeration getAllAppenders() {
    return NullEnumeration.getInstance();
}
Run Code Online (Sandbox Code Playgroud)

上述方法返回其中没有元素的枚举。

另一个是在LoggerTest.java中,用于执行测试用例。

/**
 * Add an appender and see if it can be retrieved.
 *  Skipping this test as the Appender interface isn't compatible with legacy Log4j.
public void testAppender1() {
    logger = Logger.getLogger("test");
    a1 = new ListAppender("testAppender1");
    logger.addAppender(a1);

    Enumeration enumeration = logger.getAllAppenders();
    Appender aHat = (Appender) enumeration.nextElement();
    assertEquals(a1, aHat);
} */

/**
 * Add an appender X, Y, remove X and check if Y is the only
 * remaining appender.
 * Skipping this test as the Appender interface isn't compatible with legacy Log4j.
public void testAppender2() {
    a1 = new FileAppender();
    a1.setName("testAppender2.1");
    a2 = new FileAppender();
    a2.setName("testAppender2.2");

    logger = Logger.getLogger("test");
    logger.addAppender(a1);
    logger.addAppender(a2);
    logger.removeAppender("testAppender2.1");
    Enumeration enumeration = logger.getAllAppenders();
    Appender aHat = (Appender) enumeration.nextElement();
    assertEquals(a2, aHat);
    assertTrue(!enumeration.hasMoreElements());
}  */
Run Code Online (Sandbox Code Playgroud)

看到上面的评论,看起来它已经被弃用了,甚至测试用例都被注释掉了。但我不确定,我实际上试图查明他们是否在任何地方声明过,但找不到。

所以我认为这会很有帮助,除非现在浪费时间进行调试。


正如这个答案中所解释的,使用 getAppenders api 像

Logger logger = LogManager.getLogger();
Map<String, Appender> appenderMap = 
        ((org.apache.logging.log4j.core.Logger) logger).getAppenders();
Run Code Online (Sandbox Code Playgroud)


rgo*_*ers 5

您将 Log4j 1 构造与 Log4j 2 混合。您无法使用 Log4j 1 API 查询 Log4j 2 配置。

要打印 FileAppender 的文件名,请执行以下操作:

final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
for (Map.Entry<String, Appender> entry : config.getAppenders().entrySet()) {
    if (entry.getValue() instanceof FileAppender) {
        System.out.println("File: " + ((FileAppender)entry.getValue()).getFileName());
    }
}
Run Code Online (Sandbox Code Playgroud)