Spring - 7 ( 13000 字 Spring 入门级教程 )

news2024/12/26 23:39:48

一:Spring Boot 日志

1.1 日志概述

日志对我们来说并不陌生,我们可以通过打印日志来发现和定位问题, 或者根据日志来分析程序的运行过程,但随着项目的复杂度提升, 我们对日志的打印也有了更高的需求, 而不仅仅是定位排查问题

比如有时需要记录⼀些用户的喜好等等. 但是 System.out.print 不能很好的满足我们的需求, 此时我们就需要使用⼀些专门日志框架

1.2 日志的用途

通过前面的学习, 我们知道日志主要是为了发现问题, 分析问题, 定位问题的, 但除此之外, 日志还有很多用途

  1. 系统监控

我们可以通过日志记录这个系统的运行状态, 每⼀个方法的响应时间, 响应状态等, 对数据进行分析, 设置不同的规则, 超过阈值时进星报警,比如统计日志中关键字的数量,并在关键字数量达到⼀定条件时报警

  1. 数据采集

数据采集是⼀个比较大的范围, 采集的数据可以作用在很多方面, 比如数据统计, 推荐排序等,下图中的数据源, 其中⼀部分就来自于日志记录的数据.

在这里插入图片描述
3. 日志审计

通过系统日志分析,可以判断⼀些非法攻击, 非法调用,还可以解决系统处理过程中的安全隐患.

1.3 日志使用

Spring Boot 项目在启动的时候默认就有日志输出,如下图所示:

在这里插入图片描述

SpringBoot 内置了日志框架 Slf4j , 我们可以直接在程序中调用 Slf4j 来输出日志

1.4 打印日志

打印日志的步骤:

  1. 在程序中得到日志对象.
  2. 使用日志对象输出要打印的内容

1.4.1 在程序中得到日志对象

在程序中获取日志对象需要使用日志工厂 LoggerFactory,如下代码所示:

private static Logger logger = LoggerFactory.getLogger(LoggerController.class);

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

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

在这里插入图片描述

在这里插入图片描述

1.4.2 使用日志对象打印日志

日志对象的打印方法有很多种,我们可以先使用 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 LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
    
    @RequestMapping("/logger")
    public String logger(){
        logger.info("--------------要输出日志的内容----------------");
        return "打印日志";
    }
}

这段代码的执行流程如下:

  1. 当请求到达 /logger 路径时,Spring框架会根据 @RequestMapping(“/logger”) 注解找到对应的处理方法 logger()。
  2. 接着 Spring 框架调用 logger 方法,该方法返回一个字符串 “打印日志”。
  3. 在 logger() 方法中,通过 LoggerFactory.getLogger(LoggerController.class) 获取了一个日志记录器对象 logger。
  4. 使用这个 logger 对象调用 info(),将日志消息--------------要输出日志的内容----------------"` 记录到日志中。
  5. 最后,方法返回字符串 “打印日志”,Spring 框架将其作为 HTTP 响应返回给客户端。

日志打印效果:

在这里插入图片描述

1.5 SLF4J 日志框架介绍

SLF4J 是门面模式的典型应用
在这里插入图片描述

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

1.6 门面模式

门面模式又称为外观模式, 它提供了⼀个统⼀的接口,用来访问子系统中的⼀群接口,其主要特征是定义了⼀个高层接口,让子系统更容易使用.

在这里插入图片描述

门面模式主要包含2种角色:

  • 外观角色:也称门面角色,系统对外的统一接口.
  • 子系统角色: 可以同时有⼀个或多个子系统.,每个子系统都不是⼀个单独的类,而是⼀个类的集合.,子系统并不知道门面角色的存在,对于子系统而言,门面角色只是另⼀个客户端而已,门面角色对子系统是透明的

举个例子:去医院看病可能要去挂号, 门诊, 化验, 取药, 这些流程可能会让患者或患者家属觉得很复杂, 但如果有提供接待人员, 只让接待人员来处理, 就变得很方便.

在这里插入图片描述

1.6.1 门面模式的实现

场景: 回家后我们会开各个屋的灯. 离开家时, 会关闭各个屋的灯,如果家里设置⼀个总开关, 来控制整个屋的灯就会很方便,我们使用门面模式的实现

