Saturday, November 6, 2010

Send different logs to separate files in Tomcat with log4j

Everyone who works with web applications must have at least once wished for separating out his/her log files. It is painful to scan for infomation when multiple threads are dumping information from all over. I'm sure that all the great admins who watch over production or staging systems must quickly learn to use tools that allow them to set up rules and get a clean view of what they need but developers tend to be a more lethargic breed.

I finally decided to dig though the web and put this extremely basic skill into my bag of known tricks.
  1. If you use log4j, do not waste your time reading the instructions for JULI when you land on the page in Tomcat's documentation which talks about logging.properties file etc.
  2. Everything that you need to do in order to send the logs to a separate file can be done in log4j.properties.
    • Unless you are looking to do something really advanced, in which case you should use log4j.xml file.
    • You can read more about that in this Log4j tutorial with Tomcat examples.
  3. Here's the basic blurb (+/-) that you can throw in with minimal edits to get the job done.
    ##
    # Name your appender whatever you want, and choose whatever
    # implementation makes most sense for you.
    ##
    log4j.appender.yourAppenderNameGoesHere=org.apache.log4j.RollingFileAppender
    ##
    # You will most likely want to place the log file in a known location.
    # Leverage ${catalina.base}/logs/yourFilename.log to accomplish this.
    ##
    log4j.appender.yourAppenderNameGoesHere.File=${catalina.base}/logs/yourFileName.log
    ##
    # The rest is generic stuff which you can tweak as you please.
    ##
    log4j.appender.yourAppenderNameGoesHere.MaxFileSize=2MB
    log4j.appender.yourAppenderNameGoesHere.MaxBackupIndex=10
    log4j.appender.yourAppenderNameGoesHere.layout=org.apache.log4j.PatternLayout
    log4j.appender.yourAppenderNameGoesHere.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} %5p [%t] (%F:%L) - %m%n
  4. Use this blurb to direct the output from a particular package or a class to the appender you have created for the new separate file.
    # Redirect the logs from an entire package
    log4j.logger.com.my.packageName=ERROR, yourAppenderNameGoesHere
    # Redirect logs from only a specific class
    log4j.logger.com.my.packageName.MyClass=DEBUG, yourAppenderNameGoesHere
    # Set the additivity flag to false if you do NOT want the logs to show up redundantly in log files that the parent loggers point to
    log4j.additivity.com.my.packageName=false
    log4j.additivity.com.my.packageName.MyClass=false
  5. By the way, do NOT make the mistake of putting the name of your appender as one of the values in the following line of your log4j.properties file.
    # don't change this
    log4j.rootLogger=INFO, blah, blah, yourAppenderNameGoesHere

2 comments:

  1. Why must you NOT put the name of your appender as one of the values in the "log4j.rootLogger=" line!!?? An explanation would be helpful, thanks.

    ReplyDelete
    Replies
    1. Its been so long, I forgot! You can try putting it and report back about what, if anything, screws up.

      Delete