Java Logging Techniques Summary(Log4j Example)

本文详细介绍了Log4j日志框架的核心组件及其工作原理,包括Logger、Appender和Layout,通过实例展示了如何配置日志级别、目的地和输出格式,并提供了配置文件和代码示例,帮助开发者掌握Log4j的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Three Main Components:

    1) Logger

    2) Appender

    3) Layout

    These three types of components work together to enable developers to log message according to message type and level, and to control at runtime how these messages are formatted and where they are reported.

    Relationship between these important components



2. Logger may be assigned levels.

    1) TRACE

    2) DEBUG

    3) INFO

    4) WARN

    5) ERROR

    6) FATAL

    If a given logger is not assigned a level, then it inherits one from its closest ancestor with an assigned level.

    Inside it is managed by LoggerManager. Which has a map set the name as key, and the Logger as value.

 

3. Appender

    1) Log4j allows logging requests to print to multiple destinations.

    2) Main sub class of Appender

        1) ConsoleAppender

        2) FileAppender/RollingFileAppender

        3) JMSAppender

        4) SMTPAppender

        5) JDBCAppender

        6) SocketAppender

    3) A Logger may have multiple Appender.

        Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy. <Observer Design Pattern>

        In other words, appenders are inherited additively from the logger hierarchy.

        For example, if a console appender is added to the root logger, then all enabled logging requests will at least print on the console.

 

4. Layout

    1) More often than not, users wish to customize not only the destination but also the output format.

        This is accomplished by associating a layout with an appender.

    2) The hierarchy of Layout is shown as below.

 

5. A simple example of using Log4j

    1) pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>edu.xmu.logging</groupId>
	<artifactId>Logging-Log4J</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
		</dependency>
	</dependencies>

</project>

    2) log4j.properties in the class path

# Define the root logger with appender X
log = C:/YangKunLun/logging
log4j.rootLogger = ERROR, FILE

# Define the file appender
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
# Set the name of the file
log4j.appender.FILE.File=${log}/log.out

# Set the immediate flush to true(default)
log4j.appender.FILE.ImmediateFlush=true

# Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug

# Set the append to true, override
log4j.appender.FILE.Append=true

# Set the maxmium file size before rollover
# log4j.appender.FILE.MaxFileSize=5KB

# Set the date pattern
log4j.appender.FILE.DatePattern='.' yyyy-MM-dd-HH-mm

# Set the backup index
# log4j.appender.FILE.MaxBackupIndex=2;

# Define the layout for X appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n 

    3) Log4jExampleTest.java

package edu.xmu.log4j;

import java.util.Date;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jExampleTest
{
	private static Logger logger = Logger.getLogger("edu.xmu");
	static
	{
		logger.setLevel(Level.INFO);
	}

	@Test
	public void test()
	{
		// Debug < Info < Warn < Error < Fatal
		logger.debug((new Date()) + " [DEBUG] Hello this is an debug message");
		logger.info((new Date()) + " [INFO] Hello this is an info message");
		logger.warn((new Date()) + " [WARN] Hello this is an warn message");
		logger.error((new Date()) + " [ERROR] Hello this is an error message");
		logger.fatal((new Date()) + " [FATAL] Hello this is an fatal message");
	}

}

    4) Log4jExampleTest2.java

package edu.xmu.log4j;

import java.util.Date;

import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.junit.Test;

public class Log4jExampleTest2
{
	private static Logger logger = Logger.getLogger("edu.xmu.log4j");

	@Test
	public void test()
	{
		// Log4jExampleTest test = new Log4jExampleTest();
		Layout layout = new SimpleLayout();
		Appender appender = new FileAppender();
		appender.setLayout(layout);
		logger.addAppender(appender);
		
		logger.debug((new Date()) + " [DEBUG] Hello this is an debug message");
		logger.info((new Date()) + " [INFO] Hello this is an info message");
		logger.warn((new Date()) + " [WARN] Hello this is an warn message");
		logger.error((new Date()) + " [ERROR] Hello this is an error message");
		logger.fatal((new Date()) + " [FATAL] Hello this is an fatal message");
	}

}

    Comments:

    1) When we de-comment the comments in Log4jExampleTest2.java, we can find that the level of this logger in this class is no longer that inherits from RootLogger that is ERROR.

        But inherits from "edu.xmu" which is INFO.

 

