前面介绍了Spring Boot 异常处理,不清楚的朋友可以看看之前的文章。
今天主要讲解Spring Boot中的日志收集,日志是追踪错误定位问题的关键,特别在生产环境中,我们需要通过日志快速定位解决问题。
Springboot的日志的框架比较丰富,而且Springboot本身就内置了日志功能,不过实际项目中会出现:只记录想要的日志,日志输出到磁盘,按天归档,日志信息同步到其他系统等功能。这些是Springboot本身就内置了日志功能不具备的。所以我推荐使用logback。下面我们就以logback讲讲Spring Boot中的日志收集。
为什么要统一日志
前面我们说了Springboot 本身就可以日志功能,为什么还需要统一规范日志?
1、日志统一,方便查阅管理。
2、日志分割归档功能。
3、日志持久化功能。
4、方便日志系统(ELK)收集。
配置
在resource下创建logback-spring.xml文件,以下直接贴出配置信息,介绍信息可以直接参考备注
<code><
configuration
scan
="true"
scanPeriod
="10 seconds"
><
contextName
>logbackcontextName
><
property
name
="log.path"
value
="D:/nmyslog/nmys"
/><
conversionRule
conversionWord
="clr"
converterClass
="org.springframework.boot.logging.logback.ColorConverter"
/><
conversionRule
conversionWord
="wex"
converterClass
="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"
/><
conversionRule
conversionWord
="wEx"
converterClass
="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"
/><
property
name
="CONSOLE_LOG_PATTERN"
value
="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"
/><
appender
name
="CONSOLE"
class
="ch.qos.logback.core.ConsoleAppender"
><
filter
class
="ch.qos.logback.classic.filter.ThresholdFilter"
><
level
>infolevel
>filter
><
encoder
><
Pattern
>${CONSOLE_LOG_PATTERN}Pattern
><
charset
>UTF-8charset
>encoder
>appender
><
appender
name
="DEBUG_FILE"
class
="ch.qos.logback.core.rolling.RollingFileAppender"
><
file
>${log.path}/log_debug.logfile
><
encoder
><
pattern
>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern
><
charset
>UTF-8charset
>encoder
><
rollingPolicy
class
="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
><
fileNamePattern
>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.logfileNamePattern
><
timeBasedFileNamingAndTriggeringPolicy
class
="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
><
maxFileSize
>100MBmaxFileSize
>timeBasedFileNamingAndTriggeringPolicy
><
maxHistory
>15maxHistory
>rollingPolicy
><
filter
class
="ch.qos.logback.classic.filter.LevelFilter"
><
level
>debuglevel
><
onMatch
>ACCEPTonMatch
><
onMismatch
>DENYonMismatch
>filter
>appender
><
appender
name
="INFO_FILE"
class
="ch.qos.logback.core.rolling.RollingFileAppender"
><
file
>${log.path}/log_info.logfile
><
encoder
><
pattern
>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern
><
charset
>UTF-8charset
>encoder
><
rollingPolicy
class
="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
><
fileNamePattern
>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.logfileNamePattern
><
timeBasedFileNamingAndTriggeringPolicy
class
="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
><
maxFileSize
>100MBmaxFileSize
>timeBasedFileNamingAndTriggeringPolicy
><
maxHistory
>15maxHistory
>rollingPolicy
><
filter
class
="ch.qos.logback.classic.filter.LevelFilter"
><
level
>infolevel
><
onMatch
>ACCEPTonMatch
><
onMismatch
>DENYonMismatch
>filter
>appender
><
appender
name
="WARN_FILE"
class
="ch.qos.logback.core.rolling.RollingFileAppender"
><
file
>${log.path}/log_warn.logfile
><
encoder
><
pattern
>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern
><
charset
>UTF-8charset
>encoder
><
rollingPolicy
class
="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
><
fileNamePattern
>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.logfileNamePattern
><
timeBasedFileNamingAndTriggeringPolicy
class
="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
><
maxFileSize
>100MBmaxFileSize
>timeBasedFileNamingAndTriggeringPolicy
><
maxHistory
>15maxHistory
>rollingPolicy
><
filter
class
="ch.qos.logback.classic.filter.LevelFilter"
><
level
>warnlevel
><
onMatch
>ACCEPTonMatch
><
onMismatch
>DENYonMismatch
>filter
>appender
><
appender
name
="ERROR_FILE"
class
="ch.qos.logback.core.rolling.RollingFileAppender"
><
file
>${log.path}/log_error.logfile
><
encoder
><
pattern
>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern
><
charset
>UTF-8charset
>encoder
><
rollingPolicy
class
="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
><
fileNamePattern
>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.logfileNamePattern
><
timeBasedFileNamingAndTriggeringPolicy
class
="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
><
maxFileSize
>100MBmaxFileSize
>timeBasedFileNamingAndTriggeringPolicy
><
maxHistory
>15maxHistory
>rollingPolicy
><
filter
class
="ch.qos.logback.classic.filter.LevelFilter"
><
level
>ERRORlevel
><
onMatch
>ACCEPTonMatch
><
onMismatch
>DENYonMismatch
>filter
>appender
><
springProfile
name
="dev"
><
logger
name
="com.nmys.view"
level
="debug"
/>springProfile
><
root
level
="info"
><
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
>configuration
>/<code>
注意
- 日志的环境即spring.profiles.acticve,跟随项目启动。
- 启动后,即可到自定目录查找到生成的日志文件。
- 官方推荐使用的xml名字的格式为:logback-spring.xml而不是logback.xml。
配置application.properties
在application.properties配置logback
<code> logging.config=classpath:logback-spring.xml /<code>
收集异常日志
上一篇文章已经讲过统一异常处理,请看这篇文章《SpringBoot入门系列(十一)统一异常处理的实现》。
修改统一异常处理器GlobalExceptionHandler类,将异常方法中的直接打印改为日志输入并打印:
<code>public
Object errorHandler(HttpServletRequest reqest, HttpServletResponse response, Exception e) throws Exception { logger.error(ExceptionUtils.getMessage(e));if
(isAjax(reqest)) {return
JSONResult.errorException(e.getMessage()); }else
{ ModelAndView mav = new ModelAndView(); mav.addObject("exception"
, e); mav.addObject("url"
, reqest.getRequestURL()); mav.setViewName(ERROR_VIEW);return
mav; } }/<code>
程序中记录日志
在com.weiz.controller 中创建LoggingController 控制器
<code>package
com.weiz.controller;import
com.weiz.utils.JSONResult;import
org.slf4j.Logger;import
org.slf4j.LoggerFactory;import
org.springframework.web.bind.annotation
.RequestMapping;import
org.springframework.web.bind.annotation
.RestController;public
class
LoggingController
{ Logger logger = LoggerFactory.getLogger(getClass());public
JSONResult writeLog(){ /<code>
测试
启动项目,在浏览器输入:http://localhost:8080/log/write ,去相关目录下查看日志文件
异常日志:
最后
以上,就把Spring Boot集成logback进行统一日志收集介绍完了。还是比较简单的,还有其他实际应用场景中的相关需求如:日志压缩,同步kafka等,大家自己去研究吧。
这个系列课程的完整源码,也会提供给大家。大家关注我的微信公众号(架构师精进),回复:springboot源码。获取这个系列课程的完整源码。