Java Logging Techniques Summary(JUL in Depth)

1. JUL is an inbeded util tool for logging.

 

2. The work flow of JUL

Java Logging Techniques Summary(JUL in Depth)_第1张图片

3. JUL has abstracted Logging procession into the interaction of several Classes.

    1) Level --> Define the the severe level of the log. 

                  --> JUL has used a different logging level compared with Log4j.

                  -->  1) SEVERE

                         2) WARNING

                         3) INFO

                         4) CONFIG

                         5) FINE

                         6) FINER

                         7) FINEST

                         In addition to that, you have also the levels OFF and ALL to turn the logging of or to log everything.

     2) LogRecord --> Encapsulated a record that to be printed.

                           --> It contains following information:

                           1) Level (The level of this record)

                           2) sequenceNumber (Every time a record is created, sequenceNumber increased by 1)

                           3) sourceClassName (The class where this record is printed)

                           4) sourceMethodName (The method where this record in printed)

                           5) message (The message itself)

                           6) ...

    3) Formatter --> It a formatter that is used to format a LogRecord.

                        --> JUL provides two kinds of Formatter: SimpleFormatter(Default) & XMLFormatter

                        --> SimpleFormatter is used by default. It prints record information as the following format:

                           --> Date + Time + LoggerName/sourceClassName + methodName

                           --> Level + Message

                           --> Exception Info

May 21, 2013 2:35:30 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
INFO: Main running

                      --> XMLFormatter is not often used. As the format of below:

                           --><record></record>                         

    4) Handler  --> The position where the record to be printed.

                       --> The hierarchy of Handlers is as below:

 
Java Logging Techniques Summary(JUL in Depth)_第2张图片

                     --> The Handler contains a reference to Formatter, Level, Filter

                          --> The reference of Formatter is used to format the LogRecord into String.

                          --> The reference of Level is used to define the Level supported by this Handler

                          --> The Filter?...

                     --> The function publish() in Handler is the real function that realize the print LogRecord function.

     5) LogManager  --> An singleton instance that is used to read the configuration file.

                               --> Maintains a map of Logger instance.

                                  -->  When instantiating the LogManager, user can use java.util.logging.manager to point out the custom LogManager.

                                         If we do not point out, then it will use LogManager by default.

                                         After Instantiation, a RootLogger is created and put in the logMap in LogManager.

                                  --> About the logMap in the LogManager

    // Table of known loggers.  Maps names to Loggers.
    private Hashtable<String,Logger> loggers = new Hashtable<String,Logger>();
                                 --> The loggers is organized as the format of Tree:  edu<--xmu<--logging. So the if we getLogger("edu.xmu.logging.LoggingTest"), manager will find in this tree/map, when cannot find this, then it will try to find as getLogger("edu.xmu.logging"), and if cannot find, then will getLogger("edu.xmu") ... So as the level organized.
Java Logging Techniques Summary(JUL in Depth)_第3张图片

                                 --> But the LogManager will allow us to control things at more than just the class level. We could set the logging level for a package, or even a set of packages, by calling the LogManager.setLevel(String name, Level level) method.                                                                 So, for example, we could set the logging level of all loggers for this article to Level.FINE by making this call:

 

LogManager.getLogManager().setLevel("logging", Level.FINE);

 

                                      This would make every  Logger with the package prefix of " logging" have a level of  Level.FINE, unless that particular  Logger already had a  Level explicitly set:

                                      We would still need to turn up the levels of the root handlers as before, but would not have to set the individual loggers one at a time.
                                 --> As the name of RootLogger is "", all the configuration for RootLogger is started with "."

     6) Logger  --> The interfact that user used to print log.

                      -->  It contains "name、Handlers、resourceBundleName、useParentHandlers、filter、anonymous、levelObject、parent、kids" fields.

                         -->  It provides getLogger() interface. When user passes into a name, then it returns a Logger instance.  

    public static synchronized Logger getLogger(String name) {
	LogManager manager = LogManager.getLogManager();
	Logger result = manager.getLogger(name);
	if (result == null) {
	    result = new Logger(name, null);
	    manager.addLogger(result);
	    result = manager.getLogger(name);
	}
	return result;
    }

 

