当前位置: 首页 > article >正文

一文详解Spring Boot如何配置日志

一、写在前面

对于日志文件,相信大家都并不陌生,通过在关键位置打印相关的日志,有利于快速跟踪和定位软件系统运行中存在的问题。

在之前的 Java 实现日志记录的文章中,我们介绍了能实现日志记录的主流框架有 Log4j、Log4j2、Logback 等,通过一些性能测试发现,Logback 和 Log4j2 两个都比较优秀。同时,它们都支持与 SLF4J 框架的集成,可以轻松实现系统日志框架实现的切换,这主要得益于门面模式的设计。

当采用 Slf4j 来实现日志输出时,我们不需要再纠结到底是用 Log4j2 还是用 Logback 。Slf4j 相当于一个门面接口,可以让代码更加统一,同时它并不是一个日志实现框架,具体的实现会在 Slf4j 接口被调用的时候委托给具体的日志框架来实现。比如,当系统中有 Logback 时,就委托 Logback 来输出日志;当有 Log4j2 时,就委托 Log4j2 来实现;如果两者同时存在,可能会报循环依赖的错误,因此在项目添加依赖的时候,只能选择其中一个,如果有不兼容的问题,需要手动排除。

对于一个 Java web 项目,当采用Slf4j + Logback来实现日志信息的输出时,通常会添加类似于如下的相关依赖包。

<!-- 添加slf4j依赖包 -->
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version>
</dependency>
<!-- 添加logback依赖包 -->
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.7</version>
</dependency>

然后,在项目根目录下创建logback.xml并配置相关参数,示例如下。

<?xml version="1.0" encoding="UTF-8"?>
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false"><!-- %d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%nLogger: %loggerClass: %classFile: %fileCaller: %callerLine: %lineMessage: %mMethod: %MRelative: %relativeThread: %threadException: %exxException: %xExnopException: %nopexrException: %rExMarker: %markernewline:%n--><property name="CUSTOM_LOG_PATTERN"value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n" /><!-- 上下文名称 --><contextName>${CONTEXT_NAME}</contextName><!-- 日志输出组件 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!-- 对日志进行格式化。 --><encoder><pattern>${CUSTOM_LOG_PATTERN}</pattern><charset>UTF-8</charset></encoder></appender><!-- 日志级别为INFO,日志输出到控制台 --><root level="INFO"><appender-ref ref="CONSOLE" /></root>
</configuration>

最后,通过门面接口来输出日志,示例如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class LogPrintUtil {private static final Logger LOGGER = LoggerFactory.getLogger(LogPrintUtil.class);public static void main(String[] args){LOGGER.info("info信息");LOGGER.warn("warn信息");LOGGER.error("error信息");}
}

二、Spring Boot 日志配置

当我们采用 SpringBoot 框架来开发系统的时候,其实默认已经帮我们集成好了spring-boot-starter-logging日志依赖包,它底层采用的就是上面介绍的logback日志实现框架,同时也集成了Slf4j依赖库。

默认的logback日志配置文件在org/springframework/boot/logging/logback/defaults.xml下,我们只需要在相关的位置采用slf4j接口来打印日志即可,示例如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class LogApplication {private static final Logger LOGGER = LoggerFactory.getLogger(LogApplication.class);public static void main(String[] args) {SpringApplication.run(LogApplication.class, args);LOGGER.error("Hello World");LOGGER.warn("Hello World");LOGGER.info("Hello World");LOGGER.debug("Hello World");LOGGER.trace("Hello World");}
}

启动服务,可以看到类似于如下的打印结果:

在这里插入图片描述

默认的日志级别为info,如果想更改日志级别,可以在application.properties文件配置日志打印级别,比如改成trace,参数如下:

logging.level.root=trace

重新启动服务,日志打印结果如下:

在这里插入图片描述

从控制台输出的结果可以初步分析出,trace级别最低,可以打印所有级别的日志。在整个日志体系中,级别从低到高分为:

TRACE < DEBUG < INFO < WARN < ERROR

级别越底,可打印的日志就更多;相反,级别越高,输出的日志就更少。

从实际情况来看,太多的日志打印也未必是一件好事,有时候会把服务器磁盘撑爆,导致服务宕机。通常我们会配置INFO级别,在关键的位置打印相关信息即可。

