Spring Boot日志系统大揭秘:从零开始学习Spring Boot日志:常见问题解答和最佳实践

news2024/12/27 13:41:55

一. 关于 Spring Boot 日志的使用

Spring Boot 日志机制和工具用于记录应用程序的日志信息和追踪应用程序的执行过程。它集成了常用的日志框架,如 Log4j、logback、Java Util Logging等,并提供简单易用的配置方式,让开发人员可以方便地监控应用程序的运行状态和性能。在项目启动时,日志已经开始输出,但尚未持久化。下面是一个最简单、最常见的日志示例。
在这里插入图片描述

二. 日志的作用

日志是记录应用程序运行状态和运行过程中所发生的事件的一种技术手段。它能够帮助开发人员更容易地追踪和排查问题,同时还可以提高应用程序的安全性、稳定性和可靠性。

在软件开发过程中,日志可以:

1.调试程序:当程序出现问题时,可以查看日志文件以分析问题的原因,从而进行适当的修复。

2.跟踪操作:在应用程序中记录用户操作,以便进行回顾和审计,保证系统安全。

3.监控性能:对于服务器端应用程序,可以记录响应时间、CPU、内存和硬盘使用情况等指标,以便及时发现并解决性能问题。

4.系统运行情况:记录应用程序在不同环境下的运行状态、故障等,以便于开发人员和管理员及时了解系统运行情况,保证系统的稳定性和可靠性。

5.统计数据:将日志文件作为数据来源,进行统计分析,以便了解用户行为、访问量等信息,从而进行决策和规划。

总而言之,日志是一种非常重要的技术手段,它能够帮助开发人员更好地维护应用程序、改进用户体验和提高应用程序的稳定性和可靠性。从上面的 Spring Boot 项目启动日志可以看出,启动过程中打印了一些信息,其中包括 BUG 等级和端口号等。然而,这些仅仅是启动日志的一小部分,实际上日志还能记录更多的信息。

记录登陆日志, 利于分析用户是否正常登陆, 防止其恶意攻击破解用户倘若我们记录用户的登陆日志,就能利用用户登陆的频率、输入次数、地理位置等信息,对其进行分析以判断是否存在异地风险登陆、多次暴力破解等异常情况。
记录系统的操作日志, 方便数据恢复和定位操作比如一个医院的病历系统,记录每位患者的就诊情况、诊断结果、治疗方案等信息。当医生误诊或操作失误时,比如开错药、做错手术等,可以根据系统的操作日志进行回滚操作,及时发现问题并进行纠正。同时,系统还可以记录每位医生的操作记录,便于管理人员进行追责和改进工作。
记录系统执行时间, 方便优化程序做数据支撑记录一个程序开始时间, 在结束时也记录一下时间, 从而可以获取到该程序的执行时间. 执行时间过长, 那么需要考虑去如何优化它.
当然, 除了上面列举的一些作用, 日志还有其他重要用途, 大家可以自行探索

三.如何使用日志

对于 Spring Boot 中, 它内置了 SLF4J 框架, 可以直接在程序中进行调用 SLF4J 来打印日志, 并且日志一个门面模式, 何为门面模式呢?

在这举例来说就像找房子一样, SLF4J 在这就充当了这个房屋中介的作用, 而它手下不同房子就是它的实现. 例如大平层( Log4j ) 、小洋房(logback ) 、海景别墅( Java Util Logging ). 某一天你需要租一个房子来装你得东西, 你就去找房屋中介, 房屋中介就会给你介绍上面的几种房屋类型, 你可以自己进行选择. 比如你选择了大平层, 你住腻了可以换一个通过中介在海景别墅, 这样你就可以省去找房子的时间, 想更换只需要通过中介进行更换就可以了
带入到我们的日志中, 中介就是日志的门面, 中介控制的房子就是日志的实现 , 这样有什么好处呢 ? 我们不再需要去关注门面, 托管给别人帮我们做了,只需要去看喜欢那个房子( 用什么日志方式去输出就行 ) 有一天住腻了 ( 这个日志方式出了问题 ) 就可以快速的通过中介在换一个房子( 换一个日志方式 )
, 避免在没有地方可以去( 你所有的日志都用的这个方法去控制, 没有中介那你想要换个房子就需要很长时间去修改 )

了解了日志得门面模式以后, 接下来看看如何自定义实现也给日志

1. 得到日志对象

