springboot推荐使用logback-spring.xml而不是logback.xml
而logback-spring.xml文件与logback.xml文件还是有一定的区别,所以简单讲解一下。
一、logback-spring.xml
配置文件实例:
logback
debug
${CONSOLE_LOG_PATTERN}
UTF-8
${log.path}/debug.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/debug-%d{yyyy-MM-dd}.%i.log
100MB
15
debug
ACCEPT
DENY
${log.path}/info.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/info-%d{yyyy-MM-dd}.%i.log
100MB
15
info
ACCEPT
DENY
${log.path}/warn.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/warn-%d{yyyy-MM-dd}.%i.log
100MB
15
warn
ACCEPT
DENY
${log.path}/error.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/error-%d{yyyy-MM-dd}.%i.log
100MB
15
ERROR
ACCEPT
DENY
${log.path}/all.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/all-%d{yyyy-MM-dd}.%i.log
100MB
15
DEBUG
DENY
ACCEPT
大部分标签都比较类似,简单说一下:
共有一个父标签、两种属性、三个节点: (与logback.xml类似)
一个父标签:configuration
两种属性:contextName和property
三个节点:appender、root、logger
当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true
设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
如果同时存在logback.xml和logback-spring.xml,或者同时存在logback.xml和自定义的配置文件,则会先加载logback.xml,再根据application配置加载指定配置文件,或加载logback-spring,xml。如果这两个配置文件的contextName不同,就会报错:
# logback.xml
logback
12345
# logback-spring,xml
logback_demo
12345
# application.properties
logging.config=classpath:logback-spring.xml
12
ERROR in ch.qos.logback.classic.joran.action.ContextNameAction - Failed to rename context [logback] as [logback_demo] java.lang.IllegalStateException: Context has been already given a name 1
用来定义变量值的标签, 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
例如使用定义上下文名称,然后在设置logger上下文时使用。
${APP_Name}
就相当于自定义一个全局变量!
1.该
2.标签的工作方式与Logback的标准
意思就是可以读取properties配置文件中的属性。读取示例如下:
1.yml配置
logging:
name: app
2.xml配置
使用springProperty标签读取yml配置
标签配置解读:scope 作用区域:context全局
name 变量名
source 资源值(yml对应资源)
defaultValue 默认值
3.使用
直接使用${变量名}
定义转换器,可以用来对日志进行特殊的转换,比如,SpringBoot后启动项目控制台会带有彩色日志样式,是因为使用了org.springframework.boot.logging.logback.ColorConverter
颜色转换器,会把日志用AnsiOutput
进行输出。就是可以用来进行彩色日志转换。
appender 使用
元素配置,该元素采用两个必需属性 name 和 class。
元素可以包含零个或一个
元素,零个或多个
元素以及零个或多个
元素。
重要:在 logback 中,输出目标称为 appender,addAppender 方法将 appender 添加到给定的记录器 logger。
给定记录器的每个启用的日志记录请求都将转发到该记录器中的所有 appender 以及层次结构中较高的 appender。 换句话说,appender 是从记录器层次结构中附加地继承的。
例如,如果将控制台 appender 添加到根记录器,则所有启用的日志记录请求将至少在控制台上打印。
如果另外将文件追加器添加到记录器(例如L),则对 L 和 L 的子项启用的记录请求将打印在文件和控制台上。
通过将记录器的 additivity 标志设置为 false,可以覆盖此默认行为,以便不再添加 appender 累积。
Appender 是一个接口,它有许多子接口和实现类,具体如下图所示:
其中最重要的两个Appender为:ConsoleAppender 、RollingFileAppender。
ConsoleAppender,如名称所示,将日志输出到控制台上。
RollingFileAppender,是 FileAppender 的一个子类,扩展了 FileAppender,具有翻转日志文件的功能。
例如,RollingFileAppender 可以记录到名为 log.txt 文件的文件,并且一旦满足某个条件,就将其日志记录目标更改为另一个文件。
有两个与 RollingFileAppender 交互的重要子组件。
因此,RollingPolicy 负责什么和 TriggeringPolicy 负责什么时候。
作为任何用途,RollingFileAppender 必须同时设置 RollingPolicy 和 TriggeringPolicy。
但是,如果其 RollingPolicy 也实现了TriggeringPolicy 接口,则只需要显式指定前者。
TimeBasedRollingPolicy:可能是最受欢迎的滚动策略。它根据时间定义翻转策略,例如按天或按月。
TimeBasedRollingPolicy 承担滚动和触发所述翻转的责任。实际上,TimeBasedTriggeringPolicy 实现了 RollingPolicy 和 TriggeringPolicy 接口。
SizeAndTimeBasedRollingPolicy:有时您可能希望按日期归档文件,但同时限制每个日志文件的大小,特别是如果后处理工具对日志文件施加大小限制。为了满足此要求,logback 提供了 SizeAndTimeBasedRollingPolicy ,它是 TimeBasedRollingPolicy 的一个子类,实现了基于时间和日志文件大小的翻滚策略。
encoder:
encoder 中最重要就是 pattern 属性,它负责控制输出日志的格式,这里给出一个我自己写的示例:
%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n
输出格式
%d{yyyy-MM-dd HH:mm:ss.SSS}:日期
%-5level:日志级别
%highlight():颜色,info为蓝色,warn为浅红,error为加粗红,debug为黑色
%thread:打印日志的线程
%15.15():如果记录的线程字符长度小于15(第一个)则用空格在左侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符
%logger:日志输出的类名
%-40.40():如果记录的logger字符长度小于40(第一个)则用空格在右侧补齐,如果字符长度大于40(第二个),则从开头开始截断多余的字符
%cyan:颜色
%msg:日志输出内容
%n:换行符
通常encoder标签中只需要设置两个标签:
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
5)、filter
级别过滤器 ch.qos.logback.classic.filter.LevelFilter。对指定级别的日志进行具体的操作
阀值过滤器 ch.qos.logback.classic.filter.ThresholdFilter。
表达式过滤器 ch.qos.logback.core.filter.EvaluatorFilter。
Groovy的表达式 ch.qos.logback.classic.boolex.GEventEvaluator。
Java的表达式ch.qos.logback.classic.boolex.JaninoEventEvaluator。使用 Janino 解析java script。
包含标记 ch.qos.logback.classic.boolex.OnMarkerEvaluator
filter 中最重要的两个过滤器为:LevelFilter、ThresholdFilter。
LevelFilter 根据精确的级别匹配过滤事件。
如果事件的级别等于配置的级别,则筛选器接受或拒绝该事件,具体取决于 onMatch 和 onMismatch 属性的配置。
例如下面配置将只打印 INFO 级别的日志,其余的全部禁止打印输出:
INFO
ACCEPT
DENY
%-4relative [%thread] %-5level %logger{30} - %msg%n
ThresholdFilter 过滤低于指定阈值的事件。
对于等于或高于阈值的事件,ThresholdFilter 将在调用其 decision方法时响应 NEUTRAL。
但是,将拒绝级别低于阈值的事件,例如下面的配置将拒绝所有低于 INFO 级别的日志,只输出 INFO 以及以上级别的日志:
INFO
%-4relative [%thread] %-5level %logger{30} - %msg%n
logger 和 root
logger对单个包或类添加配置,相当于局部配置,root相当于全局配置
意思就是说,logger标签可以对某个类进行单独配置,而root是整体配置。
举例说明:
logger
对单个包或类添加配置:
元素。这样引用的每个 appender 都被添加到指定的 logger 中,logger 元素级别具有继承性。如果logger里面配置了additivity=“false”,就会覆盖root的,只打印一遍;但是additivity=“true”,就会向上层再次传递,不会覆盖,而是打印两遍!
7、included
在微服务里使用了logback来对日志输出进行配置,由于配置文件里有很多通用的设置,所以有必要将通用的都提取到一个公共文件里,这样所有的微服务更改配置格式的话,只需更新通用文件即可,不用每个地方都改一遍了。
如果一个logback.xml文件想在其他的项目中被引用,那么就需要用iucluded标签,将定义的appender跟logger包围起来,表示这个是可以被导入其他项目的。
下面的是通用配置文件:logback-common.xml:
[%d{yyyy-MM-dd HH:mm:ss.SSS,GMT+8}] %-5level [%t] [%c] - %msg%n
INFO
ACCEPT
DENY
[%d{yyyy-MM-dd HH:mm:ss.SSS,GMT+8}] %-5level [%t] [%c] - %msg%n
${LOG_DIR}/${LOG_SERVICE_NAME}-info.%d.log
${LOG_HIS_MAX}
${LOG_TOTAL_SIZE}
true
ERROR
[%d{yyyy-MM-dd HH:mm:ss.SSS,GMT+8}] %-5level [%t] [%c] - %msg%n
${LOG_DIR}/${LOG_SERVICE_NAME}-error.%d.log
${LOG_HIS_MAX}
${LOG_TOTAL_SIZE}
true
下面的是每个微服务自己的配置文件:logback-spring.xml:
在测试过程中出现了一个问题,就是控制台输出的日志时间是正常的,但在日志文件里输出的日志时间和实际时间相差了8个小时,判断是logback的配置文件还需要加上时区,如下:
[%d{yyyy-MM-dd HH:mm:ss.SSS,GMT+8}] %-5level [%t] [%c] - %msg%n
在时间格式后面增加了 GMT+8,表示输出的日志时区设定为东8区,即北京时间。
经过测试发现问题解决,文件里显示的也是实际时间了。
配置文件 示例:
${CONSOLE_LOG_PATTERN}
UTF-8
${FILE_LOG_PATTERN}
UTF-8
${LOG_FILE}
${ROLLINGPOLICY_FILE_NAME_PATTERN}
${ROLLINGPOLICY_CLEAN_HISTORY_ON_START}
${ROLLINGPOLICY_MAX_FILE_SIZE}
${ROLLINGPOLICY_TOTAL_SIZE_CAP}
${ROLLINGPOLICY_MAX_HISTORY}
0
1024
false
true
0
1024
false
MyContextName
debug
${CONSOLE_LOG_PATTERN}
UTF-8
${logging.path}/web_debug.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${logging.path}/web-debug-%d{yyyy-MM-dd}.%i.log
100MB
15
debug
ACCEPT
DENY
${logging.path}/web_info.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${logging.path}/web-info-%d{yyyy-MM-dd}.%i.log
100MB
15
info
ACCEPT
DENY
${logging.path}/web_warn.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${logging.path}/web-warn-%d{yyyy-MM-dd}.%i.log
100MB
15
warn
ACCEPT
DENY
${logging.path}/web_error.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${logging.path}/web-error-%d{yyyy-MM-dd}.%i.log
100MB
15
ERROR
ACCEPT
DENY
logback-test
debug
${CONSOLE_LOG_PATTERN}
UTF-8
${log.path}/debug.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/debug-%d{yyyy-MM-dd}.%i.log
100MB
15
10GB
debug
ACCEPT
DENY
${log.path}/info.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/info-%d{yyyy-MM-dd}.%i.log
100MB
15
info
ACCEPT
DENY
${log.path}/warn.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/warn-%d{yyyy-MM-dd}.%i.log
100MB
15
warn
ACCEPT
DENY
${log.path}/error.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/error-%d{yyyy-MM-dd}.%i.log
100MB
15
ERROR
ACCEPT
DENY
${log.path}/all.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/all-%d{yyyy-MM-dd}.%i.log
100MB
15
DEBUG
DENY
ACCEPT
%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n
UTF-8
logs/project_info.log
true
ERROR
DENY
ACCEPT
logs/project_info.%d.%i.log
30
20GB
10MB
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n
UTF-8
logs/project_error.log
true
ERROR
logs/project_error.%d.%i.log
30
20GB
10MB
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n
UTF-8
logback
debug
${CONSOLE_LOG_PATTERN}
UTF-8
${log.path}/log_debug.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log
100MB
30
20GB
debug
ACCEPT
DENY
${log.path}/log_info.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log
100MB
30
20GB
info
ACCEPT
DENY
${log.path}/log_warn.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log
100MB
30
20GB
warn
ACCEPT
DENY
${log.path}/log_error.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log
100MB
30
20GB
ERROR
ACCEPT
DENY