23、springboot日志使用入门-- SLF4J+Logback 实现(springboot默认的日志实现),日志打印到控制台及日志输出到指定文件

news2024/11/25 20:20:14

springboot日志使用入门

★ 典型的Spring Boot日志依赖:

 spring-boot-start.jar   
     -- spring-boot-starter-logging.jar (Spring Boot的日志包)
          -- logback(core、classic)
          -- log4j-to-slf4j.jar
          -- jul-to-slf4j.jar

就是springboot的默认的日志依赖实现。创建项目的时候存在这个依赖里面。
在这里插入图片描述

★ Java领域的日志框架可分为:

▲ 门面类(抽象层):SLF4J、JCL(Apache commons logging)、JBoss Logging

▲ 日志实现:Log4j、Log4j2、Logback、JUL(JDK内置的java.util.logging)

推荐应用程序面向日志门面编程,以便底层可以在不同的日志实现之间自由切换。

项目中的日志框架,通常是两个:日志门面(抽象)+ 日志实现

★ Spring Boot的日志设计

下面的日志实现就是基于 SLF4J+Logback
SLF4J+Logback:SLF4J是门面,Logback是实现

▲ Spring Boot日志采用如下组合:

- SLF4J+Logback:SLF4J是门面,Logback是实现

▲ 由于Spring Boot要整合大量其他框架,这些框架底层可能采用了各种不同的日志实现,
    因此Spring Boot需要将这些日志全部“路由”给SLF4J(把所有日志统一交给SLF4J来输出),
    以后开发者就只需要设置SLF4J的日志即可。

   因此还需要
   - log4j-to-slf4j.jar:它负责将Log4j日志路由到SLF4J。
   - jul-to-slf4j.jar:负责将JUL日志路由到SLF4J。


 【说明】:当你项目用了Spring Boot之后,Spring boot会负责将所有第三方框架日志都路由给SLF4J,
        开发者就只需要配置SLF4J日志,即可对所有的日志进行全盘控制。

 【注意】:将Spring Boot应用部署到服务器上,JUL生成的日志将不再路由到Spring Boot应用的日志。
         ——由于应用服务器底层往往都使用JUL日志,由于应用服务器本身、及服务器上可能部署了其他应用的日志
         这些日志当然与我们Spring Boot应用无关,所以Spring Boot默认不会将这些日志路由到SLF4J上。


 【总结】 Spring Boot统一了Java领域的所有框架所可能用到的日志实现,并将这些日志全部“路由”给SLF4J来管理,
          因此开发者只要管理SLF4J日志,即可对项目中所有日志框架进行管理。

★ 使用日志:

(1)在程序中获取Logger对象(org.slf4j包下的),通过LoggerFactory。
     也可用Lombok的@Slf4j注解来获取。

(2)在要输出日志的地方(相当于以前Systme.out.println)
     Logger的trace\debug\info\warn\error来输出不同级别的日志。

★ 日志级别

▲ 日志级别:
  
  TRACE < DEBUG < INFO < WARNING < ERROR


▲ 当日志输出方法的级别高于或等于应用日志的设置级别时,该日志才会实际输出。

   Spring Boot应用默认的日志级别是INFO,因此它默认只输出info、warn、error方法输出的日志。

★ 设置日志级别:

设置日志的级别,可通过以下方式:

▲ 改变Spring Boot的核心日志级别

  通过debug=true或trace=true等属性(通过配置文件、命令行参数、系统变量、OS环境变量等方式)

  改变整个Spring Boot核心的日志级别。

▲ 改变程序组件(包括所有各种框架)的核心日志级别

  通过logging.level.<logger-name>=<level>属性(可通过配置文件、命令行参数、系统变量等方式)设置指定日志的日志级别。

 其中<logger-name>代表日志名,通常就是包名或全限定的类名,
  如果<logger-name>使用包名,那就意味着对该包下所有类统一设置日志级别。
  如果<logger-name>使用类名,那就意味着对该类设置日志级别。

而level则可以是trace、debug、info、warn和error等级别。

【小技巧】实际项目开发时,尽量避免使用System.out.println来做输出,而应该用日志来做输出。
System.out.println 在输出的时候,每打印一行都是需要进行IO的,所以会很耗性能。

如果你在调试时用了大量的System.out.println来做输出,到了项目上线时必须要删除这些输出语法,否则会因为IO造成性能影响。