注意级别根据上述系统日志的启动记录可以发现,所有日志信息都属于同一类别,因此所获取的日志对象必定为类级别的日志对象,而非仅在某个具体方法中实现的方法级别对象。
image.png

注意作用域启动系统日志后,每个日志都会带有其位置信息,即可以清晰看到其所在的包和类名。因此,为避免日志位置混乱,日志对象必须私有化,只能在该类内使用,而不能在其他类中使用。
image.png

注意框架的选择由于我们在使用 SLF4J 作为门面模式时, 去创建日志对象需要通过门面去调用具体的实现方式, 因此创建日志对象时应当选择 SLF4J 下的 Logger
image.png

综上, 最终通过 SLF4J 的 Logger 创建一个 log 对象, 并通过提供的日志工程去调用 getLogger ( 因为是类级别的, 因此此处选择类 的 getLogger 方法 )成功创建一个日志对象

image.pngimage.png

2. 使用 log 对象**image.png

访问路由后在控制台可以看到如下信息 :

PS : 日志信息打印此处和你们默认的不一样, 我在配置文件中设置了默认等级为 debug, 日志系统默认等级为 info, 下面会说这个问题,
此处只关注日志对象输出日志有哪些内容即可

image.png

时间信息、日志等级信息、日志位置信息、日志内容信息. 可以说是非常的齐全日志

四. 日志等级

日志等级用于指示日志消息的重要性或严重程度,开发人员可以设置日志级别以过滤掉不必要的日志消息,同时也可以根据日志级别快速定位和解决日志问题。

常见的日志等级包括:

1.DEBUG:用于调试或开发阶段,产生大量日志;
2.INFO:提示性消息,用于标记应用程序的主要分支和进度;
3.WARN:警告性消息,用于提示可能会导致程序问题或潜在错误的情况;
4.ERROR:标记错误事件,用于记录程序中的错误;
5.FATAL:严重错误,可能导致程序崩溃或无法工作,是最高级别的日志等级。

当设置日志级别时,高级别的日志消息也会同时输出更低级别的所有日志消息,例如设置日志级别为WARN将输出所有的WARN、ERROR和FATAL日志消息。

总之,日志等级是日志记录中非常重要的一个概念,它可以帮助开发人员精确排查和调试日志问题,提高应用程序的可维护性和可读性。

1.trace : 微量级别, 级别最低
2.debug : 需要调试的时候使用, 调试级别
3.info : 普通的打印信息 ( 日志默认的级别 )
4.warn : 警告, 不影响使用, 但是需要注意的问题
4.error : 错误信息, 级别比较高的错误日志信息
6.fatal : 致命的, 因代码异常导致程序执行退出的事件上面就是日志的级别, 但是我们能够操作的日志级别只有前五个, 最后一个致命的日志级别是无法操控的, 当程序错误退出的时候, 系统会自动帮我们打印fatal 级别的日志信息.
从上之下, 级别是越来越高的, 越往下接收的消息越少, 遵守一个原则低级别的无法查看高级别的

image.png

image.png

可以看到, 只能查看到 info、warn 和 error 级别的错误信息, 而 trace 和 debug 是无法查看的, 这是为什么呢 ?当我们把 info 注销掉在看看

image.png
可以看到, 只有 info 不见了, 在把 warn 和 error 注释掉看看
image.png

此时没有任何日志信息, 可以得到结论 日志的默认等级是 info, 哪当我们想查看 trace 和 debug 的日志信息怎么办呢 ?
毕竟调试日志对于写程序来说是很重要的, 可以定位问题所在 ,
下面就介绍一下 Spring Boot 中项目中日志的等级设置

五. 日志级别设定

开发人员可以根据实际需要设置日志级别,从而控制日志输出的内容。通常来说,开发人员应该将日志级别设置为INFO或者以上级别,避免输出过多无用信息。同时,可以根据实际情况将日志级别调整为更高或更低级别,以满足具体的需求。

日志级别的设定是优化日志输出的关键。在开发过程中,合理设定日志级别可以帮助开发人员快速定位、解决程序中的问题。因此,开发人员需要根据实际需求,合理设置日志级别。在 properties 配置文件中,可以使用以下代码来设置日志等级:

# 设置日志记录级别
log4j.rootLogger=INFO

其中,log4j.rootLogger 表示根日志记录器,INFO 表示记录 INFO 级别及以上的日志信息。如果需要记录更详细的日志,可以将 INFO 换成 DEBUG 或 TRACE。

另外,也可以针对特定的包或类进行日志等级的设置,如下所示:

