Spring Boot 日志~

一、日志概述

1. 为什么要学习日志

日志对我们来说并不陌生,通过打印日志来发现和定位问题,或者根据日志来分析程序的运行过程。在Spring的学习中, 也经常根据控制台的日志来分析和定位问题,随着项目的复杂度提升, 我们对日志的打印也有了更高的需求, 而不仅仅是定位排查问题

2. 日志的用途

  1. 系统监控
    监控现在几乎是一个成熟系统的标配,我们可以通过日志记录这个系统的运行状态,每一个方法的响应时间,响应状态等,对数据进行分析,设置不同的规则,超过阈值时进行报警。比如统计日志中关键字的数量,并在关键字数量达到一定条件时报警,这也是日志的常见需求之一
  2. 数据采集
    数据采集是一个比较大的范围,采集的数据可以作用在很多方面,比如数据统计,推荐排序等。
    数据统计: 统计页面的浏览量(PV),访客量(UV),点击量等,根据这些数据进行数据分析, 优化公司运营策略
    推荐排序: 目前推荐排序应用在各个领域,我们经常接触的各行各业很多也都涉及推荐排序,比如购物,广告,新闻等领域。数据采集是推荐排序工作中必须做的一环, 系统通过日志记录用户的浏览历史,停留时长等, 算法人员通过分析这些数据,训练模型,给用户做推荐
  3. 日志审计
    随着互联网的发展,众多企业的关键业务越来越多的运行于网络之上。网络安全越来越受到大家的关注,系统安全也成为了项目中的一个重要环节,安全审计也是系统中非常重要的部分。国家的政策法规、行业标准等都明确对日志审计提出了要求。通过系统日志分析,可以判断一些非法攻击, 非法调用,以及系统处理过程中的安全隐患

二、日志使用

1. 打印日志

打印日志的步骤:

在程序中得到日志对象

使用日志对象输出要打印的内容

1. 在程序中得到日志对象

在程序中获取日志对象需要使用日志工厂 LoggerFactory

java 复制代码
private static final Logger logger = LoggerFactory.getLogger(LoggerController.class);

LoggerFactory.getLogger 需要传递一个参数,标识这个日志的名称。这样可以更清晰的知道是哪个类输出的日志。当有问题时,可以更方便直观的定位到问题类

注意:Logger 对象是属于 org.slf4j 包下的, 不要导入错包

2. 使用日志对象打印日志

java 复制代码
@RestController
@RequestMapping("/logger")
public class LoggerController {
    private static final Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/print")
    public String print(){
        System.out.println("打印日志");
        logger.info("打印日志");
        return "日志打印成功";
    }
}


2. 日志框架

SLF4J不同于其他日志框架,它不是一个真正的日志实现,而是一个抽象层,对日志框架制定的一种规范,标准,接口。所有SLF4J并不能独立使用,需要和具体的日志框架配合使用

1. 门面模式

门面模式,也叫外观模式,是一种结构型设计模式

它的核心思想非常简单:通过为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用

简单来说,门面模式就像是为一个复杂的系统安装了一个总开关统一柜台

场景: 回家, 我们会开各个屋的灯。离开家时,会关闭各个屋的灯

如果家里设置一个总开关,来控制整个屋的灯就会很方便

我们使用门面模式的实现

java 复制代码
public interface Light {
    void on();
    void off();
}
java 复制代码
public class BathroomLight implements Light{
    @Override
    public void on() {
        System.out.println("打开洗手间灯");
    }

    @Override
    public void off() {
        System.out.println("关闭洗手间灯");
    }
}

public class LivingLight implements Light{
    @Override
    public void on() {
        System.out.println("打开客厅灯");
    }

    @Override
    public void off() {
        System.out.println("关闭客厅灯");
    }
}

public class BedroomLight implements Light{
    @Override
    public void on() {
        System.out.println("打开卧室灯");
    }