但如果你用的日志(debug)来输出,项目上线时,只要将应用级别调高,这些日志输出就会被自动关闭,因此无需输出这些日志输出语句。


▲  互联网上常问如何控制日志输出

  Spring Boot让MyBatis输出它执行的SQL语句啊?非常简单:

   logging.level.<Mapper组件所在包>=debug
   组件可以理解是类

  Spring Boot看到Redis的详细执行过程?非常简单:
   logging.level.io.lettuce.core=debug

   Spring Boot整合Redis默认使用Lettuce依赖,而io.lettuce.core就是Lettuce组件核心API所在的包。

  Spring Boot看到MongoDB的详细执行过程?非常简单:
   logging.level.com.mongodb=debug

  上面com.mongodb就是MongoDB核心API所在的包。

  由此可见,通过Spring Boot可以让它输出任意框架的执行过程,只需要如下设置

  logging.leve.<框架核心API所在的包>=debug

代码示例:

1、先创建一个类,获取日志对象。
2、然后在application.yml配置类里面配置一些日志信息—改变Spring Boot的核心日志级别

通过debug=true或trace=true等属性(通过配置文件、命令行参数、系统变量、OS环境变量等方式)改变整个Spring Boot核心的日志级别。

如图:这里在配置文件里面设置核心日志级别为 trace = true,就是级别为 trace。
但是打印出来的还是只有 info、warn 和error,但是控制台的启动记录里面还是有trace的,如图

在这里插入图片描述

这个是改变项目程序组件的核心日志级别,设置特定包下所有类的日志级别,打印的时候就可以如图,把 trace 和 debug 都打印出来

这个是让controller包下面的所有类的日志级别设置为 trace
在这里插入图片描述
这个是让LogController这个类的日志级别设置为 trace
在这里插入图片描述

★ 日志输出到文件:

Spring Boot默认只将日志输出到控制台,不输出到文件,如果要将日志输出到文件,

可为Spring Boot设置如下两个属性的其中之一:

- logging.file.name:设置日志文件的文件名。

- logging.file.path:设置日志文件的目录。使用默认的spring.log作为文件名。

logging.file.path 这个有一个好处,就是当日志文件过大的时候,就会自动把日志文件分成多个文件。

代码示例:

- logging.file.path:设置日志文件的目录。使用默认的spring.log作为文件名。

在这里插入图片描述
这个就是生成在文件夹中的日志文件,跟控制台的打印出来的是一样的。
在这里插入图片描述

Logback设置

logging.logback.rollingpolicy.file-name-pattern: 设置对日志归档的文件名模板
logging.logback.rollingpolicy.clean-history-on-start:设置应用启动时是否清除日志归档
logging.logback.rollingpolicy.max-file-size日志文件归档之前的最大大小
logging.logback.rollingpolicy.total-size-cap:日志归档在被删除之前所能容纳的最大大小
logging.logback.rollingpolicy.max-history: 保留多少天的日志归档(默认为7)

Java 的日志归档是指对生成的日志文件进行周期性或大小限制的管理,以便保留和存档旧的日志文件,以便后续的检查、分析和备份。
通常情况下,应用程序会生成大量的日志数据,这些日志文件会越来越大,占用系统存储空间。为了避免过多的日志文件影响系统性能和存储空间的占用,可以对日志进行归档管理。
具体来说,归档通常有以下几种方式:
基于时间的归档:按照一定的时间间隔(如每天、每周、每月)将日志文件进行归档,将旧的日志文件存档到特定的文件夹或压缩文件中,以便后续查阅。
基于大小的归档:当日志文件达到一定大小时,将当前的日志文件存档,然后重新创建一个新的日志文件,以确保日志文件的大小始终在一个可接受的范围内。

★ 日志组:

(1)将多个包定义一个组名,

(2)然后对整个组设置指定的日志级别

——这样即可将该组对应的所有包统一设置成相同的日志级别。

 日志组也是一个提高项目可维护性的小技巧。

就是一个项目有很多个包(文件夹),比如 controller,service、dao、domain、config 等等,然后我们想让controller、service、dao这三个包的日志级别设置为 debug 级别。但是又不可能在配置文件中一个包一个包的写配置,所以这个时候就可以用到日志组。

代码示例:

