https://logging.apache.org/log4j/2.x/
Log4j的1.x版本已经被广泛使用于很多应用程序中。然而,它这些年的发展已经放缓。它变得越来越难以维护,因为它需要严格遵循很老的Java版本,并在2015年8月寿终正寝。它的替代品,SLF4J和Logback对框架做了很多必要的改进。
那么为什么还要费心去做Log4j 2呢?几个原因如下:
应用程序要使用Log4j 2的API,需要从LogManager中获取一个有明确名称的Logger。
LogManager将会定位到一个合适的LoggerContext并且从中获取Logger。
如果Logger必须被创建,那么它会和包含这些信息的LogConfig相关联:
a)与Logger相同的名称;
b)父包的名称;
c)根LoggerConfig。LoggerConfig对象根据配置中的Logger声明而创建。
LoggerConfig与实际处理LogEvent事件的Appender关联。
在表格中,垂直列为LogEvent的级别,水平列为从合适的LoggerConfig中分配到的级别。二者的交点处标识了LogEvent是否会被通过并传递给下一步处理,是(YES)或否(NO)。
Log4j提供Filter并可应用于:控制被传递到任何LoggerConfig之前、控制被传递到达一个LoggerConfig但在调用任何Appender之前、控制被传递到一个LoggerConfig单在调用一个指定的Appender和每一个Appender之前。
与防火墙过滤的方式类似,每一个Filter都将返回三个结果之一:Accept(接受)、Deny(拒绝)或Neutral(中立)。
尽管一个事件可能被Filter接受,但事件仍然可能不被记录。这种情况会发生于事件被LoggerConfig之前的Filter接受,但被LoggerConfig的Filter拒绝或者被所有的Appender拒绝。
http://logging.apache.org/log4j/2.x/manual/appenders.html
Log4j允许将日志请求打印到多个目标。用Log4j的说法,一个输出的目标位置被称为Appender。目前,Appender存在几种:控制台、文件、远程Socket服务器、Apache Flume、JMS、远程UNIX系统日志后台以及好几种数据库API。
一个Logger上可以装配多个Appender。
用户不仅希望自定义输出的目的位置,也希望自定义输出格式。
这可以通过将一个Layout与Appender关联来实现。Layout负责根据用户的希望来格式化LogEvent,然而是Appender负责将格式化的内容输出到目的位置。
PatternLayout,Log4j中的一部分,让用户根据C语言printf函数的方式来具体化输出格式。
例如,使用转换模式“%r [%t] %-5p %c - %m%n”
的PatternLayout将会输出类似于下面的内容:
176 [main] INFO org.foo.Bar - Located nearest gas station.
第一个字段是程序启动以来锁经过的毫秒时间。
第二个字段是发出日志请求的线程。
第三个字段是日志声明的级别。
第四个字段是与日志请求相关联的Logger名称。
在“-”之后的文本是日志的消息内容。
Log4j带有很多不同的Layout以支持诸如JSON、XML、HTML和Syslog
大多数情况下,从Log4j 1.x API转换到Log4j 2相当简单。很多日志声明都不需要修改,但以下这些变更是必要的
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
Console>
Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="info"/>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
Root>
Loggers>
Configuration>
<Configuration>
<Appenders>
<File name="A1" fileName="A1.log" append="false">
<PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
Console>
Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
Root>
Loggers>
Configuration>
<Configuration>
<Appenders>
<Socket name="A1" host="localHost" port="5000">
<SerializedLayout/>
Socket>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
Console>
Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
Root>
Loggers>
Configuration>
<Configuration status="debug">
<Appenders>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
Async>
Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
Root>
Loggers>
Configuration>
注意AsyncAppender应该在它引用Appender的后面被配置,这会让它正确地关闭。
<Configuration status="debug">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
Console>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
<AppenderRef ref="CONSOLE"/>
Async>
Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
Root>
Loggers>
Configuration>
Log4j 2的配置可以通过以下4种方式之一完成:
举例,具体请根据实际需要修改
<configuration status="debug">
<Properties>
<Property name="fileName">loginModule.logProperty>
<Property name="backupFilePatch">D:/workspace/workspace-jee/HelloSpring/hello-spring4/log/Property>
Properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
Console>
<RollingFile name="RollingFile" fileName="${backupFilePatch}${fileName}"
filePattern="${backupFilePatch}$${date:yyyy-MM}/app-%d{yyyyMMddHHmmssSSS}.log.gz">
<PatternLayout
pattern="%d{yyyy.MM.dd 'at' HH:mm:ss.SSS z} %-5level %class{36} %L %M - %msg%xEx%n" />
<SizeBasedTriggeringPolicy size="20MB" />
<DefaultRolloverStrategy max="20"/>
RollingFile>
appenders>
<loggers>
<Logger name="org.apache.log4j.xml" level="trace"
additivity="true">
<AppenderRef ref="RollingFile" />
Logger>
<Root level="error">
<AppenderRef ref="Console" />
Root>
loggers>
configuration>
maven 的引用
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-apiartifactId>
<version>${log4j2.version}version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>${log4j2.version}version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-webartifactId>
<version>${log4j2.version}version>
dependency>
<properties>
<log4j2.version>2.8.2log4j2.version>
properties>
import com.foo.Bar;
// 导入Log4j的类
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class MyApp {
// 定义一个静态的日志器变量,引用名为MyApp的实例
private static final Logger logger = LogManager.getLogger(MyApp.class);
public static void main(final String... args) {
// 设置一个简单的配置,日志显示在控制台中
logger.trace("Entering application.");
Bar bar = new Bar();
if (!bar.doIt()) {
logger.error("Didn't do it.");
}
logger.trace("Exiting application.");
}
}
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class Bar {
static final Logger logger = LogManager.getLogger(Bar.class.getName());
public boolean doIt() {
logger.entry();
logger.error("Did it again!");
return logger.exit(false);
}
}
如果Log4j找不到配置文件,它将提供默认配置。DefaultConfiguration类中提供的默认配置将设置:
注意,默认情况下Log4j将根日志记录器分配给Level.ERROR。
MyApp的输出类似如下:
17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
17:13:01.540 [main] ERROR MyApp - Didn't do it.
如前所述,Log4j将首先尝试从配置文件配置自身。与默认配置相同的配置如下所示:
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
Console>
Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
Root>
Loggers>
Configuration>
一旦上述文件作为log4j2.xml放入到类路径中,你将得到与上面列出的相同结果。将根级别更改为trace将得到类似于以下的结果:
17:13:01.540 [main] TRACE MyApp - Entering application.
17:13:01.540 [main] TRACE com.foo.Bar - entry
17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
17:13:01.540 [main] TRACE com.foo.Bar - exit with (false)
17:13:01.540 [main] ERROR MyApp - Didn't do it.
17:13:01.540 [main] TRACE MyApp - Exiting application.
请注意,使用默认配置时,将禁用状态日志的记录。