Posts tagged: logging

Apache Tomcat 6.0 Logging

ApacheĀ  Tomcat 6.0 logging

There are two easy places to find configuration information about Tomcat logging.

  • Apache Tomcat Home Documentation – http://tomcat.apache.org/tomcat-6.0-doc/logging.html
  • In any Tomcat instance – http://localhost:8080/docs/logging.html

A summary for the faint of heart.

Apache Tomcat 6.0 changes the logging model from Apache Tomcat 5.5. All comments from here on that refer to Apache Tomcat are referring to Apache Tomcat 6.0.

  • Java provides java.util.logging as a default logging package, configured by default in the JVM at $JAVA_HOME/lib/logging.properties
  • Apache Tomcat replaces the default Java java.util.logging implementation with org.apache.juli to add features, improve logging isolation and per-webapp control
  • The Apache Tomcat core configures logs based on settings in $CATALINA_HOME/conf/logging.properties.
  • Individual webapps configure logging based on settings in WEB-INF/classes/logging.properties.

Log4j can be used instead of the org.apache.juli package for Tomcat’s internal logging and/or individual webapp logging.

  • Log4j can be used to manage Tomcat’s internal logging instance of the org.apache.juli package. Refer to the Apache Tomcat logging documentation for further information.
  • To use log4j within a specific webapp, two simple steps are required
    • Copy a log4j-x.y.z.jar to WEB-INF/lib
    • Create a log4j.properties file in WEB-INF/classes

Java – log4j configuration

Log4j is a widely-used Java logging package.

How does Log4j find configuration information?

From the Log4j Manual – Default initialization procedure

The log4j library does not make any assumptions about its environment. In particular, there are no default log4j appenders. Under certain well-defined circumstances however, the static inializer of the Logger class will attempt to automatically configure log4j. The Java language guarantees that the static initializer of a class is called once and only once during the loading of a class into memory. It is important to remember that different classloaders may load distinct copies of the same class. These copies of the same class are considered as totally unrelated by the JVM.

The default initialization is very useful in environments where the exact entry point to the application depends on the runtime environment. For example, the same application can be used as a stand-alone application, as an applet, or as a servlet under the control of a web-server.

The exact default initialization algorithm is defined as follows:

  1. Setting the log4j.defaultInitOverride system property to any other value then “false” will cause log4j to skip the default initialization procedure (this procedure).
  2. Set the resource string variable to the value of the log4j.configuration system property. The preferred way to specify the default initialization file is through the log4j.configuration system property. In case the system property log4j.configuration is not defined, then set the string variable resource to its default value “log4j.properties”.
  3. Attempt to convert the resource variable to a URL.
  4. If the resource variable cannot be converted to a URL, for example due to a MalformedURLException, then search for the resource from the classpath by calling org.apache.log4j.helpers.Loader.getResource(resource, Logger.class) which returns a URL. Note that the string “log4j.properties” constitutes a malformed URL. See Loader.getResource(java.lang.String) for the list of searched locations.
  5. If no URL could not be found, abort default initialization. Otherwise, configure log4j from the URL. The PropertyConfigurator will be used to parse the URL to configure log4j unless the URL ends with the “.xml” extension, in which case the DOMConfigurator will be used. You can optionaly specify a custom configurator. The value of the log4j.configuratorClass system property is taken as the fully qualified class name of your custom configurator. The custom configurator you specify must implement the Configurator interface.

From the Log4j Manual – Default initialization under Tomcat

The default log4j initialization is particularly useful in web-server environments. Under Tomcat 3.x and 4.x, you should place the log4j.properties under the WEB-INF/classes directory of your web-applications. Log4j will find the properties file and initialize itself. This is easy to do and it works. You can also choose to set the system property log4j.configuration before starting Tomcat. For Tomcat 3.x The TOMCAT_OPTS environment variable is used to set command line options. For Tomcat 4.0, set the CATALINA_OPTS environment variable instead of TOMCAT_OPTS. Example 1

The Unix shell command

   export TOMCAT_OPTS="-Dlog4j.configuration=foobar.txt"

