Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

slf4j,change logger or add appender at runtime

I'm using SLF4J for logging (with Log4J). The used appender is configured using an xml.

<appender name="business" class="org.apache.log4j.RollingFileAppender">
    <param name="maxFileSize" value="10MB" />
    <param name="maxBackupIndex" value="10" />
    <param name="File" value="${jboss.server.log.dir}/business.log" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %p [%t] %c - %m%n" />
    </layout>
</appender>
<category name="BusinessLogger" additivity="false">
    <level value="INFO" />
    <appender-ref ref="business" />
</category>

The log process is called in an interceptor. Now, I'm trying to test the output of the log. I call the logger at runtime using:

private static final Logger BUSINESS_LOGGER = LoggerFactory.getLogger("BusinessLogger");

In order to test the log (using junit), the output of the log needs to be saved somewhere as a variable. I have an idea about creating a custom appender which saves the last log into variable, but I can't seem to add an appender or change the appender because the Logger class in slf4j is an interface. Does anyone maybe know any workaround for this?

like image 630
Rowanto Avatar asked Oct 07 '13 14:10

Rowanto


3 Answers

slf4j is just a facade on the top of log4j/log4j2/logback. Once you declare the slf4j logger object:

private static final Logger BUSINESS_LOGGER = LoggerFactory.getLogger("BusinessLogger");

You can add your log4j appender using log4j LogManager.

LogManager.getLogger("BusinessLogger").addAppender(consoleAppender);

like image 149
Amit Samdarshi Avatar answered Dec 15 '22 00:12

Amit Samdarshi


So I kind of solved it with the help from alterfox.

When I called the logger using slf4j:

private static final Logger BUSINESS_LOGGER = LoggerFactory.getLogger("BusinessLogger");

It returns me an implementation of the logger adapter from slf4j which doesn't have the add appender method. So I called the logger using log4j Logger class

private static final Logger BUSINESS_LOGGER = Logger.getLogger("BusinessLogger")

Even though the class names are "Logger", they are from different package. The latter one, which is Log4J method, returns the actual Logger object from Log4J. Then the addAppender method becomes available. Well, I tried this, and it doesn't work (except it does). The thing is, I forgot to set the log level. So after adding the appender, I set the log level and then I see the logs coming through the second appender.

like image 33
Rowanto Avatar answered Dec 14 '22 23:12

Rowanto


This may seem simple but I found when I encountered this error I had forgotten to place the binder package in my POM for my application.

  <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.7</version>
  </dependency>
like image 34
shinds Avatar answered Dec 14 '22 23:12

shinds