'Find out what appenders will my logger use?

Summary:

Given a Logger object I want to find out the appender or file name(s) that this logger will write the message to.

(Logger -> org.slf4j.Logger interface that implements ch.qos.logback.classic.Logger)

Details:

I am migrating from traditional log files to splunk.

The logback.xml is configured to use different log file (names) for different modules.

    <appender name="FLYWAY_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/flyway.log</file>
        ...
    </appender>
    <logger level="INFO" name="com.awesomeness.scripts.flyway" additivity="false">
        <appender-ref ref="FLYWAY_LOG"/>
    </logger>

    <appender name="API_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/api.log</file>
        ...
    </appender>
    <logger level="INFO" name="com.awesomeness.common.filter.LogbackFilter" additivity="false">
        <appender-ref ref="API_LOG"/>
    </logger>

This used to work well and good in past as different things would be logged in different files.

But for Splunk, I am simply emitting the log messages to one endpoint. This logs the messages in Splunk but am unable to segregate logs into categories like API_LOG, FLYWAY_LOG etc.

So all I want to do is in the following function figure out the appender name(s) from the logger object.

private static void logMessage(Logger logger, String logLevel, Throwable e, Object... objects) {
   /// Some way to get logger.getCurrentAppenders() -> API_LOG
}

What am I planning to do?

If worse comes to worse I will write a code that keeps on climbing the parent using the logger name till I find an attached Appender.

(Sadly, the "parent" object in ch.qos.logback.classic.Logger is private)


// Check if the logger itself has any appender
if (logger.iteratorForAppenders().hasNext()) {
  return logger.iteratorForAppenders().next().getName();
}

// If not then keep going up the package name hierarchy and see if that has any appenders. Eg.

// Lets say this is "com.awesomeness.common.masterData.service.impl.MasterDataServiceImpl"
String name = logger.getName();

// Check one by one
// "com.awesomeness.common.masterData.service.impl" -> return if has any appender else,
// "com.awesomeness.common.masterData.service" -> return if has any appender else,
// "com.awesomeness.common.masterData" -> return if has any appender else,
// .. and so on

Not a big fan of the above! Any other cleaner way would be appreciated.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source