Spring Boot日志

Spring Boot日志

日志简介

为什么要学习日志呢

像在JavaSE中,我们会使用System.out.print来打印日志 ,打印一些信息,这样当程序出现错误,通过打印的日志来发现和定位问题,在Spring学习中,经常使用控制台日志进行分析问题

但是在复杂的项目中仅仅使用这个是不行的,日志不仅需要排查问题,还需要记录用户的操作记录等信息,因此需要专门来打印日志的东西

日志可以发现问题、排查问题、分析问题和定位问题,日志还可以系统监控、数据采集和日志审计

日志使用

打印日志

Spring Boot项目启动的时候默认有日志输出

这个和我们使用System.out.print有区别的

java 复制代码
@RestController
@RequestMapping("/logger")
public class LoggerController {

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

这里和日志打印缺少了一些东西

在Spring Boot中内置了slf4j日志框架,可以直接使用

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

LoggerFactory.getLogger()中有个参数是标识这个日志的名称,这里通常标识为类名,当然只要是个字符串都可以

这里是通过日志工厂获取一个日志对象

java 复制代码
logger.info("打印日志");

这里要引入的是org.slf4j包下Logger

java 复制代码
@RestController
@RequestMapping("/logger")
public class LoggerController {

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

这里通过login.info,来输出对应信息

日志框架简单介绍

上面我们引入的 org.slf4j下的Logger 对象,但是这个其实并不是一个真正日志实现而是一个抽象层,对日志的一种规范,标准和接口,所以其需要具体的框架配合使用,不能独立使用

门面模式(外观模式)

Provide a unified interface to a set of interfaces in a subsystem.Facade defines a higherlevelinterface that makes the subsystem easier to use

⻔⾯模式 (Facade Pattern)⼜称为外观模式, 提供了⼀个统⼀的接⼝,⽤来访问⼦系统中的⼀群接⼝.其主要特征是定义了⼀个⾼层接⼝,可以容易使用子接口

门面角色(Facade) :系统对外的同一接口

子系统角色(SubSystem) :可以同时有一个或多个SubSystem,每个通常是一个类的集合,这里Facade相当于客户端,接收到请求后,会进入到对应的SubSystem来执行后续操作

类似于去买房,有接待人员和销售人员,接待人员负责接待你然后会交给销售人员,具体买房等后续操作都是由销售人员来处理

门面模式的优缺点

1.减少了系统的相互依赖,这里实现客户端与子系统的关系,这样子系统变化,并不影响到客户端的调用

2.提高了灵活性,简化了对子系统的操作,无需了解子系统详细实现,只需要了解和通过门面对象交互即可

3.提高了安全性,可以设置访问权限,不在门面对象中使用,就无法访问

SLF4J框架介绍

在以前常用日志框架有log4J, logback,这里使用对应框架需要引入对应的东西,这样没有做到同一,如果用其他框架使用了其他的日志框架还需要重新引

问题

1.不同日志框架的API接口和配置文件不同,如果有多个日志框架,这样就需要维护多个

2.如果更换日志框架,这里需要将这里对应代码进行修改

3.第三方框架可能使用不同的日志框架,这样就需要维护多个

SLF4J就是这个⽇志⻔⾯来解决日志框架不统一的问题

统一了API接口,此时只需要维护一套日志文件配置,尽管其门面使用的日志框架底层代码改变,此时这里程序代码不需要更改

日志格式说明

1.日期时间

2.日志级别:FATAL、ERROR、WARN、INFO、DEBUG 、TRACE

3.进程ID

4.线程名

5.日志对象

6.日志内容

日志级别

⽇志级别代表着⽇志信息对应问题的严重性 ,为了更快的筛选符合⽬标的⽇志信息

FATAL:致命信息,需要立即处理的系统错误

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

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

INFO:普通信息,记录正常运行的一些信息

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

TRACE:追踪信息,比DEBUG更细粒度的信息

从上到下级别升高 级别越高,收到的信息越少

java 复制代码
@RestController
@RequestMapping("/logger")
public class LoggerController {

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

http://127.0.0.1:8080/logger/print

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

一个进程最多有一个FATAL记录

发现一个问题,这里只打印了ERROR、WARN和INFO级别的信息,这里DEBUG和TRACE,因为这里默认等级是INFO,所以只会打印这个及其级别以上

配置日志

https://docs.spring.io/spring-boot/reference/features/logging.html

上面只是日志的简单使用,当然这里日志框架是支持我们灵活的输出日志内容和格式等

配置日志级别

只需要在配置文件中配置logging.level 即可

properties和yml只需要配置其中⼀个

这里以yml配置文件为例

yaml 复制代码
logging:
  level:
    root: debug

这里打印日志水平是从debug开始,不建议设置为trace,如果这样会打印很多信息

这里也可以专门设置某个类日志文件

yaml 复制代码
logging:
  level:
    root: info
    com.example.captcha.Controller: debug

com.example.captcha.Controller这里只将这个包中日志水平设置为debug

日志持久化

上面将日志放到了cmd控制台上,但是线上环境,需要把日志保存下来,以便后续追溯问题

配置日志文件名和日志存储路径

配置文件路径

yaml 复制代码
logging:
  level:
    com.bit.ioc.controller: debug
  file:
    path: logger/

配置文件名

yaml 复制代码
logging:
  level:
    com.bit.ioc.controller: debug
  file:
#    path: logger/
    name: logger2/SpringBoot.log

如果这里既有配置文件名和文件路径会怎样

yaml 复制代码
logging:
  level:
    com.bit.ioc.controller: debug
  file:
    path: logger/
    name: logger2/SpringBoot.log

这里以name名称为准

这里默认是放到当前程序下的文件下,也可以自己设置路径

yaml 复制代码
# 设置⽇志⽂件的⽬录 
logging:
 file:
 path: D:/temp

但是这种情况无法配置文件名,只可以配置路径 ,文件名固定为spring.log

如果这里没有配置文件名称格式,这里就会默认是.gz

yaml 复制代码
logging:
  level:
    root: info
    com.bit.ioc.controller: debug
  file:
    path: D:/temp
  logback:
    rollingpolicy:
      max-file-size: 1KB
#      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i

配置日志文件分割

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

配置名称格式

每个文件最大容量

这里将每个文件最大容量设置为1KB方便演示分割效果

yaml 复制代码
logging:
  level:
    com.bit.ioc.controller: trace
  file:
    path: D:/temp
  logback:
    rollingpolicy:
      max-file-size: 1KB
      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i

文件名:⽇志名.⽇期.索引

配置日志格式

默认是这样

控制台日志格式

日志文件的日志格式

yaml 复制代码
%clr(%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}){yellow}

1.%clr(表达式){颜⾊}设置输⼊⽇志的颜⾊

blue cyan faint green magenta red yellow

2.%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MMdd'T'HH:mm:ss.SSSXXX}} ⽇期和时间--精确到毫秒