public class FacadePatternDemo {
    public static void main(String[] args) {
        LightFacade lightFacade = new LightFacade();
        lightFacade.lightOn();
    }
}
/**
 * 灯的⻔⾯
 */
class LightFacade{
    private Light livingRoomLight = new LivingRoomLight();
    private Light hallLight = new HallLight();
    private Light 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.7 SLF4J 框架介绍

SLF4J 就是其他日志框架的门面. SLF4J 可以理解为是提供日志服务的统⼀ API 接口, 并不涉及到具体的日志逻辑实现.

1.7.1 不引入日志门面

常见的日志框架有 log4J, logback 等. 如果⼀个项目已经使用了 log4j,而你还依赖另⼀个类库,假设这个类库是 Apache Active MQ, 它依赖于另外⼀个日志框架 logback, 那么你就需要把 logback 也加载进去.

在这里插入图片描述

存在问题:

  1. 不同日志框架的 API 接口和配置文件不同, 如果多个日志框架共存, 那么不得不维护多套配置文件
  2. 如果要更换日志框架, 应用程序将不得不修改代码, 并且修改过程中可能会存在⼀些代码冲突.
  3. 如果引如的第三方框架, 使用了多套, 那就不得不维护多套配置.

1.7.2 引入日志门面

引入门面日志框架之后, 应用程序只需要维护⼀套日志文件配置, 并且当底层实现框架改变时, 我们也不需要更改应用程序代码.

在这里插入图片描述

SLF4J 就是这个日志门面

1.8 日志格式的说明

我们之前打印的日志分别代表什么信息呢?

在这里插入图片描述
从上图可以看到,日志输出内容元素具体如下:

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

1.9 日志级别

日志级别代表着日志信息对应问题的严重性, 能够让我们更快的筛选符合目标的日志信息,日志的级别从高到低依次为: FATAL、ERROR、WARN、INFO、DEBUG、TRACE

  • FATAL: 致命信息,表示需要立即被处理的系统级错误.
  • ERROR: 错误信息, 级别较高的错误日志信息, 但仍然不影响系统的继续运行.
  • WARN: 警告信息, 不影响使用, 但需要注意的问题
  • INFO: 普通信息, 用于记录应用程序正常运行时的⼀些信息, 例如系统启动完成、请求处理完成等.
  • DEBUG: 调试信息, 需要调试时候的关键信息打印.
  • TRACE: 追踪信息, 比 DEBUG 更细粒度的信息事件(除非有特殊用意,否则请使用DEBUG 级别替代)

在这里插入图片描述

1.10 日志级别的使用

日志级别是开发人员自己设置的. 开发人员根据自己的理解来判断该信息的重要程度,针对这些级别, Logger 对象分别提供了对应的方法, 来输出日志.

/**
 * 打印不同级别的⽇志
 * @return
 */
@RequestMapping("/printLog")
public String printLog() {
        logger.trace("================= trace ===============");
        logger.debug("================= debug ===============");
        logger.info("================= info ===============");
        logger.warn("================= warn ===============");
        logger.error("================= error ===============");
        
        return "打印不同级别的⽇志" ;
}

观察打印的日志结果:

在这里插入图片描述

结果发现, 只打印了 info, warn 和 error 级别的日志,这与日志级别的配置有关, 日志的输出级别默认是 info 级别, 所以只会打印大于等于此级别的日志, 也就是 info, warn 和 error,fatal 就没必要打印了,因为是致命信息。

1.11 日志配置

1.11.1 配置日志级别

日志级别配置只需要在配置文件中设置 “logging.level” 配置项即可,如下所示:

