优势
看了一下Logback的官方文档,说换成LogBack的原因大概有一下几个:
1. 说是logBack的设计开发和log4j是同一批人员,重写了内核,习惯上总体跟log4j一样,不会有太多生疏感。在一些关键路径上性能快乐很多, 初始化的内存更小。
2. 文档说最推荐的一点是 logBack经过了比log4j更长时间和全面的测试,更加稳定。
3. Logback-classic非常自然实现了SLF4j:Logback-classic实现了SLF4j。在使用SLF4j中,你都感觉不到logback-classic。而且因为logback-classic非常自然地实现了slf4j , 所 以切换到log4j或者其他,非常容易,只需要提供成另一个jar包就OK,根本不需要去动那些通过SLF4JAPI实现的代码
其他的云云就不细追究了。
配置部分:
LogBack有以下几个模块。
- logback-core:其它两个模块的基础模块
- logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
- logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能
logback的默认配置
如果配置文件 logback-test.xml 和 logback.xml 都不存在,那么 logback 默认地会调用BasicConfigurator ,创建一个最小化配置。最小化配置由一个关联到根 logger 的ConsoleAppender 组成。输出用模式为%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 的 PatternLayoutEncoder 进行格式化。root logger 默认级别是 DEBUG。
导入以下依赖
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
如果与spring集成,那么就在项目resource目录下创建 logback-spring.xml文件,spring会自动识别。
配置文件示例和作用:
<?xml version="1.0" encoding="UTF-8"?> <!-- 根节点 , logback的全局配置 , 包含3个属性 scan : 当文件发生变更时是否重载 , 默认值ture scanPeriod : 监测文件的间隔时间 , 即每隔多少时间扫描一次配置文件 仅当scan=true时生效. 默认间隔时间1min , 如果不写单位默认是毫秒; debug : 是否为debug模式 , 为true时会打印出logack内部日志 , 便于查看logback实时信息 . 默认值false --> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 上下文名称 , 每个logger都关联到上下文 , 默认值为default . 设置之后不可动态修改 --> <contextName>logback</contextName> <!-- 定义变量 , 在配置文件其他地方可通过${变量名}访问 --> <property name="appName" value="xdemo"/> <!-- 内部变量 , 获取时间戳字符串 . key为变量名 , datePattern为解析的日期字符串格式 , 与SimpleDateFormat格式相同 --> <timestamp key="time" datePattern="yyyyMMdd HHmmss"/> <!-- 日志输出组件 有两个必须的属性 name : 当前appender的名称 , 在logger组件中相关联 class : 日志的输出控制类 , 通过class将日志输出到控制台/文件/远程socket服务器/数据库等 不同的class有着不同的配置 --> <!-- ConsoleAppender , 将日志输出到控制台 . 有encoder和target两个子节点(新版本有filter子节点 , 在下文中详细说明) --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!-- 子节点encoder , 指定日志输出的格式 , 具体格式配置见下方表格 --> <encoder> <pattern>%d{HH:mm:ss} [%thread][%X{traceId}] %-5level %logger{36} - %msg%n</pattern> </encoder> <!-- 子节点target , 日志输出的对象 System.out 或 System.err --> <target></target> </appender> <!-- FileAppender , 将日志输出到文件 . 有file/append/encoder/prudent四个子节点(新版本有filter子节点 , 在下文中详细说明) --> <appender name="file" class="ch.qos.logback.core.FileAppender"> <!-- 子节点file , 输出的目标文件名 , 父级目录不存在会自动创建 . 无默认值 --> <file>xdemo.log</file> <!-- 子节点append , 是否为追加模式 . 为true则日志被追加到文件末尾 , false则清空现文件重新写入 . 默认值true --> <append>true</append> <!-- 子节点encoder , 指定日志输出的格式 --> <encoder> <pattern>%d{HH:mm:ss} [%thread][%X{traceId}] %-5level %logger{36} - %msg%n</pattern> </encoder> <!-- 子节点produent , 是否为安全写入模式 . 为ture则日志会被安全的写入文件 , 即使其他FileAppender同时做写入操作 , 效率低 . 默认值false --> <prudent>true</prudent> </appender> <!-- RollingFileAppender , 将日志动态输出到文件 . 通过clas指定策略 , 符合某个策略时 , 会自动创建新日志文件并输出(按日期/大小等) . 有file/append/rollingPolicy等几个节点 --> <appender name="log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- RollingFileAppender详细配置其中有file/append/pruduent几个通用节点 , 不再详述 .具体讲一下rollingPolicy节点相关 , 该节点通过class属性指定不同的配置指定RoolingFileAppender的动态行为 , 涉及日志文件的移动/重命名等--> <!-- TimeBasedRollingPolicy 最常用的动态策略 , 根据时间来分割日志 主要有fileNamePattern和maxHistory子节点 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 子节点fileNamePattern : 文件目录表达式 , 包含文件名及%d转换表达式 , %d可以包含一个SimpleDateFormat格式的日期字符串 , 如"yyyyMMdd" , 如省略直接写%d则默认为"yyy-MM-dd", 则按照日期自动分割每天产生的日志配置该节点后 , RollingFileAppender的file节点可有可无 , 如果同时配置了两个节点的话 , 日志文件会归档为两套(一套按日期分割 , 一套整个写入file指定的文件) --> <fileNamePattern>/data/logs/%d/xdemo_%d{yyMMdd}.log</fileNamePattern> <!-- 子节点maxHistory : 非必填节点 , 控制历史归档的最大数量 , 超出该配置则删除旧文件 . 如果配置按天归档且maxHistory为30 , 则只保存最近30天的日志文件(包括为该文件而创建的目录) --> <maxHistory>30</maxHistory> <!-- 子节点totalSizeCap , 在 1.1.6版本后才开始支持, 配置总日志文件的大小上限 --> <totalSizeCap>20GB</totalSizeCap> </rollingPolicy> <!-- SizeBasedTriggeringProlicy 根据大小来分割日志 , 只有一个专属子节点maxFileSize --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <file>/data/logs/xdemo.log</file> <!-- 单个日志的大小上限 , 超出该上线则新建日志(后缀名_1/2/3)继续写入 --> <maxFileSize>500MB</maxFileSize> </rollingPolicy> <!-- SizeAndTimeBasedRollingPolicy 综合时间和大小分割 , 单个时间段内超过大小继续分割 --> <!-- ?FixedWindowRollingPolicy 根据固定窗口算法分割文件? --> <!--filter: 日志过滤器 , 可以过滤不符合规则的内容 , 使之不输出到控制台或文件 , 为appender的子节点
logback过滤器是基于Ternary Logic, 允许多个过滤器搭配使用 , 配置多个过滤器时按照书写顺序依次执行执行一个过滤器会返回以下几个枚举值
ACCEPT: 该日志符合规则 , 接受处理 . 同时不会再经过其他过滤器
NEUTRAL: 当前过滤器不处理 , 下个过滤器继续处理
DENY: 该日志将被过滤抛弃 , 且不再经过其他过滤器
LevelFilter: 级别过滤器; 过滤掉非配置等级的日志 , 只有等于当前级别时才会处理 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch><!-- 匹配等级的返回值 -->
<onMismatch>DENY</onMismatch><!-- 不匹配的返回值 -->
</filter>
<!-- ThresholdFilter: 阀值过滤器; 过滤掉低于阀值的日志 , 当日志级别等于或高于阀值 , 过滤器返回NEUTRAL , 否则直接返回DENY -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- EvaluatorFilter: 条件过滤器; 评估鉴别日志是否符合指定条件 , 有一个主要的evaluator(鉴定器)子节点 -->
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<!-- 过滤器 -->
<evaluator> <!-- 默认为 ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
<expression>return message.contains("xinfo");</expression><!-- 布尔表达式 , 还有一种正则表达式的形式 -->
</evaluator>
<OnMatch>ACCEPT</OnMatch>
<OnMismatch>DENY</OnMismatch>
</filter>
</appender>
<!-- logger 日志返回/级别及输出目标配置 有必填属性name和选填属性level/additivity , 一个appender-ref 子节点(可配置1个或多个)
name : 指定遵守该logger约束的一个包或具体的某个类
level : 日志级别 ,有以下值TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF , 不区分大小写
additivity : 是否向上级logger传递日志信息 , 默认为ture . (如果上级logger也输出日志 , 则会输出两份 . 所以通常情况下配置为false)
-->
<logger name="org.springframework" level="INFO" additivity="false">
<appender-ref ref="console"/><!-- 输出到相关联的appender中 -->
<appender-ref ref="file"/>
</logger>
<!-- 更多常用的三方框架logger配置见下文 -->
<!-- root本身也是一个logger节点(相当于name="root"的logger) , 但仅能配置一个 , 是所有logger的父级(可以理解为Java中的Object) , 只有一个level属性, 默认值DEBUG -->
<root level="error">
<appender-ref ref="console"/>
<appender-ref ref="file" />
</root>
</configuration>
<!-- 常用的三方框架logger配置 -->
<!-- myBatis/JDBC 日志 -->
<logger name="com.apache.ibatis" level="DEBUG"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- hibernate日志 -->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="DEBUG" />
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
日志输出格式详细说明
参数 | 说明 | 示例 |
c{length} lo{legnth} logger{length} | 输出日志的logger , length缩短logger名 , 设置为0表示只输入logger最右边点符号之后内容(从右开始缩短 ,每个层级至少保留1位) | 完整logger名 : cn.xbz.test.HelloController %logger : cn.xbz.test.HelloController %logger{0}: HelloController %logger{5}: c.x.t.HelloController %logger{20}: c.x.test.HelloController |
C{length} class{length} | 输出当前调用者的全名(包名+类名) , 参数与上面一致 , 效率不高 , 尽量避免使用 | %class |
contextName cn | 输出xml中配置的上下文名称 | %contextName |
d{pattern} date{pattern} | 输出当前的时间 , 字符串语法与SimpleDateFormat相同 | %d : 2019-01-10 10:01:10,816 %date : 2019-01-10 10:01:10,816 %date{HH:mm:ss.SSS} : 10:01:10,816 %date{yyyy-MM-dd hh:mm:ss} : 2019-01-10 10:01:10 |
F file | 输出日志写入目标的文件名 , 尽量避免使用 | %file |
caller{depth} caller{depth, evaluator-1, ... evaluator-n} | 当前调用者的位置信息 | ? |
L line | 输出日期请求的行号 , 尽量避免使用 | %line |
m msg message | 输出日志信息(必用) | %message |
M method | 当前执行日志请求的方法名 , 尽量避免使用 | %method |
n | 输出平台相关的换行符("\n" 或 "\r\n") | %n |
p le level | 输出日志级别(TRACE/DEBUG/INFO/WARN/ERROR/FATAL) | %level |
r relative | 输出自程序启动到创建日志记录的时间 , 单位毫秒 | %relative |
t thread | 输出调用日志的线程名 | %thread |
replace(p){r,t} | 替换输出内容 , p为日志内容 , r是正则表达式 , 将p中符合r的内容替换为t | %replace(%msg){'\s',''} |
日志格式修饰符
可选的格式修饰符位于“%”和转换符之间。(%-5level / %.6logger)
第一个可选修饰符是左对齐 标志,符号是减号“-”;接着是可选的最小宽度 修饰符,用十进制数表示。如果字符小于最小宽度,则左填充或右填充,默认是左填充(即右对齐),填充符为空格。如果字符大于最小宽度,字符永远不会被截断。最大宽度 修饰符,符号是点号"."后面加十进制数。如果字符大于最大宽度,则从前面截断。点符号“.”后面加减号“-”在加数字,表示从尾部截断。
例如:%-4relative 表示,将输出从程序启动到创建日志记录的时间 进行左对齐 且最小宽度为4
转载请注明出处!
参考自: https://blog.csdn.net/xingbaozhen1210/article/details/89330520