Working with the Apache log4j Configuration File

The Apache log4j package (org.apache.log4j) provides a means for logging behavior, priority levels, and output formats with no need to change or recompile application code. Upon application initialization, log4j looks for a configuration properties file called log4j.properties in a Java™ 2 Enterprise Edition (J2EE) module's classpath. The lookup takes place at static initialization time and the properties file can be written in XML or in a Java properties format (keyword=value pairs). In this section, we will describe how to modify a provided sample file to configure logging for your client application.

CAUTION  If you choose to leverage the server-side implementation of the TraceLoggingConfiguration object to enable trace logging, you cannot also use the log4j.properties file to provide additional logging configuration. However, you can instruct the system to bypass the server implementation, and only use the settings in the log4j.properties file, by specifying the "-DskipTLC=true" command line option. This may be useful when troubleshooting specific server startup issues, such as when the Global Configuration Database (GCD) is not able to load.

Sample log4j Configuration Files

During Content Engine installation, two log4j sample files are placed on the system in the ContentEngine\config\samples\ folder:

In order to leverage the log4j functionality, these configuration files should be copied into the ContentEngine\config\ folder as log4j.properties and log4j.xml, respectively, with their suffix extensions removed. You can then make adjustments as necessary to the copied configuration files in the ContentEngine\config\ folder, depending on your requirements. Upon application initialization, log4j performs a lookup operation to locate and automatically read the ContentEngine\config\log4j.properties file.

NOTE  If you do modify the trace logging settings within the log4j.properties client configuration file during runtime, you do not need to restart the application server.

The following sections describe how to configure log4j by modifying various statements in the sample log4j.properties file. For information on working with an XML format file, refer to the Apache log4j documentation.

Modifying the log4j Configuration File

Logging behavior (what we want to log, enabling and disabling logging, output targets, and formatting of output) is configurable and can be set at runtime. In a Java format configuration file, the log4j package looks for keyword=value pairs to control the logging behavior. You determine the subsystems for which you want to perform trace level logging and the level of error logging detail to include in the log entries, and then specify the appropriate values in the properties file. (Refer also to Level inheritance.) You can configure log4j to record its log entries to many types of output locations, both local and remote, and specify the type of output location to use through configuration options.

Specify the Root Logging Operation for Gathering Data

The rootLogger log4j keyword represents the core class of the log4j package and is the highest entity in the logger hierarchy. Its assigned level of ERROR is used by any child logger that does not have an explicitly-set level of its own or does not have an ancestor in the logger hierarchy from which to inherit.

The rootLogger is the first keyword specified in the log4j.properties file, as follows:

################################################################################
# Root logger
################################################################################
log4j.rootLogger=off, FileNetNullAppender

In the provided sample file, the rootLogger is also configured to use the FileNetNullAppender. This is explained in more detail in the following subsection.

Specify Where the Data Will Be Written Using Appenders

An appender sends formatted log entries to a specified output destination. Destination types can be a file, a console, redirected to a Windows® Event logger, forwarded to a remote log4j server, and so on. (See the log4j documentation for all of the output destination options.)

You can attach more than one appender to a single logger. For example, you might want to write the output to the console, but also to a backup file that can be retained. The logger writes enabled logging requests to each appender.

In the provided log4j.properties file, FileNet specifies the following default appenders:

################################################################################
# Appenders
################################################################################
#=== FileNetNullAppender
log4j.appender.FileNetNullAppender=org.apache.log4j.varia.NullAppender
#=== FileNetConsoleAppender
log4j.appender.FileNetConsoleAppender=org.apache.log4j.ConsoleAppender
...
#=== FileNetErrorAppender
log4j.appender.FileNetErrorAppender=org.apache.log4j.FileAppender
log4j.appender.FileNetErrorAppender.File=/p8_api_error.log
...
#=== FileNetTraceAppender
log4j.appender.FileNetTraceAppender=org.apache.log4j.FileAppender
log4j.appender.FileNetTraceAppender.File=/p8_api_trace.log
...
#=== FileNetErrorRollingAppender
log4j.appender.FileNetErrorRollingAppender=org.apache.log4j.RollingFileAppender
log4j.appender.FileNetErrorRollingAppender.File=/p8_api_error.log
log4j.appender.FileNetErrorRollingAppender.MaxFileSize=100MB
log4j.appender.FileNetErrorRollingAppender.MaxBackupIndex=1
...
#=== FileNetTraceRollingAppender
log4j.appender.FileNetTraceRollingAppender=org.apache.log4j.RollingFileAppender
log4j.appender.FileNetTraceRollingAppender.File=/p8_api_trace.log
log4j.appender.FileNetTraceRollingAppender.MaxFileSize=100MB
log4j.appender.FileNetTraceRollingAppender.MaxBackupIndex=1
...

For more information about appenders, see Trace Log Appender Names.

Specify the Format of the Gathered Data Using Layout

The configuration settings for an Appender may include the layout keyword. The Layout abstract class is used to format the Appender output according to specified criteria and is assigned using other keywords:

In the provided log4j.properties file, layouts with ConversionPatterns are defined for the following appenders:

#=== FileNetConsoleAppender
...
log4j.appender.FileNetConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileNetConsoleAppender.layout.ConversionPattern=%d %5p [%t] - %m\r\n
#=== FileNetErrorAppender
...
log4j.appender.FileNetErrorAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileNetErrorAppender.layout.ConversionPattern=%d %5p [%t] - %m\r\n
#=== FileNetTraceAppender
...
# This is the layout that the TraceLoggingConfiguration framework on the server uses.
# To use this layout, Jace.jar must be present in the classpath.
#log4j.appender.FileNetTraceAppender.layout=com.filenet.apiimpl.util.TraceLayout
# Comment out the following lines if using the FileNet TraceLayout
log4j.appender.FileNetTraceAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileNetTraceAppender.layout.ConversionPattern=%d %5p [%t] - %m\r\n
#=== FileNetErrorRollingAppender
...
log4j.appender.FileNetErrorRollingAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileNetErrorRollingAppender.layout.ConversionPattern=%d %5p [%t] - %m\r\n
#=== FileNetTraceRollingAppender
...
# This is the layout that the TraceLoggingConfiguration framework on the server uses.
# To use this layout, Jace.jar must be present in the classpath.
#log4j.appender.FileNetTraceRollingAppender.layout=com.filenet.apiimpl.util.TraceLayout
# Comment out the following lines if using the FileNet TraceLayout
log4j.appender.FileNetTraceRollingAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileNetTraceRollingAppender.layout.ConversionPattern=%d %5p [%t] - %m\r\n

Choose the Custom Layout Class or a ConversionPattern

In the above example, certain statements are colored blue for FileNetTraceAppender and FileNetTraceRollingAppender. These statements can be used to instruct the system to use the custom FileNet Layout class, com.filenet.apiimpl.util.TraceLayout, to format trace output. This layout class is used when the server automatically configures log4j based on the TraceLoggingConfiguration object. If you have instructed the system to bypass the TraceLoggingConfiguration implementation, but would still like trace output to be formatted in the same manner as if TraceLoggingConfiguration were in use, uncomment the statements colored blue and comment out the statements colored olive. In addition, be sure that the Jace.jar file is present in the startup classpath.

Specify the Error Logging Operations

The logger class is responsible for handling most of the log operations. You can set the level of a logger to any of the normal, special, or custom levels available. (When assigning levels, refer to Performance Considerations.) If you do not explicitly set the logger’s level, it inherits its level according to the log4j inheritance rules.

In the sample log4j.properties file, FileNet provides configuration settings for the default error logger filenet_error, as well as the API subsystem (commented out):

################################################################################
# Error Loggers:
#
# Set log level to either one of off/fatal/error/warn/info.
# Child logger's value overwrites parent logger's value.
# If a logger is not specified, it inherits its value from its parent.
# By default, error logging is set to level ERROR.
################################################################################
# Don't comment out the following line since it has appenders.
log4j.logger.filenet_error = error, FileNetConsoleAppender, FileNetErrorRollingAppender, FileNetTraceRollingAppender
#=== SubSystem: api
# Uncomment to set error logging level to WARN.
#log4j.logger.filenet_error.api = warn

Select the Error Logging Level

