【Spring】SpringBoot日志
SpringBoot日志
日志概述
- 为什么要学习?志
?志对我们来说并不陌?, 从JavaSE部分, 我们就在使? System.out.print 来打印?志了. 通过打印?志来发现和定位问题, 或者根据?志来分析程序的运?过程.在Spring的学习中, 也经常根据控制台的?志来分析和定位问题.
随着项?的复杂度提升, 我们对?志的打印也有了更?的需求, ?不仅仅是定位排查问题.
?如需要记录?些??的操作记录(?些审计公司会要求), 也可能需要使??志来记录??的?些喜好,把?志持久化, 后续进?数据分析等. 但是 System.out.print 不能很好的满?我们的需求, 我们就需要使??些专??志框架(专业的事情交给专业的?去做)
日志使用
Spring Boot 项?在启动的时候默认就有?志输出,如下图所?:
我们可以看到SpringBoot答应出来的日志却少了很多信息
SpringBoot打印出来的日志有 日志时间 日志级别 线程 打印日志的位置 日志信息等
springboot内置了日志框架slf4j,我们可以直接在程序中调用slf4j来输出日志
打印日志
打印日志的步骤:
- 在程序中得到日志对象
- 使用日志对象输出要打印的内容
获取日志对象
在程序中获取?志对象需要使??志?? LoggerFactory,如下代码所?:
public class LogController {
private static Logger logger = LoggerFactory.getLogger(LogController.class);
}
LoggerFactory.getLogger需要传递一个参数,标识这个日志的名称,这样可以更清晰的直到是哪个类输出的日志,当有问题时,可以更方便直观的定位到问题类
使用日志对象打印日志
日志对象的打印方法有很多种,我们可以先使用info()方法来输出日志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogController {
private static Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/log")
public String logger(){
logger.info("这是一段日志");
return "打印日志";
}
}
日志框架介绍
SLF4J不同于其他日志框架,他不是一个真正的日志实现,而是一个抽象层,对日志框架指定的一种规范,标准,接口,所有SLF4J并不能独立使用,需要和具体的日志框架配合使用
门面模式
SLF4J是门面模式的典型应用
门面模式(Facade Pattern)是一种软件设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。这个模式通过创建一个高层接口,简化了客户端与子系统之间的交互,从而降低了系统之间的耦合度。
通常情况下,一个系统由多个子系统组成,每个子系统都有自己的接口和功能。而客户端需要与这些子系统进行交互,这样可能会导致客户端代码变得复杂,并且对系统的变化比较敏感。门面模式的出现正是为了解决这个问题。
通过门面模式,客户端只需要和门面对象交互,而门面对象负责将请求委派给相应的子系统进行处理。这样一来,客户端就不需要了解子系统的具体实现细节,从而降低了客户端和子系统之间的耦合度,同时也方便了对子系统的修改和维护。
总的来说,门面模式可以帮助简化复杂系统的接口,提高系统的灵活性和可维护性,同时也能够隐藏系统的复杂性,使客户端更加容易使用。
门面模式主要包含两种角色
外观角色,也成为门面角色,系统对外的统一接口
子系统角色,可以同时有一个或多个SubSystem,每个SubSystem都不是一个单独的类,而是一个类的集合,SubSystem并不知道Facade的存在,
SLF4J框架介绍(simple logging facade for java)
SLF4J就是其他日志框架的门面,SLF4J可以理解为是提供日志服务的统一API接口,并不涉及到具体的日志逻辑实现
不引入日志门面
常见的日志框架有log4j ,logback等 如果一个项目已经使用log4j,而你依赖的另一个类库,假如依赖另一个日志框架logback,那么就需要吧logback也加进去
存在问题
- 不同的日志框架的API接口和配置文件不同,如果多个日志框架并存,那么不得不维护多套配置文件(这里的配置文件指的是用户自定义的配置文件)
- 如果要更换日志框架,应用程序将不得不修改代码,并且修改过程中可能会存在一些代码冲突
- 如果引入的第三方框架,使用了多套,那就不得不维护多套配置
引入日志门面
引入日志门面框架后,应用程序和日志框架之间有了统一 的API接口,此时应用程序只需要维护一套日志文件配置,且当底层实现框架改变时,也不需要更改应用程序代码
日志格式说明
从上图可以看到,?志输出内容元素具体如下:
- 时间?期:精确到毫秒
- ?志级别:ERROR, WARN, INFO, DEBUG 或TRACE
- 进程ID
- 线程名
- Logger名(通常使?源代码的类名)
- ?志内容
日志级别
?志级别代表着?志信息对应问题的严重性, 为了更快的筛选符合?标的?志信息
日志级别的分类
在Spring框架中,日志级别通常遵循通用的日志级别标准,比如 SLF4J 或 Logback 中定义的日志级别。Spring框架本身并没有定义自己的日志级别,而是使用这些通用的标准。以下是常见的日志级别:
TRACE:提供非常详细的日志信息,通常用于调试,跟踪程序执行过程中的细节。
DEBUG:用于输出调试信息,用于辅助定位问题和调试程序。
INFO:提供一般性的运行时信息,表明应用程序正在运行。
WARN:表示潜在的问题,不会导致应用程序停止运行,但可能需要引起注意。
ERROR:用于指出虽然发生了错误,但仍然允许程序继续运行。
FATAL:指出严重的错误,可能导致应用程序退出。
在配置Spring应用程序的日志级别时,可以通过配置文件(比如logback.xml或log4j2.xml)或者通过代码来设置。一般来说,通过配置文件进行设置更为灵活,可以根据不同的包或类设置不同的日志级别。在Spring中,也可以通过Spring Boot的application.properties或application.yml文件来配置日志级别。
总的来说,通过合理设置日志级别,可以帮助开发人员了解应用程序的运行情况,快速定位问题,提高系统的可维护性和稳定性。
日志级别的使用
?志级别是开发?员??设置的. 开发?员根据??的理解来判断该信息的重要程度
针对这些级别, Logger 对象分别提供了对应的?法, 来输出?志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogController {
private static Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/log")
public String logger(){
logger.trace("这是一段trace日志");
logger.debug("这是一段debug日志");
logger.info("这是一段info日志");
logger.warn("这是一段warn日志");
logger.error("这是一段error日志");
return "打印日志";
}
}
SpringBoot 默认的?志框架是Logback, Logback没有 FATAL 级别, 它被映射到 ERROR .
出现fatal?志,表?服务已经出现了某种程度的不可?, 需要需要系统管理员紧急介?处理. 通常情况下, ?个进程?命周期中应该最多只有?次FATAL记录.
结果发现只打印了info,warn和error级别的日志
这与日志级别的配置有关,日志的输出默认级别时info级别 ,所以只会打印大于等于此级别的日志,也就是info,warn和error
日志配置
上述是?志的使?, ?志框架?持我们更灵活的输出?志, 包括内容, 格式等
配置日志级别
我们可以在配置文件application.yml中配置logging.level配置项即可
我们可以发现此时就可以打印出Debug级别的日志了
日志持久化
以上的?志都是输出在控制台上的, 然?在线上环境中, 我们需要把?志保存下来, 以便出现问题之后追溯问题. 把?志保存下来就叫持久化.
日志持久化的两种方式
- 配置日志文件名
- 配置日志的存储目录
配置日志文件的路径和文件名
yml配置文件配置
设置文件的文件名
配置日志文件的保存路径
这种方式只能设置日志的路径,文件名为固定的spring.log
注意:
logging.file.name 和 logging.file.path 两个都配置的情况下, 只?效其?, 以logging.file.name 为准
配置日志文件分割
如果我们的?志都放在?个?件中, 随着项?的运?, ?志?件会越来越?, 需要对?志?件进?分割
当然, ?志框架也帮我们考虑到了这?点, 所以如果不进?配置, 就??动配置
默认?志?件超过10M就进?分割
配置项 | 说明 | 默认值 |
---|---|---|
logging.logback.rollingpolicy.file-name-pattern | ?志分割后的?件名格式 | ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz |
logging.logback.rollingpolicy.max-file-size | ?志?件超过这个??就?动分割 | 10MB |
配置文件分割
yml配置
logging:
logback:
rollingpolicy:
max-file-size: 1KB
file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
- ?志?件超过1KB就分割(设置1KB是为了更好展?. 企业开发通常设置为200M, 500M等, 此处没
有明确标准)- 分割后的?志?件名为: ?志名.?期.索引
更简单的日志输出
每次都使? LoggerFactory.getLogger(xxx.class) 很繁琐, 且每个类都添加?遍, lombok给我们提供了?种更简单的?式.
- 添加 lombok 框架?持
- 使? @slf4j 注解输出?志。
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class LogController {
// private static Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/log")
public String logger(){
//此时对象名称为固定的log
log.trace("这是一段trace日志");
log.debug("这是一段debug日志");
log.info("这是一段info日志");
log.warn("这是一段warn日志");
log.error("这是一段error日志");
return "打印日志";
}
}
我们可以发现 这个注解的生命周期只存在于源代码阶段
**代码在经过编译之后 自动为我们生成了Logger对象 **
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!