  1. Properties 配置
logging.level.root: debug
  1. yml配置
logging:
	level:
		root: debug

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

重新运行上述代码, 观察结果:

在这里插入图片描述

1.11.2 日志持久化

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

日志持久化有两种方式:

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

在这里插入图片描述

1.11.2.1 配置日志文件名
  1. Properties 配置
logging.file.name: logger/springboot.log
  1. yml 配置
# 设置⽇志⽂件的⽂件名
logging:
	file:
		name: logger/springboot.log

运行结果显示, 日志内容保存在了对应的目录下:

在这里插入图片描述

1.11.2.2 配置日志的存储目录
  1. Properties 配置
logging.file.path: D:/temp
  1. yml 配置
# 设置⽇志⽂件的⽬录
logging:
	file:
		path: D:/temp

运行程序, 该路径下多出⼀个日志⽂件: spring.log

在这里插入图片描述
注意: logging.file.name 和 logging.file.path 两个都配置的情况下, 只有 logging.file.name 生效

1.11. 3 配置日志文件分割

如果我们的日志都放在⼀个文件中, 随着项目的运行, 日志文件会越来越大, 需要对日志文件进行分割.(默认情况下日志文件超过 10M 就进行分割)

配置项说明默认值
logging.logback.rollingpolicy.file-name-pattern日志分割后的文件名格式${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
logging.logback.rollingpolicy.max-file-size日志文件超过这个大小就自动分割10MB
  1. Properties 配置
logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i
logging.logback.rollingpolicy.max-file-size=1KB
  1. yml 配置
logging:
	logback:
		rollingpolicy:
			max-file-size: 1KB
			file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
  1. 日志文件超过 1KB 就分割(设置 1KB 是为了更好展示. 企业开发通常设置为 200M, 500M 等)
  2. 分割后的日志文件名为: 日志名.日期.索引

项目运行, 多打印⼀些日志, 日志分割结果:
在这里插入图片描述

1.11.4 配置日志格式

目前日志打印的格式是默认的:

在这里插入图片描述

打印日志的格式, 也是支持配置的. 支持控制台和日志文件分别设置,配置日志格式我们通常使用 logging.pattern.console 和 logging.pattern.file 这两个配置项,下面我们来详细说说

1.11.4.1 logging.pattern.console

logging.pattern.console 用于控制台日志格式,它的默认值为:

%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} 
%clr(${LOG_LEVEL_PATTERN:-%5p}) 
%clr(${PID:- }){magenta} 
%clr(---){faint} 
%clr([%15.15t]){faint} 
%clr(%-40.40logger{39}){cyan} 
%clr(:){faint}
%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

第一个参数:

  1. %clr: 完整语法是:%clr(表达式){颜色} 这个部分可能表示设置日志级别的颜色。在许多日志系统中,可以通过颜色来突出显示不同级别的日志消息,比如红色表示错误,黄色表示警告,绿色表示信息,等等,因为代码有很多重复,接下来将不再讲解这个知识点

支持颜色有以下几种:

  • blue(蓝色)
  • cyan(青色)
  • faint(淡色)
  • green(绿色)
  • magenta(品红色)
  • red(红色)
  • yellow(黄色)
  1. %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}: 这是用于格式化日期的部分。
    • %d: 这是一个占位符,用于指示要格式化的日期和时间。
    • ${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}: 这是一个用于指定日期格式的模式。在这里,${LOG_DATEFORMAT_PATTERN:-}是一个占位符,它的含义是如果环境变量 LOG_DATEFORMAT_PATTERN 存在,则使用它作为日期格式的模式;否则,使用默认模式 yyyy-MM-dd'T'HH:mm:ss.SSSXXX。这个模式中包含了以下元素:
      • yyyy: 年份,比如 2022、2023 等等。
      • MM: 月份,使用两位数表示,比如 01 表示一月,02 表示二月,以此类推。
      • dd: 日期,使用两位数表示,比如 01 表示一号,02 表示二号,以此类推。
      • 'T': 字符 ‘T’,可能用于表示日期和时间之间的分隔符。
      • HH: 小时,使用两位数表示,24 小时制,比如 00 表示午夜零点,01 表示凌晨一点,以此类推。
      • mm: 分钟,使用两位数表示,比如 00 表示整点,01 表示一分,以此类推。
      • ss: 秒,使用两位数表示,比如 00 表示整秒,01 表示一秒,以此类推。
      • SSS: 毫秒,使用三位数表示,比如 000 表示整毫秒,001 表示一毫秒,以此类推 - XXX: 时区偏移,表示与 UTC 时间的偏移量。例如,-07:00 表示比 UTC 时间晚七个小时的时区。