tells log4j to use the file foobar.txt as the default configuration file. This file should be place under the WEB-INF/classes directory of your web-application. The file will be read using the PropertyConfigurator. Each web-application will use a different default configuration file because each file is relative to a web-application.

Example 2

The Unix shell command

   export TOMCAT_OPTS="-Dlog4j.debug -Dlog4j.configuration=foobar.xml"

tells log4j to output log4j-internal debugging information and to use the file foobar.xml as the default configuration file. This file should be place under the WEB-INF/classes directory of your web-application. Since the file ends with a .xml extension, it will read using the DOMConfigurator. Each web-application will use a different default configuration file because each file is relative to a web-application.

Example 3

The Windows shell command

   set TOMCAT_OPTS=-Dlog4j.configuration=foobar.lcf -Dlog4j.configuratorClass=com.foo.BarConfigurator

tells log4j to use the file foobar.lcf as the default configuration file. This file should be place under the WEB-INF/classes directory of your web-application. Due to the definition of the log4j.configuratorClass system property, the file will be read using the com.foo.BarConfigurator custom configurator. Each web-application will use a different default configuration file because each file is relative to a web-application.

Example 4

The Windows shell command

   set TOMCAT_OPTS=-Dlog4j.configuration=file:/c:/foobar.lcf

tells log4j to use the file c:\foobar.lcf as the default configuration file. The configuration file is fully specified by the URL file:/c:/foobar.lcf. Thus, the same configuration file will be used for all web-applications.

Different web-applications will load the log4j classes through their respective classloaderss. Thus, each image of the log4j environment will act independetly and without any mutual synchronization. For example, FileAppenders defined exactly the same way in multiple web-application configurations will all attempt to write the same file. The results are likely to be less than satisfactory. You must make sure that log4j configurations of different web-applications do not use the same underlying system resource.

Initialization servlet

It is also possible to use a special servlet for log4j initialization. Here is an example,

package com.foo;

import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.IOException;

public class Log4jInit extends HttpServlet {

  public
  void init() {
    String prefix =  getServletContext().getRealPath("/");
    String file = getInitParameter("log4j-init-file");
    // if the log4j-init-file is not set, then no point in trying
    if(file != null) {
      PropertyConfigurator.configure(prefix+file);
    }
  }

  public
  void doGet(HttpServletRequest req, HttpServletResponse res) {
  }
}

Define the following servlet in the web.xml file for your web-application.

  <servlet>
    <servlet-name>log4j-init</servlet-name>
    <servlet-class>com.foo.Log4jInit</servlet-class>

    <init-param>
      <param-name>log4j-init-file</param-name>
      <param-value>WEB-INF/classes/log4j.lcf</param-value>
    </init-param>

    <load-on-startup>1</load-on-startup>
  </servlet>

Writing an initialization servlet is the most flexible way for initializing log4j. There are no constraints on the code you can place in the init() method of the servlet.

Configuring java.util.logging

What a pain.

Good article Logger.properties file for configuring logger settings from IBM Websphere.

Logging.properties not logging.properties in

  • the META-INF directory of the Java archive (JAR) file for the application
  • the WEB-INF/classes directory of a Web Archive (WAR)
  • directories included in the class path of an application module
  • directories included in the application class path
  • Java command-line -Djava.util.logging.config.file=

Centralized logging

Most approaches seem to use some variant of syslog + remote access

Enhanced version of syslog syslog-ng.

Centralized (aka remote) syslog discussion and tutorial. Another article.

Adding new facilities – apparently not just a configuration issue.

  • Facilities are defined in /usr/include/syslog.h
  • Looks like it’s pretty involved
  • Probably better to use local0 – local7

Managing the daemon – Linux

  • /etc/init.d/syslog restart / reload

Managing the daemon – OS X

  • OS X – enabling remote syslog access – article
  • /System/Library/LaunchDaemons/com.apple.syslogd.plist
  • # launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist
  • # launchctl load /System/Library/LaunchDaemons/com.apple.syslogd.plist

Enable remote logging – Linux

  • /sbin/syslogd -r
  • Probably edit somewhere like /etc/init.d/syslog and/or /etc/sysconfig/syslog

Testing syslog setups manually

  • logger -p local3.debug [message]

WordPress Themes