|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 5
The log4j environment can be fully configured programmatically. However, it is far more flexible to configure log4j by using configuration files. Currently, configuration files can be written in XML or in Java properties (key=value) format.
Let us give a taste of how that is done with the help of an imaginary application -- MyApp -- that uses log4j:
import com.foo.Bar;
// Import log4j classes.
import org.log4j.Category;
import org.log4j.BasicConfigurator;
public class MyApp {
// Define a static category variable so that it references the
// Category instance named "MyApp".
static Category cat = Category.getInstance(MyApp.class.getName());
public static void main(String[] args) {
// Set up a simple configuration that logs on the console.
BasicConfigurator.configure();
cat.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
cat.info("Exiting application.");
}
}
As seen in the code above, MyApp begins by importing log4j related classes. It then defines a static category variable with the name MyApp, which happens to be the class' fully qualified name.
MyApp uses the Bar class defined in the package com.foo:
package com.foo;
import org.log4j.Category;
public class Bar {
static Category cat = Category.getInstance(Bar.class.getName());
public void doIt() {
cat.debug("Did it again!");
}
}
In MyApp, the invocation of the BasicConfigurator.configure() method creates a rather simple log4j setup. That method is hardwired to add to the root category a FileAppender printing on the console. The output will be formatted by using a PatternLayout set to the pattern %-4r [%t] %-5p %c %x - %m%n.
Note that by default, the root category is assigned to Priority.DEBUG.
The output of MyApp is:
0 [main] INFO MyApp - Entering application. 36 [main] DEBUG com.foo.Bar - Did it again! 51 [main] INFO MyApp - Exiting application.
Figure 1 depicts MyApp's object diagram immediately after it calls the BasicConfigurator.configure() method.

Figure 1. MyApp's object diagram after calling the BasicConfigurator.configure() method
The MyApp class configures log4j by invoking BasicConfigurator.configure() method. Other classes need only import the org.log4j.Category class, retrieve the categories they want to use and log away.
The previous example always outputs the same log information. Fortunately, it is easy to modify MyApp so that the log output can be controlled at runtime. Below, you'll see a slightly modified version:
import com.foo.Bar;
import org.log4j.Category;
import org.log4j.PropertyConfigurator;
public class MyApp {
static Category cat = Category.getInstance(MyApp.class.getName());
public static void main(String[] args) {
// BasicConfigurator replaced with PropertyConfigurator.
PropertyConfigurator.configure(args[0]);
cat.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
cat.info("Exiting application.");
}
}
This version of MyApp instructs PropertyConfigurator to parse a configuration file and set up logging accordingly.
Let's look at a sample configuration file that results in exactly the same output as the previous BasicConfigurator-based example:
# Set root category priority to DEBUG and its only appender to A1. log4j.rootCategory=DEBUG, A1 # A1 is set to be a FileAppender which outputs to System.out. log4j.appender.A1=org.log4j.FileAppender log4j.appender.A1.File=System.out # A1 uses PatternLayout. log4j.appender.A1.layout=org.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Suppose we no longer wish to see the output of any component belonging to the com.foo package. The following configuration file shows one possible way of achieving that:
log4j.rootCategory=DEBUG, A1 log4j.appender.A1=org.log4j.FileAppender log4j.appender.A1.File=System.out log4j.appender.A1.layout=org.log4j.PatternLayout # Print the date in ISO 8601 format log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n # Print only messages of priority WARN or above in the package com.foo. log4j.category.com.foo=WARN
The output of MyApp configured with this file is shown below:
2000-09-07 14:07:41,508 [main] INFO MyApp - Entering application. 2000-09-07 14:07:41,529 [main] INFO MyApp - Exiting application.
As the category com.foo.Bar does not have an assigned priority, it inherits its priority from com.foo, which was set to WARN in the configuration file. The log statement from the Bar.doIt() method has the priority DEBUG, lower than the category priority WARN. Consequently, doIt()'s log request is suppressed.
Next, we see another configuration file that uses multiple appenders:
log4j.rootCategory=debug, stdout, R log4j.appender.stdout=org.log4j.FileAppender log4j.appender.stdout.File=System.out log4j.appender.stdout.layout=org.log4j.PatternLayout # Pattern to output the caller's file name and line number. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n log4j.appender.R=org.log4j.RollingFileAppender log4j.appender.R.File=example.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
Calling the enhanced MyApp with the that configuration file will output the following on the console:
INFO [main] (MyApp2.java:12) - Entering application. DEBUG [main] (Bar.java:8) - Doing it again! INFO [main] (MyApp2.java:15) - Exiting application.
In addition, as the root category has been allocated a second appender, output will also be directed to the example.log file. That file will be rolled over when it reaches 100 KB. When rollover occurs, the old version of example.log automatically moves to example.log.1.
Note that to obtain those different logging behaviors, we did not need to recompile code. We could just as easily have logged
to a Unix Syslog daemon and redirected all com.foo output to an NT Event logger. Similarly, we could have forwarded logging events to a remote log4j server, which would log
according to local server policy -- for example, by logging to a local file as well as forwarding the log event to a second
log4j server.