赞
踩
目录
从JavaSE部分到现在少不了日志,最初使用System.out.print来打印日志,通过打印日志来发现和定位问题,或者根据日志来分析程序的运行过程,在Spring的学习中,也经常根据控制台的日志来分析和定位问题,除此之外,日志还有更多的用途,比如系统监控和数据采集
在SpringBoot项目启动的时候默认就有日志输出
我们通过System.out.print来打印日志
- @RestController
- public class LoggerController {
- @PostConstruct
- public void logger() {
- System.out.println("打印日志");
- }
- }
可以看到,通过System.out.print打印的日志,比SpringBoot打印的日志缺少很多信息
在SpringBoot中内置了日志框架Slf4j,可以直接在程序中调用Slf4j来输出日志
打印日志的步骤:
1)在程序中得到日志对象
2)使用日志对象输出要打印的内容
在程序中获取日志对象需要使用日志工厂LoggerFactory,这里需要选择slf4j这个接口
- @RestController
- public class LoggerController {
- private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
- @PostConstruct
- public void logger() {
- logger.info("需要打印的日志");
- }
- }
SLF4J不同其他日志框架,它不是一个真正的日志框架实现,而是一个抽象层,对日志框架制定的一种规范,标准,接口,因此所有的SLF4J不能独立使用,需要和具体的日志框架配合使用
SLF4J是门面模式的典型应用,但不仅仅使用了门面模式
门面模式(Facade Pattern)又称为外观模式,提供了一个统一的接口,用来访问子系统中的一群接口,其主要特征是定义了一个高层接口,让子系统更容易使用
门面模式主要包含2中角色:
1)外观角色(Facade):也称门面角色,系统对外的统一接口
2)子系统角色(SubSystem):可以同时有一个或者多个 SubSystem,每个SubSystem都不是一个单独的类,而是一个类的集合,SubSystem并不知道Facade的存在,对于SubSystem来说,Facade只是另一个客户端
例如:去医院看病,需要挂号、门诊、化验、取药,如果病人自己去办会很麻烦,但是如果由接待人员,让接待人员来处理,就会很方便
场景:回到家我们会开每个房间的灯,离开家,会关闭房间的灯,如果在家里设置一个总开关,来控制整个家的灯会很方便,此时可以直接使用门面模式来实现
普通模式:
- public class Main {
- public static void main(String[] args) {
- LivingRoomLight livingRoomLight = new LivingRoomLight();
- livingRoomLight.on();
- HallLight hallLight = new HallLight();
- hallLight.on();
- DiningLight diningLight = new DiningLight();
- diningLight.on();
- }
- }
- interface Light {
- void on();
- void off();
- }
- /**
- * 客厅灯
- */
- class LivingRoomLight implements Light{
- @Override
- public void on() {
- System.out.println("打开客厅灯");
- }
-
- @Override
- public void off() {
- System.out.println("关闭客厅灯");
- }
- }
- /**
- * 走廊灯
- */
- class HallLight implements Light{
- @Override
- public void on() {
- System.out.println("打开走廊灯");
- }
-
- @Override
- public void off() {
- System.out.println("关闭走廊灯");
- }
- }
- /**
- * 餐厅灯
- */
- class DiningLight implements Light{
- @Override
- public void on() {
- System.out.println("打开餐厅灯");
- }
-
- @Override
- public void off() {
- System.out.println("关闭餐厅灯");
- }
- }
可以看出在普通模式中,我们需要一步一步的打开灯,这样就会有点麻烦,门面模式就可以帮我们解决这个问题
门面模式(外观模式)
- public class Main {
- public static void main(String[] args) {
- LightFacade lightFacade = new LightFacade();
- lightFacade.lightOn();
- }
- }
-
- /**
- * 灯的门面
- */
- class LightFacade {
- LivingRoomLight livingRoomLight = new LivingRoomLight();
- HallLight hallLight = new HallLight();
- DiningLight diningLight = new DiningLight();
-
- public void lightOn() {
- livingRoomLight.on();
- hallLight.on();
- diningLight.on();
- }
-
- public void lightOff() {
- livingRoomLight.off();
- hallLight.off();
- diningLight.off();
- }
- }
-
- interface Light {
- void on();
-
- void off();
- }
-
- /**
- * 客厅灯
- */
- class LivingRoomLight implements Light {
- @Override
- public void on() {
- System.out.println("打开客厅灯");
- }
-
- @Override
- public void off() {
- System.out.println("关闭客厅灯");
- }
- }
-
- /**
- * 走廊灯
- */
- class HallLight implements Light {
- @Override
- public void on() {
- System.out.println("打开走廊灯");
- }
-
- @Override
- public void off() {
- System.out.println("关闭走廊灯");
- }
- }
-
- /**
- * 餐厅灯
- */
- class DiningLight implements Light {
- @Override
- public void on() {
- System.out.println("打开餐厅灯");
- }
-
- @Override
- public void off() {
- System.out.println("关闭餐厅灯");
- }
- }
可以看出使用门面模式可以减少系统之间的相互依赖,使子系统的变化不会影响到调用它的客户端,从而降低了它们之间的耦合
门面模式的优点:
1)减少系统的相互依赖,降低客户端和子系统之间的耦合,使子系统的变化不会影响到调用它的客户端
2)提高灵活性,简化了客户端对子系统的使用难度,客户端无需关心子系统的具体实现,而只需要和门面对象交互即可
3)提高安全性,可以灵活设置访问权限,不在门面对象中开通方法,就无法访问
SLF4J就是其他日志框架的门面,SLF4J可以理解为是提供日志服务的统一API接口,并不涉及到具体的日志逻辑实现
常见的日志框架由log4j,logback等,如果一个项目已经使用了log4j,而依赖的另一个库假如是Apache Active MQ,它依赖另一个日志框架logback,此时就需要把logback也加载进去
存在问题:
1)不同日志框架的API接口和配置文件不同,如果多个日志框架共存,就必须维护多套配置文件
2)如果要更换日志框架,应用程序将必须修改代码,并且修改过程中可能会存在一些冲突
3)如果引入第三方框架,使用了多套,就需要维护多套配置
引入门面日志框架之后,应用程序和日志框架之间就有了统一的API接口,此时应用程序只需要维护一套日志文件配置,当底层实现框架改变时,不需要更改应用程序代码
SLF4J就是这个日志门面,SLF4J可以使代码独立于任意一个特定的日志API
日志级别代表日志信息对应问题的严重性,为了更快的筛选符合目标的日志信息
之日级别从高到低依次为:FATAL、ERROR、WARN、INFO、DEBUG、TRACE
FATAL:致命信息,表示需要立即被处理的系统级错误
ERROR:错误信息,级别较高的错误日志信息,但不影响系统的继续运行
WARN:警告信息,不影响使用,但需要注意的问题
INFO:普通信息,用于记录应用程序正常运行时的一些信息
DEBUG:调试信息
TRACE:追踪信息
级别越高,收到的信息越少
日志级别是开发人员自己设置的,开发人员根据自己的理解来判断该信息的重要程度,针对这些级别,Logger对象分别提供了对应的方法,来输出日志
- @RestController
- public class LoggerController {
- private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
- @PostConstruct
- public void logger() {
- logger.error("error日志");
- logger.warn("warn日志");
- logger.info("info日志");
- logger.debug("debug日志");
- logger.trace("trace日志");
- }
- }
可以看出只打印了erroe、warn、info级别的日志,这是因为日志的默认级别是info,所以只会打印大于等于此级别的日志
上述日志的使用,日志框架支持我们更灵活的输出日志,包括内容,格式等
- logging:
- level:
- root: debug
以上的日志都是输出在控制台上的,在线上环境中,需要把日志保存下来,一遍出现问题之后追溯问题,把日志保存下来就叫持久化
日志持久化有两中方式
1)配置日志文件名
logging.file.name
2)配置日志的存储目录
logging.file.path
配置日志文件的路径和文件名
- logging:
- file:
- name: logger/springboot.log
后面可以跟绝对路径或者相对路径
此时日志内容就保存在对应的目录下
配置日志文件的保存路径
- logging:
- file:
- path: E:/logger
这种方式只能设置日志的路径,文件名为固定的spring.log
注意:
logging.file.name和logging.file.path两个都配置的情况下只能生效一个,以logging.file.name为准
如果日志都放在一个文件中,随着项目的运行,日志文件会越来越大,因此需要对日志文件进行分割,如果不进行配置的话,就会自动配置,默认日志文件超过10MB就进行分割
配置项 | 说明 | 默认值 |
logging.logback.rollingpolicy.fil e-name-pattern | ⽇志分割后的⽂件名 格式 | ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz |
logging.logback.rollingpolicy.m ax-file-size | ⽇志⽂件超过这个⼤ ⼩就⾃动分割 | 10MB |
配置文件分割:
- logging:
- file:
- path: E:/logger
- logback:
- rollingpolicy:
- max-file-size: 2KB
- file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
启动控制台,观察颜色
每次使用LoggerFactory.getLogger(xxx.class)输出日志非常繁琐,并且每个类都要添加一遍,lombok给我们提供了一种更简单的方式
1)添加lombok框架支持
2)使用@slf4j注解输出日志
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
- @Slf4j
- @RestController
- public class LoggerController {
- @PostConstruct
- public void logger() {
- log.error("error日志");
- log.warn("warn日志");
- log.info("info日志");
- log.debug("debug日志");
- log.trace("trace日志");
- }
- }
lombok提供的@Slf4j会帮我们提供一个日志对象log,直接使用即可
1)日志是程序中的重要组成部分,使⽤日志可以快速的发现和定位问题,Spring Boot 提供了日志框架,默认情况下使用的是 info 日志级别将日志输出到控制台的,我们可以通过 lombok 提供的 @Slf4j 注解和 log 对象快速的打印自定义日志
2)日志包含6个级别,日志级别越高,收到的信息越少,可以通过配置日志的保存名称或者日志目录来将日志持久化
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。