The error logging level reflects the type of error logging you want to occur. Apache log4j supports 5 normal levels (WARN, DEBUG, FATAL, ERROR, and INFO) and 2 special logging levels (ALL and OFF), as well as custom levels.

In the sample log4j.properties file, the default error logger "filenet_error" is assigned the ERROR level of logging, and the error logger for the API subsystem is assigned the WARN level (commented out):

...
log4j.logger.filenet_error = error, FileNetConsoleAppender, FileNetErrorRollingAppender, FileNetTraceRollingAppender
#=== SubSystem: api
# Uncomment to set error logging level to WARN.
#log4j.logger.filenet_error.api = warn

The descriptions below reflect the configuration options used in the sample log4j.properties file. (For information about other levels and about defining custom levels for your environment, refer to the log4j documentation.)

Level Description
WARN Requests logging for potentially harmful situations. Provides sufficient info for debugging (specific RPC names, frequencies, and durations) but no detail.
DEBUG Requests logging for fine-grained informational events that are most useful to debug an application. DEBUG logs the same information as WARN but with additional detail. You can also limit the amount of detail. For example, if you specify a RemoteCommand-only logger to log at the DEBUG level, you'll get specific RPC names, frequencies, durations, parameters, and return values. However, if you specify logging detail for all Content Java API activity, you'll get the most detail but the additional info logged may not be that helpful for resolving problems. Keep in mind that the more detail you collect, the more severe the performance impact.
ERROR Requests logging exceptions thrown from within the API (internally caught exceptions are logged at DEBUG level).
FATAL Requests logging for only very severe error events that will presumably lead the application to abort.
INFO Requests informational messages that describe the progress of the application at a coarse-grained level.

Utilize Level Inheritance

Apache log4j supports level inheritance through a hierarchy structure. Inheritance guarantees that every logger is assigned a level, even if one is not explicitly specified. If no level assignment is made for a logger, it inherits its level from its parent in the logger hierarchy. If the parent has no level assignment, the hierarchy is searched upward for the closest inheritable level. The root logger always has an assigned level to assure that a level is always available. For more information about level inheritance, refer to the log4j documentation.

Specify the Subsystems to Trace

Trace logging is supported for a variety of FileNet P8 operations which are organized into logical subsystems, such as operations pertaining to the Content Engine Java API, the Global Configuration Database, or application authentication. Each supported subsystem is represented by an abbreviation (API, GCD, SEC, and so on) which is used to identify that particular subsystem in the output trace log file.

In the sample log4j.properties file, FileNet disables trace logging operations by default, but defines specific settings for the API subsystem if they should become necessary (commented out):

################################################################################
# Trace loggers:
#
# Setting log level to "off" will turn off trace logging.
# Setting log level to "debug" will turn on trace logging.
#
# Child logger's value overwrites parent logger's value.
# If a logger is not specified, it inherits its value from its parent.
# By default, trace logging is off. 
#
# The general message trace logging has a hierarchy of three detail levels represented with
# hierarchical logger names:
#    ...detail.moderate.summary  -- Enables a summary level of tracing
#    ...detail.moderate          -- Enables a moderate level of tracing
#    ...detail                   -- Enables the most detailed level of tracing
#
# Uncomment corresponding lines to turn tracing on.  To enable trace logging
# for all subsystems and all flags, set the level of the filenet_tracing
# logger to debug.
#
# Here are the trace flags used for each sub system.  For message tracing, enable the line
# corresponding to the desired detail level.
#    log4j.logger.filenet_tracing.<SubSystem>.timer                   = debug
#    log4j.logger.filenet_tracing.<SubSystem>.detail.moderate.summary = debug
#    log4j.logger.filenet_tracing.<SubSystem>.detail.moderate         = debug
#    log4j.logger.filenet_tracing.<SubSystem>.detail                  = debug
#
# For example:
#    log4j.logger.filenet_tracing.api.detail.moderate = debug
################################################################################
# Don't comment out the following line since it includes an appender.
log4j.logger.filenet_tracing = off, FileNetTraceRollingAppender

#=== SubSystem: api
# Uncomment one or more lines to enable tracing.
#log4j.logger.filenet_tracing.api                          = debug
#log4j.logger.filenet_tracing.api.timer                    = debug
...

