[JavaEE] Spring Boot 日志

目录

[1. 日志的介绍](#1. 日志的介绍)

[2. 日志的作用](#2. 日志的作用)

[3. 日志的使用](#3. 日志的使用)

[3.1 认识日志](#3.1 认识日志)

[3.2 使用日志](#3.2 使用日志)

[3.3 日志框架介绍](#3.3 日志框架介绍)

门面模式介绍:

[3.4 日志级别](#3.4 日志级别)

[3.5 日志配置](#3.5 日志配置)

配置日志级别:

日志的持久化:

日志的分割:

日志格式的修改:

[3.6 使用注解@Slf4j注解](#3.6 使用注解@Slf4j注解)


1. 日志的介绍

日志就是程序在运行过程中记录下来程序所做的工作。

2. 日志的作用

系统监控,我们可以通过日志来记录系统的工作状况,及时发现问题。

数据采集,通过日志获取到用户请求的数据,对数据进行分析,进而推测出用户的特点。

日志审计,可以通过日志来判断一些网络安全问题。

3. 日志的使用

3.1 认识日志

我们在启动Spring Boot项目时候,就会发现控制台打印了很多日志,我们就分析下这些日志的结构:

如果我们在该项目的配置文件中,没有写下面的配置信息,此时打印的日志里面就不会显示项目名称:

java 复制代码
spring:
  application:
    name: spring-captcha-demo

3.2 使用日志

我们创建一个类来打印日志:

Spring Boot给我们提供了一个打印日志的框架,我们直接使用就行,使用LoggerFactory类里面的getLogger方法,参数是类对象,来打印出来的日志就会显示是哪个类打印的日志,然后调用日志对象的info方法,输入日志内容,就会打印出来日志。

java 复制代码
package com.sias.log.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 Logger logger = LoggerFactory.getLogger(LogController.class);

    @RequestMapping("/print")
    public String print() {
        //普通输出打印日志
        System.out.println("打印日志");
        //使用info方法打印日志
        logger.info("打印日志");
        return "打印日志";
    }
}

打印结果:

使用info方法打印出来的日志,格式就是Spring Boot自带的格式。

3.3 日志框架介绍

日志门面: SLF4J

日志实现:log4J JUL logback

这里的日志门面相当于是一种规范,不具体实现操作,而是直接调用日志实现的框架,具体的操作实现由下面三个框架去实现。

门面模式介绍:

上面的这种设计模式就是门面模式,提供一个统一的接口去使用,这个接口再去调用其他子接口,更方便的去调用子接口。

比如我们想要关家里的灯,但是需要关很多开关但是此时我们可以设置一个总开关,来控制所有的灯,直接关闭这个总开关就可以关闭所有的灯。

代码简单实现:

控制所有子接口的类:

java 复制代码
package com.sias.log.facade;

public class FacadeClient {
    private BedRoomLight bedRoomLight = new BedRoomLight();
    private LivingRoomLight livingRoomLight = new LivingRoomLight();
    private HallLight hallLight = new HallLight();

    //开灯
    void on() {
        bedRoomLight.on();
        livingRoomLight.on();
        hallLight.on();
    }
    //关灯
    void off() {
        bedRoomLight.off();
        livingRoomLight.off();
        hallLight.off();
    }
}

子接口类:

java 复制代码
public class BedRoomLight implements Light {
    @Override
    public void on() {
        System.out.println("打开卧室灯");
    }

    @Override
    public void off() {
        System.out.println("关闭卧室灯");
    }
}
java 复制代码
public class LivingRoomLight implements Light {
    @Override
    public void on() {
        System.out.println("打开客厅灯");
    }

    @Override
    public void off() {
        System.out.println("关闭客厅灯");
    }
}
java 复制代码
public class HallLight implements Light {
    @Override
    public void on() {
        System.out.println("打开走廊灯");
    }

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

我们就可以在main方法调用这个总接口:

java 复制代码
public class Main {
    public static void main(String[] args) {
        FacadeClient facadeClient = new FacadeClient();
        facadeClient.on();
        facadeClient.off();
    }
}

而在Spring Boot中使用的是SLF4J+logback框架,来进行打印日志的。

3.4 日志级别

日志的级别由高到低分为:

FATAL:致命错误,表示必须立即处理的错误。

ERROR:错误信息,级别较高的错误信息,不影响程序正常运行。

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

INFO:普通信息,用于记录程序正常运行时的信息,比如:系统启动完成,请求处理完成等。

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

TRACE:追踪信息,一般不使用。

Spring Boot默认的打印日志的级别是INFO级别。

我们可以调用对应的方法来打印不同级别的日志:

java 复制代码
package com.sias.log.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 Logger logger = LoggerFactory.getLogger(LogController.class);

    @RequestMapping("/print")
    public String print() {
        //普通输出打印日志
        System.out.println("打印日志");
        //使用info方法打印日志
        logger.info("打印日志");
        
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("gebug");
        logger.trace("trace");
        return "打印日志";
    }
}

输出结果:

这里fatal级别日志就没有对应的方法,如果真发生严重错误就不需要靠日志来进行提醒了。

这里控制台只打印到info,因为默认是info及以上的日志才会打印。

3.5 日志配置

配置日志级别:

我们可以在配置文件里面修改日志的级别:

我们还可以设置某个具体的包下面的代码的打印日志的级别:

这里就是在具体某个包下打印的日志是debug级别的。

java 复制代码
logging:
  level:
    root: info
    com:
      sias:
        log:
          controller: debug

日志的持久化:

我们可以把打印的日志保存下来,通过设置配置文件将日志保存在文件里面:

java 复制代码
logging:
  file:
    name: log.log

打印结果存储在log.log文件里面:

这里name还可以设置目录:

java 复制代码
logging:
  file:
    name: dee/log.log

还有一个path属性设置路径:

java 复制代码
logging:
  file:
    path: pa/log

使用这个属性只能设置路径,文件名字是固定的spring.log

如果path和name两个属性同时存在,此时就会使用name属性设置的值。

日志的分割:

我们在存储日志时候,默认情况下当一个文件大小超过10MB,此时就会分割,存储到一个新的文件里面,我们也可以设置这个分页的阈值:

java 复制代码
logging:
  level:
    root: debug
  file:
    name: ff/log.log
  logback:
    rollingpolicy:
      max-file-size: 1KB

默认分开后的文件是个压缩文件,我们也可以通过配置去修改分开后的文件名和类型:

java 复制代码
logging:
  level:
    root: debug
  file:
    name: ff/log.log
  logback:
    rollingpolicy:
      max-file-size: 1KB
      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i

日志格式的修改:

我们可以修改控制台的日志格式和日志文件中的日志格式:

%clr(表达式){yanse} 设置输入日志的颜色。

%d{${时间格式}} 日期和时间--精确到毫秒。

%5p 显示日志级别

%t 线程名 %c 类的全限定名 %M method

%L 行号 %thread 线程名称 %m/%msg 显示输出消息 %n换行符

%5 如果字符串长度小于5,右边用空格填充,%-5字符串长度小于5,左边用空格填充。

%.15字符串长度大于15,截取多余字符。

%15.15字符串长度小于15,右边用空格填充,字符串长度大于15,截取多余字符。

我们可以看到默认日志设置了颜色,但是控制台显示的都是黑色,这里需要修改设置:

按照下面步骤操作:

最后点击OK,就好了。

我们就可以使用上面的两个属性来修改格式:

java 复制代码
logging:
  pattern:
    console: '%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'
    file: '%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'

此时打印的日志格式如下:

3.6 使用注解@Slf4j注解

我们在使用@Slf4j注解时候,需要添加下面的依赖:

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

我们通过上面发现,我们打印日志时候,需要先创建一个打印日志的对象,还要填入类对象的参数,这个过程就可以使用@Slf4j注解来解决。

原来的代码:

java 复制代码
@RequestMapping("/log")
@RestController
public class LogController {
    //生成一个日志对象
    private Logger logger = LoggerFactory.getLogger(LogController.class);

    @RequestMapping("/print")
    public String print() {
        //普通输出打印日志
        System.out.println("打印日志");
        //使用info方法打印日志
        logger.info("打印日志");

        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("gebug");
        logger.trace("trace");
        return "打印日志";
    }
}

修改后的代码:

此时使用@Slf4j注解就会生成一个log的注解对象,对应上面的logger对象,可以打印日志。

java 复制代码
@Slf4j
@RequestMapping("/log2")
@RestController
public class LogController2 {
    @RequestMapping("/print")
    public String print() {
        log.error("error");
        log.warn("warn");
        log.info("info");
        log.debug("gebug");
        log.trace("trace");
        return "打印日志";
    }
}
相关推荐
葫芦和十三6 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp7 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑7 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯8 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan10 小时前
多Agent之间的区别
后端
青石路12 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充12 小时前
1.面向对象设计思想
后端
IT_陈寒12 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro13 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗13 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端