2. AGENDA
• Why we need logging
• What is a logging framework
• What are different logging level
• How to choose correct logging level
• How logging affects performance
• Which framework to use
3. WHY WE NEED LOGGING
• Logging is a basic need when you create software
• Some logging use-cases are:
• debugging the software during development
• help diagnose bugs during production
• trace access for security purposes
• create data for statistical use
• etc.
• Whatever the use, logs should be
• detailed
• configurable
• Reliable
• Logging is not by choice it’s must to understand
4. HISTORY
• Historically, Java logs where done with
• Debug logs where put in System.out.println()
• error logs in System.err.println()
• e.printStackTrace()
• In Production, both were redirected:
• System.out on the null output,
• System.err to the desired error log file.
• Useful enough but they suffered from big drawbacks
• they were not very configurable - all or nothing switch
• could not focus detailed logs on a particular layer or package
5. WHAT IS A LOGGING FRAMEWORK
A logging framework is layered and consists of three main components
• Logger
• the most essential component of the logging process
• responsible for capturing the logging information
• 5 different log levels of the Logger
• Handler/Appender
• responsible for publishing the log to a destination
• Formator/Layout
• responsible for formatting the log output in different layouts
6. WHAT ARE DIFFERENT LOGGING LEVEL
• DEBUG
• lowest restricted logging level
• write everything we need to debug an application
• should only be used on Development and Testing
• must not be used in production
• INFO
• more restricted than DEBUG
• informative purpose like
• Server has been started
• Incoming messages
• outgoing messages
7. WHAT ARE DIFFERENT LOGGING LEVEL(2)
• WARN
• more restricted than INFO
• used to log warning sort of messages
• Connection lost between client and server.
• Database connection lost
• Socket reaching to its limit
• let support team monitor health of application and react on this messages
• ERROR
• more restricted logging level than WARN
• used to log Errors and Exception
• ERROR is serious for logging in Java and you should always print
8. HOW LOGGING AFFECTS PERFORMANCE
• More you log, more you perform file IO which slows down your application.
• Choose correct logging level for every single message is quite important.
• Since having no logging is not a choice
• What you can control is
• logging level
• logging messages on that level
• Always log DEBUG messages inside isDebugEnabled() block
• Never use DEBUG level logging in java in production
9. WHICH FRAMEWORK TO USE
• Log4J would be the framework of choice
• But it is no longer developed
• Version 1.2 is the reference, 1.3 is abandoned
• version 2.0 is still in its early stage
• Commons Logging is a good choice for a library (as opposed to an application)
• but I suffered once classloaders issues, and once is enough to veto it (finally, i threw
Commons Logging out and used Log4J directly)
• JDK 1.4 Logging is a standard and does not raise concurrent versions problems.
• But it lacks so many features
• it cannot be used without redeveloping
• Too bad… but it does not answers the question: which framework to use?
10. CUSTOM ABSTRACTION
Core
interfaces
base-
impl
log4j-
impl
jdk-impl
• LoggerFactory
• AbstractFactor
y
• Logger
• Binder • Binder
• Log4jFactory
• Logj4Logger
• Binder
• JdkFactory
• JdkLogger
Looks for Binder to get the
instance of
AbstractFactory impl and
returns concrete logger
Empty binder for
compile time use
only
Provide the
instance of
AbstractFactory
impl
(Log4jFactory)
Provide the
instance of
AbstractFactory
impl
(Log4jFactory)
11. SLF4J
• Simple Logging Façade for Java
• Abstract layer for logging APIs
• Completely independent of the logging implementation
• Manually/statically select underlying logging framework
• Easily to change the logging implementation without modifying the
existing code
• Only have to change the configuration of the implementation
14. THE API
1: import org.slf4j.Logger;
2: import org.slf4j.LoggerFactory;
3:
4: public class NumTag extends Tag {
5:
6: private static final Logger log = LoggerFactory.getLogger(NumTag.class);
7:
8: private Integer value;
9:
10: public void setCV(Integer newValue) {
11:
12: Integer oldValue = value;
13: value = newValue;
14:
15: log.debug("Tag CV set to {}. Old CV was {}.", newValue, oldValue);
16:
17: if(newValue.intValue() > 50) {
18: log.info("CV has risses above 50.");
19: }
20: }
21: }
15. USING API
• Every class should have a class level log instance
private static final Logger log =
LoggerFactory.getLogger(NumTag.class);
• Abstract Class provides an object level log instance
protected final Logger log = LoggerFactory.getLogger(getClass());
• Always use proper logging method to log relevant message
log.trace(); // general logging messages
log.debug(); // development or testing level logging
log.info(); // information like service start/load/stop, incoming
req.
log.warn(); // warnings like time out, connection lost, limit reached
log.error(); // exceptions, failures, errors
17. BEST PRACTICES
• Use parameterized version of various log methods, they are faster as
compared to normal method.
• Carefully choose which kind of message should go to which level for
logging (If you log too much information your performance will be
affected)
• I would recommend log4j watchdog, it continuously look for
configuration in a particular directory
• Carefully choose format of logging at logger level
• Don’t forget to include Thread Name and fully qualified Class Name
while printing logs
• Both no logging and excessive logging is bad