Thursday, December 12, 2013

How to configure Log4j in Java program without XML or Properties File

Sometime configuring Log4j using XML or properties file looks annoying, especially if your program not able to find them because of some classpath issues, wouldn't it be nice if you can configure and use Log4j without using any configuration file e.g. XML or properties. Well, Log4j people has thought about it and they provide a BasicConfigurator class to configure log4j programmatically, thought this is not as rich as there XML and properties file version is, but it's really handy for quickly incorporating Log4j in your Java program. One of the reason programmer prefer to use System.out.println() over Log4j, of-course for testing purpose, because it doesn't require any configuration, you can just use it, without bothering about XML or properties file configuration, but most programmer will agree that, they would prefer to use Log4j over println statements, even for test programs if it's easy to set them up.

By the way, for production use prefer SLF4J over Log4J.  In this Java tutorial, we will see a nice little tip to use Log4j right away by configuring in couple of lines. In fact you can configure Log4J in just one line, if you intend to use there basic configuration which set's the log level as DEBUG.

Log4J Configuration without XML file

Configure Log4j in one line Java programHere is the code to configure Log4J in one line without using any external configuration file i.e. Log4j.xml or First one uses XML file to configure this logging library, while second one uses Java specific properties files, which are essentially text files. This code leverage configuration options defined in BasicConfigurator class.

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

  * Java program to configure log4j without using XML or properties file.
  * By using BasicConfigurator class, you can configure Log4j in one line.
  * @author
public class Log4JConfigurator {
    private static final Logger logger = Logger.getLogger(Log4JConfigurator.class);
    public static void main(String args[]) {
        BasicConfigurator.configure(); //enough for configuring log4j
        Logger.getRootLogger().setLevel(Level.WARN); //changing log level
        logger.error("Critical message, almost fatal");
        logger.warn("Warnings, which may lead to system impact");"Information");
        logger.debug("Debugging information ");

0 [main] ERROR Log4JConfigurator  - Critical message, almost fatal
0 [main] WARN Log4JConfigurator  - Warnings, which may lead to system impact

Couple of things to note about basic Log4j Configuration :

1) BasicConfigurator display log messages into console by using PatternLayout with pattern "%-4r [%t] %-5p %c %x - %m%n" to display log messages.

2) Root logger is set to use DEBUG log level, which means it will display all messages. If you look at our example, we have reset the log level to WARN, which means only ERROR and WARN level message will be displayed into console, and INFO and DEBUG level messages will be suppressed. This is one of the important logging tips in Java to remember, because amount of  logging is inversely proportional to performance, more you log, slower your program will be. Use ERROR or WARN level on production and DEBUG during development

3) You can reset configuration by calling BasiConfigurator.reset() method.

Isn't it great to use Log4j just like this, I really liked it. Yes, I still prefer Sytem.out.println() statement for simplest task but like to use Log4j more often now. Though, it still make sense to use XML based logger for production use, Log4j with basic configuration is just fine for temporary or tutorial purpose. 

Further Learning
Design Patterns Library
Clean Code: Writing Code for Humans
SOLID Principles of Object Oriented Design


Anonymous said...

This is still giving the output on console, what exactly are we benefiting by using log4j in place of system.out

Javin Paul said...

You get all meta data logged for you e.g. class name, thread name, and also most importantly you are getting formatted logging, rather than plain vanila system.out print statement. having said that, if your requirement is to log on file, you can easily configure log4j, this tip is mainly for testing and writing small program, where most of prefer console logging.

Pankaj Joshi said...

I have a quick very basic question. In order to have the encapsulation we make member variable private. So that no one can access this variable and at the same time we inject public setter and gettor methods to access that variable. Would any one please want to have any comment. Is - 1) Just to maintain the standard 2) To support ORM with hibernate 3) For immutability 4) anything else.....Many Thanks.

Anonymous said...

Well you can have formatted output using printf or String.format as well along with printing the className. You do not need to initialize a logger for it.

Anonymous said...

what is the difference between basic configurator , property configurator and xml configurator?????????

Post a Comment