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

一: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)被输出到相应的日志文件或控制台中。

在这里插入图片描述

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
spring-data-elasticsearch官方教程文档提供了关于如何使用spring-data-elasticsearch框架进行Elasticsearch数据库操作的详细指导。该文档分为几个部分,包括介绍、快速入门、基本概念、查询构造器和复杂查询等。 文档的介绍部分简要介绍了spring-data-elasticsearch框架以及它提供的主要功能。快速入门部分通过一个简单的示例演示了如何配置spring-data-elasticsearch并进行基本的CRUD操作。该示例涵盖了创建索引、映射实体类、保存数据、查询数据以及删除数据。通过这个示例,读者可以迅速了解到spring-data-elasticsearch的基本用法。 基本概念部分详细介绍了spring-data-elasticsearch中的一些重要概念,包括实体类映射、索引操作、文档操作、段映射、分页和排序等。这些概念对于深入理解spring-data-elasticsearch的使用非常重要。 查询构造器部分介绍了spring-data-elasticsearch提供的查询构造器的使用方法。该部分通过实例演示了如何使用查询构造器进行基本查询、范围查询、模糊查询以及布尔查询等。读者可以通过这些示例快速掌握查询构造器的使用。 最后一部分是关于复杂查询的介绍。这一部分介绍了如何使用原生查询、使用注解进行查询以及使用自定义实现进行查询等。复杂查询是spring-data-elasticsearch一个非常重要的特性,通过它可以实现更加灵活和高级的查询功能。 总体来说,spring-data-elasticsearch官方教程文档提供了丰富的实例和详细的说明,对于想要学习和使用spring-data-elasticsearch框架的开发者来说,是一份非常有价值的指南。读者可以通过该文档逐步了解spring-data-elasticsearch的相关概念和基本用法,并通过实例演示快速上手。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ice___Cpu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值