spring boot 日志

news2024/9/23 20:11:23

目录

什么是日志呢 ? 日志有什么作用呢?

什么是日志呢 ?

日志的作用是什么呢 ?

我们需要学会日志的什么 ?

自定义输出日志

日志持久化

为什么要将日志持久化呢?

如何进行日志的持久化

设置日志级别

日志级别有什么用呢 ?

日志都有哪些级别呢 ?

如何设置日志级别?

多种环境下日志级别设置

使用注解自定义输出日志

lombox实现原理


什么是日志呢 ? 日志有什么作用呢?

什么是日志呢 ?

就像我们平时写的代码,运行结果输出到控制台上,控制台显示的其实就是日志.比如下面的

虽然这是日志,但是并不能替代我们项目中的日志. 如下就是我们项目中的日志

这就是我们项目中的日志,日志中包含许多信息,可以帮助我们排查和定位问题.

日志的作用是什么呢 ?

我们通过日志可以帮助我们定位和排查问题,这是非常重要的,在日常开发中,有的时候只看代码并不能看出问题,看下日志,与我们的需求是否出现差异,在程序运行的时候是否出现异常等等...

处理定位和排查问题之外,还可以实现一些功能 :

  • 可以记录用户的登陆日志; 可以发现用户是否是正常登录状态的,如果有人尝试暴力破解该用户密码就可以被发现,程序猿也可以及时去处理(方便分析用户是正常登录还是恶意破解用户)
  • 可以记录系统的操作日志, 可以看数据恢复情况 以及 定位具体是谁操作的.(方便数据恢复和定位操作人)
  • 记录程序的执行时间,; 比如这次程序执行了5min,但正常只需3分钟,程序猿就可以根据程序执行时间做出优化和调整.(方便为以后优化程序提供数据支持)

我们需要学会日志的什么 ?

我们再来看一下我们spring boot 的项目日志. 我分别介绍一下日志都包含哪些内容.

2022-12-26T08:54:20.859+08:00  INFO 6200 --- [           main] o.s.b.d.f.s.MyApplication                : Starting MyApplication using Java 17 with PID 6200 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2022-12-26T08:54:20.872+08:00  INFO 6200 --- [           main] o.s.b.d.f.s.MyApplication                : No active profile set, falling back to 1 default profile: "default"
2022-12-26T08:54:22.892+08:00  INFO 6200 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-12-26T08:54:22.917+08:00  INFO 6200 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-12-26T08:54:22.917+08:00  INFO 6200 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.4]
2022-12-26T08:54:23.189+08:00  INFO 6200 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-12-26T08:54:23.192+08:00  INFO 6200 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2200 ms
2022-12-26T08:54:23.797+08:00  INFO 6200 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-12-26T08:54:23.810+08:00  INFO 6200 --- [           main] o.s.b.d.f.s.MyApplication                : Started MyApplication in 4.539 seconds (process running for 5.555)
  • Date和时Time:精确到毫秒,易于排序。
  • 日志级别: ERROR, WARN, INFO, DEBUG, 或 TRACE.
  • 进程ID。
  • 一个 --- 分隔符,以区分实际日志信息的开始。
  • 线程名称:包含在方括号中(对于控制台输出可能会被截断)。
  • 记录器名称:这通常是源类的名称(通常是缩写)。
  • 日志消息。

我们springboot 项目日志包含很多内容,所以我们也说那种System.out.println()是替代不了我们springboot项目的日志. 同时System.out.println() 也无法替代不同环境下的日志筛选

在日常开发中我们要学会

  • 输出自定义日志信息

我们也可以在日志信息中根据我们的需求输出我们自己定义的内容,方便排查出问题.

  • 将日志持久化

有些时候,开发人员,测试人员.. 不能一直盯着机器看哪里出现了问题,需要将日志打印出来,进行排查问题,因为输出在控制台上的日志,一关闭项目就没有了.

  • 通过设置日志的级别来筛选和控制日志的内容

由于日志的需求不同,我们需要通过设置日志的级别来控制日志的输出,比如开发环境我们需要很详细的信息进行排查问题,而对于生产环境下,为了保证产品的性能和安全性就会输入尽量少的日志,通过日志的级别就可以筛选日志,完成我们对不同环境下的需求.

自定义输出日志

我们自定义输出日志需要2步

  • 得到日志对象
  • 调用日志对象对应方法,输出日志自定义内容

1.得到日志对象

//得到日志对象-->使用slf4j
private static Logger log = LoggerFactory.getLogger(TestLogging.class);

2..调用日志对象对应方法,输出日志自定义内容

@RestController
public class TestLogging {