第二个参数:

  1. ${LOG_LEVEL_PATTERN:-%5p}: 这个部分是一个环境变量的占位符,用于指定日志级别的格式。如果环境变量 LOG_LEVEL_PATTERN 已经设置,那么就会使用它的值。如果没有设置,则使用默认值 %5p

    • ${LOG_LEVEL_PATTERN:-}: 这个部分表示一个环境变量的默认值的语法。在这种语法中,如果 LOG_LEVEL_PATTERN 环境变量存在,则将其值插入到这里;否则,使用默认值。

    • %5p: 这是日志级别的占位符。p 代表显示日志级别 ERROR,MARN,INFO,DEBUG,TRACE。数字 5 表示固定宽度格式化,即每个日志级别将占用 5 个字符的宽度。

例如,如果日志级别是 INFO,且使用 %5 的格式化,则输出将是 " INFO",以确保每行日志的日志级别部分对齐。这在查看日志时有助于提高可读性。

第三个参数:

  1. ${PID:- } 的含义是,如果环变量 PID 存在,则使用它的值作为进程ID;否则,使用空格替。这样设计的目的是在没有明确指定 PID 的情况下,使志保持整洁可读。

第四个参数:

这个参数 %clr(---){faint} 是一个用于设定日志输出样式和格式的表达式。

  1. ---:这是要显示的文本。在这种情况下,文本是三个连字符,可能用作日志中的分隔线或者标记。

第五个参数:

这个参数 %clr([%15.15t]){faint} 是一个用于设定日志输出样式和格式的表达式。

  1. [%15.15t]:15.15:这是时间戳格式化的规则,指了时间戳字符串的长度。在这种情况下,两个数字分别表示最小和最大的字符数限制。因此,15.15 意味着时间戳的长度被限制在15个字符。如果时间戳长度不足15个字符,则会在前面填充空格,如果超过15个字符会进行截断。

第六个参数:

这个参数 %clr(%-40.40logger{39}){cyan} 是用于设定日志输出样式和格式的表达式,

  1. (%-40.40logger{39}): 这部分指定日志消息的格式或布局。
    • -40.40: 这可能是一个指定字段宽度的格式说明符。这里的 -40 可能表示该字段的最小宽度为 40 个字符,40 可能表示最大宽度也为 40 个字符。这可以确保字段的对齐和格式整齐。
    • logger{39}: 这部分可能是在字段中指定要填充的内容。在这种情况下,logger 可能表示日志记录器的名称或标识符,而 {39} 则表示填充的内容是由长度为 39 的字符串表示的,即使日志记录器本身不到 39 个字符,通过填使其达到指定的宽度,可以确保日志输出的格式整齐,易于阅和理解。

第七个参数:

这个参数 %clr(:){faint} 是用于设定日志输出样式和格式的表达式,

  • %clr(:)(faint}:这部分主要用于设置日志输出中冒号的样式。

第八个参数:

%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}这个参数是与日志记录相关的配置项

  • %m: 这个标记代表了日志消息。在日志中,通常会包含一条消息,用描述事件、错误或者其他需要记录的信息。m标记表示该位置被替换为日志消息。

  • %n: 这个标记代表了换行符,为了更好地阅读和解析

  • %w: 这个标记代表了异常信息。%w标记表示该位置将被替换为异常信息。

  • %Ex: 这个标记代表了异常的堆跟踪。,%Ex标记表示该位置将被替换为异常的堆栈跟踪信息。

  • LOG_EXCEPTION_CONVERSION_WORD: 这个部分表示一个环境变量的默认值的语法。在这种语法中,如果 LOG_EXCEPTION_CONVERSION_WORD 环境变量存在,则将其值插入到这里;否则,使用默认值。

1.11.4.2 logging.pattern.file

logging.pattern.file 用于控制日志文件的日志格式,它的默认值为:

%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}} 
${LOG_LEVEL_PATTERN:-%5p} 
${PID:- }--- [%t] 
%-40.40logger{39} :
%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

让我们逐段解释它:

