Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j getAllAppenders() returns null enumeration

Tags:

java

log4j2

I am trying to get the file name of my log4j log file. I tried the solution given in following answer.

https://stackoverflow.com/a/4401387/1015678

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

But, Logger.getRootLogger().getAllAppenders() returns a null enumeration. (I took care to use rootLogger as mentioned in the answer)

Following is my 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>

Any idea why?

like image 919
Lahiru Chandima Avatar asked Oct 25 '25 14:10

Lahiru Chandima


2 Answers

I just did grep on the whole source of apache-log4j-2.3-src for getAllAppenders and I found only in one place it is getting implemented.

In Category.java

@SuppressWarnings("rawtypes")
public Enumeration getAllAppenders() {
    return NullEnumeration.getInstance();
}

The above method returns Enumeration having no elements in it.

The other was in LoggerTest.java, to execute the test case.

/**
 * 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());
}  */

Seeing the above comments, it looks like it is deprecated, even test case is commented out. But I'm not sure, I tried to find out actually if they have declared anywhere, but couldnt find.

So I thought this will be helpful, unless wasting time on this now for debugging.


As explained in this answer use getAppenders api like

Logger logger = LogManager.getLogger();
Map<String, Appender> appenderMap = 
        ((org.apache.logging.log4j.core.Logger) logger).getAppenders();
like image 89
rajuGT Avatar answered Oct 27 '25 04:10

rajuGT


You are mixing Log4j 1 constructs with Log4j 2. You cannot query the Log4j 2 configuration using the Log4j 1 API.

To print out the name of the file for the FileAppender do:

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());
    }
}
like image 21
rgoers Avatar answered Oct 27 '25 03:10

rgoers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!