    @Override
    public void off() {
        System.out.println("关闭卧室灯");
    }
}
java 复制代码
//灯的门面
public class FacadeLight {
    BathroomLight bathroomLight = new BathroomLight();
    BedroomLight bedroomLight = new BedroomLight();
    LivingLight livingLight = new LivingLight();

    void lightOn(){
        bathroomLight.on();
        bedroomLight.on();
        livingLight.on();
    }

    void lightOff(){
        bathroomLight.off();
        bedroomLight.off();
        livingLight.off();
    }
}
java 复制代码
public class Main {
    public static void main(String[] args) {
        FacadeLight light = new FacadeLight();
        light.lightOff();
    }
}


门面模式优点

降低复杂度: 客户端不需要了解子系统内部繁琐的细节

松耦合: 客户端只与门面类耦合,子系统的变化不会直接影响到客户端

更好的分层: 门面定义了访问系统的入口点

2. SLF4J 框架

在 SLF4J 出现之前,Java 社区存在多种日志框架(如 Log4j, JUL, Tinylog 等)。如果你开发一个开源库,你很难决定使用哪种日志:

如果你选了 Log4j,但使用你库的用户在项目里用的是 Logback,就会导致项目依赖混乱

SLF4J 解决了这个问题: 它提供了一套统一的接口。作为开发者,你只需要针对 SLF4J 的接口写日志,而底层的具体实现可以在部署时动态更换
动态绑定机制

虽然代码里写的是 LoggerFactory.getLogger(),但在运行时,SLF4J 会去类路径(Classpath)下寻找 StaticLoggerBinder

如果找到了 Logback 的包,日志就由 Logback 输出

如果找到了 Log4j 的桥接包,日志就交给 Log4j 输出。 这种设计体现了门面模式的解耦:客户端代码(你的业务逻辑)与具体实现逻辑(日志怎么落盘)彻底分离

总的来说,SLF4J使你的代码独立于任意一个特定的日志API,这是一个对于开发API的开发者很好的思想

3. 日志格式

从上图可以看到,日志输出内容元素具体如下:

  1. 时间日期:精确到毫秒
  2. 日志级别:ERROR, WARN, INFO, DEBUG 或TRACE
  3. 进程ID
  4. 线程名
  5. Logger名(通常使用源代码的类名)
  6. 日志内容

4. 日志级别

1. 日志级别的分类

日志的级别从高到低依次为: FATAL、ERROR、WARN、INFO、DEBUG、TRACE

• FATAL: 致命信息,表示需要立即被处理的系统级错误

• ERROR: 错误信息, 级别较高的错误日志信息, 但仍然不影响系统的继续运行

• WARN: 警告信息, 不影响使用, 但需要注意的问题

• INFO: 普通信息, 用于记录应用程序正常运行时的一些信息, 例如系统启动完成、请求处理完成等

• DEBUG: 调试信息, 需要调试时候的关键信息打印

• TRACE: 追踪信息, 比DEBUG更细粒度的信息事件(除非有特殊用意,否则请使用DEBUG级别替代)

2. 日志级别的使用

日志级别是开发人员自己设置的,开发人员根据自己的理解来判断该信息的重要程度

针对这些级别,Logger 对象分别提供了对应的方法,来输出日志

java 复制代码
@RestController
@RequestMapping("/logger")
public class LoggerController {
    private static final Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/print")
    public String print(){
        System.out.println("打印日志");
        logger.error("打印 error 日志");
        logger.warn("打印 warn 日志");
        logger.info("打印 info 日志");
        logger.debug("打印 debug 日志");
        logger.trace("打印 trace 日志");
        return "日志打印成功";
    }
}

SpringBoot 默认的日志框架是Logback,Logback没有 FATAL 级别,它被映射到 ERROR

结果发现, 只打印了info,warn和error级别的日志

这与日志级别的配置有关,日志的输出级别默认是 info级别,所以只会打印大于等于此级别的日志,也就是info,warn和error