2.1、Logback 自定义配置

在实际的业务开发中,通常我们会自定义Logback相关配置文件,有两种做法。

  • 第一种:创建logback.xml配置文件,这种配置文件会直接被日志框架加载
  • 第二种:创建logback-spring.xml配置文件,这种配置文件不会直接被日志框架加载,而是先由 SpringBoot 去解析日志配置再加载,可以使用 SpringBoot 的一些高级功能,比如 Profile 属性。

这里,我们选择第二种方式,在src/main/resources目录下,创建logback-spring.xml文件,一般标准写法如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--定义相关变量--><property name="log.dir" value="log-demo" /><property name="custom.log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n" /><!-- 控制台文件输出 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${custom.log.pattern}</pattern><charset>UTF-8</charset></encoder></appender><!-- 文件输出 --><appender name="APP_LOG"class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.dir}/log_info.log</file><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${custom.log.pattern}</pattern><charset>UTF-8</charset></encoder><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.dir}/histroy/log-%d{yyyy-MM-dd}-%i.log</fileNamePattern><maxHistory>30</maxHistory><timeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>250MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy></appender><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="APP_LOG" /></root></configuration>

其中CONSOLE节点,表示将日志输出到控制台;APP_LOG节点,表示将日志输出到文件中,并自动将最近 30 天的日志文件进行归档到histroy 文件夹中。

如果想要读取 Spring Boot properties 或根据 Spring profile 定义日志配置,可以通过如下方式实现。

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--获取application.properties中定义的变量--><springProperty scope="context"name="customLogPattern"source="custom.log.pattern"defaultValue="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n"/><springProperty scope="context"name="LogDir"source="custom.log.dir"defaultValue="log-demo"/><!-- 控制台文件输出 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${customLogPattern}</pattern><charset>UTF-8</charset></encoder></appender><!-- 文件输出 --><appender name="APP_LOG"class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LogDir}/log_info.log</file><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${customLogPattern}</pattern><charset>UTF-8</charset></encoder></appender><!--获取springProfile变量--><springProfile name="dev"><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="APP_LOG" /></root></springProfile><springProfile name="prod"><root level="INFO"><appender-ref ref="APP_LOG" /></root></springProfile></configuration>

application.properties文件相关的配置参数如下:

# 指定spring profiles 参数
spring.profiles.active=dev
# 自定义打印格式
custom.log.pattern=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n
# 自定义日志存储路径
custom.log.dir=app-demo

2.2、Log4j2 自定义配置

如果项目更倾向于使用 Log4j2 而不是 Logback,迁移方式也很简单。

首先,需要排除掉默认 Logback 相关依赖库,然后添加log4j2相关依赖包,示例如下:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Logback类似,当添加相关依赖包之后,Spring Boot 默认带了一个log4j2.xml日志配置文件,在org/springframework/boot/logging/log4j2/log4j2.xml

但是,基于业务的需要,通常我们会自定义配置文件,一般写法如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="3"><!--变量配置--><Properties><!--定义日志存储的路径 --><property name="log.dir" value="app-demo"/><!-- 定义日志输出格式 --><property name="custom.log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n"/></Properties><Appenders><!-- 控制台输出 --><Console name="CONSOLE" target="SYSTEM_OUT"><PatternLayout pattern="${custom.log.pattern}"/></Console><!-- 文件输出 --><RollingFile name="APP_LOG" fileName="${log.dir}/app.log"filePattern="${log.dir}/app-%d{MM-dd-yyyy}-%i.log.gz"><PatternLayout pattern="${custom.log.pattern}"/><Policies><TimeBasedTriggeringPolicy/><!-- size根据实际的日志量填写 --><SizeBasedTriggeringPolicy size="100 MB"/></Policies></RollingFile></Appenders><Loggers><!-- 日志记录级别 --><Root level="info"><AppenderRef ref="CONSOLE"/><AppenderRef ref="APP_LOG"/></Root></Loggers>
</Configuration>

此时如果代码中采用的是门面模式的编程方式,无需做任何的调整,即可实现日志框架的切换改造。

小结

最后总结一下,对于简单的应用场景,并发量不高的环境下,可以采用 Logback 来实现日志打印;如果对性能要求较高,可以采用 Log4j2,据官方提供的测试报告中,Log4j2 在性能和新技术的应用,比 Logback 领先,毕竟是后起之秀,但是兼容性方面,Logback 更优。


The end.

相关文章:

一文详解Spring Boot如何配置日志

一、写在前面 对于日志文件&#xff0c;相信大家都并不陌生&#xff0c;通过在关键位置打印相关的日志&#xff0c;有利于快速跟踪和定位软件系统运行中存在的问题。 在之前的 Java 实现日志记录的文章中&#xff0c;我们介绍了能实现日志记录的主流框架有 Log4j、Log4j2、Lo…...

Springboot | 如何上传文件

文章目录 1. 核心上传逻辑&#xff1a;FileUploadController2. 使文件系统中的文件可通过 HTTP 访问&#xff1a;WebConfig3. 安全性配置&#xff1a;WebSecurityConfig4. 前端实现&#xff08;这里用的是Angular&#xff09; 在许多应用程序开发中&#xff0c;我们经常需要实现…...

axios结合AbortController取消文件上传

<template><div><input type"file" multiple change"handleFileUpload" /><button click"cancelUpload" :disabled"!isUploading">取消上传</button><div>总进度&#xff1a;{{ totalProgress }}…...

spring中的@Async注解详解

一、核心功能与作用 Async 是Spring框架提供的异步方法执行注解&#xff0c;用于将方法标记为异步任务&#xff0c;使其在独立线程中执行&#xff0c;从而提升应用的响应速度和吞吐量。其主要作用包括&#xff1a; 非阻塞调用&#xff1a;主线程调用被标记方法后立即返回&…...

MyBatis 报错:Column count doesn‘t match value count at row 1 详解与解决

本文适用于使用 MyBatis MySQL 开发中出现 “Column count doesnt match value count at row 1” 报错的朋友&#xff0c;尤其是在批量插入或更新数据时&#xff0c;遇到 XML 映射文件中 insert 标签报错的问题。 一、遇到的问题&#xff1a; 二、错误原因分析 列数与值数量不…...

第四天——贪心算法——种花

1. 题目 有一个花坛&#xff0c;其中0 表示该位置是空的&#xff0c;可以种花。1 表示该位置已经有花&#xff0c;不能种花。 规则&#xff1a;新种的花不能种在相邻的位置&#xff08;即如果某个位置已经种了花&#xff0c;它的左右两个相邻位置不能再种花&#xff09;。给定…...

【人工智能】自然语言编程革命:腾讯云CodeBuddy实战5步搭建客户管理系统,效率飙升90%

CodeBuddy 导读一、产品介绍1.1 **什么是腾讯云代码助手&#xff1f;**1.2 插件安装1.2.1 IDE版本要求1.2.2 注意事项1.2.4 插件安装1.2.4.1 环境安装1.2.4.2 安装腾讯云AI代码助手** 1.2.5 功能介绍1.2.5.1 Craft&#xff08;智能代码生成&#xff09;1.2.5.2 Chat&#xff08…...

麦肯锡110页PPT企业组织效能提升调研与诊断分析指南

“战略清晰、团队拼命、资源充足&#xff0c;但业绩就是卡在瓶颈期上不去……”这是许多中国企业面临的真实困境。表面看似健康的企业&#xff0c;往往隐藏着“组织亚健康”问题——跨部门扯皮、人才流失、决策迟缓、市场反应滞后……麦肯锡最新研究揭示&#xff1a;组织健康度…...

【MySQL】第二弹——MySQL表的增删改查(CRUD)初阶

文章目录 &#x1f393;一. CRUD&#x1f393;二. 新增(Create)&#x1f393;三. 查询(Rertieve)&#x1f4d6;1. 全列查询&#x1f4d6;2. 指定列查询&#x1f4d6;3. 查询带有表达式&#x1f4d6;4. 起别名查询(as )&#x1f4d6; 5. 去重查询(distinct)&#x1f4d6;6. 排序…...

内存、磁盘、CPU区别,Hadoop/Spark与哪个联系密切