    //得到日志对象-->使用slf4j
    private static Logger log = LoggerFactory.getLogger(TestLogging.class);

    @RequestMapping("/logging")
    public void sayHi(){
        log.trace("hi trace~~~");
        log.debug("hi debug~~~");
        log.info ("hi info ~~~");
        log.warn ("hi warn ~~~");
        log.error("hi error~~~");
    }
}

日志持久化

我们知道控制台输出的内容,当我们重新打开项目,内容就消失了.所谓日志持久化,就是将程序输出的日志保存到我们电脑的硬盘中就可以了.

为什么要将日志持久化呢?

你想啊,开发人员,测试人员.. 不能一直盯着项目看哪里出现了异常,于是我们就可以把日志进行保存起来,当出现了问题,我们在去排查保存的日志,看哪里出现了问题,再去调整.

如何进行日志的持久化

我们需要在配置文件进行配置, 我们配置保存的文件的名称就可以将其日志保存到文件中

logging.file.name

logging.file.path

Example

Description

(none)

(none)

只在控制台进行记录。

指定文件

(none)

my.log

写入指定的日志文件。 名称可以是一个确切的位置,也可以是与当前目录的相对位置。

(none)

指定目录

/var/log

将 spring.log 写到指定目录。 名称可以是一个确切的位置,也可以是与当前目录的相对位置。

比如我们配置 文件名称为springboot.log(根据名称配置)

#  进行日志持久化 将日志内容保存到 spring-boot.log文件下
logging:
  file:
    name: spring-boot.log

还可以根据路径进行配置

当配置了就会在idea显示出相应配置的文件.

日志内容就会保存该spring-boot.log文件下,如果日志找不到了,就可以在这里查看日志,进行排查问题

但是有的时候,你会发现怎么也不显示出你配置的日志文件,这时候你就可以打开当前项目目录,然后将target目录删除掉,在重新启动项目.->原因是idea可能会做一些优化,发现代码与上次启动的一样,就加载上次的项目.

对于日志这块又有两个问题,

这个日志每次是在上次的基础上是追加还是覆盖呢 ?

我们可以演示一下.

所以说,日志是在上次的基础上,继续追加,不会使得日志丢失/覆盖的情况

日志太大会怎么办 ?

我们再来根据上面继续做演示

当我一直输出日志

日志文件在达到10MB时就会轮换,与控制台输出一样,默认情况下会记录 ERRORWARN 级和 INFO 级别的信息.

当日志比较大的时候会自动分割,分割成多个文件,在原有的文件上,加上时间,分割成多个

设置日志级别

日志级别有什么用呢 ?

  • 通过设置日志的级别来筛选和控制日志的内容以及不同环境下需求不一样,开的日志也不一样

由于日志的需求不同,我们需要通过设置日志的级别来控制日志的输出,比如开发环境我们需要很详细的信息进行排查问题,而对于生产环境下,为了保证产品的性能和安全性就会输入尽量少的日志,通过日志的级别就可以筛选日志,完成我们对不同环境下的需求.

日志都有哪些级别呢 ?

  • trace : 级别最低
  • debug : 需要调试的时候关键信息的打印.
  • info : 普通的打印信息 (默认的日志级别)
  • warn : 警告,不影响使用,但需要注意的问题
  • error: 错误的信息,级别较高的错误日志信息;
  • fatal:致命的,因为代码异常导致程序退出执行的事件

fatal 只会在真正出现异常导致程序退出的时候的时候,fatal日志才会发生,

这些日志自上而下,日志级别越来越高,当设置了一个日志级别,日志只能看见大于等于该日志级别的日志.

比如 : 当你设置日志级别为warn,你就只能看见warn,error日志级别的日志

再比如,当你设置日志级别为info的时候,你就能看见大于等于info级别的日志,info,warn,error

我们可以来打印一下看一下对应的日志

@RestController
public class TestLogging {
    //得到日志对象-->使用slf4j
    private static Logger log = LoggerFactory.getLogger(TestLogging.class);

    @RequestMapping("/logging")
    public void sayHi(){
        log.trace("hi trace~~~");
        log.debug("hi debug~~~");
        log.info ("hi info ~~~");
        log.warn ("hi warn ~~~");
        log.error("hi error~~~");
    }
}

从这里能看出来,能够打印3条信息,info,warn,error.

那为啥debug,trace,fatal打印不出来呢 ?

首先debug和trace打印不出来是因为日志级别的问题,因为debug和trace的日志级别比info低所以不会打印,而fatal不会打印,只会在真正出现异常导致程序退出的时候的时候,fatal日志才会发生,

如何设置日志级别?

# 设置日志级别-->设置root目录下的日志级别为warn
logging:
  level:
    root: warn

这样当我在启动的时候,就只能看见一个图标,因为启动默认没有warn级别的日志.

当实现自己打印的时候就会看到大于等于warn的级别,所以就会看到日志级别为warn,error.

我们也可以自定义目录进行设置

logging:
  level:
    root: warn
    com:
      example:
        demo: debug

比如像上面的配置,我配置了com.example.demo目录下的日志级别为debug,同时root目录(根目录)的日志级别为warn,他们是同时生效的.

多种环境下日志级别设置

我们同样也可以进行多环境下的日志级别,比如在生产环境下,我就需要程序性能高一些避免一些冗余的日志,就会设置日志级别高一些,而在开发环境下我就需要看一些调试信息来帮助我们排查信息就需要设置日志级别低一些.

举一个例子,我来进行配置:

使用注解自定义输出日志

要想使用注解来输出日志我们要借助lombok,所以我们先要在pom.xml中引入依赖

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.20</version>
  <optional>true</optional>
</dependency>

我们也可以使用插件引入

当我们引入完依赖之后就可以使用一个注解 为 @Slf4j

我来演示一下 :

lombox实现原理

所以我们可以得出@Slf4j是在编译期间生效的,在编译器将.java文件变成.class期间,就把注解变成了功能代码.

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

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

相关文章

十二、Express接口编写 —— 跨域问题

在前面的HTTP模块内容内容当中讲到这个跨域的问题&#xff0c;跨域就涉及到浏览器的同源策略&#xff0c;跨域只出现在浏览器当中&#xff0c;在浏览器当中去执行脚本的时候会进行一个同源检测&#xff0c;只有是同源的脚本才会被浏览器执行&#xff0c;不同源就是跨域&#xf…

MySQL高级 SQL优化【order bygroup by优化】

目录 1&#xff1a;SQL优化 1.1&#xff1a;order by优化 A. 数据准备 B. 执行排序SQL C. 创建索引 D. 创建索引后&#xff0c;根据age, phone进行升序排序 E. 创建索引后&#xff0c;根据age, phone进行降序排序 F. 根据phone&#xff0c;age进行升序排序&#xff…

STM32MP157驱动开发——Linux 网络设备驱动

STM32MP157驱动开发——Linux 网络设备驱动一、简介STM32MP1 GMAC 接口简介YT8511C 详解二、驱动开发1.网络外设的设备树2.设备驱动三、测试网速测试参考文章&#xff1a;【正点原子】I.MX6U嵌入式Linux驱动开发——Linux 网络驱动 一、简介 网络驱动是 linux 驱动三巨头之一&…

[C语言]三种方法实现n的k次方(递归/调用math库函数/实现pow函数)[含递归图解说明]

目录 1.调用math库函数中的pow函数实现n的k次方 2.创造pow函数实现n的k次方 3.递归实现n的k次方&#xff08;含图解&#xff09; 1.调用math库函数中的pow函数实现n的k次方 pow函数的功能&#xff1a;计算n的k次幂 pow格式&#xff1a;pow(n,k) #include <stdio.h>#in…

@NotEmpty、@NotBlank、@NotNull 区别和使用

这种注解通常使用场景在前端发送过来的数据&#xff0c;先进行校验处理&#xff0c;在进行逻辑判断的&#xff0c;所以在进行校验处理的时候&#xff0c;我们通常会使用这三种注解来进行判断传过来的值 1NotNull 适用于基本数据类型(Integer&#xff0c;Long&#xff0c;Doubl…

回收租赁商城系统功能拆解01讲-产品架构

回收租赁系统适用于物品回收、物品租赁、二手买卖交易等三大场景。 可以快速帮助企业搭建类似闲鱼回收/爱回收/爱租机/人人租等回收租赁商城。 回收租赁系统支持智能评估回收价格&#xff0c;后台调整最终回收价&#xff0c;用户同意回收后系统即刻放款&#xff0c;用户微信零…

【谷粒商城基础篇】基础环境搭建

谷粒商城笔记合集 分布式基础篇分布式高级篇高可用集群篇简介&环境搭建项目简介与分布式概念&#xff08;第一、二章&#xff09;基础环境搭建&#xff08;第三章&#xff09;整合SpringCloud整合SpringCloud、SpringCloud alibaba&#xff08;第四、五章&#xff09;前端知…

关于yum源的总结

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; 目录1 相关概念1.1 rpm与yum1.2 yum源与repo文件2 yum源的种类2.1 官方源2.…

