Papertrail Knowledge Base

Java log4j logging

Intro

log4j is "a popular logging package written in Java. One of its distinctive features is the notion of inheritance in loggers. Using a logger hierarchy it is possible to control which log statements are output at arbitrary granularity."

Before implementing log4j on a new app, seriously consider using:

Papertrail supports aggregating messages from a native log4j appender, providing a live searchable console for your Java (JRE/JVM) app logs. Here's how.

Installation

Install log4j

Install log4j in your app or J2EE servlet container. This is basically adding the log4j jar to your classpath, creating a config file, and loading and invoking the classes to output messages.

Here's more specifics for using log4j in:

log4j includes SyslogAppender in the standard distribution. log4j 1.2.14 and newer support user-specified destination ports, which make Papertrail configuration easier. The steps below assume 1.2.14 or newer.

Setup SyslogAppender for Papertrail

Edit log4j.xml and add this within the <log4j:configuration> block.

Important: In the sample below, replace <host>.papertrailapp.com and XXXXX with the details from Papertrail's Add Systems page.

<appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender"> 
  <errorHandler/>
  <param name="Facility" value="LOCAL7"/>
  <param name="FacilityPrinting" value="false"/>
  <param name="Header" value="true"/>
  <param name="SyslogHost" value="<host>.papertrailapp.com:XXXXX"/>
  <param name="ConversionPattern" value="%p: %c{2} %x %m %n"/>
</appender>

Important: where the config snippet above has <errorHandler/>, you may need to provide a class attribute that is your app server's ErrorHandler implementation. For example, for Tomcat:

<errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler" />

or for JBoss:

<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler" />

Alternatively, to use log4j.properties, add the following (replacing <host>.papertrailapp.com and XXXXX as explained above):

log4j.rootLogger=INFO, syslog

log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
log4j.appender.syslog.Facility=LOCAL7 
log4j.appender.syslog.FacilityPrinting=false 
log4j.appender.syslog.Header=true 
log4j.appender.syslog.SyslogHost=<host>.papertrailapp.com:XXXXX
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout 
log4j.appender.syslog.layout.ConversionPattern=%p: (%F:%L) %x %m %n

Enable appender

Outside of the appenders section (in the <root> block), add this to enable the syslog appender you just created:

<appender-ref ref="SYSLOG" />

Change sender identifier (optional)

With the configuration option Header above, SyslogAppender automatically prepends the timestamp (in MMM dd HH:mm:ss format) and the system hostname, which Papertrail uses as the sender identifier. In most cases, this is the best sender identifier.

To use a different sender identifier (such as the name of the app or an arbitrary string), disable the Header option and include those within the ConversionPattern. This configuration:

  <param name="Header" value="true"/>
  <param name="ConversionPattern" value="%p: %c{2} %x %m %n"/>

Is functionally equivalent to this one, except that this configuration is manually outputting the date and sender ID my-app instead of relying on log4j's Header option:

  <param name="Header" value="false"/>
  <param name="ConversionPattern" value="%d{MMM dd HH:mm:ss} my-app %p: %c{2} %x %m %n"/>

When editing the ConversionPattern, retain the %d{MMM dd HH:mm:ss} my-app at the start.

Edit Format (optional)

Finally, you can optionally edit the message format using standard log4j output formatting parameters. To do so, include a <layout> block within <appender>. Here's an extremely verbose example:

<layout>
  <param name="ConversionPattern" value="%t %5r %-5p %c{2} [%x] %m %n"/>
</layout>

For more details about the ConversionPattern you can refer to the documentation for PatternLayout.

Use

Papertrail is just another log4j target, so no code changes should be needed.

If you aren't yet using log4j, generate messages with a snippet like this. From the log4j manual:

// get a logger instance named com.foo.Bar
Logger barlogger = Logger.getLogger("com.foo.Bar");
barlogger.warn("Low fuel level.");
barlogger.debug("Starting search for nearest gas station.");