第一个参数:

  • %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}: 这部分定义了日期格式。%d表示日期时间,${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}指定了日期的格式。如果环境变量LOG_DATEFORMAT_PATTERN未定义,则默认使用yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式。

  • y: 年份,表示年份的数字。例如,2024年将被表示为"2024"。

  • M: 月份,月份的数字。例如,4月份将被表示为"04"。

  • d: 日期,表示日期的数字。例如,29号将被表示为"29"。

  • 'T': 字符 ‘T’,它用于分隔日期和时间部分,通常在ISO 8601格式中使用。

  • H: 小时,表示小时的数字(24小时制)。例如,晚上11点将被表示为"23"。

  • m: 分钟,表示分钟的数字。例如,33分钟将被表示为"33"。

  • s: 秒,表示秒数的数字。例如,54秒将被表示为"54"。

  • S: 毫秒,表示毫秒数的数字。例如,123毫秒将表示为"123"。

  • X: 时区,表示时区的偏移量。例如,东八区北京时间)将被表示为"+08:00"。

第二个参数:

  • ${LOG_LEVEL_PATTERN:-%5p}: 这部分定义了日志级别格式。${LOG_LEVEL_PATTERN:-%5p}指定了日志级别的格式。如果环境变量LOG_PATTERN未定义,则默认使用%5p,它表示日志级别的最小宽度为5个字符,右对齐。

  • ${LOG_LEVEL_PATTERN}:这是一个环境变量,用于指定日志级别的输出格式

  • :-:这是一个默认值分隔符,用于指定当环境变量未设置时所采用的默认值。

  • %5p:这是实际的日志级别格式。

    • %p:这是日志级别的占位符。它会被替换为实际的日志级别。表示显示日志级别 ERROR,MARN,INFO,DEBUG,TRACE.

    • %5p:这表示日志级别的最小宽度为5个字符如果实际的日志级别的字符数少于5个,将会在左侧填充空格,使其达到5个字符宽度。如果超过个字符,则保持原样输出。

第三个参数:

${PID:- }--- [%t] : 用于定义日志记录中的进程ID、线程名。

  • ${PID:- }:这个部分定义了进程ID的输出格式。${PID}是一个环境变量,它表示进程ID。如果环境变量PID被设置了值(比如一个进程的实际ID),那么它将被替换为这个值;如果未设置,则会输出一个空格,这里的冒号:表示了进程ID结束的标志。

  • ---:这个部分是一个分隔符,用于分隔进程ID和线程名。

  • [%t]:这个部分定义了线程名的输出格式。%t是一个占位符,表示线程名。通常,线程名是指当前执行线程的名称。方括号[]用于包裹线程名,以区分它与其他日志信息。例如,[main]表示主线程。

第四个参数:

  • %-40.40logger{39}::这个部分定义了日志记录器名称的输出格式。

    • %-40: 这表示日志记录器名称的最小宽度为40个字符。如果日志记录器名称的长度不足40个字符,将会在右侧用空格填充,以达到40个字符的宽度。

    • .40: 这表示日志记录器名称的最大宽度为40个字符。如果日志记录器名称的长度超过40个字符,将会被截断,只保留前40个字符,并在末尾添加省略号以表示截断。

    • logger: 这是日志记录器名称的占位符。在实际的日志记录中,这个占位符会被替换为实际的日志记录器名称。

    • {39}:这部分指定了在无法确定日志记录器名称长度时显示的字符数。在这个例子中,如果日志记录器名称的长度无法确定,将会显示39个字符。

  • ::这个部分是一个隔符,用于分隔日志记录器名称和日志消息。

第五个参数:

  1. %m%n 这个参数是用来定义日志消息格式的

    • %m 是一个占位符,表示日志消息。在实际的日志记录中,这个占位符会被替换为实际的日志消息内容。

    • %n 是一个转义符,表示换行符。它用于在每条日志消息之后添加一个换行,以使日志输出更易读。