5. 日志配置

1. 配置日志级别

日志级别配置只需要在配置文件中设置logging.level 配置项即可

2. 日志持久化

以上的日志都是输出在控制台上的,然而在线上环境中,我们需要把日志保存下来,以便出现问题之后追溯问题,把日志保存下来就叫持久化

日志持久化有两种方式

  1. 配置日志文件名
  2. 配置日志的存储目录
    配置日志文件的路径和文件名


    配置日志文件的保存路径


    注意 :
    logging.file.name 和 logging.file.path 两个都配置的情况下,只生效其一,以logging.file.name 为准

3. 配置日志文件分割

如果我们的日志都放在一个文件中, 随着项目的运行,日志文件会越来越大,需要对日志文件进行分割


4. 配置日志格式

打印日志的格式,也是支持配置的,支持控制台和日志文件分别设置

设置了颜色, 却没有生效?

需要配置,让idea支持控制台颜色显示

  1. 打开启动配置, 添加VM options
  2. 添加VM options -Dspring.output.ansi.enabled=ALWAYS
  3. 重新启动程序, 就发现控制台支持颜色了


三、更简单的日志输出

每次都使用 LoggerFactory.getLogger(xxx.class) 很繁琐,且每个类都添加一遍,lombok给我们提供了一种更简单的方式

  1. 添加 lombok 框架支持
  2. 使用 @slf4j 注解输出日志

1. 添加 lombok 依赖

xml 复制代码
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <optional>true</optional>
</dependency>

2. 输出日志

java 复制代码
@Slf4j
@RestController
@RequestMapping("/logger2")
public class LoggerController2 {

    @RequestMapping("/print")
    public String print(){
        System.out.println("打印日志");
//        logger.info("打印日志");
        log.error("打印 error 日志");
        log.warn("打印 warn 日志");
        log.info("打印 info 日志");
        log.debug("打印 debug 日志");
        log.trace("打印 trace 日志");
        return "日志打印成功";
    }
}

@Slf4j等同于提供了

private static final Logger log = LoggerFactory.getLogger(LoggerController.class)

四、总结

  1. 日志是程序中的重要组成部分,使用日志可以快速的发现和定位问题,Spring Boot 内容了日志框架,默认情况下使用的是 info 日志级别将日志输出到控制台的,我们可以通过 lombok 提供的@Slf4j 注解和 log 对象快速的打印自定义日志
  2. 日志包含6个级别,日志级别越高,收到的日志信息也就越少,我们可以通过配置日志的保存名称或保存目录来将日志持久化

本期内容到此为止,喜欢的话请点个赞,谢谢观看!!!

相关推荐
李白的粉4 小时前
基于springboot的火锅店管理系统(全套)
java·spring boot·毕业设计·课程设计·源代码·火锅店管理系统
狂奔小菜鸡4 小时前
Day32 | Java Stream流式编程详解
java·后端·java ee
我命由我123454 小时前
Python Flask 开发 - Flask 快速上手(Flask 最简单的案例、Flask 处理跨域、Flask 基础接口)
服务器·开发语言·后端·python·学习·flask·学习方法
雨中飘荡的记忆4 小时前
Canal深度解析:MySQL增量数据订阅与消费实战
java
hhzz4 小时前
Activiti7工作流(五)流程操作
java·activiti·工作流引擎·工作流
慧都小项4 小时前
JAVA自动化测试平台Parasoft Jtest 插件Eclipse/IDEA安装教程
java·软件测试·测试工具·eclipse·intellij-idea
摇滚侠4 小时前
Redis 零基础到进阶,Spring Boot 整合 Redis,笔记93-99
spring boot·redis·笔记
running up5 小时前
Spring核心深度解析:AOP与事务管理(TX)全指南
java·数据库·spring
一水鉴天5 小时前
整体设计 定稿 之6 完整设计文档讨论及定稿 之1(豆包周助手)
java·前端·数据库