%d{}表示日期,LOG_DATEFORMAT_PATTERN获取系统属性,如果不存在,就用后面格式

3.%5p显示日志等级分别ERROR,MARN,INFO,DEBUG,TRACE

4.%t线程名,%c类的全限定名,%L为行号,%thread线程名称,%m/%msg显示输出信息,%n换行

5.%5若长度小于5,右边用空格填充,%-5长度小于5,左边用空格填充,%.15若字符长度超过15,截取多余字符

yaml 复制代码
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'   
yaml 复制代码
logging:
  level:
    com.bit.ioc.controller: trace
  file:
    path: D:/temp
  logback:
    rollingpolicy:
      max-file-size: 1KB
      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i

但是这里还是没有颜色

这里需要进行相关配置

Modify options -> Add VM options

-Dspring.output.ansi.enabled=ALWAYS

更简单的日志输出(@Slf4j注解)

引入lombok依赖

xml 复制代码
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <optional>true</optional>
</dependency>
java 复制代码
@Slf4j
@RestController
@RequestMapping("/logger")
public class LoggerController {

    private static final Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/print")
    public String print(){
        log.info("========info日志=========");
        logger.info("info日志");
        return "日志打印成功";
    }
}

原本是创建一个Logger对象,但是使用@Slf4j注解会自动创建一个对象为log可以直接使用和手动创建的一样

总结

1.日志是程序中重要的一部分,使用日志可以快速排除和定位问题,SpringBoot中有日志框架,默认情况下将等级为info及其以上的信息输出到控制台,当然可以设置等级,原本是使用LoggerFactory.getLogger创建一个日志对象,这里可以使用lombok提供的@Slf4j注解有log对象进行日志相关操作

2.日志包含6个等级,等级越高,收到日志信息越少,这里可以将日志保存到指定目录(文件下),指定文件名格式,每个文件最大大小来让日志持久化

相关推荐
程序员清风1 小时前
Java 后端如何接入大语言模型
java·spring boot·架构·aigc
逃逸线LOF1 小时前
Spring Boot4 整合 Shiro3 & Thymeleaf
spring boot·spring
右耳朵猫AI1 小时前
Java周刊2026W38 | Micronaut 修补三漏洞、JDK 27 提速 54%、Jetty 修复抖动测试
java·后端·spring
她说..2 小时前
常见设计模式-模板方法模式
java·spring·设计模式·springboot
步行cgn2 小时前
BeanFactory 与 FactoryBean 的区别:面试深度解析
java·后端·spring
杨杨杨大侠14 小时前
RAG 到底是怎么工作的?从用户提问到模型回答的完整链路
spring·openai·ai编程
Joy T14 小时前
Spring AI 2.0 Agent 进阶:Memory、State 与 Context Engineering 常见技术全景
java·人工智能·后端·spring·agent入门·agent state
linmengmeng_131416 小时前
【总结】MyBatis-Plus批量插入与清表的正确姿势
java·spring boot·mysql·mybatis
高级程序源16 小时前
django大学生创新创业项目管理系统94923-计算机课程设计、毕业设计
javascript·vue.js·spring boot·后端·python·django·课程设计