4. Several ways to config Logger [Reference to DLevin]

     1) 对Logger的配置支持一下几种方式:  

         <name>.level=INFO|CONFIG….             

         handers=<handlerName1>,<handlerName2>…. (以”,”分隔或以空格、TAB等字符分隔,全局Handler)       

         config=<configClassName1>,<configClassName2>….(自定义类,实现在其构造函数中实现自定义配置)

         <name>.userParentHandlers=true|false|1|0

         <name>.handlers=<handlerName1>,<handlerName2>…(以”,”分隔或以空格、TAB等字符分隔)

         <handlerName>.level=INFO|CONFIG….

        以及各自Handler本身支持的配置,具体各自的Handler。

     2) 用户可以通过以下方式自定义配置文件:

     a. 设置系统属性java.util.logging.config.class,由自定义类的构造函数实现自定义配置,如调用LogManager、Logger中的一些静态方法。

     b.设置系统属性java.util.logging.config.file,自定义配置文件路径。读取该文件中的内容作为配置信息。

     c. 默认使用${java.home}/lib/logging.properties文件作为配置文件(JDK已经提供了一些默认配置,一般是${JRE_HOME}/lib/logging.properties文件)

5. A simple exmple for configuration JUL

    In the path of ${JRE_HOME}/lib/logging.properties

############################################################
#  	Default Logging Configuration File
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property.  
# For example java -Djava.util.logging.config.file=myfile
############################################################

############################################################
#  	Global properties
############################################################

# "handlers" specifies a comma separated list of log Handler 
# classes.  These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
handlers= java.util.logging.ConsoleHandler

# To also add the FileHandler, use the following line instead.
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers.  For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= INFO

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter


############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
edu.xmu.logging.Logging_JDKLogging.level = ALL

   Comments:

       1) Here we can see that the default handler is ConsoleHandler. So if we didn't change this, by default, the information will be printed in console.

       2) Here we can see that the default level for RootLogger is INFO. So if we didn't change this, by default, the information at levels that is lower than INFO will not be printted.

       3) The default level for ConsoleHander is INFO.

       4) The default formatter is SimpleFormatter. So the output information will be printed as the format specified by SimpleFormatter.  

 

6. A simple example for using JUL

    1. Test Class

package edu.xmu.logging.Logging_JDKLogging;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import org.junit.Before;
import org.junit.Test;

/**
 * Unit test for simple App.
 */
public class AppTest
{
	private static Logger logger = null;
	private static SimpleFormatter fileFormatter = null;
	private static FileHandler fileHandler = null;

	@Before
	public void setUp() throws SecurityException, IOException
	{
		logger = Logger.getLogger(AppTest.class.getName());

		fileFormatter = new SimpleFormatter();
		fileHandler = new FileHandler("Logging.txt");
		fileHandler.setFormatter(fileFormatter);
		fileHandler.setLevel(Level.ALL);

		logger.addHandler(fileHandler);
		logger.setLevel(Level.FINE);
	}

	@Test
	public void loggerTest()
	{
		logger.severe("Severe Logging");
		logger.warning("Warning Logging");
		logger.info("Info Logging");
		logger.config("Config Logging");
		logger.fine("Fine Logging");
		logger.finer("Finner Logging");
		logger.finest("Finest Logging");
	}
}

   2. Console output

May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
SEVERE: Severe Logging
May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
WARNING: Warning Logging
May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
INFO: Info Logging

    3. File output (Logging.txt)

May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
SEVERE: Severe Logging
May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
WARNING: Warning Logging
May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
INFO: Info Logging
May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
CONFIG: Config Logging
May 23, 2013 6:22:54 PM edu.xmu.logging.Logging_JDKLogging.AppTest loggerTest
FINE: Fine Logging

    1) Q: Why does the console output?

        A: Because the FileHandler is configured in ${JRE_HOME}/lib/logging.properties files. And this FileHandler is ConsoleHander and is the parent of all applications.

        X: We can add a sentence like below: Then the console output will gone.

logger.setUseParentHandlers(false);

    2) Q: Why does we only have the ConsoleOutput has only three items and fileOutput has five output items?

        A: Because in the configuration file(Refer Below).

java.util.logging.ConsoleHandler.level = INFO

    3) Q: What's the relationship of level in Handler and in Logger?

        A:  We can regard the relationship of them as below figure:<Think LogRecord as water that flows through the two pieces of pie>

Java Logging Techniques Summary(JUL in Depth)_第4张图片
    4) Q: How can we make different configuration files for different application/modules instead of configure in code/jre-global-configuration-file? 
        A: This configuration file need to be pass to your application using java -Djava.util.logging.config.file option

 

Reference Links:

    1) http://www.blogjava.net/DLevin/archive/2012/11/08/390992.html

    2) http://www.onjava.com/pub/a/onjava/2002/06/19/log.html?page=2

    3) http://tutorialswithexamples.com/java-logging-configuration-using-properties-file/

 

你可能感兴趣的:(in,Class,work,flow,depth,diagram)