In my last blog I explained the importance of logging in
your enterprise application. In this post I am going to explain how we can used
logging using Log4J logging framework.
As always using a
framework makes your life much easier and efficient. And main use of using a
framework is it takes care of the underline platform. So when it comes to log4j
which is an open source project created by Apache foundation and currently
there are three logging frameworks
- Log4j for java
- log4cxx for C++
- log4net for the Microsoft .NET framework.
So lets look at how log4j works...
Log4j takes care of
logging using three main components. 1) Loggers, 2) Appenders, 3) Layouts
In simple terms if
you want to know what these three main components does is mainly logger logs to
an appender in a particular layout (pattern/style). But lets look at these
three components in details
Loggers
If you look it in the simplest way Loggers are actually
logical class of file names. These names
are known to your java application. For
example if you have a class call HelloWorld.
The standard logger
should be
Logger logger = Logger.getLogger("HelloWorld.class");
Logger should be defined class level. So one of the main advantage of using a framework for logging is you can control what you log in a hierarchical manner. If you put system.printline instead of using a logging platform you cannot actually disable some printlines while others are enabled. So here using a logger you can actually define your log lines in an hierarchical order.
Loggers have 5 different hierarchical categories. I’l list them down by their order
Fatal - “The FATAL level designates very severe error
events that will presumably lead the application to abort.” Fatal is the
highest log level used to indicate that application is in a severe stage and
application will get terminated due to this condition.
log.fatal(“Program termination”);
Error – “The ERROR level designates error events that might
still allow the application to continue running.” Errors are not soo serious as
Fatal and program can still run with
this condition however, it implies that program is going through an unexpected
behavior in the execution flow. For example when the application is suppose to
read a file and if that file not found you can log the exception using
log.error(e.getMessage) to tell the user that this file is not there in the
system.
Warn – warnings are used to tell the user that there is a
chance of having a harmful situation due to a certain condition. “The WARN level designates potentially
harmful situations.”
Info – “ The INFO level designates informational messages
that highlight the progress of the application at coarse-grained level.” Info
is the most commonly used logger method. It is used to highlight the process of
the event flow in an application.
Debug - “The DEBUG
Level designates fine-grained informational events that are most useful to
debug an application.” This is used for debugging purposes if you need to debug
your application you can enable debug level logs and see the execution flow.
Trace – “The TRACE Level designates finer-grained
informational events than the DEBUG”
Gives more detail information than debug level. The lowest logger level.
This is enable mainly to see finer grained information regarding the
application.
Appenders
Another important feature of a logging API is to send logs to different locations. Depending on the user requirements logs should be sent to the console, remote monitor, o file systems. This is achieved by the appenders. Appender is responsible for the log destination. There are couple of pre-define appenders in log4j.
- ConsoleAppender - Sends log events to the System.out or System.err using a layout specified by the user. The default target is System.out
- FileAppender - Sends log events to a file. (DailyRollingFileAppender, RollingFileAppender)
- SoketAppender - Sends events to a remote log server, usually a SoketNode
- JMSAppender - Sends events to a JMS topic.
- NTEventLogAppender - Sends events to the NT event log system.
- SyslogAppender - Sends events to a remote syslog daemon.
And many more .. You can also define your own appender so that it will send log events to differant/multiple destnations. You can easily do it by extending AppenderSkeleton class. I will explain how that can be done in my next blogs.
Layouts
Layouts
Layouts allow you to format your log messages before it is sent to the log destination. It actually stype your log message which can be very useful for filtering purposes and better monitoring approaches. By adding a pattern to your layout, you can exclude/include log event properties such as date time, log level, logger, message etc. You can also define your of layout by extending the log4j Layout class . Howeverm there are couple of predefine layouts in log4j such as PatternLayout, SimpleLayout, DateLayout, HTMLLayout, and XMLLayout.
Defining the layout in log4j.
log4j.appender.CARBON_LOGFILE.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout
log4j.appender.CARBON_LOGFILE.layout.ConversionPattern=TID:
[%T] [%S] [%d] %P%5p {%c} - %x %m {%c}%n
log4j.appender.CARBON_LOGFILE.layout.TenantPattern=%U%@%D [%T] [%S]
Sample patternlayout using log4j
TID: [-1234] [Application Server] [2012-06-30 20:26:17,156] INFO {org.wso2.carbon.coordination.core.services.impl.ZKCoordinationService} - Coordination service disabled. {org.wso2.carbon.coordination.core.services.impl.ZKCoordinationService}