所以%m%n 保证了每条日志消息输出后都会有一个换行符。

  1. ${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} 用来指定在记录日志时发生异常时如何转换异常信息的格式。这个参数可以分为两个部分来理解${LOG_EXCEPTION_CONVERSION_WORD}:-%wEx

    1. ${LOG_EXCEPTION_CONVERSION_WORD}:这部分是一个环境变量或者参数的引用,它表示如果 LOG_EXCEPTION_CONVERSION_WORD 这个环境变量被设置了,就使用其所指定的值;如果没有设置,就使用默认值。

    2. :-%wEx这部分是一个默认设定,如果环变量 LOG_EXCEPTION_CONVERSION_WORD 没有被设置,则使用该默认值。:- 表示如果环境变量没有设置,则采用后面的值。

现在让我们更详细地解释一下 %wEx 这个默认值的含义:

  • %w:这个占位符表示异常的引发位置(where)。在记录日志时,它会被替换为异常发生的位置信息,比如文件名、行号等。这可以帮助开发者追踪异常发生的具体位置,从而更容易地进行调试和排查问题。

  • E:这个占位符表示异常的类型(exception)。在记录日志时,它会被替换为异常的类型,比如错误的类型名或者错误代码。

  • x:这个占位符表示异常的详细信息(extra)。在记录日志时,它会被替换为异常的详细描述,通常包括异常的消息、堆栈跟踪等。

1.11.5 设置了颜色, 却没有生效的问题

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

  1. 打开启动配置, 添加 VM options

在这里插入图片描述

  1. 添加 VM options -Dspring.output.ansi.enabled=ALWAYS

在这里插入图片描述

  1. 重新启动程序, 就发现控制台支持颜色了

在这里插入图片描述

1.11.6 修改日志的默认格式

下面举一个简单的代码例子来修改日志的默认格式

  1. Properties 配置
logging.pattern.console='%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'
  1. yml 配置
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'
  • %d{yyyy-MM-dd HH:mm:ss.SSS}: 这是日期时间的格式化字符串,其中 %d 表示输出日期时间,{} 中的内容 yyyy-MM-dd HH:mm:ss.SSS 则规定了日期时间的显示格式为年-月-日 时:分:秒.毫秒。

  • %c: 这个标记代表了日志记录器(Logger)的名称。在日志中,Logger 通常用于标识记录日志的组件或类。

  • %M: 这个标记代表了调用日志记录器的方法名。它记录了日志记录发生的位置,即调用日志记录语句的方法名。

  • %L: 这个标记代表了日志记录发生的行号。它记录了日志记录语句在源代码中的行号。

  • [%thread]: 这个标记代表了线程名,用于记录日志记录发生时所处的线程。

  • %m: 这个标记代表了日志消息。它记录了需要被记录的具体信息。

  • %n: 这个标记代表了换行符。在日志中,为了更好地阅读和解析,通常会在不同的日志条目之间插入换行符。

项目运行, 观察日志变化:

在这里插入图片描述

通常情况下, 咱们就使用默认的日志格式打印即可.

1.11.7 更简单的日志输出

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

  1. 添加 lombok 框架支持
  2. 使⽤ @slf4j 注解输出日志。
1.11.7.1 添加 lombok 依赖
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
1.11.7.2 输出日志
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class LogController {
    public void log(){
        log.info("--------------要输出⽇志的内容----------------");
    }
}

这段代码的执行流程如下:

  1. 导入库和注解

    • import lombok.extern.slf4j.Slf4j;: 导入 Lombok 的 @Slf4j 注解
    • import org.springframework.web.bind.annotation.RestController;: 导入 Spring Framework 的 @RestController 注解
  2. 类定义

    • @Slf4j: 这个注解告诉 Lombok 自动生成一个名为 log 的 Logger 对象,可以在类中直接使用。
    • @RestController: 用于处理 HTTP 请求并返回响应。
  3. 方法定义

    • log.info("--------------要输出⽇志的内容----------------");: 在 log 方法中调用 Logger 的 info 方法,输出一条信息到日志中。
  4. 执行流程

    • 当这个类被实例化,并且调用了 log() 方法时,会执行方法体内的代码。
    • log() 方法内部,使用了 log.info() 方法,表示以 INFO 级别记录一条日志信息。
    • 由于使用了 Lombok 的 @Slf4j 注解,因此无需手动创建 Logger 对象,可以直接使用 log 对象来记录日志。
    • 这条日志信息会根据日志配置的格式(如前面提到的 logging.pattern.consolelogging.pattern.file)被输出到相应的日志文件或控制台中。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1653149.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于 c++ 中字符串 string 及 常量字符串的换行与使用