需求:我这个项目有三个包c1,c2,c3,我想让 c2 和 c3 这两个包的日志级别为 warn ,然后项目的其他包的日志级别为trace。

这里建3个包
在这里插入图片描述

我配置让 c2 c3这两个包的日志级别为warn
项目其他包的日志级别为 trace,其他包不可能一个一个写出来,所以直接把最大的包 boot 进行设置。
但是 c2 c3 这两个包又被包含在 boot 包里面,所以要看看c2 c3 这两个包的日志级别是我们要的 warn 级别,还是会因为被boot包 包含而变成trace级别
在这里插入图片描述

如图可以看出 c2 c3 这两个包的日志级别没有被 boot 包影响,还是我们要的warn级别。
而项目的其他包,如 c1 ,就是我们要的 trace 级别
在这里插入图片描述

这两个设置,谁放上面谁放下面都没有影响各自的日志级别,不会有那种放下面然后覆盖上面的情况。
在这里插入图片描述

上面的日志实现就是基于 SLF4J + Logback:SLF4J是门面,Logback是实现

▲ 门面类(抽象层):SLF4J、JCL(Apache commons logging)、JBoss Logging
▲ 日志实现:Log4j、Log4j2、Logback、JUL(JDK内置的java.util.logging)

★ 如何替换默认的日志实现(Logback)

▲  两步:

(1)去掉Logback依赖库,添加新日志实现的依赖库。
    Logback日志实现的优先级最高,当该日志实现的JAR存在时,Spring Boot总会使用该JAR包作为默认的日志实现。       

(2)在类加载路径的根路径下为新日志实现提供对应的配置文件。

     默认从类加载路径的根路径下加载日志配置文件,也可通过logging.config属性来设置新的加载路径。

     除了可根据底层依赖库自动选择日志实现外——根据JAR包来自动选择日志实现,找到哪个日志实现的JAR包,Spring Boot就是用哪个日志实现。

     还可通过org.springframework.boot.logging.LoggingSystem属性显式指定日志实现,
该属性的值可以是LoggingSystem实现类的全限定名。


▲  不同日志实现的配置文件:

Logback:logback-spring.xml、logback-spring.groovy、logback.xml或 logback.groovy

Log4j2: log4j2-spring.xml或log4j2.xml

JDK(JUL):logging.properties

Spring Boot 推荐 使用带-spring后缀的配置文件作为对应日志框架的配置文件。

★ 控制日志只输出到文件(不输出到控制台)

项目上线时比较实用!


 两步:

(1)控制日志输出到文件。
     指定logging.file.name或logging.file.path两个属性的其中之一。

(2)还需要显式提供日志实现对应的配置文件,通过该配置文件关闭日志在控制台的输出。

     ——这一步的配置文件往往应该是日志实现相关的,和Spring Boot关系并不大。

代码示例

1、创建一个 logback-spring.xml 配置文件,这个配置文件专门用来控制 logback 日志的,现在在这个配置文件进行配置,让日志不要输出到控制台,只输出到指定的文件就行
application.yml 的配置不需要改,还是那样。

在这里插入图片描述

启动项目,然后再访问方法,发现控制台都没有任何的日志输出,一片空白,然后打开日志输出的文件,发现成功只输出在文件中
如图:项目的启动时间是16:36分,文件中的日志也是同个时间,证明日志只输出在指定文件中,没有输出在控制台
在这里插入图片描述

logback-spring.xml配置文件

<!--  关闭LogBack的日志在控制器的输出  -->
<configuration>
    <!--  导入Logback通用的日志配置  -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <!--  定义日志文件  -->
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
    <!--  导入输入到文件的日志配置  -->
    <include resource="org/springframework/boot/logging/logback/file-appender.xml"/>
    <!--  指定将日志输出到文件 ,只输出到文件,不输出到控制台 -->
    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>
</configuration>

上面用的是默认的 Logback,现在要改成 log4j2

★ 通过例子示范使用log4j2替换Logback

 ——比较小众的应用场景。用的比较少,因为 springboot 推荐用 SLF4J+Logback ,所以没必要改成其他的
 但是这里可以尝试一下。

(1)去掉去掉Logback依赖库,添加Log4j2日志实现的依赖库。

(2)添加log4j2日志的配置文件——这一步是可选的。

代码示例