log4j.logger.com.example=DEBUG

其中,com.example 表示需要设置日志等级的包或类名,DEBUG 表示记录 DEBUG 级别及以上的日志信息。或者在配置文件中设定日志级别:完成配置后,我们需要使用 log 方法对程序执行过程中的信息进行记录。在进行观察之前,建议首先打印一下 log 信息,以便了解程序在执行时的日志情况。根据配置文件中的设置,我们可以看到由于默认等级是 debug,因此程序执行过程中 debug 等级的错误日志信息可以被记录下来。然而,如果想查看比 debug 更低等级的trace级别的日志信息的话,就需要将日志等级设置为 trace 了。
另外, 配置文件中除了 root(根记录器 ) 设置为日志等级外, 还有更加详细的日志等级设置, 为特定的包设置日志等级 ,
例如下面这个配置文件中, 设置 com.example 包下的类日志等级为 info, 而 com.example.demo 包下的日志等级为 debug
在这里插入图片描述

六. 日志的存储

日志作为记录系统运行状态和问题的重要组成部分,其存储方式至关重要。为了保证系统日志的完整性和可靠性,需要采用合适的存储方式,通常包括以下几种:

1.文件存储:将日志记录到文件中,便于查阅和分析。可以按照时间、事件等方式进行分类保存,也可以对日志进行压缩和归档处理。

2.数据库存储:将日志记录到数据库中,可以方便的进行查询、分析和统计处理。同时还可以利用数据库的事务机制保证数据的一致性和完整性。

3.日志聚合:将多个日志源的信息聚合到一起,形成一个整体的日志记录。通过对这些日志进行统计和分析,可快速定位问题和进行优化。

不同的存储方式各有优劣,需要根据具体的需求和场景选择合适的方案。无论采用何种方式,都要注意日志的保密性和安全性,在存储和传输过程中采取相应的加密和认证措施,避免信息泄露和攻击。当然, 日志如此重要不仅仅是因为它可以定位问题, 更重要的时候它可以作为数据分析, 想要数据分析肯定不能通过控制台 sout 的方式打印日志,
下次启动就没有了, 因此就必须将日志进行持久化, 下面就来实现日志的持久化操作

在 yml 配置文件中设置. 设置文件路径, 文件的名称可以不写( 写了生成的就是你设置的名称 ), 会自动生成一个名为 spring.log 的文件
在这里插入图片描述
再去运行刚刚的 log 方法, 此时在我刚刚的保存路径底下就生成了这样一个 spring.log 文件
在这里插入图片描述
当我重复去访问这个方法时, 它会重复打印日志, 我们来看看会不会覆盖
在这里插入图片描述
事实上, 它是不会覆盖的, 如果真的覆盖了那才是出大问题了 !

PS 1 : 在文件的保存路径设置中, 如果没有设置路径, 它会在项目底下生成一个你设置的名称的文件
在这里插入图片描述
PS 2 : 在官网中可以看到说明, 当日志文件超过 10MB 大小时, 它会将你后续得日志文件保存在一个新的文件中(
并且它会按照自己的命名规则替你命名和分割日志 ), 但是这个日志文件的大小也是可以去设置的
# 七. 使用Lombok简化日志记录

Lombok是一个Java库,通过注解实现了简化Java代码的编写,包括简化日志记录的编写。在Java应用程序中,日志记录是非常重要的,但是传统的Java日志记录方式通常需要编写大量的冗余代码。Lombok的日志相关注解可以让我们轻松地实现日志记录功能,大大减少了代码量。下面将介绍如何使用Lombok简化日志记录。

1. 添加依赖

首先需要在项目中添加Lombok依赖,具体方式可以在项目的pom.xml文件中添加以下代码:

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
</dependency>

2. 使用注解

使用Lombok实现日志记录功能非常简单,只需要使用@Slf4j注解即可,如下所示:

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TestLog {
    
    public static void main(String[] args) {
        log.debug("debug message");
        log.info("info message");
        log.warn("warn message");
        log.error("error message");
    }
}

@Slf4j注解实际上会自动为我们生成一个名为log的静态变量,在代码中可以直接使用log对象输出日志信息。当然,我们也可以手动定义日志对象,如下所示:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestLog {

    private static final Logger LOGGER = LoggerFactory.getLogger(TestLog.class);

    public static void main(String[] args) {
        LOGGER.debug("debug message");
        LOGGER.info("info message");
        LOGGER.warn("warn message");
        LOGGER.error("error message");
    }
}