1. 内存、磁盘、CPU的区别和作用 1.1 内存&#xff08;Memory&#xff09; 作用&#xff1a; 内存是计算机的短期存储器&#xff0c;用于存储正在运行的程序和数据。它的访问速度非常快&#xff0c;比磁盘快几个数量级。在分布式计算中&#xff0c;内存用于缓存中间结果、存储…...

hz2新建Keyword页面

新建一个single-keywords.php即可&#xff0c;需要筛选项再建taxonomy-knowledge-category.php 参考&#xff1a;https://www.tkwlkj.com/customize-wordpress-category-pages.html WordPress中使用了ACF创建了自定义产品分类products&#xff0c;现在想实现自定义产品分类下的…...

离散制造企业WMS+MES+QMS+条码管理系统高保真原型全解析

在离散型制造企业的生产过程中&#xff0c;库存管理混乱、生产进度不透明、质检流程繁琐等问题常常成为制约企业发展的瓶颈。为了帮助企业实现全流程数字化管控&#xff0c;我们精心打造了一款基于离散型制造企业&#xff08;涵盖单件生产、批量生产、混合生产模式&#xff09;…...

【并发编程基石】CAS无锁算法详解:原理、实现与应用场景

一、什么是CAS&#xff1f; CAS&#xff08;Compare-And-Swap&#xff09; 是现代并发编程的核心算法之一&#xff0c;它通过处理器指令级的原子操作实现线程安全&#xff0c;无需传统锁机制。其核心逻辑可以用一个公式表示&#xff1a; CAS(V, E, N) {if (V E) { // 比较当…...

(自用)Java学习-5.8(总结,springboot)

一、MySQL 数据库 表关系 一对一、一对多、多对多关系设计外键约束与级联操作 DML 操作 INSERT INTO table VALUES(...) DELETE FROM table WHERE... UPDATE table SET colval WHERE...DQL 查询 基础查询&#xff1a;SELECT * FROM table WHERE...聚合函数&#xff1a;COUNT()…...

GOOSE 协议中MAC配置

在 GOOSE&#xff08;Generic Object Oriented Substation Event&#xff09;协议中&#xff0c;主站&#xff08;Publisher&#xff09;发送的 MAC 地址不需要与从站&#xff08;Listener&#xff09;的 MAC 地址一致&#xff0c;其通信机制与 MAC 地址的匹配逻辑取决于 GOOSE…...

机器学习之决策树与决策森林:机器学习中的强大工具

机器学习之决策树与决策森林&#xff1a;机器学习中的强大工具 摘要&#xff1a;本文深入探讨决策树和决策森林在机器学习中的应用优势及其适用场景。决策树凭借其易于配置、原生处理多种数据类型、鲁棒性及可解释性等特点&#xff0c;在小数据集和表格数据处理方面表现卓越。…...

【Redis】谈谈Redis的设计

Redis&#xff08;Remote Dictionary Service&#xff09;是一个高性能的内存键值数据库&#xff0c;其设计核心是速度、简单性和灵活性。以下从架构、数据结构、持久化、网络模型等方面解析 Redis 的设计实现原理&#xff1a; 1. 核心设计思想 内存优先&#xff1a;数据主要存…...

【C++】流(Stream)详解:标准流、文件流和字符串流

【C】流(Stream)详解&#xff1a;标准流、文件流和字符串流 在C编程中&#xff0c;流(Stream)是一个非常重要的概念&#xff0c;它为我们提供了统一的数据输入输出接口。本文将详细介绍C中的三种主要流类型&#xff1a;标准流、文件流和字符串流。 一、标准流(Standard Strea…...

基于 Spring Boot 瑞吉外卖系统开发(十三)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;十三&#xff09; 查询套餐 在查询套餐信息时包含套餐的分类名&#xff0c;分类名称在category表中&#xff0c;因此这里需要进行两表关联查询。 自定义SQL如下&#xff1a; select s.* ,c.name as category_name from setmeal…...

POSE识别 神经网络

Pose 识别模型介绍 Pose 识别是计算机视觉领域的一个重要研究方向&#xff0c;其目标是从图像或视频中检测出人体的关键点位置&#xff0c;从而估计出人体的姿态。这项技术在许多领域都有广泛的应用&#xff0c;如动作捕捉、人机交互、体育分析、安防监控等。 Pose 识别模型的…...

CSS3 基础知识、原理及与CSS的区别

