Creating multiple log files of different content with log4j

JavaLog4j

Java Problem Overview


Is there a way to configure log4j so that it outputs different levels of logging to different appenders?

I'm trying to set up multiple log files. The main log file would catch all INFO and above messages for all classes. (In development, it would catch all DEBUG and above messages, and TRACE for specific classes.)

Then, I would like to have a separate log file. That log file would catch all DEBUG messages for a specific subset of classes, and ignore all messages for any other class.

Is there a way to get what I'm after?

Java Solutions


Solution 1 - Java

This should get you started:

log4j.rootLogger=QuietAppender, LoudAppender, TRACE
# setup A1
log4j.appender.QuietAppender=org.apache.log4j.RollingFileAppender
log4j.appender.QuietAppender.Threshold=INFO
log4j.appender.QuietAppender.File=quiet.log
...


# setup A2
log4j.appender.LoudAppender=org.apache.log4j.RollingFileAppender
log4j.appender.LoudAppender.Threshold=DEBUG
log4j.appender.LoudAppender.File=loud.log
...

log4j.logger.com.yourpackage.yourclazz=TRACE

Solution 2 - Java

Perhaps something like this?

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 <!-- general application log -->
 <appender name="MainLogFile" class="org.apache.log4j.FileAppender">
  <param name="File" value="server.log" />
  <param name="Threshold" value="INFO" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-5p %t [%-40.40c] %x - %m%n"/>
  </layout>
 </appender> 
 <!-- additional fooSystem logging -->
 <appender name="FooLogFile" class="org.apache.log4j.FileAppender">
  <param name="File" value="foo.log" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-5p %t [%-40.40c] %x - %m%n"/>
  </layout>
 </appender>
 <!-- foo logging -->
 <logger name="com.example.foo">
  <level value="DEBUG"/>
  <appender-ref ref="FooLogFile"/>
 </logger>
 <!-- default logging -->
 <root>
  <level value="INFO"/>
  <appender-ref ref="MainLogFile"/>
 </root>
</log4j:configuration>

Thus, all info messages are written to server.log; by contrast, foo.log contains only com.example.foo messages, including debug-level messages.

Solution 3 - Java

I had this question, but with a twist - I was trying to log different content to different files. I had information for a LowLevel debug log, and a HighLevel user log. I wanted the LowLevel to go to only one file, and the HighLevel to go to both a file, and a syslogd.

My solution was to configure the 3 appenders, and then setup the logging like this:

log4j.threshold=ALL
log4j.rootLogger=,LowLogger

log4j.logger.HighLevel=ALL,Syslog,HighLogger
log4j.additivity.HighLevel=false

The part that was difficult for me to figure out was that the 'log4j.logger' could have multiple appenders listed. I was trying to do it one line at a time.

Hope this helps someone at some point!

Solution 4 - Java

For the main logfile/appender, set up a .Threshold = INFO to limit what is actually logged in the appender to INFO and above, regardless of whether or not the loggers have DEBUG, TRACE, etc, enabled.

As for catching DEBUG and nothing above that... you'd probably have to write a custom appender.

However I'd recommend not doing this, as it sounds like it would make troubleshooting and analysis pretty hard:

  1. If your goal is to have a single file where you can look to troubleshoot something, then spanning your log data across different files will be annoying - unless you have a very regimented logging policy, you'll likely need content from both DEBUG and INFO to be able to trace execution of the problematic code effectively.
  2. By still logging all of your debug messages, you are losing any performance gains you usually get in a production system by turning the logging (way) down.

Solution 5 - Java

Demo link: https://github.com/RazvanSebastian/spring_multiple_log_files_demo.git

My solution is based on XML configuration using spring-boot-starter-log4j. The example is a basic example using spring-boot-starter and the two Loggers writes into different log files.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanielView Question on Stackoverflow
Solution 1 - JavajasonnerothinView Answer on Stackoverflow
Solution 2 - JavaaraqnidView Answer on Stackoverflow
Solution 3 - JavaKieveliView Answer on Stackoverflow
Solution 4 - Javamatt bView Answer on Stackoverflow
Solution 5 - JavaRzv RazvanView Answer on Stackoverflow