这里采用了传统的Java日志记录方式,不过使用了Lombok简化变量定义的代码量。

3. 注意事项

在使用Lombok进行日志记录时,需要注意以下几点:

1.需要在项目中正确添加Lombok依赖。
2.在使用Lombok的@Slf4j注解时,需要保证项目中至少引入了一种日志框架。
3.在使用Lombok的@Data注解时,需要特别注意成员变量的访问权限,避免数据泄露问题。

4. 总结

Lombok的日志相关注解能够很好地简化Java代码的编写,特别是对于Java应用程序中频繁使用的日志记录功能,使用Lombok可以大大减少代码量和开发时间,提高开发效率。在使用Lombok进行日志记录时,需要注意Lombok的使用约定和注意事项,避免引入不必要的麻烦。可以发现,在不同类中实现日志输出时,都需要手动创建日志对象并修改getLogger方法中的类对象,这样操作有些繁琐。因此,lombok提供了一种更加简便的方式来实现日志输出。这个步骤比较简单,只需要手动添加 lombok 依赖即可。2. 增加 @slf4j 注解
在这里插入图片描述
除了 @slf4j 注解, lombok 还提供许多其他的注解, 您可以前往官网进行查看.

关于Spring Boot的文章就分享到这里,另外给大家准备了两个关于【Spring Boot入门到精通】以及【手写Spring Boot源码实现】两套非常干货的笔记,有需要的可以看文章末尾免费领取!

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

【web基础与HTTP协议】

目录 一、Web基础1、域名1.1、域名的概述1.2、域名空间结构1.3、域名注册 2、网页的概念2.1、网页的概述2.2、网址的概述1、URI和URL的区别 二、HTML概述1、HTML 基本标签2、HTML 文件结构如下3、头标签中常用标签4、内容标签中常用标签 三、静态网页与动态网页3.1、目前常用的…

day4--链表内指定区间反转

迭代方法 1. 第m个节点的前一个节点pre和第n个节点&#xff1b; 2. 将第m个节点到第n个节点的链表部分反转&#xff1b; 3. 将pre节点的next指向反转后链表的头节点&#xff0c;将反转后链表的尾节点的next指向n1节点。 /*** struct ListNode {* int val;* struct ListNode…

hive如何实现oracle中复杂的update sql

hive3.1有update语法&#xff0c;但是目前没用还是采用的非事务表&#xff0c;所以我们用其他的办法来解决hive的update问题 简单的update oracle update student set namecclovezbf where id1 hive insert overwrite table student select id, if(id1,cclovezbf,name) n…

【正点原子STM32连载】 第十九章 窗口门狗(WWDG)实验摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第十九…

Unreal Niagara粒子入门2

本次学习一下如何将Niagara参数暴露给蓝图、材质编辑器。 1.暴露参数给蓝图 首先在左侧Parmeters参数面板的User Exposed处创建参数&#xff1a; 然后将参数拖入到想要绑定的粒子字段上&#xff0c;例如这里绑定给粒子发射数&#xff1a; 在调用粒子时&#xff0c;可通过Se…

【Java EE 初阶】网络编程套接字UDP

目录 1.为什么需要网络编程&#xff1f; 2.什么是网络编程&#xff1f; 3.发送端和接收端 4.请求和响应 5.客户端和服务端 6.如何进行网络编程&#xff08;Socket套接字&#xff09; 1.如何进行网络编程 2.TCP与UDP的区别 1.流套接字&#xff1a;使用传输层TCP协议 2.…

5月跳槽会有风险,不跳也会有?

今天讲讲跳槽。 说实话跳槽是为了寻求更好的发展&#xff0c;但在跳槽前我们也不能确定下家就是更好的归宿&#xff0c;这就更加需要我们审慎地去对待&#xff0c;不能盲目跳槽。 其次&#xff0c;我们离职和跳槽&#xff0c;其中的原因很大一部分是目前薪资不符合预期。 那…

Kyligence 客户案例招商银行批发业务分析平台获评金融数字化最佳实践案例

近日&#xff0c;“2023 爱分析金融数字化最佳实践案例”评选结果正式揭晓。Kyligence 携手招商银行申报的“招商银行‘火眼’批发业务分析平台”项目经过领先性、案例创新性、应用成熟度、价值创造等维度综合评选&#xff0c;最终获评“金融数字化最佳实践案例”。 招商银行“…

