tags:

views:

229

answers:

2

With log4j, I'd like to revert to a ConsoleAppender if the FileAppender has problems writing to the specified log file. This means catching a FileNotFoundException or an IOException and switching to a ConsoleAppender.

Has this been done before or will I have to create a new appender - something along the lines of:

private WriterAppender appender;

public FileOrConsoleAppender(Layout layout, String filename, boolean append) {
    try {
        appender = new FileAppender(layout, filename, append, bufferedIO, bufferSize);
    }
    catch (IOException e) {
        appender = new ConsoleAppender(layout);
    }
}

UPDATE - HOW I DID IT:

Thanks to @jsight, for pointing me to FallBackErrorHandler.

Here is my log4j xml configuration which reverts to a ConsoleAppender, if FileAppender fails:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">

  <!-- A Console appender -->
  <appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d %-5p %30.30c - %m%n"/>
    </layout>
  </appender>

  <!-- A File appender, with fallback to Console-->
  <appender name="file" class="org.apache.log4j.DailyRollingFileAppender">
  <errorHandler class="org.apache.log4j.varia.FallbackErrorHandler">
       <root-ref/>
       <appender-ref ref="console"/>
  </errorHandler>
    <param name="File" value="C:/temp/test.log"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d %-5p %30.30c - %m%n"/>
    </layout>
  </appender>

<root>
       <level value="INFO" />
       <appender-ref ref="file" />
</root>

</log4j:configuration>
+1  A: 

You would have to create a new/custom appender, as log4j will never throw an Exception to your code if there is a problem logging to an appender. This is a design goal and feature of log4j.

From the log4j FAQ:

Is log4j a reliable logging system?
No. log4j is not reliable. It is a best-effort fail-stop logging system.

By fail-stop, we mean that log4j will not throw unexpected exceptions at run-time potentially causing your application to crash. If for any reason, log4j throws an uncaught exception, please send an email to the [email protected] mailing list. Uncaught exceptions are handled as serious bugs requiring immediate attention.

Moreover, log4j will not revert to System.out or System.err when its designated output stream is not opened, is not writable or becomes full. This avoids corrupting an otherwise working program by flooding the user's terminal because logging fails. However, log4j will output a single message to System.err indicating that logging can not be performed.

What are the features of log4j?
...
log4j is fail-stop. However, altough it certainly strives to ensure delivery, log4j does not guarantee that each log statement will be delivered to its destination.

matt b