007-log-log4j2、slf4j+log4j2
一、概述
而log4j2的性能无论在同步日志模式还是异步日志模式下都是最佳的.
根本原因在于log4j2使用了LMAX, 一个无锁的线程间通信库代替了, logback和log4j之前的队列. 并发性能大大提升,
区别于log4j存在天然缺陷:
- log4j采用同步输出模式,当遇到高并发&日志输出过多情况,可能导致线程阻塞,消耗时间过大
- log4j无法实现自动删除按照日期产生的日志,现有项目都采用定时脚本删除日志。
通过调研,log4j2采用异步输出,并且能通过配置实现自动删除日志。
关于log4j2的新特性
- 丢数据这种情况少,可以用来做审计功能。而且自身内部报的exception会被发现,但是logback和log4j不会。
- log4j2使用了disruptor技术,在多线程环境下,性能高于logback等10倍以上。
- (garbage free)之前的版本会产生非常多的临时对象,会造成GC频繁,log4j2则在这方面上做了优化,减少产生临时对象。尽可能少的GC
- 利用插件系统,使得扩展新的appender,filter,layout等变得容易,log4j不可以扩展 插件????
- 因为插件系统的简单性,所以在配置的时候,可以不用具体指定所要处理的类型。class
- 可以自定义level
- Java 8 lambda support for lazy logging
- Support for Message objects
- 对filter的功能支持的更强大
- 系统日志(Syslog)协议supports both TCP and UDP
- 利用jdk1.5并发的特性,减少了死锁的发生。
- Socket LogEvent SerializedLayout
- 支持kafka queue
1.1、pom依赖
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.11.1</version> </dependency>
log4j只需要引入一个jar包即可1.2.17,而log4j 2则是需要2个核心,log4j和log4j 2的包路径是不同的,Apache为了区分,包路径都更新了
1.2、基础配置
在classpath或者resources下增加log4j2.xml配置即可
<?xml version="1.0" encoding="UTF-8"?> <!--设置log4j2的自身log级别为warn--> <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置, 当设置成trace时,你会看到log4j2内部各种详细输出--> <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> <configuration status="warn" monitorInterval="30"> <!--全局参数--> <Properties> <Property name="logPath">log</Property> </Properties> <!--先定义所有的appender--> <appenders> <!--这个输出控制台的配置--> <console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}-%t] [%p] - %l - %m%n"/> </console> <!--文件输出,--> <RollingFile name="RollingFileInfo" fileName="${logPath}/info.log" filePattern="${logPath}/info_%d{yyyy-MM-dd}.log"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}-%t] [%p] - %l - %m%n"/> <Policies> <!--按照filePattern 时间单位 interval 间隔生成文件--> <TimeBasedTriggeringPolicy modulate="true" interval="1"/> </Policies> </RollingFile> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <loggers> <!--过滤掉spring和hibernate的一些无用的debug信息--> <logger name="org.springframework" level="INFO"></logger> <logger name="org.elasticsearch" level="INFO"></logger> <logger name="com.jd.jsf.gd" level="warn"></logger> <logger name="org.mybatis" level="INFO"></logger> <logger name="org.apache.ibatis.logging.jdbc" level="warn"></logger> <!-- 将业务dao接口填写进去,并用控制台输出即可 --> <logger name="com.github.bjlhx15.data.repository" level="debug" additivity="false"> <appender-ref ref="Console"/> <appender-ref ref="RollingFileInfo"/> </logger> <root level="info"> <appender-ref ref="Console"/> <appender-ref ref="RollingFileInfo"/> </root> </loggers> </configuration>
1.3、程序使用
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class ApplicationMain { private static Logger logger = LogManager.getLogger(ApplicationMain.class); public static void main(String[] args) { // 记录debug级别的信息 logger.debug("This is debug message."); // 记录info级别的信息 logger.info("This is info message."); // 记录error级别的信息 logger.error("This is error message."); } }
二、配置详解
2.1、配置文件
2.1.1.关于配置文件的名称以及在项目中的存放位置
log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn".
系统选择配置文件的优先级(从先到后)如下:
(1).classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件.
(2).classpath下的名为log4j2-test.xml的文件.
(3).classpath下名为log4j2.json 或者log4j2.jsn的文件.
(4).classpath下名为log4j2.xml的文件.
我们一般默认使用log4j2.xml进行命名。如果本地要测试,可以把log4j2-test.xml放到classpath,而正式环境使用log4j2.xml,则在打包部署的时候不要打包log4j2-test.xml即可。
2.1.2.缺省默认配置文件
<?xml version="1.0" encoding="UTF-8"?> <configuration status="OFF"> <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"> <appender-ref ref="Console"/> </root> </loggers> </configuration>
2.1.3.配置文件节点解析
(1).根节点Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger).
status用来指定log4j本身的打印日志的级别.
monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.
(2).Appenders节点,常见的有三种子节点:Console、RollingFile、File.
a、Console:节点用来定义输出到控制台的Appender.
name:指定Appender的名字.
target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.
PatternLayout:输出格式,不设置默认为:%m%n.
b、File:节点用来定义输出到指定位置的文件的Appender.
name:指定Appender的名字.
fileName:指定输出日志的目的文件带全路径的文件名.
PatternLayout:输出格式,不设置默认为:%m%n.
c、RollingFile:节点用来定义超过指定大小自动删除旧的创建新的的Appender。rollover
表示的是当日志文件大小满足指定大小后,就生成一个新的文件的过程。
RollingFileAppender
是一个OutputStreamAppender
,它(会把日志)写入到filename
参数命名的文件中,并且会根据TriggeringPolicy
和RolloverPolicy
来rollover
(rolls the file over)。RollingFileAppender
会使用RollingFileManager
(继承OutputStreamManager)来实际执行文件的I/O和执行rollover
。尽管不能共享来做不同配置的RolloverFileAppenders
,但是如果Manager
可以访问的话,那么RolloverFileAppenders
可以(进行共享)。
例如:在一个servlet
容器中的两个web
应用程序,他们有自己的配置,如果他们Log4j
是共用一个类加载器(ClassLoader)那么就可以安全的写入到一个文件中。
RollingFileAppender 需要TriggeringPolicy
和RolloverStrategy
。triggering policy
决定是否应该执行rollover
的操作,而RolloverStrategy
定义了应该如何完成rollover
。如果RolloverStrategy
没有配置的话,RollingFileAppender
将使用DefaultRolloverStrategy
。从log4j
2.5版本开始,在DefaultRolloverStrategy
中配置的自定义删除操作在rollover
时将被执行。
从2.8版本开始,如果在DirectWriteRolloverStrategy
中没有配置文件名,将使用DefaultRolloverStrategy
进行替换。
RollingFileAppender
不支持文件锁的。
参数概述
参数名 | 类型 | 描述 |
---|---|---|
append | boolean | 默认为true,记录追加到文件的最后,否则就先清除以前的记录再写入 |
bufferedIO | boolean | 默认true,记录将会写入到缓存区,当缓存区满的时候,就会写入磁盘。或者如果设置immediateFlush 将会立即写入。文件锁定不能和bufferedIO一起使用。 |
bufferSize | int | 当bufferedIO设置为true是,默认是8192 bytes |
createOnDemand | boolean | 默认为false,该appender按需创建文件,当日志事件通过所有的filters并且通过路由指向了该appender,该appender仅仅创建该文件 |
filter | Filter | 过滤器决定事件是否应该由这个Appender来处理。通过使用CompositeFilter 来使用多个Filter |
fileName | String | 要写入的文件的名称。如果文件或其父目录不存在,它们都将被创建出来,指定输出日志的目的文件带全路径的文件名. |
filePattern | String |
压缩日志文件的文件名的模式。该模式的格式取决于所使用的 这个模式也支持运行时插值,所以任何的查找( eg:DateLookup)都可以包含在模式中 |
immediateFlush | boolean |
默认为true,每次写入都会执行flush。这可以保证每次数据都被写入磁盘,但是会影响性能。在同步的loggers中每次写入执行flush,那就非常有用。 异步loggers和appenders将会在一系列事件结束后自动执行flush,即使设置为false。这也保证了数据写入到磁盘而且很高效 |
layout | Layout | 这个Layout 用于格式化LogEvent .如果没有提供默认的layout ,默认为layout 模式为%m%n 。 |
name | String | 该Appender名称 |
policy【Policies】 | TriggeringPolicy | 用于决定是否发生rollover 的策略 |
strategy | RolloverStrategy | 用于决定压缩文件的名称和路径 |
ignoreExceptions | boolean | 默认为true,遇到异常时,会将事件追加到内部日志并忽略它。设置false时,异常会传递给调用者,当这个appender被FailoverAppender包裹时,必须设置为false |
c.1、PatternLayout
输出格式,不设置默认为:%m%n.具体含义桶log4j意义一致:002-log-log4j
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}-%t] [%p] - %l - %m%n"/>
c.2、【Policies】Triggering Policies以下是Policies子节点
c.2.1、Composite Triggering Policy【组合使用】
Composite Triggering Policy
组合了多个triggering policies
,如果配置的策略中的任何一个返回true
,则返回true。CompositeTriggeringPolicy
简单的通过在policies
元素包裹其他的policies
来配置。
例如,以下XML片段定义了当JVM启动时,当日志大小达到二十兆字节以及当前日期与日志的开始日期不匹配时滚动日志的策略。
<Policies> <OnStartupTriggeringPolicy /> <SizeBasedTriggeringPolicy size="20 MB" /> <TimeBasedTriggeringPolicy /> </Policies>
c.2.2、Cron Triggering Policy【基于cron
表达式的CronTriggeringPolicy
触发rollover
。】
CronTriggeringPolicy 参数
参数名称 | 类型 | 描述 |
---|---|---|
schedule | String | cron表达式。该表达式和Quartz调度所允许的表达式相同,有关表达式的完整描述,请参阅CronExpression |
evaluateOnStartup | boolean | 在启动时,将根据文件的最后修改时间戳评估cron表达式。如果cron表达式表示在该时间和当前时间之间应该发生rollover ,则文件将立即rollover 。 |
c.2.3、OnStartup Triggering Policy【程序启动时候执行一次rollover,如果日志文件比当前jvm
启动时间更早以及满足或者超过最小文件的大小就会触发rollover】
OnStartupTriggeringPolicy 参数说明:
参数名称 | 类型 | 描述 |
---|---|---|
minSize | long | 文件必定发生rollover 操作的最小尺寸。要是大小为0的话,那么无论文件大小是多少都将引起rollover 。默认值为1,这将阻止空文件发送rollover |
c.2.4、SizeBased Triggering Policy【一旦文件大小达到指定大小后,就会发送rollover
。 单位可以使KB、MB、GB】
<SizeBasedTriggeringPolicy size="200 MB"/>
c.2.5、TimeBased Triggering Policy【按照filePattern 时间单位 interval 间隔生成文件】
该策略接受一个interval
属性和modulate
布尔属性。其中interval
属性表示的是,基于时间模式应该发送rollover
的频率。
TimeBasedTriggeringPolicy参数说明:
参数名称 | 类型 | 描述 |
---|---|---|
interval | integer | 根据日期格式中最具体的时间单位来决定应该多久发生一次rollover 。例如,在日期模式中小时为具体的时间单位,那么每4小时会发生4次rollover ,默认值为1 |
modulate | boolean | 表示是否调整时间间隔以使在时间间隔边界发生下一个rollover 。例如:假设小时为具体的时间单元,当前时间为上午3点,时间间隔为4,第一次发送rollover 是在上午4点,接下来是上午8点,接着是中午,接着是下午4点等发生。 |
maxRandomDelay | integer | 表示随机延迟翻转的最大秒数。默认情况下,该值为0表示没有延迟。此设置在将多个应用程序配置为同时翻转日志文件的服务器上非常有用,并且可以跨时间分担这样做的负担。 |
c.3、Rollover Strategies
c.3.1、DefaultRolloverStrategy
默认的rollover strategy
接受一个日期/时间模式和一个整数,其中这个整数,是RollingFileAppender
本身指定的filePattern
属性。如果date/time
模式存在的话,它将会替换当前日期和时间的值。如果这个模式包含整数的话,它将会在每次发生rollover
时,进行递增。如果模式同时包含date/time
和整数,那么在模式中,整数会递增直到结果中的data/time
模式发生改变。如果文件模式是以".gz", ".zip", ".bz2", ".deflate", ".pack200", or ".xz"
结尾的,将会与后缀相匹配的压缩方案进行压缩文件。格式为:bzip2, Deflate, Pack200 和 XZ
需要Apache Commons Compress,此外,XZ
需要XZ for Java
该模式还可以包含可以在运行时解析的查找引用,如下面的示例所示:
默认的rollover
策略支持三种增加计数的方式。第一种叫做:fixed window
策略。为了说明它的工作原理,假设min属性设置为1,max属性设置为3,文件名为“foo.log”,文件名模式为:foo-%i.log。
rollover次数 | 输出的目标 | 压缩的日志文件 | 描述 |
---|---|---|---|
0 | foo.log |
- | 所有的日志都输出到初始文件中 |
1 | foo.log |
foo-1.log | 在第一次rollover 时,foo.log会被重命名为foo-1.log。同时会创建一个新的foo.log 并开始写入。 |
2 | foo.log |
foo-1.log, foo-2.log | 在第二次发生rollover 时,foo-1.log会重命名为foo-2.log并且foo.log会重命名为foo-1.log。同时会创建一个新的foo.log 并开始写入。 |
3 | foo.log | foo-1.log, foo-2.log, foo-3.log | 在第三次发生rollover 时,foo-2.log会重命名为foo-3.log。foo-1.log重命名为foo-2.log,foo.log会重命名为foo-1.log。同时会创建一个新的foo.log 并开始写入。 |
4 | foo.log | foo-1.log, foo-2.log, foo-3.log | 在第四次和随后的rollover 时,foo-3.log会被删除,foo-2.log重命名为foo-3.log。foo-1.log重命名为foo-2.log。foo.log重命名为foo-1.log。后面同理 |
相比之下,当 fileIndex属性设置了max
,其他设置和上面相同,将执行以下操作:
rollover次数 | 输出的目标 | 压缩的日志文件 | 描述 |
---|---|---|---|
0 | foo.log | - | 所有的日志都输出到初始文件中 |
1 | foo.log | foo-1.log | 在第一次rollover时,foo.log会被重命名为foo-1.log。同时会创建一个新的foo.log并开始写入。 |
2 | foo.log | foo-1.log foo-2.log | 在第二次rollover时,foo.log重命名为foo-2.log。同时会创建一个新的foo.log并开始写入。 |
3 | foo.log | foo-1.log foo-2.log foo-3.log | 在第三次发生rollover时,fool.log重命名为foo-3.log,同时会创建一个新的foo.log并开始写入。 |
4 | foo.log | foo-1.log foo-2.log foo-3.log | 在第四次和随后的rollover时,foo-1.log会被删除,foo-2.log重命名为foo-1.log,foo-3.log重命名为foo-2.log,foo.log重命名为foo-3.log。同时会创建一个新的foo.log并开始写入。 |
最后,从2.8版本开始,如果fileIndex
属性设置为nomax
,那么最大和最小值,都将会被忽略掉,文件编号将从1开发增加,并且每次rollover时递增都从编码最大开始(项目于max效果),而且没有文件数的限制。
DefaultRolloverStrategy参数
参数名称 | 类型 | 描述 |
---|---|---|
fileIndex | String | 如果设置了max(默认就是),文件索引(编号)高的比低的更 新些。如果设置min,文件重命名将遵循Fixed Window 策略 |
min | integer | 计数器的最小值。默认值为1。 |
max | integer | 计数器的最大值。一旦达到这个值,旧的档案将在随后的rollover 中被删除。 |
compressionLevel | integer | 设置压缩级别0-9,其中0=无,1=最佳速度,通过9=最佳压缩。只适用于ZIP文件。 |
tempCompressedFilePattern | String | 压缩期间存档日志文件的文件名模式。 |
c.3.2、DirectWrite Rollover Strategy
会将日志事件会直接写入文件模式表示的文件中去。使用这个策略不会执行文件重命名。如果基于大小的触发策略导致在指定的时间段内写入多个文件,则它们将从一个编号开始,并持续递增,直到发生基于时间的rollover
。
警告:如果文件模式里有压缩的后缀,那么当应用程序关闭时,当前文件将不被压缩。此外,如果时间变化使得文件模式不再匹配当前文件,则它也不会在启动时被压缩。
DirectWriteRolloverStrategy 参数
参数名称 | 类型 | 描述 |
---|---|---|
maxFiles | String | 在与文件模式(file pattern)匹配的时间段内允许的最大文件数。如果这个数字被突破了,则最旧的文件将被删除。如果指定了,那么这个值必须大于1。如果值小于零或省略,则文件数不受限制。 |
compressionLevel | integer | 设置压缩级别0-9,其中0=无,1=最佳速度,通过9=最佳压缩。只适用于ZIP文件。 |
示例一、它使用RollingFileAppender同时具有基于时间和大小的触发策略,将在同一天(1-7)创建最多7个存档,这些存档存储在基于当前年份和月份的目录中,并将使用gzip压缩每个存档:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Appenders> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
示例二、显示一个翻转策略,在删除之前最多可保留20个文件。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Appenders> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> <DefaultRolloverStrategy max="20"/> </RollingFile> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
示例三、它使用RollingFileAppender同时具有基于时间和大小的触发策略,将在同一天(1-7)创建最多7个存档,这些存档基于当前年份和月份存储在目录中,并将使用gzip压缩每个存档,并且当小时可被6整除时将每6小时滚动一次:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Appenders> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="6" modulate="true"/> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
示例四、配置使用RollingFileAppender同时具有基于cron和size的触发策略,并直接写入无限数量的归档文件。cron触发器每小时导致翻转,而文件大小限制为250MB:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Appenders> <RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <CronTriggeringPolicy schedule="0 0 * * * ?"/> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
示例五、与上一个相同,但将每小时保存的文件数限制为10:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Appenders> <RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <CronTriggeringPolicy schedule="0 0 * * * ?"/> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> <DirectWriteRolloverStrategy maxFiles="10"/> </RollingFile> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
c.3.3、日志存档保留策略:Delete on Rollover
log4j-2.5开始引入了删除操作,使得用户更有效的的控制在rollover
时间内删除文件,而不是使用DefaultRolloverStrategy max属性进行删除。删除操作允许用户配置一个或多个条件,选择要删除相对于基本目录的文件。
注意:删除任何文件这是允许的操作。不仅仅是rollover
时的文件。所以使用这个操作时,一定要小心。使用testMode
参数可以测试您的配置,而不会意外删除错误的文件。
参 数名称 | 类型 | 描述 |
---|---|---|
basePath | String | 必参。从哪里扫描要删除的文件的基本路径。 |
maxDepth | int |
要访问的目录的最大级别数。值为0表示仅访问起始文件(基本路径本身),除非被安全管理者拒绝。 Integer.MAX_VALUE的值表示应该访问所有级别。默认为1,意思是指定基本目录中的文件。 |
followLinks | boolean | 是否遵循符号链接默认值为false。 |
testMode | boolean | 默认false。如果为true,文件将不会被删除,而是将信息打印到info级别的status logger,可以利用这个来测试,配置是否和我们预期的一样 |
pathSorter | PathSorter | 一个实现了PathSorter接口的插件在选择删除文件前进行排序。默认是最近修改的文件排在前面 |
pathConditions | PathCondition[] |
如果没有指定ScriptCondition,则为必需。一个或多个PathCondition元素。 如果指定了多个条件,在删除之前,他们需要接受全部的路径。条件是可以嵌套的,在这种情况下,只有在外部路径被接受的情况下,才会去评估内部路径。 如果条件没有嵌套,则可以按照任何顺序去评估。条件也可以通过 用户可以创建自定义条件或使用内置条件: IfFileName:接受路径(相对于基本路径)与正则表达式或glob匹配的文件。 IfLastModified:接受与指定持续时间相同或更早的文件。 IfAccumulatedFileCount :在 IfAccumulatedFileSize:在 ifAll:如果所有嵌套条件都接受它(逻辑与),则接受路径。嵌套条件可以按任何顺序进行评估。 IfAny:如果其中一个嵌套条件接受(OR或OR),则接受路径。嵌套条件可以按任何顺序进行评估。 IfNot:如果嵌套条件不接受(逻辑NOT),则接受路径。 |
scriptCondition | ScriptCondition |
如果没有指定PathConditions,则为必需。指定脚本的ScriptCondition元素。 ScriptCondition应包含一个Script,ScriptRef或ScriptFile元素,用于指定要执行的逻辑。 有关配置ScriptFiles和ScriptRefs的更多示例,请参阅ScriptFilter文档。该脚本传递了许多参数, 包括在基本路径下找到的路径列表(最多为maxDepth),并且必须返回具有要删除路径的列表。 |
IfFileName 条件参数:
参数名称 | 类型 | 描述 |
---|---|---|
glob | String | 如果regex 没有指定的话,则必须。使用类似于正则表达式但是又具有更简单的有限模式语言来匹配相对路径(相对于基本路径) |
regex | String | 如果glob 没有指定的话,则必须。使用由Pattern类定义的正则表达式来匹配相对路径(相对于基本路径) |
nestedConditions | PathCondition[] | 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果路径名称匹配)时,才会评估嵌套条件。 |
IfLastModified条件参数:
参数名称 | 类型 | 描述 |
---|---|---|
age | String | 必须。指定持续时间duration。该条件接受比指定持续时间更早或更旧的文件。 |
nestedConditions | PathCondition[] | 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果文件足够老)时,才会评估嵌套条件。 |
IfAccumulatedFileCount 条件参数
参数名称 | 类型 | 描述 |
---|---|---|
exceeds | int | 必须。将要删除文件的计数阈值。也就是需要保留的文件数。 |
nestedConditions | PathCondition[] | 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果超过阈值计数)时,才会评估嵌套条件。 |
IfAccumulatedFileSize 条件参数
参数名称 | 类型 | 描述 |
---|---|---|
exceeds | String | 必须。将删除文件累计阀值的大小。大小可以指定字节。后缀可以是KB, MB or GB 例如:20MB 。也就是要保留最接近该值大小的文件。 |
nestedConditions | PathCondition[] | 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果超过了阈值累积文件大小)时,才会评估嵌套条件。 |
示例一、它使用RollingFileAppender和cron触发策略配置为每天午夜触发。档案存储在基于当前年份和月份的目录中。在转存时删除基本目录下与“* / app - * .log.gz”glob匹配且60天或更早的所有文件。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Properties> <Property name="baseDir">logs</Property> </Properties> <Appenders> <RollingFile name="RollingFile" fileName="${baseDir}/app.log" filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}.log.gz"> <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" /> <CronTriggeringPolicy schedule="0 0 0 * * ?"/> <DefaultRolloverStrategy> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="*/app-*.log.gz" /> <IfLastModified age="60d" /> </Delete> </DefaultRolloverStrategy> </RollingFile> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
示例二、它使用RollingFileAppender同时具有基于时间和大小的触发策略,将在同一天(1-100)创建最多100个存档,这些存档存储在基于当前年份和月份的目录中,并将使用gzip压缩每个存档并每小时滚动一次。在每次翻转期间,此配置将删除与“* / app - * .log.gz”匹配且30天或更早的文件,但保留最新的100 GB或最新的10个文件,以先到者为准。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Properties> <Property name="baseDir">logs</Property> </Properties> <Appenders> <RollingFile name="RollingFile" fileName="${baseDir}/app.log" filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz"> <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> <DefaultRolloverStrategy max="100"> <!-- Nested conditions: the inner condition is only evaluated on files for which the outer conditions are true. --> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="*/app-*.log.gz"> <IfLastModified age="30d"> <IfAny> <IfAccumulatedFileSize exceeds="100 GB" /> <IfAccumulatedFileCount exceeds="10" /> </IfAny> </IfLastModified> </IfFileName> </Delete> </DefaultRolloverStrategy> </RollingFile> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
(3).Loggers节点,常见的有两种:Root和Logger.
Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出
level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender.
Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。
level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.
AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出。
(4).关于日志level.
共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
All:最低等级的,用于打开所有日志记录.
Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.
Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.
Info:消息在粗粒度级别上突出强调应用程序的运行过程.
Warn:输出警告及warn以下级别的日志.
Error:输出错误信息日志.
Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.
OFF:最高等级的,用于关闭所有日志记录.
程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。
4.比较完整的log4j2.xml配置模板
<?xml version="1.0" encoding="UTF-8"?> <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> <configuration status="WARN" monitorInterval="30"> <!--先定义所有的appender--> <appenders> <!--这个输出控制台的配置--> <console name="Console" target="SYSTEM_OUT"> <!--输出日志的格式--> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> </console> <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用--> <File name="log" fileName="log/test.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --> <DefaultRolloverStrategy max="20"/> </RollingFile> <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <loggers> <!--过滤掉spring和mybatis的一些无用的DEBUG信息--> <logger name="org.springframework" level="INFO"></logger> <logger name="org.mybatis" level="INFO"></logger> <root level="all"> <appender-ref ref="Console"/> <appender-ref ref="RollingFileInfo"/> <appender-ref ref="RollingFileWarn"/> <appender-ref ref="RollingFileError"/> </root> </loggers> </configuration>
三、slf4j+log4j2
3.1、POM依赖
<!-- 日志 门面 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- 桥接器--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.11.1</version> </dependency> <!-- log4j2 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.11.1</version> </dependency>
3.2、配置文件
使用上述log4j2.xml 配置文件即可
3.3、程序代码
需修改,使用slf4j统一的日志门面工厂
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ApplicationMain { private static Logger logger = LoggerFactory.getLogger(ApplicationMain.class); public static void main(String[] args) { // 记录debug级别的信息 logger.debug("This is debug message."); // 记录info级别的信息 logger.info("This is info message."); // 记录error级别的信息 logger.error("This is error message."); } }