&#xff08;1&#xff09;例如 cout << " ddddddddddddddddddd" 。当输出字符太长&#xff0c;就需要换行。疑问是如何写代码&#xff0c;才可以保证源代码中的字符串换行被正确编译呢&#xff1f;测试一下&#xff0c;如下图可见&#xff0c;如此换行&#x…

STM32:GPIO输入输出

文章目录 1、GPIO介绍1.1 GPIO的基本结构1.1 GPIO的位结构 2、 GPIO工作模式3、GPIO标准外设库接口函数3.1 RCC接口函数3.2 GPIO接口函数3.2.1 GPIO的读取函数3.2.1 GPIO的写入函数 4、GPIO的初始化 1、GPIO介绍 GPIO&#xff08;General Purpose Input Output&#xff09;通用…

【MQTT】服务端、客户端工具使用记录

目录 一、服务端 1.1 下载 1.2 相关命令 &#xff08;1&#xff09;启动 &#xff08;2&#xff09;关闭 &#xff08;3&#xff09;修改用户名和密码 1.3 后台管理 &#xff08;1&#xff09;MQTT配置 &#xff08;2&#xff09;集群概览 &#xff08;3&#xff09;…

场外期权个股怎么对冲?

今天期权懂带你了解场外期权个股怎么对冲&#xff1f;场外个股期权是一种在非交易所市场进行的期权交易&#xff0c;它允许投资者针对特定的股票获得未来买入或卖出的权利。 场外期权个股怎么对冲&#xff1f; 持有相反方向的期权&#xff1a;这是最直接的对冲方法&#xff0c…

今晚 19:00 | 从这两个问题入手,带你了解数据要素相关税务问题

五一假期已经结束&#xff0c;返工后当然是继续劳动啦~数据要素系列直播《星光对话》第三期也将在今晚19:00&#xff0c;继续跟大家见面。 本期直播&#xff0c;依然由 星光数智咨询总监 刘靖 主讲&#xff0c;带来&#xff1a;《数据要素相关税务问题解读》。 主要围绕两个问题…

怎么快速分享视频文件?用二维码看视频的方法

怎样不通过传输下载分享视频内容呢&#xff1f;以前分享视频内容&#xff0c;大多会通过微信、QQ、邮箱、网盘等形式来传递。但是这种方式需要下载后才可以观看&#xff0c;不仅占用手机内存&#xff0c;而且效率也比较低&#xff0c;所以现在很多人会采用视频生成二维码的方式…

为 Flutter 应用设置主题:ThemeData 和 ColorScheme 指南

在媒体和其他来源中有许多关于这个主题的文章&#xff0c;那么这篇文章的必要性是什么&#xff1f; 在本文中&#xff0c;我计划仅关注 ThemeData 小部件的关键点以及我的开发经验中最常用的参数&#xff0c;并且您将获得有关每个参数如何对您的应用程序执行操作的简要说明。 …

LeetCode70:爬楼梯

题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 解题思想 1.确定dp数组以及下标的含义 dp[i]&#xff1a; 爬到第i层楼梯&#xff0c;有dp[i]种方法 2.确定递推公式 从dp[i]的定义可以…

旋转测径仪的常见故障和排除方法

关键字: 旋转测径仪,测径仪常见故障,测径仪故障排除方法,测径仪维护,测径仪较零 点击 “开始测量”按钮时提示“初始化失败&#xff01;”无法进行测量。 ◆ 检查控制柜面板“工作”指示灯&#xff08;绿&#xff09;是否点亮&#xff1b; ◆ 最小化软件窗口&#xff0c;查看…

解密某游戏的数据加密

前言 最近有个兄弟通过我的视频号加我&#xff0c;咨询能否将这个dubo游戏游戏开始前就将数据拿到从而进行押注&#xff0c;于是通过抓包工具测试了下&#xff0c;发现数据有时候是明文&#xff0c;有时候确实密文&#xff0c;大致看了下有这几种加密&#xff1a;Md5aes、Md5&a…