6. Configuration file in depth

    1) You may wonder there are so many differents choice for us to choose from. How can we remember all the properties in order to config the configuration file properly?

        Let take a look at a simple configuration file.

# Here we define the root logger for log4j.
# The syntax of defining root logger is : 
# log4j.rootLogger = "RootLevel", "RootAppender1", "RootAppender02"
# Here we using "STDOUT" as micro variables.
log4j.rootLogger = INFO, STDOUT

# Here we specify what the STDOUT is.
# As STDOUT must be an Appender.
# Here we specify that STOUT is the instance of ConsoleAppender
# So every time we encounter log4j.appender.STDOUT, we can use "org.apache.log4j.ConsoleAppender" as replacement.
log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender

# Then we dig into the source code of "org.apache.log4j.ConsoleAppender"
# We can find a method named public void setTarget(String value)
# So we can set as below:
log4j.appender.STDOUT.Target = System.out
# It equals : org.apache.log4j.ConsoleAppender.setTarget("System.out");

    2) Extends

        Let's take a look at the more complex configuration file

       <log4j.logger.edu.xmu is a custom logger that defined in configuration file>

       <When we want to get this custom logger, we just use Logger.getLogger("edu.xmu");>

       Please pay attention that we ignore the prefix of "log4j.logger" when getting the logger.

# Here we define macro named "log" whose value is "c:/..." 
log = C:/YangKunLun/logging

# Here we define the default level for root loggger
# And added two Appenders for this root logger 
log4j.rootLogger = INFO, FILE, STDOUT
log4j.logger.edu.xmu = WARN, FILE, STDOUT
# This has been explained in example above
log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.Target = System.out

# Here we define the log4j.appender.FILE is an instance of DailyRollingFileAppender
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender

# When we look up the class org.apache.log4j.DailyRollingFileAppender
# We can find a method named setFile(String file)
# This means we want to set the output file as "c:/yangkunlun/logging/log.out"
log4j.appender.FILE.File=${log}/log.out

# We have to define the Layout for each Appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n
log4j.appender.STDOUT.layout = org.apache.log4j.PatternLayout

# Regard configuration file as java code.

 

7. Code configuration in depth

package edu.xmu.log4j;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Date;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.junit.Test;

public class Log4jExampleTest2
{
	private static Logger logger = Logger.getLogger("edu.xmu.log4j");

	@Test
	public void test() throws IOException
	{
		// Log4jExampleTest test = new Log4jExampleTest();
		Layout layout = new SimpleLayout();

		ConsoleAppender consoleAppender = new ConsoleAppender();
		consoleAppender.setName("SYSOUT");
		consoleAppender.setLayout(layout);
		consoleAppender.setWriter(new OutputStreamWriter(System.out));
		consoleAppender.setThreshold(Level.ERROR);

		FileAppender fileAppender = new FileAppender();
		fileAppender.setName("FILE");
		fileAppender.setLayout(layout);
		fileAppender.setAppend(true);
		fileAppender.setImmediateFlush(true);
		fileAppender.setWriter(new FileWriter(new File(
				"C:/YangKunLun/logging/log2.out")));
		fileAppender.setThreshold(Level.DEBUG);

		logger.addAppender(fileAppender);
		logger.addAppender(consoleAppender);
		logger.setLevel(Level.WARN);

		logger.debug((new Date()) + " [DEBUG] Hello this is an debug message");
		logger.info((new Date()) + " [INFO] Hello this is an info message");
		logger.warn((new Date()) + " [WARN] Hello this is an warn message");
		logger.error((new Date()) + " [ERROR] Hello this is an error message");
		logger.fatal((new Date()) + " [FATAL] Hello this is an fatal message");
	}

}

    Comments:

        1) The code above is equivalent to the configuration file in 6-2

        2) Pay attention to that fileAppender.setWriter(new FileWriter(...)) is not fileAppender.setFile("...");

            Pay attention to that console.setWriter(new OutputStreamWriter(...)) is not consoleAppender.setTarget("...");

        3) The relationship of levels of Logger and Appender is like that in JUL. Please refer to previous chapter.

 

Reference Links:

    1) http://logging.apache.org/log4j/1.2/manual.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值