CSS3 基础知识、原理及与CSS的区别 CSS3 基础知识 CSS3 是 Cascading Style Sheets 的第3个版本&#xff0c;是CSS技术的升级版本&#xff0c;于1999年开始制订&#xff0c;2001年5月23日W3C完成了CSS3的工作草案。 CSS3 主要模块 选择器&#xff1a;更强大的元素选择方式盒…...

电能质量扰动信号信号通过hilbert变换得到瞬时频率

利用Hilbert变换从电能质量扰动信号中提取瞬时频率、瞬时幅值、Hilbert谱和边际谱的详细步骤及MATLAB代码实现。该流程适用于电压暂降、暂升、谐波、闪变等扰动分析。 1. Hilbert变换与特征提取流程 1.1 基本步骤 信号预处理&#xff1a;滤波去噪&#xff08;如小波去噪&…...

Linux工作台文件操作命令全流程解析(高级篇之awk精讲)

全文目录 1 工具介绍2 核心优势3 命令格式3.1 命令格式说明3.2 组成部分详解3.2.1 选项3.2.2 模式3.2.3 动作3.2.4 输入文件 4 使用说明4.1 常用示例4.2 awk 编程解析4.2.1 基础说明4.2.2 编程进阶 4.3 温馨提示 5 内置变量6 参考文献 写在前面 前面一篇《Linux工作台文件操作命…...

力扣119题:杨辉三角II(滚动数组)

小学生一枚&#xff0c;自学信奥中&#xff0c;没参加培训机构&#xff0c;所以命名不规范、代码不优美是在所难免的&#xff0c;欢迎指正。 标签&#xff1a; 杨辉三角、滚动数组 语言&#xff1a; C 题目&#xff1a; 给定一个非负索引 rowIndex&#xff0c;返回「杨辉三角…...

c++:算法(Algorithms)

目录 常用 STL 算法 1️⃣ std::sort&#xff08;排序&#xff09; 2️⃣ std::find&#xff08;查找等于某值的元素&#xff09; 3️⃣ std::count&#xff08;统计出现次数&#xff09; 4️⃣ std::next&#xff08;获取迭代器的下一个位置&#xff09; 5️⃣ .erase(…...

大疆无人机(全系列,包括mini)拉流至电脑,实现直播

参考视频 【保姆级教程】大疆无人机rtmp推流直播教程_哔哩哔哩_bilibili VLC使用教程&#xff1a; VLC工具使用指南-CSDN博客 目录 实现效果&#xff1a; 电脑端 ​编辑 ​编辑 无人机端 VLC拉流 分析 实现效果&#xff1a; (实验机型&#xff1a;大疆mini4kRC-N2遥控器、大…...

uniapp-商城-54-后台 新增商品(页面布局)

后台页面中还存在商品信息的添加和修改等。接下来我们逐步进行分析和展开。包含页面布局和数据库逻辑等等。 1、整体效果 样式效果如下&#xff0c;依然采用了表单形式来完成和商家信息差不多&#xff0c;但在商品属性上多做了一些弹窗等界面&#xff0c;样式和功能点表多。 …...

深入浅出MySQL 8.0:新特性与最佳实践

MySQL作为开源关系型数据库的佼佼者&#xff0c;近年来持续更新迭代&#xff0c;尤其是在8.0版本中引入了一系列令人兴奋的新特性。本文将介绍一些MySQL 8.0的关键新功能&#xff0c;并提供最佳实践&#xff0c;旨在帮助开发人员和DBA更好地利用这一强大的数据库管理系统。 一…...

JIT+Opcache如何配置才能达到性能最优

首先打开php.ini文件&#xff0c;进行配置 1、OPcache配置 ; 启用OPcache opcache.enable1; CLI环境下启用OPcache&#xff08;按需配置&#xff09; opcache.enable_cli0; 预加载脚本&#xff08;PHP 7.4&#xff0c;加速常用类&#xff09; ; opcache.preload/path/to/prel…...

(2)python开发经验

文章目录 1 pyside6加载ui文件2 使用pyinstaller打包 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发 &#x1f448;&#x1f449;python开发 &#x1f448; 1 pyside6加载ui文件 方法1&#xff1a; 直接加载ui文件 from PySide6.QtWidgets import QAp…...