【HTML】耗时一下午,整理出了一个精美的响应式登陆注册表单(附源码)

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…

【OpenDDS开发指南V3.20】第八章:opendds_idl

opendds_idl是构建opendds和opendds应用程序过程中使用的代码生成器之一。 它可以用多种不同的方式定制如何从IDL文件生成源代码。 有关默认使用模式的概述,请参见第2.1.2节。 OpenDDS IDL编译器是使用位于$DDS_ROOT/bin/(PATH上)的OpenDDS_IDL可执行文件调用的。 它解析…

SpringBoot+RabbitMQ(官方案例)

在线文档项目结构 1.源码克隆&#xff1a;git clone https://github.com/spring-guides/gs-messaging-rabbitmq.git 2.包含两个项目initial和complete&#xff0c;initial可以根据文档练习完善&#xff0c;complete是完整项目 3.功能描述&#xff1a;构建应用程序&#xff0c;S…

inventor(2):设置单位,显示完整工具区/功能区,创建分割面

好久没用inventor了&#xff0c;记录一些重新学习的基本操作 文章目录1. inventor设置单位为cm2. inventor显示完整工具区/功能区3. inventor创建分割面1. inventor设置单位为cm inventor默认单位为in(英尺)&#xff0c;国内常用习惯为cm 一次点击&#xff1a;工具–选项–文档…

这篇文章会让你熟悉文件的各种操作,让你对文件的认识更加深入【c语言】

文章目录为什么使用文件什么是文件文件名文件的打开和关闭文件指针文件的顺序读写fgetcfputcfgetsfprintffscanffwritefread对比一组函数sprintfsscanf文件的随机读写fseekftellrewind文本文件和二进制文件文件读取结束的判定文件缓冲区为什么使用文件 把数据存放在磁盘文件、存…

2022 SuperMap开发者大会全议程公布,16个专场快来pick

2022年10月12日-14日&#xff0c;2022 SuperMap开发者大会(2022 SuperMap Developer Conference,简称“SDC 2022”)将在线举办。3天时间&#xff0c;16场专题论坛&#xff0c;聚焦GIS前沿技术和热点应用领域开发&#xff0c;分享50场开发实战报告&#xff0c;面向不同应用场景&…

基于小程序语法的跨端开发平台大盘点

2022年12月18日&#xff0c;微信推出了“Donut”开发平台&#xff0c;目前已经开始限时免费公测。这款跨端开发平台与Flutter、React Native、Taro等跨端框架最大的不同是&#xff1a;跨端的能力是基于小程序原生语法进行转译。这背后不得不让人联想到此次开发平台的推出&#…

P1046 [NOIP2005 普及组] 陶陶摘苹果————C++

文章目录题目[NOIP2005 普及组] 陶陶摘苹果题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示解题思路Code运行结果题目 [NOIP2005 普及组] 陶陶摘苹果 题目描述 陶陶家的院子里有一棵苹果树&#xff0c;每到秋天树上就会结出 101010 个苹果。苹果成熟的时候&…

实验十一、多级放大电路的参数设置

一、题目 利用 Multism 为图1所示电路选择电路参数&#xff0c;使之正常工作&#xff0c;并测试 QQQ 点、电压放大倍数和输入电阻。 图1多级放大电路图1\,多级放大电路图1多级放大电路 二、仿真电路 在Multism环境下搭建图1所示电路&#xff0c;选择电路参数&#xff0c;如图…

【谷粒商城基础篇】商品服务开发:基础概念、三级分类

谷粒商城笔记合集 分布式基础篇分布式高级篇高可用集群篇简介&环境搭建项目简介与分布式概念&#xff08;第一、二章&#xff09;基础环境搭建&#xff08;第三章&#xff09;整合SpringCloud整合SpringCloud、SpringCloud alibaba&#xff08;第四、五章&#xff09;前端知…

再快一点?动态内容如何加速

未来已来&#xff0c;只是不均衡地分布在当下 大家好&#xff0c;我是菜农&#xff0c;欢迎来到我的频道。 近年来 Web 3 的概念在程序员的小圈子也几乎是人尽皆知了。功能再强&#xff0c;噱头再足&#xff0c;但是如果访问速度没有跟上&#xff0c;一起都是浮云。哪怕拿现在…

封装和解封装、跨层封装

封装和解封装 我们一般把数据从应用层开始到数据链路层的加工过程称为封装&#xff0c;反过程称为解封装 封装 — 将每一层最重要的数据添加到原始数据当中&#xff0c;来实现这一层的功能。 应用层 — 应用需要进行封装&#xff0c;但是&#xff0c;封装方式取决于不同的应用…