Home: www.vipan.com | Vipan Singla | e-mail: vipan@vipan.com |
Use Log4j
Quick Start to Using Log4j
- Download the Log4j software (about 2.3MB as of log4j 1.1.3) and extract
log4j.jar
(about 156KB) out of it. Includelog4j.jar
in your application's classpath so that logging methods can find the needed classes. (I copied thelog4j.jar
file in java installation directory'slib/ext
subdirectory because Java will automatically pick it up from there and add it to classpath!) - Save the following sample code in a file named
TestLogging.java
somewhere in the classpath.import org.apache.log4j.*; // How to use log4j public class TestLogging { // Initialize a logging category. Here, we get THE ROOT CATEGORY //static Category cat = Category.getRoot(); // Or, get a custom category static Category cat = Category.getInstance(TestLogging.class.getName()); // From here on, log away! Methods are: cat.debug(your_message_string), // cat.info(...), cat.warn(...), cat.error(...), cat.fatal(...) public static void main(String args[]) { // Try a few logging methods cat.debug("Start of main()"); cat.info("Just testing a log message with priority set to INFO"); cat.warn("Just testing a log message with priority set to WARN"); cat.error("Just testing a log message with priority set to ERROR"); cat.fatal("Just testing a log message with priority set to FATAL"); // Alternate but INCONVENIENT form cat.log(Priority.DEBUG, "Calling init()"); new TestLogging().init(); } public void init() { java.util.Properties prop = System.getProperties(); java.util.Enumeration enum = prop.propertyNames(); cat.info("***System Environment As Seen By Java***"); cat.debug("***Format: PROPERTY = VALUE***"); while (enum.hasMoreElements()) { String key = (String) enum.nextElement(); cat.info(key + " = " + System.getProperty(key)); } } }
Log4j by default can log messages with five priority levels.
- Use
debug
to write debugging messages which should not be printed when the application is in production. - Use
info
for messages similar to the "verbose" mode of many applications. - Use
warn
for warning messages which are logged to some log but the application is able to carry on without a problem. - Use
error
for application error messages which are also logged to some log but, still, the application can hobble along. Such as when some administrator-supplied configuration parameter is incorrect and you fall back to using some hard-coded default value. - Use
fatal
for critical messages, after logging of which the application quits abnormally.
- Use
- Save the following lines in a file named
log4j.properties
in the same directory as TestLogging.class (after compiling TestLogging.java above). Log4j looks for this file by default in the application's classpath when you callgetRoot()
orgetInstance("category_name")
in your code.log4j.rootCategory=DEBUG, dest1 log4j.appender.dest1=org.apache.log4j.ConsoleAppender log4j.appender.dest1.layout=org.apache.log4j.PatternLayout
The PatternLayout defaults to
%m%n
which means print your-supplied message and a newline. This is exactly the same as printed out by Java'sSystem.out.println(...)
method, except that Log4j methods are shorter to write, among other great advantages! - Now, when you compile and run TestLogging.java, you will get output similar to:
Start of main() Just testing a log message with priority set to INFO Just testing a log message with priority set to WARN Just testing a log message with priority set to ERROR Just testing a log message with priority set to FATAL Calling init() ***System Environment As Seen By Java*** ***Format: PROPERTY = VALUE*** java.runtime.name = Java(TM) 2 Runtime Environment, Standard Edition sun.boot.library.path = c:/jdk1.3/jre/bin java.vm.version = 1.3.0_02 java.vm.vendor = Sun Microsystems Inc. ... and so on
- If you want to print the priority (you assigned to the message) next to the message, append the following line to the end of the
log4j.properties
file and save it:log4j.appender.dest1.layout.ConversionPattern=%-5p: %m%n
You will override the default %m%n. %p will print the message priority, %m is the message itself, %n is newline. Since you only made changes to a properties file, not to any Java code, there is no need to re-compile TestLogging.java. Just run it again. You should get the folowing output:
DEBUG: Start of main() INFO : Just testing a log message with priority set to INFO WARN : Just testing a log message with priority set to WARN ERROR: Just testing a log message with priority set to ERROR FATAL: Just testing a log message with priority set to FATAL DEBUG: Calling init() INFO : ***System Environment As Seen By Java*** DEBUG: ***Format: PROPERTY = VALUE*** INFO : java.runtime.name = Java(TM) 2 Runtime Environment, Standard Edition INFO : sun.boot.library.path = c:/jdk1.3/jre/bin INFO : java.vm.version = 1.3.0_02 INFO : java.vm.vendor = Sun Microsystems Inc. ... and so on
- If you are tired of all those DEBUG and INFO messages and want to disable them but still want to log other messages (for example, when the application is ready to go into production), change the
log4j.rootCategory=DEBUG, dest1
line to:log4j.rootCategory=WARN, dest1
This line tells Log4j to skip messages with priority lower than WARN (such as DEBUG and INFO). Now, it will just print:
WARN : Just testing a log message with priority set to WARN ERROR: Just testing a log message with priority set to ERROR FATAL: Just testing a log message with priority set to FATAL
Log4j Details
| <script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> |
- The name of a
Category
is a case-sensitive string of dot-separated words which you supply. For convenience, you will usually use your-class-name.class.getName()
to get the fully-qualified name of the Java class and set it as the category name. (In addition, at run time, logging the category name is much faster than logging the class name. If you want speed and class name, use the class name as the name of the category and then, just log the category name!) - Each word in the category name is said to be an ancestor of the subsequent words and a parent of the immediately following word. This is important because Log4j has this concept of inheriting priorities and appenders from ancestors until overridden in a particular category.
- There is always a
root
category which has no name, just like the root of an XML document. Use static methods in the Category class to instantiate categories:Category cat = Category.getRoot(); Category cat2 = Category.getInstance("your.category.name");
For a particular Category name,
Category.getInstance(...)
method always returns the exact same Category object. So, you don't need to instantiate a Category and keep passing it around. Instead, anywhere you need it, just sayCategory.getInstance("wanted.category.name");
. - Typical category instantiation for a class named "TestApp" in a package named "com.comp":
static Category cat = Category.getInstance(TestApp.class.getName());
Note that
TestApp
is the class name itself, not an instance. Also, theTestApp.class
statement does not create a new instance of classTestApp
. - Five priority constants in the
Priority
class areFATAL, ERROR, WARN, INFO
andDEBUG
, in the order of decreasing priority. You can make more by subclassing if you want. - You can assign priorities to categories, but you don't have to. If you don't assign a priority to a category, log4j will walk up its ancestor hierarchy and use the first one it finds as assigned. The root category always has a priority assigned to it (default is Priority.DEBUG), so all categories are always guaranteed to have a priority.
- Typical logging methods in the Category class:
// Generic logging method (INCONVENIENT) public void log(Priority p, Object message); // Convenient shortcuts to the generic logging method public void debug(Object message); public void info(Object message); public void warn(Object message); public void error(Object message); public void fatal(Object message);
- log4j only logs if and only if the category's log(...) method specifies a priority which is equal to or higher than the category's assigned or inherited priority.
Category cat = Category.getRoot(); cat.setPriority(Priority.ERROR); // Later... //cat.info("Started processing..."); //Will not log cat.error("User input is erroneous!"); //Will log cat.fatal("Cannot process user input. Program terminated!"); //Will log
Configuring Log4j
- Before logging is enabled, you have to configure log4j first. Configuring Log4j means adding appenders (destinations/targets/handlers) to categories (loggers) and assigning a layout (formatter) to each appender.
- Categories can be created and configured in any order. In particular, a category will find and link to its descendants even if it is instantiated after them.
- You will usually configure Log4j just once which is during application initialization, usually by reading a configuration file.
- You can also configure a category programmatically to log to a particular appender using a category object's
addAppender()
method. Add as many as you want (or none if you don't). This method is usually not recommended as it involves changing the source code and recompiling it. The better way is to use external configuration files such as a Java properties file or an XML file. - Beware that appenders are not singletons, they are additive! A category inherits all the appenders from its ancestors also (by default). If you add an appender to a category and it writes to the same underlying stream (console, same file etc.) as some other appender, the same log message will appear twice (or more) in the log. In addition, if two categories in a hierarchy are configured to use the same appender name, Log4j will write twice to that appender. Use
cat.setAdditivity(false)
on a category to disable inheriting of appenders. Then, log messages will only be sent to the appenders specifically configured for that category. - Calling the static
BasicConfigurator.configure()
method configures log4j to log to console just like asystem.out.println(...)
statement would. This method is hardwired to add to the root category aConsoleAppender
printing on the console. The output will be formatted using a PatternLayout set to the pattern%-4r [%t] %-5p %c %x - %m%n
. This is usually not needed as usinglog4j.properties
file is simpler and more flexible. - The default file which configures log4j is
log4j.properties
. Place it anywhere in the application classpath. - Use one of the static
PropertyConfigurator.configure(...)
methods to read in the configuration information from a Java properties file. The existing configuration is neither cleared nor reset. To do so, call the staticBasicConfigurator.resetConfiguration()
method before calling this method. This has the potential to make long-term code management more complicated. For starters, stick with onelog4j.properties
in each application's root directory. - A sample log4j configuration file:
# Set root category priority to DEBUG and set its only appender to A1 log4j.rootCategory=DEBUG, A1 # A1 is set to be a ConsoleAppender (writes to system console). log4j.appender.A1=org.apache.log4j.ConsoleAppender # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
This sample file configures log4j in exactly the same way as the
BasicConfigurator.configure()
method. But this way, you can later change, for example, DEBUG to FATAL in the properties file and not have to recompile any Java code! - Another more complex log4j configuration file:
#### Use two appenders, one to log to console, another to log to a file log4j.rootCategory=debug, stdout, R # Print only messages of priority WARN or higher for your category log4j.category.your.category.name=WARN # Specifically inherit the priority level #log4j.category.your.category.name=INHERITED #### First appender writes to console log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n #### Second appender writes to a file log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=example.log # Control the maximum log file size log4j.appender.R.MaxFileSize=100KB # Archive log files (one backup file here) log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
Here, output will also be appended to the "example.log" file. This file will be rolled over when it reaches 100KB. When roll-over occurs, the old version of example.log is automatically moved to example.log.1. Also available is
DailyRollingFileAppender
to roll a log file every minute, hour, day, week, month or twice-a-day. - For long-lived programs such as servers, use
configureAndWatch(String configFilename, long delay_in_milliseconds)
to configure using a Java properties file. Log4j will keep monitoring the property file for any changes every so many milliseconds, and if the file changes, Log4j will update the configuration. - When moving code to production, for speedy performance, you can disable logging wholesale equal to or below a certain priority for all categories in a hierarchy. For example, To log nothing at all ever, specify
log.disable=FATAL
in the configuration properties file.Only exception is if
log.disableOverride
property is not set tofalse
. So, a system administrator can (temporarily) specifylog.disableOverride=true
in the configuration file to overridelog.disable
property and log all messages to troubleshoot something.
Useful Layouts
- Some layout classes are
TTCCLayout, HTMLLayout, PatternLayout, SimpleLayout
andXMLLayout
. - SimpleLayout and PatternLayout classes ignore Java
Throwable
errors and exceptions. HTMLLayout and XMLLayout handle them. SimpleLayout
consists of the priority of the log statement, followed by " - " and then the log message itself. For example:DEBUG - Hello world
PatternLayout
lets you specify the output format according to conversion patterns similar to the C language printf function. For example, PatternLayout with the conversion pattern%r [%t] %-5p %c - %m%n
will output something like:176 [main] INFO org.foo.Bar - Located nearest gas station.
- The first field is the number of milliseconds elapsed since the start of the program.
- The second field is the thread making the log request.
- The third field is the priority of the log statement.
- The fourth field is the name of the category associated with the log request.
- The text after the '-' is the message of the statement.
- You can insert any literal text within the conversion pattern.
- Conversion characters are:
-
- %m: Outputs your message.
- %p: Outputs the priority of the logging event.
- %r: Outputs the number of milliseconds elapsed since the start of the application until the creation of the logging event.
- %c: Outputs the category of the logging event. Example: For the category name "a.b.c", the pattern
%c{2}
will output "b.c".{2}
means "output last two components of the dot-separated category name". If no{n}
is there, full Category name is output by default. - %t: Outputs the name of the thread that generated the logging event.
- %x: Outputs the nested diagnostic context (NDC) associated with the thread that generated the logging event. Useful when multiple clients are handled by separate threads such as in Java servlets. : Outputs the platform-dependent newline character(s). Preferable to specifying "/n" or "/r/n" etc. The date conversion specifier may be followed by a date format specifier enclosed between braces. Example:
%d{HH:mm:ss,SSS}
or%d{dd MMM yyyy HH:mm:ss,SSS}
. If no date format specifier is given then ISO8601 format is assumed. The date format specifier admits the same syntax as the time pattern string of Java'sSimpleDateFormat
which is slow. For faster performance, use%d{ISO8601}
(millisecs since program start, fastest) or%d{DATE}
which use log4j'sISO8601DateFormat, AbsoluteTimeDateFormat, RelativeTimeDateFormat
andDateTimeDateFormat
date formatters respectively. : Outputs source code location information. Shortcut for%C.%M(%F:%L)
. , %d{ABSOLUTE}, %d{RELATIVE} - %n
- %%: Outputs a single percent sign.
- WARNING: The patterns below will slow down the execution of your program somewhat. Avoid unless execution speed is not an issue.
- %d: Outputs the date of the logging event.
- %l
- %C: Outputs the fully-qualified class name of the caller issuing the logging request. Example: For the class name "org.apache.xyz.SomeClass", the pattern
%C{1}
will output "SomeClass".{1}
means "output last one component of the fully-qualified class name". If no{n}
is there, full class name is output by default. - %M: Outputs the method name where the logging request was issued.
- %F: Outputs the file name where the logging request was issued.
- %L: Outputs the line number from where the logging request was issued.
-
- Optionally, use format modifiers between the percent sign and the conversion character to change the minimum field width, the maximum field width and text justification within a field.
- Use the minus sign (
-
) to left-justify within a field. Default is to right-justify (pad on left). - Use a positive integer to specify the minimum field width. If the data item requires fewer characters, it is padded with space(s) on either the left or the right until the minimum width is reached. If the data item is larger than the minimum field width, the field is expanded to accommodate the data.
- Use a period followed by a positive integer to specify the maximum field width. If the data item is longer than the maximum field, then the extra characters are removed from the beginning of the data item and not from the end. For example, it the maximum field width is eight and the data item is ten characters long, then the first two characters of the data item are dropped. This behavior deviates from the printf function in C where truncation is done from the end.
- Use the minus sign (
- Examples:
-
%20c
: Right-justify (by default) the category name within 20 spaces minimum.%-20c
: Left-justify the category name within 20 spaces minimum.%.30c
: If the category name is longer than 30 characters, truncate (from the beginning). No minimum width and therefore, no padding if shorter than 30 characters.%20.30c
: Right-justify if the category name is shorter than 20 characters. If category name is longer than 30 characters, then truncate from the beginning.%-20.30c
: Left-justify if the category name is shorter than 20 characters. If category name is longer than 30 characters, then truncate from the beginning.%r [%t] %-5p %c %x - %m/n
: This is essentially theTTCCLayout
.%-6r [%15.15t] %-5p %30.30c %x - %m/n
: Similar to theTTCCLayout
except that the relative time is right padded if less than 6 digits, thread name is right padded if less than 15 characters and truncated if longer, and the category name is left padded if shorter than 30 characters and truncated if longer.
-
- ADVANCED: You don't have to pass just Strings to log. You can pass your objects to the log method also. Implement
ObjectRenderer
to log a string representation of your object to the appender.
Property Keys for Log4j, Appender and Layout Options
Overall Options for log4j
log4j.configuration=app_config.properties
: First call to Category.getRoot() or Category.getInstance(...) method makes Log4j go through an initialization process. (You can watch that happening by setting "log4j.debug=true".) During this process, Log4j looks in the application's classpath for a "log4j.properties" file or the properties file you specify via the this property key. However, you need to set this as a system property, for example by running your program withjava -Dlog4j.configuration=app_config.properties ...
. This is because, if you set it in the configuration file, it is too late. Log4j would have already started to read the log4j.properties file by default, if available!log4j.debug=true
: Default isfalse
. Outputs verbose info as log4j is configuring itself.log4j.disable=INFO
: For all categories, do not log messages with priority equal to or lower than the one specified here. Works only iflog4j.disableOverride
property isfalse
which is the default.log4j.additivity.your.category.name=false
: Default istrue
. Specifies whether the appenders should be accumulated from ancestors (true) or not (false).log4j.defaultInitOverride=false
: First call to Category.getRoot() or Category.getInstance(...) method makes Log4j go through an initialization process. (You can watch that happening by setting "log4j.debug=true".) During this process, Log4j looks in the application's classpath for a "log4j.properties" file or the properties file you specify via the "log4j.configuration=app_config.properties" property. If you don't want this to happen, set this property totrue
. However, you need to set this as a system property, for example by running your program withjava -Dlog4j.defaultInitOverride=true ...
. This is because, if you set it in the configuration file, it is too late. Log4j would have already started to read the file!ConsoleAppender Options
log4j.disableOverride=false
: Default isfalse
. Sometimes set to true to be able to ignorelog.disable
property.Threshold=WARN
: This appender will not log any messages with priority lower than the one specified here even if the category's priority is set lower. This is useful to cut down the number of messages, for example, in a file log while displaying all messages on the console.ImmediateFlush=true
: Default istrue
, meaning log messages are not buffered at all which is what you want almost all of the time.Target=System.err
: Default isSystem.out
.FileAppender Options
Threshold=WARN
: Appender will not log any messages with priority lower than the one specified here even if the category's priority is set lower. This is useful to cut down the number of messages, for example, in a file log while displaying all messages on the console.ImmediateFlush=true
: Default istrue
, meaning log messages are not buffered at all which is what you want almost all the time.File=mylog.txt
: File name to log to. You can use${some_property_key}
(for example,java.home
oruser.home
system properties) to specify the path in front. In fact, all options property keys accept this kind of value.Append=false
: Default istrue
which means append to the end of the file.false
overwrites the file at the start of each program run.RollingFileAppender Options
Threshold=INFO
: Appender will not log any messages with priority lower than the one specified here even if the category's priority is set lower. This is useful to cut down the number of messages, for example, in a file log while displaying all messages on the console.ImmediateFlush=true
: Default istrue
, meaning log messages are not buffered at all which is what you want almost all the time.File=mylog.txt
: File name to log to. You can use${some_property_key}
(for example,java.home
oruser.home
system properties) to specify the path in front. In fact, all options property keys accept this kind of value.Append=false
: Default istrue
which means append to the end of the file.false
overwrites the file at the start of each program run.MaxFileSize=100KB
: Suffixes can be KB, MB or GB. Roll the log file after this size is reached.MaxBackupIndex=2
: Maintain a maximum of 2 (for example) backup files. Erases oldest file(s).0
means no backup files at all.DailyRollingFileAppender Options
Threshold=WARN
: Appender will not log any messages with priority lower than the one specified here even if the category's priority is set lower. This is useful to cut down the number of messages, for example, in a file log while displaying all messages on the console.ImmediateFlush=true
: Default istrue
, meaning log messages are not buffered at all which is what you want almost all the time.File=mylog.txt
: File name to log to. You can use${some_property_key}
(for example,java.home
oruser.home
system properties) to specify the path in front. In fact, all options property keys accept this kind of value.Append=false
: Default istrue
which means append to the end of the file.false
overwrites the file at the start of each program run.PatternLayout Options
HTMLLayout Options
DatePattern='.'yyyy-ww
: Roll the file every week. You can specify rolling frequency to be monthly, weekly, daily, twice-a-day, hourly and even every minute. The value not only specifies the rolling frequency but also specifies the suffix for the backup file. Do not use the colon (:
) character anywhere in the value. Other than that, you can use any format string that Java'sSimpleDateFormat
will accept. In particular, you must escape literal text within a pair of single quotes (like the '.' in the example here.)'.'yyyy-MM
: Roll log file on the first of each month'.'yyyy-ww
: Roll log file at the start of each week'.'yyyy-MM-dd
: Roll log file at midnight everyday'.'yyyy-MM-dd-a
: Roll log file at midnight and midday everyday'.'yyyy-MM-dd-HH
: Roll log file at the start of every hour'.'yyyy-MM-dd-HH-mm
: Roll log file at the beginning of every minute
ConversionPattern=%m%n
: How to format each log message (What information to include).LocationInfo=true
: Default isfalse
. Outputs Java file name and line number.Title=My app title
: Default isLog4J Log Messages
. Sets the<title>
tag of HTML.XMLLayout Options
LocationInfo=true
: Default isfalse
. Outputs Java file name and line number.TTCCLayout Options (Use PatternLayout instead which is more flexible)
DateFormat=ISO8601
: Either an argument to the constructor of Java'sSimpleDateFormat
or one of the stringsNULL
,RELATIVE
,ABSOLUTE
,DATE
orISO8601
.TimeZoneID=GMT-8:00
: String in the format expected by theTimeZone.getTimeZone(java.lang.String)
method.CategoryPrefixing=false
: Default istrue
. Outputs category name.ContextPrinting=false
: Default istrue
. Outputs nested diagnostic context information belonging to the current thread.ThreadPrinting=false
: Default istrue
. Outputs thread name.
A Comprehensive Log4J Configuration Properties File
#log4j.debug=true #log4j.disable=fatal #log4j.additivity.TestLogging=false log4j.rootCategory=, dest1 log4j.category.TestLogging=DEBUG, dest1 log4j.appender.dest1=org.apache.log4j.ConsoleAppender #log4j.appender.dest1.layout=org.apache.log4j.SimpleLayout log4j.appender.dest1.layout=org.apache.log4j.PatternLayout #log4j.appender.dest1.layout.ConversionPattern=%-5p %l %x: %m%n !----------------------####### END OF PROPERTIES #######----------------------! ############################################################################### # Below I document in more detail how to write a log4j configuration file. # # SELECTIVELY copy lines beginning with #, paste and uncomment them above. # ############################################################################### !-----------------------------------------------------------------------------! ! PLACE THIS FILE ANYWHERE IN CLASSPATH ! ! Appenders are additive by default. ! ! Priorities are inherited until overridden in a category. ! ! In ${property_key}, the value of the key can be defined as a system ! ! property or in this file itself. System properties are searched first and ! ! then this file. ! !-----------------------------------------------------------------------------! !-----------------------------------------------------------------------------! ! Configure log4j's operation at the meta level ! !-----------------------------------------------------------------------------! ! Observe log4j parsing this file #log4j.debug=true ! Set this to false for log4j to actually obey the log4j.disable property(next) #log4j.disableOverride=false ! Disable all logging in all categories for messages with priority equal to ! or lower than the one given here #log4j.disable=INFO !-----------------------------------------------------------------------------! ! Configure categories (loggers) ! !-----------------------------------------------------------------------------! ! ROOT CATEGORY (Usually sufficient to set this one only) ! Here, logs messages with priority DEBUG (default) or higher #log4j.rootCategory=, dest1 ! Or, #log4j.rootCategory=debug, dest1, dest2 ! YOUR CATEGORIES (to customize logging per class/pkg/project/etc) ! Here, overrides ancestor's priority and makes it WARN or higher for this cat. #log4j.category.TestLogging=WARN, dest3 ! Or, #log4j.category.TestLogging=DEBUG, dest3 !--------DON'T DO THIS!!! APPENDERS ARE ADDITIVE BY DEFAULT!!!---------------! ! It will write the same log message TWICE to dest1. Once for root, then for ! ! this category. ! !#log4j.category.TestLogging=DEBUG, dest1, dest3 ! ! If you DO NOT want additivity for this category, say so ! !#log4j.additivity.TestLogging=false ! !-----------------------------------------------------------------------------! !-----------------------------------------------------------------------------! ! Configure appenders (log destinations/targets) and their options ! !-----------------------------------------------------------------------------! ! WRITE TO CONSOLE (stdout or stderr) #log4j.appender.dest1=org.apache.log4j.ConsoleAppender #log4j.appender.dest1.ImmediateFlush=true ! WRITE LOG TO A FILE, ROLL THE FILE AFTER SOME SIZE #log4j.appender.dest2=org.apache.log4j.RollingFileAppender ! This appender will only log messages with priority equal to or higher than ! the one specified here #log4j.appender.dest2.Threshold=ERROR ! Specify the file name (${property_key} gets substituted with its value) #log4j.appender.dest2.File=${java.home}/log4j.log ! Don't append, overwrite #log4j.appender.dest2.Append=false ! Control the maximum log file size #log4j.appender.dest2.MaxFileSize=100KB ! Keep backup file(s) (backups will be in filename.1, .2 etc.) #log4j.appender.dest2.MaxBackupIndex=2 ! WRITE LOG TO A FILE, ROLL THE FILE EVERY WEEK #log4j.appender.dest3=org.apache.log4j.DailyRollingFileAppender ! Specify the file name #log4j.appender.dest3.File=log4TestLogging2.html ! Control the maximum log file size #log4j.appender.dest3.MaxFileSize=300KB ! Rollover log file at the start of each week #log4j.appender.dest3.DatePattern='.'yyyy-ww !-----------------------------------------------------------------------------! ! Configure appender layouts (log formats) and their options ! !-----------------------------------------------------------------------------! ! USE SIMPLE LOG FORMAT (e.g. INFO - your log message) #log4j.appender.dest1.layout=org.apache.log4j.SimpleLayout ! USE A C PRINTF STYLE PATTERN TO FORMAT LOG MESSAGE #log4j.appender.dest1.layout=org.apache.log4j.PatternLayout ! For a pattern layout, specify the pattern (Default is %m%n which is fastest) #log4j.appender.dest1.layout.ConversionPattern=%-5p: %m%n ! Or, #log4j.appender.dest1.layout.ConversionPattern=%-5p %6.10r[%t]%x(%F:%L) - %m%n #log4j.appender.dest2.layout=org.apache.log4j.PatternLayout #log4j.appender.dest2.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x(%F:%L) - %m%n ! Or, (the pattern below will slow down your app) #log4j.appender.dest2.layout.ConversionPattern=[%d{yyyy-mm-dd hh:mm},%6.6r]%-5p[%t]%x(%F:%L) - %m%n ! FORMAT LOG MESSAGES IN THE FORM OF AN HTML TABLE #log4j.appender.dest3.layout=org.apache.log4j.HTMLLayout ! Include Java file name and line number (Default is false) #log4j.appender.dest3.layout.LocationInfo=true ! Set <title> tag (Default: Log4J Log Messages) #log4j.appender.dest3.layout.Title=My App Log !-----------------------------------------------------------------------------! ! PATTERN FORMATS GLOSSARY ! !-----------------------------------------------------------------------------! ! %n - newline ! ! %m - your log message ! ! %p - message priority (FATAL, ERROR, WARN, INFO, DEBUG or custom) ! ! %r - millisecs since program started running ! ! %% - percent sign in output ! ! ! !-----------------------SOME MORE CLUTTER IN YOUR LOG-------------------------! ! %c - name of your category (logger), %c{2} will outputs last two components ! ! %t - name of current thread ! ! %x - Nested Diagnostic Context (NDC) (you supply it!) ! ! ! !-------------------------SLOW PERFORMANCE FORMATS----------------------------! ! %d - date and time, also %d{ISO8601}, %d{DATE}, %d{ABSOLUTE}, ! ! %d{HH:mm:ss,SSS}, %d{dd MMM yyyy HH:mm:ss,SSS} and so on ! ! %l - Shortcut for %F%L%C%M ! ! %F - Java source file name ! ! %L - Java source line number ! ! %C - Java class name, %C{1} will output the last one component ! ! %M - Java method name ! ! ! !------------------------------FORMAT MODIFIERS-------------------------------! ! %-any_letter_above - Left-justify in min. width (default is right-justify) ! ! %20any_letter_above - 20 char. min. width (pad with spaces if reqd.) ! ! %.30any_letter_above - 30 char. max. width (truncate beginning if reqd.) ! ! %-10.10r - Example. Left-justify time elapsed within 10-wide field. ! ! Truncate from beginning if wider than 10 characters. ! !-----------------------------------------------------------------------------! !-----------------------------------------------------------------------------! ! OPTIONS GLOSSARY ! !-----------------------------------------------------------------------------! !-------------------------OVERALL OPTIONS FOR log4j---------------------------! ! Specify as command line option: -Dlog4j.defaultInitOverride=false ! Specify as command line option: -Dlog4j.configuration=app_config.properties !#log4j.debug=true !#log4j.disable=INFO !#log4j.disableOverride=false !#log4j.additivity.your.category.name=false ! !----------------------------NullAppender OPTIONS-----------------------------! !#log4j.appender.dest1.Threshold=INFO ! !---------------------------ConsoleAppender OPTIONS---------------------------! !#log4j.appender.dest1.Threshold=INFO !#log4j.appender.dest1.ImmediateFlush=true !#log4j.appender.dest1.Target=System.err ! !-----------------------------FileAppender OPTIONS----------------------------! !#log4j.appender.dest2.Threshold=INFO !#log4j.appender.dest2.ImmediateFlush=true !#log4j.appender.dest2.File=mylog.txt !#log4j.appender.dest2.Append=false ! !-------------------------RollingFileAppender OPTIONS-------------------------! !#log4j.appender.dest2.Threshold=INFO !#log4j.appender.dest2.ImmediateFlush=true !#log4j.appender.dest2.File=mylog.txt !#log4j.appender.dest2.Append=false !#log4j.appender.dest2.MaxFileSize=100KB !#log4j.appender.dest2.MaxBackupIndex=2 ! !-----------------------DailyRollingFileAppender OPTIONS----------------------! !#log4j.appender.dest2.Threshold=INFO !#log4j.appender.dest2.ImmediateFlush=true !#log4j.appender.dest2.File=mylog.txt !#log4j.appender.dest2.Append=false !#log4j.appender.dest2.DatePattern='.'yyyy-ww ! !-----------------------------SimpleLayout OPTIONS----------------------------! !**None** ! !-------------TTCCLayout OPTIONS (PatternLayout is more flexible)-------------! !#log4j.appender.dest1.layout.DateFormat=ISO8601 !#log4j.appender.dest1.layout.TimeZoneID=GMT-8:00 !#log4j.appender.dest1.layout.CategoryPrefixing=false !#log4j.appender.dest1.layout.ThreadPrinting=false !#log4j.appender.dest1.layout.ContextPrinting=false ! !-----------------------------PatternLayout OPTIONS---------------------------! !#log4j.appender.dest1.layout.ConversionPattern=%m%n ! !-------------------------------HTMLLayout OPTIONS----------------------------! !#log4j.appender.dest3.layout.LocationInfo=true !#log4j.appender.dest3.layout.Title=My app title ! !--------------------------------XMLLayout OPTIONS----------------------------! !#log4j.appender.dest3.layout.LocationInfo=true !-----------------------------------------------------------------------------!
Miscellaneous Information
- Where performance is "way too crucial" in your code, to save the time to construct the parameters of a logging method, use:
if (cat.isDebugEnabled() { cat.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); }
- When configured with the
SimpleLayout
or a pattern using only%p, %m, %n
, performance tests have shown log4j to log as quickly asSystem.out.println(...)
. - Using Nested Diagnostics Contexts: Sometimes, for example in Servlets, one code serves many clients by instantiating a different thread to serve each client. You can use nested diagnostics contexts (NDC) to differentiate logging requests from different clients. All you do is
push
a String unique to the client on to NDC before logging. The unique string can be the client's IP address, hostname or anything you desire to associate with that request. Specify%x
in your layout pattern to print that string in that request's log messages.import org.apache.log4j.*; public class TestNDC { // !Make sure log4j.properties file exists in classpath static Category cat = Category.getInstance(TestNDC.class.getName()); public static void main(String[] args) { // Nested Diagnostic Configurator to identify the client for // multithreaded client request processors such as servlets, if needed NDC.push("Client #45890"); cat.info("Testing Nested Diagnostic Context (NDC)."); cat.info("Make sure %x is in layout pattern!"); cat.info("Client #45890 should appear in this log message."); switchNDC(); cat.info("Finished."); } static void switchNDC() { NDC.push("Client #99999"); cat.debug("Client #99999 should appear nested in this log message."); NDC.pop(); } }
© Vipan Singla 2001