在创建项目的时候,就会默认有logback的日志依赖了,所以把这个logback的日志依赖从pom.xml文件中去除就可以了。

1、这个操作就是把springboot默认的日志排除在外(就是把logback排除在外)

2、添加新的日志实现

在这里插入图片描述

启动项目,发现日志输出和之前没有什么区别,因为更改日志实现,是底层实现的,不是具体的代码实现,可以理解为抽象的,所以用 logback 或者是 log4j2 ,只是底层实现方法变了,但是呈现出来的效果还是一样的。

如果:因为把logback 改成 log4j2 ,所以原本设置的 日志记录只输出到文件,不输出到控制台的作用,也失效了。

在这里插入图片描述

要看logback 和 log4j2 的区别,只能从maven 里面看了
在这里插入图片描述

改回来 logback ,原本设置的 日志记录只输出到文件,不输出到控制台的效果 就又恢复了
在这里插入图片描述

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

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

相关文章

【el-upload】批量上传图片时在before-upload中添加弹窗判断时的踩坑记录

一、初始代码 1. 初始使用组件代码片段 <!-- 上传 --> <DialogUploadFile ref"uploadFile" success"refresh" />// 上传 const uploadHandle () > {if (selections.value.length ! 1) {onceMessage.warning(请选择一条数据操作)return}u…

并行FIR滤波器

FIR 滤波器原理 FIR 滤波器是有限长单位冲击响应滤波器&#xff0c;又称为非递归型滤波器。FIR 滤波器具有严格的线性相频特性&#xff0c;同时其单位响应是有限长的&#xff0c;因而是稳定的系统。 FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积&#xff0c;表达式…

MapBox加载不同风格

初始化MapBox地图&#xff1a; var map new mapboxgl.Map({container: map,zoom: 3,center: [105, 34],//此处更改地图风格style: mapbox://styles/mapbox/satellite-v9,hash: false,});1.户外地图&#xff08;mapbox://styles/mapbox/basic-v9&#xff09;新版&#xff1a;&a…

python——案例15:判断奇数还是偶数

案例15&#xff1a;判断奇数还是偶数numint(input(输入数值&#xff1a;))if(num%2)0: #通过if语句判断print("{0}是偶数".format(num))else: #通过else语句判断print("{0}是奇数".format(num))

Linux Linux基础命令

1.pwd——显示当前位置的绝对路径 2.cd——切换目录&#xff0c;cd 后的参数表示要切换到的位置 &#xff08;1&#xff09;cd后面的参数为绝对路径&#xff1a; &#xff08;2&#xff09;cd后面的参数为相对路径&#xff1a; &#xff08;3&#xff09;cd ~回到家目录&#…

Ansys Lumerical | 针对多模干涉耦合器的仿真设计与优化

说明 本示例演示通过12端口多模干涉(MMI)耦合器计算宽带传输和光损耗&#xff0c;并使用S参数在 INTERCONNECT 中创建 MMI 的紧凑模型。(联系我们获取文章附件) 综述 低损耗光耦合器和光分路器是基于 Mach-Zehnder 的光调制器的基本组件&#xff0c;是集成电路的关键组成部分。…

数据结构——双向链表

双向链表实质上是在单向链表的基础上加上了一个指针指向后面地址 单向链表请参考http://t.csdn.cn/3Gxk9 物理结构 首先我们看一下两种链表的物理结构 我们可以看到&#xff1a;双向在单向基础上加入了一个指向上一个地址的指针&#xff0c;如此操作我们便可以向数组一样操作…

【Android NDK开发】Android Studio 编写 JNI (C++)代码无提示

随笔记 Android Studio在编写C代码时候&#xff0c;引入对应的头文件&#xff0c;Android Studio里却不提示对应的方法&#xff0c;需要在Studio中设置一下。 Mac中&#xff0c;选择 Android Studio > Preferences&#xff0c;选择Clangd >>Disable Clangd completio…

【Vue3】自动引入插件-`unplugin-auto-import`

Vue3自动引入插件-unplugin-auto-import&#xff0c;不必再手动 import 。 自动导入 api 按需为 Vite, Webpack, Rspack, Rollup 和 esbuild 。支持TypeScript。由unplugin驱动。 插件安装&#xff1a;unplugin-auto-import 配置vite.config.ts&#xff08;配置完后需要重启…