For a list of subsystems and their abbreviations, see the table of Supported FileNet P8 Subsystems.

Configure the Amount of Data to Trace

FileNet supports three trace logging levels (SUMMARY, MODERATE, and DETAIL) that are used to specify the amount and type of trace data to collect for a subsystem. In the sample Java format log4j.properties file, FileNet provides definitions for performing each level of trace logging for the API subsystem. If trace logging should become necessary for the API subsystem, simply uncomment the line corresponding to the level of trace logging desired:

...
# Remove the comment corresponding to the desired detail level
#log4j.logger.filenet_tracing.api.detail.moderate.summary  = debug
#log4j.logger.filenet_tracing.api.detail.moderate          = debug
#log4j.logger.filenet_tracing.api.detail                   = debug

For more information about trace logging levels, see the table of Trace Logging Settings.

Enabling log4j Logging

To enable Content Engine Java API logging, perform the following steps:

  1. Create a completely new JAR file with a unique name (for example, mylog4j.jar).

    NOTE  Although creating a new JAR file is not required, it is recommended. Having a separate JAR file with a unique name will help you remember that this JAR file contains your unique logging configuration.

  2. Copy the provided sample file ContentEngine\config\samples\log4j.properties.client to ContentEngine\config\log4j.properties. Do not forget to remove the ".client" suffix extension from the copied file.
  3. Modify the ContentEngine\config\log4j.properties file as necessary for your application logging needs.
  4. Add the ContentEngine\config\log4j.properties file to the copy of your new JAR file.
  5. Add the JAR file to your classpath as you would any other application JAR file.

On application initialization, log4j performs a lookup operation to locate and automatically read the ContentEngine\config\log4j.properties file.

Performance Considerations

The logging level you specify determines the amount of information that is collected. A direct correlation exists between the amount of information collected and the performance impact on the system.

If possible, try to determine how much information you'll need to resolve the problem you are investigating, then set the level accordingly. As an example, setting the WARN level provides sufficient info for debugging but does not include much detail. There is a minor performance impact (approximately 1-2%). You can safely run the WARN level in a production environment, but you might not get all the data you require.

On the other hand, running the DEBUG level only for RemoteCommand provides additional detail but can degrade performance by 10-20%. In contrast, if you run the DEBUG level for all Content Engine API activity, you'll get the most detail but at the expense of system performance, which would probably be at a level unacceptable for a production environment. Much of the additional detail collected would most likely not be useful for a debugging effort and the collection of it would severely impact system performance. In a production environment, you should run DEBUG level only when necessary and then only for short periods of time.

Another consideration is the output method you choose. For example, the console is always available. Redirecting console output to a file does not degrade performance to any great extent. However, writing output to a console using a console program can be much more expensive than writing to a file. (Some console programs store ever-growing memory buffers and repaint the window multiple times for every log line.) File output has some disadvantages as well. For example, the log directory must exist and be writable. A good rule of thumb is to minimize console logging in a production environment, and log anything important to a file to ensure the information isn’t lost.

For more information, refer to the performance-related topics in the Apache log4j documentation.

Common Problems

The table below describes some common problems you might encounter when configuring and running log4j. Where applicable, we include suggestions for how to resolve them or references to relevant documentation.

Problem Common Causes Resolution
Log file for FileAppender cannot be created. The directory in which you want to create the log file does not exist.

Permissions are insufficient to allow file creation.
Make sure that the directory in which you want to create the log file exists. If the directory exists, check the permissions and make sure that they are sufficient to allow the creation of the log file.
Your output does not reflect the settings specified in the ContentEngine\config\
log4j.properties
file.
The ContentEngine\config\
log4j.properties
file is not in the runtime classpath.

The ContentEngine\config\
log4j.properties
s file is being overridden by another log4j.properties file that is also in the classpath.
Make sure that you add the ContentEngine\config\
log4j.properties
file to the runtime classpath. If you suspect the file is being overridden by another configuration file, consider explicitly loading and setting the configuration.
Entries are being logged multiple times to the same location. Configuration error. See the Apache log4j documentation.