简介
Java 中比较常用的日志工具类,有:
- Log4j、
- SLF4j、
- Commons-logging(简称jcl)、
- Logback、
- Log4j2(Log4j 升级版)、
- Jdk Logging
Spring Boot 默认使用 Logback,但相比较而言,Log4j2 在性能上面会更好。spring-boot高版本都不再支持log4j,而是支持log4j2
log4j.xml 示例
<?xml version="1.0" encoding="UTF-8"?>
<!--
status : 这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,会看到log4j2内部各种详细输出
指的是如果 Log4j2 本身出错,打印出的日志级别配置
monitorInterval : Log4j 能够自动检测修改配置文件和重新配置本身
设置间隔秒数。此处表示每隔30秒重读一次配置文件
-->
<!--TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF-->
<Configuration status="OFF" monitorInterval="30">
<!-- 定义一些变量值,可供下面配置使用,例如日志存储目录等 -->
<Properties>
<Property name="App">mybatis-demo</Property>
<Property name="LogDir">logs</Property>
<Property name="SplitSize">10 MB</Property>
</Properties>
<!-- 定义所有的appender -->
<!-- Appenders标签,其实就是输出,有各种扩展组件 -->
<Appenders>
<!-- 输出控制台日志的配置 -->
<!-- ConsoleAppender 输出结果到控制台 -->
<Console name="Console" target="SYSTEM_OUT">
<!-- ThresholdFilter :过滤器 -->
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 输出日志的格式 -->
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} %L %M - %msg%xEx%n"/>
</Console>
<!-- 存储所有error信息 -->
<!-- FileAppender 输出结果到指定文件 -->
<!-- append:是否追加,true表示追加内容到所在的日志,false表示每次都覆盖 -->
<File name="WarnLog" fileName="${LogDir}/${App}-warn.log" append="false">
<!-- 添加过滤器ThresholdFilter,可以有选择的输出某个级别以上的类别 onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否则直接拒绝 -->
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!-- 文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,-->
<!-- 这个也挺有用的,适合临时测试用 -->
<!-- 这个appender的好处是有一个append为false的属性,这样,每次运行都会清空上次的日志,这样就不会因为一直在调试而增加这个文件的内容,查起来也方便,这个和输出到控制台就一个效果了 -->
<File name="log" fileName="${LogDir}/test.log" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M -
%msg%xEx%n"/>
</File>
<!-- Rolling File Appender -->
<!-- 打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
<!-- RollingFileAppender 同样输出结果到文件,区别是用一个buffer,因此速度会快点 -->
<!-- filePattern:表示当日志到达指定的大小或者时间,产生新日志时,旧日志的命名路径 -->
<RollingFile name="InfoLog" fileName="${LogDir}/${App}-info.log" immediateFlush="true" filePattern="${LogDir}/$${date:yyyy-MM}/${App}-info-%d{MM-dd-yyyy}.log" append="false">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} [%t] %-5level %logger{36} %L %M - %msg%xEx%n"/>
<SizeBasedTriggeringPolicy size="${SplitSize}"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 指定每天的最大压缩包个数,默认7个,超过了会覆盖之前的 -->
<DefaultRolloverStrategy max="50"/>
</RollingFile>
<!-- RollingRandomAccessFile 即表示以文件方式记录 -->
<!-- filePattern的设置,它与24行的SizeBasedTriggeringPolicy(表示单个文件最大多少容量)结合在一起,非常有用,
以这段配置为例,当单个文件达到10M后,会自动将以前的内容,先创建类似 2014-09(年-月)的目录,然后按 "xxx-年-月-日-序号"命名,打成压缩包。DefaultRolloverStrategy max="50"表示压缩包,最多保留50个 -->
<RollingRandomAccessFile name="ErrorLog" fileName="${LogDir}/${App}-error.log" immediateFlush="true" filePattern="${LogDir}/error-%d{yyyy-MM-dd}.log" append="false">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} [%t] %-5level %logger{36} %L %M - %msg%xEx%n"/>
<Policies>
<!-- 每天生成一个日志文件 -->
<!-- TimeBasedTriggeringPolicy 基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:
interval,integer型,指定两次封存动作之间的时间间隔。
单位:以日志的命名精度来确定单位,比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟 -->
<!-- 关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval,日期格式精确到哪一位,interval也精确到哪一个单位 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- 每到 10M 生成一个日志文件 -->
<SizeBasedTriggeringPolicy size="${SplitSize}"/>
</Policies>
<Filters>
<!-- 只记录error级别信息 -->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<!-- 最大保存文件数,超过了会覆盖之前的 -->
<DefaultRolloverStrategy max="50"/>
</RollingRandomAccessFile>
</Appenders>
<!--定义logger,只有定义了logger并引入的appender,appender才会生效-->
<!-- loggers标签,用于定义logger的level和所采用的appender,其中appender-ref必须为先前定义的appenders的名称 -->
<Loggers>
<!-- 用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。 -->
<!--第三方的软件日志级别 -->
<!-- additivity="true"这里注意一下,改成false,root logger就不会再起作用,即只会记录在文件里,控制台无输出 -->
<logger name="org.springframework" level="INFO" additivity="true">
<AppenderRef ref="InfoLog"/>
</logger>
<!-- 关于logger的命名,很有讲究的 -->
<!-- 如果你的logger中也有日志级别的配置,如果级别都在error以上,你的appender里面也就不会输出erro以下的信息了 -->
<Logger name="org.apache" level="ERROR" additivity="true">
<AppenderRef ref="ErrorLog"/>
</Logger>
<!-- root logger 配置,全局配置,默认所有的Logger都继承此配置 -->
<!-- All < Trace < Debug < Info < Warn < Error < Fatal < OFF. -->
<!-- 为log的默认输出形式,如果一个类的log没有在loggers中明确指定其输出level与格式,那么就会采用root中定义的格式 -->
<Root level="ERROR" additivity="true">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoLog"/>
<AppenderRef ref="WarnLog"/>
<AppenderRef ref="ErrorLog"/>
</Root>
</Loggers>
</Configuration>
Github 配置地址:SpringBoot-Note/mybatis-demo/src/main/resources/log4j2.xml
实验
<Loggers>
<logger name="org.springframework" level="INFO" additivity="true">
<AppenderRef ref="ErrorLog"/>
</logger>
<Root level="info" additivity="true">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoLog"/>
<AppenderRef ref="WarnLog"/>
<AppenderRef ref="ErrorLog"/>
</Root>
</Loggers>
- 注释了 Root 中对
InfoLog
的引用,org.springframework
Logger 等级为OFF
时,info.log
文件无内容; - 注释了 Root 中对
InfoLog
的引用,org.springframework
Logger 等级为iNFO
时,info.log
文件则会有org.springframework
包的相关日志内容;
<logger name="org.springframework" level="INFO" additivity="true">
<AppenderRef ref="InfoLog"/>
</logger>
<Root level="ERROR" additivity="true">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoLog"/>
<AppenderRef ref="WarnLog"/>
<AppenderRef ref="ErrorLog"/>
</Root>
- ROOT 等级设为
ERROR
时,org.springframework
Logger 等级设为OFF
时,发现原来的warn.log
和info.log
文件中,都只有级别大于或等于 ERROR 的日志信息了; - ROOT 等级设为
ERROR
时,org.springframework
Logger 等级设为INFO
时,发现info.log
文件中,增加了org.springframework
包的相关INFO
级别的日志信息了;
总结
- Logger 日志等级和 appender 日志等级的关系:logger 日志等级和 appender 日志登记,谁「高」听谁的;
- 普通 Logger 的优先级高
注意点
1.多个 appender
不能指向同一个日志文件,否则会报错:Configuration has multiple incompatible Appenders pointing to the same resource 'logs/mybatis-demo-warn.log'
2.Root Logger 只能有一个,普通的 Logger 可以定义多个,可以细致到给某个类定义;
3.我们使用 FileAppender
的时候,我们配置是 ImmediateFlush=true
,一旦有新日志写入,立马将日志写入到磁盘的文件中。当日志很多,这种频繁操作文件显然性能很低下
4.RollingFileAppender
是一个非常有意思的输出器。它将log信息写入一个文件后,会判断是否满足封存文件的要求,若满足,则除非封存文件的动作。
5.immediateFlush
:log4j2接收到日志事件时,是否立即将日志刷到磁盘。默认为true。
6.BufferedIO: 文件流写出是否使用缓冲,true表示使用,默认值为false即不使用缓冲。测试显示,即使在启用immediateFlush的情况下,设置bufferedIO=true也能提高性能。
7.多个 Logger 配置重复了,在日志文件中会重复
补充
PatternLayout定义了输出日志时的格式
%d{HH:mm:ss.SSS} 表示输出到毫秒的时间
%t 输出当前线程名称
%-5level 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%logger 输出logger名称,因为Root Logger没有名称,所以没有输出
%msg 日志文本
%n 换行
其他常用的占位符有:
%F 输出所在的类文件名,如Client.java
%L 输出行号
%M 输出所在方法名
%l 输出语句所在的行数, 包括类名、方法名、文件名、行数
---------------------
作者:大雨将至
来源:CSDN
原文:https://blog.csdn.net/autfish/article/details/51203709
版权声明:本文为博主原创文章,转载请附上博文链接!