日志类型
日志类型有很多,比如 JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j…,主要分为抽象层和实现层:
抽象层:
JCL:不使用,从 2014 年开始就没更新过了。
jboss-logging:不使用,使用场景有限。
SLF4j:Springboot 中使用的日志抽象层。
实现层:
Log4j
Log4j2:apache 借 Log4j 之名写的一个日志框架,并不是 Log4j 的升级版,太高端了,很多框架适配不了。
Logback:Log4j 的升级版本,和 SLF4j 出自同一个人之手(Spring Boot 约定的默认配置)。
SpringBoot 选用 SLF4j 和 Logback,大部分场景推荐 Spring Boot 自带的日志 logback,在 Spring Boot 中,logback 是基于 slf4j 实现的。
日志级别
日志级别从低到高分为:TRACE < DEBUG < INFO < WARN < ERROR < FATAL
如果设置为 WARN ,则低于 WARN 的信息都不会输出。同理,当我们指定日志级别为 INFO 级别,那么 TRACE、DEBUG 级别的日志就不会被输出打印。
Spring Boot 中默认配置 ERROR、WARN 和 INFO 级别的日志输出到控制台。
SpringBoot 整合 logback 日志
基本使用
使用方法 1
1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-logging</artifactId > </dependency >
但是实际开发中不需要直接添加该依赖,spring-boot-starter 包含了 spring-boot-starter-logging,该依赖内容就是 Spring Boot 默认的日志框架 logback。
1 2 3 4 5 6 7 8 9 10 11 12 13 @SpringBootApplication public class LogApplication { public static void main (String[] args) { Logger logger = LoggerFactory.getLogger(LogApplication.class); SpringApplication.run(LogApplication.class, args); logger.debug("This is a debug message" ); logger.info("This is an info message" ); logger.warn("This is a warn message" ); logger.error("This is an error message" ); } }
使用方法 2
1 2 3 4 <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > </dependency >
1 2 3 4 5 6 7 @Slf4j public class LogApplication { public static void main (String[] args) { log.info("====" ); } }
文件配置
日志级别设置
1 2 3 4 5 6 7 8 logging.level.com.dudu = DEBUG logging.level.root = WARN
日志输出格式设置
1 2 3 4 5 6 7 8 9 10 11 12 13 logging.pattern.console = %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n logging.pattern.file = %d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
指定日志配置文件
1 logging.config = classpath:logging-config.xml
根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:
Logback:logback-spring.xml、logback-spring.groovy、logback.xml、logback.groovy
Log4j:log4j-spring.properties、log4j-spring.xml、log4j.properties、log4j.xml
Log4j2:log4j2-spring.xml、log4j2.xml
JDK (Java Util Logging):logging.properties
Spring Boot 官方推荐优先使用带有-spring 的文件名作为日志配置(如使用 logback-spring.xml,而不是 logback.xml)。
因为命名为 logback-spring.xml 的日志配置文件,spring boot 可以为它添加一些 spring boot 特有的配置项。
logback.xml 直接就被日志框架识别了。如果使用 logback-spring.xml,日志框架就不直接加载日志的配置项,需要加上 springProfile 标签由 SpringBoot 解析日志配置,即可以使用 SpringBoot 的高级 Profile 功能
配置文件加载顺序
logback.xml-> application.properties-> logback-spring.xml
logback-spring.xml
完整文件样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 <?xml version="1.0" encoding="UTF-8" ?> <configuration scan ="true" scanPeriod ="10 seconds" > <contextName > logback</contextName > <property name ="log.path" value ="F:/java基础学习/复习testcode/logs" /> <property name ="CONSOLE_LOG_PATTERN" value ="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n" /> <appender name ="STDOUT" class ="ch.qos.logback.core.ConsoleAppender" > <filter class ="ch.qos.logback.classic.filter.ThresholdFilter" > <level > debug</level > </filter > <encoder > <Pattern > ${CONSOLE_LOG_PATTERN}</Pattern > <charset > UTF-8</charset > </encoder > </appender > <appender name ="DEBUG_FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${log.path}/log_debug.log</file > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern > <charset > UTF-8</charset > </encoder > <rollingPolicy class ="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" > <fileNamePattern > ${log.path}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log</fileNamePattern > <maxFileSize > 100MB</maxFileSize > <maxHistory > 30</maxHistory > <totalSizeCap > 20GB</totalSizeCap > </rollingPolicy > <filter class ="ch.qos.logback.classic.filter.LevelFilter" > <level > debug</level > <onMatch > ACCEPT</onMatch > <onMismatch > DENY</onMismatch > </filter > </appender > <appender name ="INFO_FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${log.path}/log_info.log</file > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern > <charset > UTF-8</charset > </encoder > <rollingPolicy class ="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" > <fileNamePattern > ${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern > <maxFileSize > 100MB</maxFileSize > <maxHistory > 30</maxHistory > <totalSizeCap > 20GB</totalSizeCap > </rollingPolicy > <filter class ="ch.qos.logback.classic.filter.LevelFilter" > <level > info</level > <onMatch > ACCEPT</onMatch > <onMismatch > DENY</onMismatch > </filter > </appender > <appender name ="WARN_FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${log.path}/log_warn.log</file > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern > <charset > UTF-8</charset > </encoder > <rollingPolicy class ="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" > <fileNamePattern > ${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern > <maxFileSize > 100MB</maxFileSize > <maxHistory > 30</maxHistory > <totalSizeCap > 20GB</totalSizeCap > </rollingPolicy > <filter class ="ch.qos.logback.classic.filter.LevelFilter" > <level > warn</level > <onMatch > ACCEPT</onMatch > <onMismatch > DENY</onMismatch > </filter > </appender > <appender name ="ERROR_FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${log.path}/log_error.log</file > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern > <charset > UTF-8</charset > </encoder > <rollingPolicy class ="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" > <fileNamePattern > ${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern > <maxFileSize > 100MB</maxFileSize > <maxHistory > 30</maxHistory > <totalSizeCap > 20GB</totalSizeCap > </rollingPolicy > <filter class ="ch.qos.logback.classic.filter.LevelFilter" > <level > ERROR</level > <onMatch > ACCEPT</onMatch > <onMismatch > DENY</onMismatch > </filter > </appender > <root level ="INFO" > <appender-ref ref ="STDOUT" /> <appender-ref ref ="DEBUG_FILE" /> <appender-ref ref ="INFO_FILE" /> <appender-ref ref ="WARN_FILE" /> <appender-ref ref ="ERROR_FILE" /> </root > <logger name ="com.pikaiqu.logbackdemo.LogbackdemoApplicationTests" level ="debug" additivity ="false" > <appender-ref ref ="STDOUT" /> <appender-ref ref ="INFO_FILE" /> </logger > </configuration >
文件配置项
一个父标签:configuration
两种属性:contextName 和 property
三个节点:appender、root、logger
父标签
Configuration:
scan:当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认为 true
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当 scan 为 true 时,此属性生效,默认的时间间隔为 1 分钟
debug:当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态,默认为 false
1 2 <configuration scan ="true" scanPeriod ="10 seconds" > </configuration >
属性
contextName
每个 logger 都关联到 logger 上下文,默认上下文名称为“default”,但可以设置成其他名字,用于区分不同应用程序的记录,可以通过%contextName 来打印日志上下文名称
如果同时存在 logback.xml 和 logback-spring.xml,或者同时存在 logback.xml 和自定义的配置文件,则先加载 logback.xml,再根据 application 配置加载指定配置文件,或加载 logback-spring.xml。
注意:如果这两个文件的 contextName 不同就会报错
使用案例
logback.xml
1 2 3 4 <?xml version="1.0" encoding="UTF-8" ?> <configuration scan ="true" scanPeriod ="60 seconds" debug ="false" > <contextName > logback</contextName > </configuration >
logback-spring.xml
1 2 3 4 <?xml version="1.0" encoding="UTF-8" ?> <configuration scan ="false" scanPeriod ="60 seconds" debug ="false" > <contextName > logback</contextName > </configuration >
application.properties
1 logging.config =classpath:logback-spring.xml
property
用来定义变量值的标签,name 是变量的名称,value 是变量定义的指。通过定义的值会被插入到 logger 上下文中,定义变量后,可以使用 “${}” 来使用变量
1 2 3 4 <configuration scan ="true" scanPeriod ="60 seconds" debug ="false" > <property name ="APP_Name" value ="myAppName" /> <contextName > ${APP_Name}</contextName > </configuration >
节点
appender
追加器,可以理解为一个日志的渲染器,有 name 和 class 两个属性,name 表示该渲染器的名字,class 表示使用的输出策略
encoder:输出格式
1 2 3 4 5 6 %d:时间 %thread:线程名 %-5level:日志级别,允许以五个字符长度输出 %logger{50}:具体的日志输出者,比如类名,括号内表示长度 %msg:具体的日志消息,就是logger.info("xxx")中的xxx %n:换行
filter:过滤
onMatch 和 onMismatch 都有三个属性值,分别为 Accept、DENY 和 NEUTRAL
1 2 3 4 5 6 onMatch="ACCEPT":表示匹配该级别及以上 onMatch="DENY":表示不匹配该级别及以上 onMatch="NEUTRAL":表示该级别及以上的,由下一个filter处理,如果当前是最后一个,则表示匹配该级别及以上 onMismatch="ACCEPT":表示匹配该级别以下 onMismatch="NEUTRAL":表示该级别及以下的,由下一个filter处理,如果当前是最后一个,则不匹配该级别以下的 onMismatch="DENY":表示不匹配该级别以下的
控制台输出 appender
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <property name ="CONSOLE_LOG_PATTERN" value ="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n" /> <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <filter class ="ch.qos.logback.classic.filter.ThresholdFilter" > <level > debug</level > </filter > <encoder > <Pattern > ${CONSOLE_LOG_PATTERN}</Pattern > <charset > UTF-8</charset > </encoder > </appender >
文件输出 appender
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <appender name ="DEBUG_FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${log.path}/log_debug.log</file > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern > <charset > UTF-8</charset > </encoder > <rollingPolicy class ="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" > <fileNamePattern > ${log.path}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log</fileNamePattern > <maxFileSize > 100MB</maxFileSize > <maxHistory > 30</maxHistory > <totalSizeCap > 20GB</totalSizeCap > </rollingPolicy > <filter class ="ch.qos.logback.classic.filter.LevelFilter" > <level > debug</level > <onMatch > ACCEPT</onMatch > <onMismatch > DENY</onMismatch > </filter > </appender >
root
root 配置必须在 appender 下边
root 节点是对所有 appender 的管理,添加哪个 appender 就会打印哪个 appender 的日志
root 节点的 level 是总的日志级别控制
如果 appender 的日志级别设定比 root 的高,会按照 appender 的日志级别打印日志
如果 appender 的日志级别比 root 的低, 会按照 root 设定的日志级别进行打印日志
总结:root 设定的日志级别是最低限制,如果 root 设定级别为最高 ERROR,那么所有 appender 只能打印最高级别的日志
1 2 3 4 5 6 7 <root level ="DEBUG" > <appender-ref ref ="CONSOLE" /> <appender-ref ref ="DEBUG_FILE" /> <appender-ref ref ="INFO_FILE" /> <appender-ref ref ="WARN_FILE" /> <appender-ref ref ="ERROR_FILE" /> </root >
logger
name:用来指定受此 loger 约束的某一个包或者具体的某一个类。
addtivity:是否向上级 loger 传递打印信息。默认是 true。
1 2 3 4 5 6 7 8 9 <logger name ="com.pikaqiu.logbackdemo" level ="debug" additivity ="false" > <appender-ref ref ="CONSOLE" /> </logger > <logger name ="com.pikaiqu.logbackdemo.LogbackdemoApplicationTests" level ="INFO" additivity ="true" > <appender-ref ref ="STDOUT" /> </logger >
root 和 logger 的关系
root 和 logger 是父子的关系
logger 的 appender 根据参数 additivity 决定是否要叠加 root 的 appender,logger 的级别是其自身定义的级别,和 root 的级别没关系
root 是全局配置,logger 对单个类或包配置,是局部配置
如果 logger 里面配置了 additivity = “false”,就会覆盖 root 的,只打印一遍;如果 additivity = “true”,就会向上层再次传递,不会覆盖,而是打印两遍
多环境配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?xml version="1.0" encoding="UTF-8" ?> <configuration scan ="true" scanPeriod ="10 seconds" > <springProfile name ="pro" > <root level ="info" > <appender-ref ref ="DEBUG_FILE" /> <appender-ref ref ="INFO_FILE" /> <appender-ref ref ="ERROR_FILE" /> <appender-ref ref ="WARN_FILE" /> </root > </springProfile > <springProfile name ="dev" > <root level ="debug" > <appender-ref ref ="CONSOLE" /> </root > </springProfile > <springProperty scope ="context" name ="logLevel" source ="log.level" defaultValue ="info" /> <springProperty scope ="context" name ="immediateFlush" source ="log.immediateFlush" defaultValue ="false" /> <springProperty scope ="context" name ="appName" source ="spring.application.name" defaultValue ="appName" /> <springProperty scope ="context" name ="APP_NAME" source ="spring.application.name" /> <springProperty scope ="context" name ="logPattern" source ="log.pattern" defaultValue ="%d{yyyy-MM-dd HH:mm:ss.SSS}| %tid | %-5level | ${appName} | %thread|%logger{20}:%line:%method{20} - %msg%n" /> </configuration >
name:自定义别名
source:对应 SpringBoot 配置文件中属性名
defaultValue:默认值