(二) 【屠龙刀】 vsomeip协议栈的编译与使用

前言 上一篇文章介绍了SOME/IP协议的报文格式,本片文章主要来介绍SOME/IP协议的具体实现,即vsomeip协议栈。 vsomeip由GENIVI组织根据SOME/IP协议标准实现的协议栈,如果说SOME/IP协议是一个人的灵魂,那么vsomeip就是受灵魂指导的肉体。本文将从如下几点去展开本文,手把手…

米尔瑞萨RZ/G2L开发板-01 开箱+环境搭建+交叉编译FFMPEG

标题有点长哈&#xff0c;首先要感谢米尔电子提供的开发板&#xff0c;异构的板子说实话还真的是最近才开始接触的&#xff0c;在我提交申请后&#xff0c;很快就收到板子了&#xff0c;而且还是顺丰给发来的&#xff0c;其实我估计很多人就是为了骗板子&#xff0c;因为米尔的…

【学习FreeRTOS】第2章——FreeRTOS基础知识

1.任务调度 1.1.任务调度简介 调度器就是使用相关的调度算法来决定当前需要执行的哪个任务FreeRTOS 一共支持三种任务调度方式&#xff1a; 抢占式调度&#xff1a;针对优先级不同的任务&#xff0c;每个任务都有一个优先级&#xff0c;优先级高的任务可以抢占优先级低的任务…

2.CUDA 编程手册中文版---编程模型

2.编程模型 更多精彩内容&#xff0c;请扫描下方二维码或者访问https://developer.nvidia.com/zh-cn/developer-program 来加入NVIDIA开发者计划 本章通过概述CUDA编程模型是如何在c中公开的&#xff0c;来介绍CUDA的主要概念。 编程接口中给出了对 CUDA C 的广泛描述。 本章…

linux环形缓冲区kfifo实践3:IO多路复用poll和select

基础知识 poll和select方法在Linux用户空间的API接口函数定义如下。 int poll(struct pollfd *fds, nfds_t nfds, int timeout); poll()函数的第一个参数fds是要监听的文件描述符集合&#xff0c;类型为指向struct pollfd的指针。struct pollfd数据结构定义如下。 struct poll…

Netty的ReplayingDecoder分析

说明 io.netty.handler.codec.ReplayingDecoder是io.netty.handler.codec.ByteToMessageDecoder的一个子类&#xff0c;是一个抽象类&#xff0c;它将字节流解码成其它的消息。需要ReplayingDecoder的子类实现decode(ChannelHandlerContext ctx, ByteBuf in, List out)这个函数…

Selenium 自动化 | 案例实战篇

Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器&#xff08;如 Chrome、Opera 和 Microsoft Edge&#xff09;中的工具&#xff0c;用于帮助开发人员调试和研究网站。 借助 Chrome DevTools&#xff0c;开发人员可以更深入地访问网站&#xf…

恒盛策略:快跌慢涨是主力洗盘?

当股市一直处于震荡状态&#xff0c;不断重复时。许多股民纷纷开端猜想股市未来走势&#xff0c;同时也有不少人议论着什么是“主力洗盘”和“快跌慢涨”。这儿&#xff0c;咱们来从多个视点来剖析这个问题。 首要&#xff0c;咱们需要了解“主力洗盘”和“快跌慢涨”两个概念。…

leetcode 475. 供暖器(java)

供暖器 供暖器题目描述双指针代码演示 双指针专题 供暖器 难度 - 中等 leetcode 475 题目描述 冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。 在加热器的加热半径范围内的每个房屋都可以获得供暖。 现在&#xff0c;给出位于一条水平线上的房屋 ho…

window下部署Yapi接口管理系统部署总结

window下部署Yapi接口管理系统部署总结 YApi 是高效、易用、功能强大的 api 管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API&#xff0c;YApi 还为用户提供了优秀的交互体验&#xff0c;开发人员只需利用平…

使用几何和线性代数从单个图像进行 3D 重建

使用几何和线性代数从单个图像进行 3D 重建 萨蒂亚 一、说明 3D重构是一个挑战性题目&#xff0c;而且这个新颖的题目正处于启发和膨胀阶段&#xff1b;因此&#xff0c;各种各样的尝试层出不穷&#xff0c;本篇说明尝试的一种&#xff0c;至于其它更多的尝试&#xff0c;我们在…