用Pycharm对图片中表格进行文字识别,并导出到xlsx文件中

需要使用到百度API对图片文字进行识别 在百度智能云官网中注册一个账号百度智能云-登录https://login.bce.baidu.com/ 之后在管理中心里创建应用 创建完成后会得到&#xff1a; 记下一下AppID&API Key&Secret Key这三个值&#xff0c;调用接口时使用。 示例图片&…

字符编码(十六进制)

题目描述 假设一个简易的变长编码规则XUTF:每个字符有一个唯一编号值 unicodeVal(如汉字“华”的编号十进制值是21326),使用1~6个字节进行编码,编码规则如下: 编码格式: 编号值范围编码后字节长度n二进制格式(x 表示有效位,其它为固定位)[0, 2^7)1字节1xxxxxxx[2^7,…

数智算网,链启未来 | 算力网络子链诚邀各方加入

4月28日&#xff0c;在中国移动算力网络大会期间&#xff0c;由中国移动集团主办&#xff0c;中国移动研究院和云能力中心联合承办的“数智算网&#xff0c;链启未来”共链行动算力网络专场会议成功召开。中国移动研究院副院长段晓东&#xff0c;中国移动集团首席专家、云能力中…

Tomcat、MySQL、Redis最大支持说明

文章目录 一、Tomcat二、MySQL三、Redis1、最大连接数2、TPS、QPS3、key和value最大支持 一、Tomcat 查看SpringBoot内置Tomcat的源码&#xff0c;如下&#xff1a; 主要就是看抽象类AbstractEndpoint&#xff0c;可以看到默认的核心线程数10&#xff0c;最大线程数200 通过…

百元挂耳式耳机哪款好?五款高品质一流机型不容错过

开放式耳机以其独特的不入耳设计&#xff0c;大大提升了佩戴的舒适度。相较于传统的入耳式耳机&#xff0c;它巧妙地避免了对耳朵的压迫&#xff0c;降低了中耳炎等潜在风险。不仅如此&#xff0c;开放式耳机还能让你保持对周边声音的灵敏度&#xff0c;无论是户外跑步还是骑行…

umount.nfs : /out:device is busy

-f, --force force unmount (in case of an unreachable NFS system) -l, --lazy detach the filesystem now, and cleanup all later-l 这么牛&#xff1f;现在分离文件系统&#xff0c;稍后再进行清理

【实战】采用jenkins pipeline实现自动构建并部署至k8s

文章目录 前言部署jenkins编写docker-compose-jenkins.yaml配置maven源启动jenkins解锁jenkins Jenkins默认插件及git、镜像仓库、k8s凭证配置host key verification configuration修改为不验证Gitee ssh阿里云镜像仓库ssh编写pipeline安装以下常用插件将kubectl命令文件拷贝到…

Google Pixel4手机刷机+Root+逆向环境详细教程

Google Pixel4手机刷机Root逆向环境配置详细教程 刷机工具下载 Windows10、Google Pixel4手机当前安卓10系统、adb工具、要刷的谷歌原生的Android11最新刷机包、安装google usb驱动、美版临时twrp-3.6.0_11-0-flame.img和美版永久twrp-installer-3.6.0_11-0-flame.zip、Magis…

前端组件库之ant-design-vue

在这里记录一个这个组件库我之前没有发现最近才发现的一个很好用的功能&#xff08;应该叫功能吧&#xff1f;&#xff09; 就是 这个flex弹性布局&#xff0c;之前在开发时&#xff0c;一直使用elementUI,是第一次使用这个组件库&#xff0c;所以没有发现这个功能这么好用 你…

适合宝妈的项目,一单20,看似不起眼的小生意,却能闷声发财!

向大家推荐一个小项目&#xff0c;信息差较大&#xff0c;每单至少有20元的利润。目前参与的人还不多&#xff0c;是个不错的机会。操作方法也非常简单&#xff0c;只需利用京东家政券赚取差价。可能很多人是第一次了解到这个——京东竟然还有家政券。 周周近财&#xff1a;让…