阿里 P9 推荐的 Spring 领域巅峰之作,直接颠覆了我对 Spring 的认知

写在前面 你第一次接触 spring 框架是在什么时候&#xff1f;相信很多人和我一样&#xff0c;第一次了解 spring 都不是做项目的时候用到&#xff0c;而是在网上看到或者是听到过一个叫做 spring 的框架&#xff0c;这个框架号称完爆之前的 structs 和 structs2&#xff0c;吸…

Jupyter设置指定的python环境

Jupyter设置指定的python环境 Jupyter在虚拟环境中启动 按理说在命令行执行如下命令 conda activate 环境名称激活一个conda环境&#xff0c;再打开jupyter&#xff0c;输入如下命令 jupyter notebook默认的python环境应该是刚刚激活的那个&#xff0c;但是我发现在window上…

git代码回滚是使用reset还是revert

时光不能回退&#xff0c;Git却允许我们改变历史。 想要让Git回退历史&#xff0c;有以下步骤&#xff1a; 使用git log命令&#xff0c;查看分支提交历史&#xff0c;确认需要回退的版本 使用git reset --hard commit_id命令&#xff0c;进行版本回退 使用git push origin命…

不需要策略模式也能避免满屏if/else

满屏if/else java 复制代码 public static void main(String[] args) { int a 1; if(a 1){ System.out.println("执行a1的逻辑"); }else if (a 2){ System.out.println("执行a2的逻辑"); }else if (a 3){ System.out.println("执行a3的逻辑&quo…

基于apache paimon实时数仓全增量一体实时入湖

用例简介 Apache Paimon&#xff08;以下简称 Paimon&#xff09;作为支持实时更新的高性能湖存储&#xff0c;本用例展示了在千万数据规模下使用全量 增量一体化同步 MySQL 订单表到 Paimon明细表、下游计算聚合及持续消费更新的能力。整体流程如下图所示&#xff0c;其中 …

R语言实践——rWCVP:世界维管植物名录的R包

rWCVP&#xff1a;世界维管植物名录的R包 介绍1. 参照github安装与简单例子1.1 安装rWCVP1.2 安装rWCVPdata1.3 github的例子 2. rWCVP原始文献阅读2.1 前言&#xff08;背景&#xff09;2.2 功能概要2.2.1 名称匹配&#xff08;wcvp_match_names(), wcvp_match_exact(), wcvp …

ChatGPT:你真的了解网络安全吗?浅谈攻击防御进行时之网络安全新定义

ChatGPT&#xff1a;你真的了解网络安全吗&#xff1f;浅谈网络安全攻击防御进行时 网络安全新定义总结 ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;美国OpenAI 研发的聊天机器人程序&#xff0c;是人工智能技术驱动…

在字节跳动做了6年测试,5月无情被辞,想给划水的兄弟提个醒

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是6年的工作经验吧。 这6年之间完成了一次…

API接口测试—详情版(拼多多根据ID取商品详情)

一、为什么要做接口测试 做接口测试的原因主要有以下几个方面&#xff1a; 1. 确保接口功能正确性&#xff1a;接口是不同软件系统或者不同模块之间的数据传输和交互的通道&#xff0c;通过接口测试能够确保不同系统或者模块之间传递的信息准确无误&#xff0c;从而保证了整个…

微信小程序点击icon实现分享功能

1.小程序分享功能实现方式 小程序分享功能有两种方式&#xff0c;监听用户点击页面内转发按钮&#xff08; 组件 open-type“share”&#xff09;或右上角菜单“转发”按钮的行为&#xff0c;并自定义转发内容。 使用微信小程序的分享功能需要定义onShareAppMessage(Object obj…

Java基础 变量与数据类型

变量 为什么需要变量 一花一世界&#xff0c;如果把一个程序看做一个世界或一个社会的话&#xff0c;那么变量就是程 序世界的花花草草、万事万物。即&#xff0c;变量是程序中不可或缺的组成单位&#xff0c;最基 本的存储单元。 初识变量 变量的概念 内存中的一个存储区域…

工作几年,涨薪4K遭拒,后一天我就裸辞走了···

19年7月大学毕业&#xff0c;当时学的计算机科学专业。因为考研之后&#xff0c;秋招结束了。也没什么更多的岗位选择&#xff0c;就想着找个工作先干着&#xff0c;刚好有个亲戚在一家大厂公司上班说要招测试&#xff0c;所以就来做测试了。 虽然都是属于计算机大类&#xff0…