目录

一、日志概述
⽇志主要是为了发现问题, 分析问题, 定位问题的, 但除此之外, ⽇志还有很多⽤途,像监控程序,当程序出现什么问题时,在日志中反应为相对应的日志,然后可以提醒程序猿。日志还可以记录数据,用于分析等等。
二、使用日志
我们先简单看一下一个Spring的日志包含的内容:
2.1 打印日志
我们在程序中打印SpringBoot的日志,我们先要拿到日志对象,在import org.slf4j
包下的Logger对象。在从这个包下的静态类日志工厂 LoggerFactor拿到实例 。
private Logger logger = LoggerFactory.getLogger(LogController.class);
在通过Logger类中的info方法打印日志。
package com.example.captcha.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/log")
@RestController
public class LogController {
private final static Logger LOGGER = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/print")
public String print() {
LOGGER.info("日志");
return "日志";
}
}
得到的日志:
2.2 日志框架
在我们使用Logger类的时候,会有很多包。
这几个包的关系如下:
以电视机和遥控器来举例子,日志实现就相当于不同品牌的电视,而日志门面就相当于一个 通用的遥控器。
2.2.1 门面 / 外观 模式
门面模式:
⻔⾯模式(Facade Pattern)⼜称为外观模式, 提供了⼀个统⼀的接⼝, ⽤来访问⼦系统中的⼀群接口. 其主要特征是定义了⼀个⾼层接⼝, 让⼦系统更容易使⽤.
⻔⾯模式主要包含2种⻆⾊:
外观⻆⾊(Facade): 也称⻔⾯⻆⾊,系统对外的统⼀接⼝.⼦系统⻆⾊(SubSystem): 可以同时有⼀个或多个 SubSystem. 每个 SubSytem都不是⼀个单独的类, ⽽是⼀个类的集合. SubSystem 并不知道 Facade的存在, 对于 SubSystem ⽽⾔, Facade 只是另⼀个客⼾端⽽已(即 Facade 对 SubSystem 透明)
2.3 日志级别
2.3.1 六大分类
⽇志的级别从⾼到低依次为: FATAL、ERROR、WARN、INFO、DEBUG、TRACE
- FATAL: 致命信息,表⽰需要⽴即被处理的系统级错误.
- ERROR: 错误信息, 级别较⾼的错误⽇志信息, 但仍然不影响系统的继续运⾏.
- WARN: 警告信息, 不影响使⽤, 但需要注意的问题
- INFO: 普通信息, ⽤于记录应⽤程序正常运⾏时的⼀些信息,例如系统启动完成、请求处理完成等.
- DEBUG: 调试信息, 需要调试时候的关键信息打印.
- TRACE: 追踪信息, ⽐DEBUG更细粒度的信息事件(除⾮有特殊⽤意,否则请使⽤DEBUG级别替代)
2.3.2 使用
对于不同级别的日志,SpringBoot的Logger类下面有对应名字的方法(FATAl)除外。
SpringBoot 默认的⽇志框架是Logback, Logback没有 FATAL 级别, 它被映射到 ERROR .出现fatal⽇志,表⽰服务已经出现了某种程度的不可⽤, 需要需要系统管理员紧急介⼊处理. 通常情况下, ⼀个进程⽣命周期中应该最多只有⼀次FATAL记录.
package com.example.captcha.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/log")
@RestController
public class LogController {
private final static Logger LOGGER = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/print")
public String print() {
//LOGGER.info("日志");
LOGGER.trace("trace级别日志");
LOGGER.debug("debug级别日志");
LOGGER.info("info级别日志");
LOGGER.warn("ware级别日志");
LOGGER.error("error级别日志");
return "日志";
}
}
上诉代码的结果如下:
只会显示info级别及其以上级别的日志,这是因为Spring在默认的配置下是显示info级以上级别日志。
2.4 日志级别配置
我们只需要在配置文件加上:logging.level.目录
就可以配置相对应目录下的日志显示级别。
如果我们在配置文件中加上这样的配置信息
logging:
level:
com:
example:
captcha:
Controller: trace
那么我们打印的日志就会变成下面的这样:
2.5 日志的持久化
日志如果不进行配置,默认⽇志都是输出在控制台上的, 然⽽在线上环境中, 我们需要把⽇志保存下来, 以便出现问题之后追溯问题.把⽇志保存下来就叫持久化。
我们就可以将日志写入文件。
Spring中有以下两个配置项,来配置日志写入的文件。
- logging.file.name配置项,可以包含文件的路径和文件名。
- logging.file.path配置项,只能包含文件路径。
- 当两个配置项同时存在的时候,只有logging.file.name会有作用。
我们进行如下配置:
logging:
file:
name: logger/log.log
path: all
得到如下结果:
2.6 日志文件分割
日志文件分割有以下两个相关的配置项:
- logging.logback. rolling policy.max-file-size配置项,用于配置每个文件的大小。
- logging.logback. rolling policy.file-name-pattern配置项,用于配置每个文件的名字及其格式。
我们写下如下配置:
logging:
logback:
rolling policy:
max-file-size: 1KB
file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
结果就如下:
注意事项:
- logging.logback. rolling policy.max-file-size配置项,并不是严格的每个文件都不会超过配置的大小,而是按照必须将当前的日志行写完才分割。
- logging.logback. rolling policy.file-name-pattern配置项,默认格式
${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
2.7 日志文件格式
日志文件格式分割有以下两个相关的配置项:
配置项 | 说明 |
---|---|
logging.pattern.console | 控制台⽇志格式 |
logging.pattern.file | ⽇志⽂件的⽇志格式 |
配置项说明:
- %clr(表达式){颜⾊}设置输⼊⽇志的颜⾊。支持blue cyan faint green magenta red yellow
- %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd’T’HH:mm:ss.SSSXXX}} ⽇期和时间–精确到毫秒
- %5p 显⽰⽇志级别ERROR,MARN,INFO,DEBUG,TRACE.
- %t 线程名.
- %c 类的全限定名.
- %M method.
- %L 为⾏号.
- %thread 线程名称.
- %m 或者%msg 显⽰输出消息.
- %n 换⾏符
- %5 若字符⻓度⼩于5,则右边⽤空格填充.
- %-5 若字符⻓度⼩于5,则左边⽤空格填充.
- %.15 若字符⻓度超过15,截去多余字符.
- %15.15 若字符⻓度⼩于15,则右边⽤空格填充.若字符⻓度超过15,截去多余字符
2.8 @Slf4j 简单打印日志
我们可以使用lombok提供的@Slf4j注解来打印日志,这个注解的作用相当于就是sping帮我们创建Logger对象,对象名为log。
例如下面代码:
package com.example.captcha.Controller;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/log")
@RestController
@Slf4j
public class LogController {
@RequestMapping("/print")
public String print() {
//LOGGER.info("日志");
log.trace("trace级别日志");
log.debug("debug级别日志");
log.info("info级别日志");
log.warn("ware级别日志");
log.error("error级别日志");
return "日志";
}
}
结果如下: