目录
前言🍭
一、日志的作用🍭
1、日志真实使用案例:🍉
二、日志怎么用🍭
1、自定义日志打印🍉
Ⅰ、在程序中得到日志对象🍓
常见的日志框架说明(了解)🍒
Ⅱ、使用日志对象打印日志 🍓
2、日志的级别🍉
Ⅰ、日志级别有什么用?🍓
Ⅱ、日志级别的分类与使用🍓
Ⅲ、日志级别设置🍓
Ⅳ、System.out.println() VS 日志🍓
3、日志持久化🍉
Ⅰ、配置日志文件的保存路径:🍓
路径:🍒
路径+文件名: 🍒
文件名: 🍒
Ⅱ、进行日志持久化 🍓
Ⅲ、日志是追加or覆盖?🍓
三、更简单的日志输出—lombok🍭
1、添加 lombok 依赖🍉
Ⅰ、旧项目添加新依赖框架 🍓
2、输出日志🍉
3、lombok原理解释🍉
4、lombok 更多注解说明🍉
❤️❤️❤️SSM专栏更新中,各位大佬觉得写得不错,支持一下,感谢了!❤️❤️❤️
Spring + Spring MVC + MyBatis_冷兮雪的博客-CSDN博客
前篇我们 讲完了SpringBoot的配置文件,讲解了为什么学配置文件&配置文件的作用,还有两种配置文件的格式与使用。这篇来讲SpringBoot 日志文件,下面我们一起进入SpringBoot 日志文件的世界!
日志是程序的重要组成部分,想象一下,如果程序报错了,不让你打开控制台看日志,那么你能找到报错的原因吗?
答案是否定的,写程序不是买彩票,不能完全靠猜,因此日志对于我们来说,最主要的用途就是排除和定位问题。
Spring Boot日志文件用于记录应用程序的运行日志。它可以帮助开发人员在应用程序出现问题时进行故障排除和调试。以下是Spring Boot日志文件的几个用途:
所以 Spring Boot日志文件是开发人员在应用程序运行过程中进行故障排除、调试、性能分析和安全审计的重要工具。
比如当我们去百度注册账号时,在注册时候百度不止要在后台添加 一条用户记录,同时也会给百度贴吧添加一条一模一样的用户记录,这样做的目的是为了实现一次注 册,多处使用的目的。不需要用户在两边系统注册了,等于在程序中以极低的成本实现的用户数据的同 步,但这样设计有一个致命的问题,用户在百度注册信息的时候,如果百度贴吧挂了,那么用户的注册 行为就会失败,因为用户在注册的时候需要同步注册到百度系统,但贴吧现在挂了,这个时候怎么办 呢?
最简单的解决方案,百度账号在注册的时候,不管贴吧是否注册成功,都给用户返回成功,如果注册失败了,记录一下日志,等贴吧恢复正常之后,把日志给贴吧的管理人员,让他手动将注册失败的用户同步到贴吧系统,这样就最低成本的解决了问题。这就是日志的重要作用。
Spring Boot 项目在启动的时候默认就有日志输出,如下图所示:
以上内容就是 Spring Boot 输出的控制台日志信息。 通过上述日志信息我们能发现以下 3 个问题:
下面我们一起来找寻这些问题的答案。
在程序中获取日志对象需要使用日志工厂 LoggerFactory:
// 1.得到⽇志对象 private static Logger logger = LoggerFactory.getLogger(UserController.class); //⽇志⼯⼚需要将每个类的类型传递进去,这样我们才知道⽇志的归属类,才能更⽅便、更直观的定位 到问题类。
Logger 对象是属于 org.slf4j 包下的,不要导入错包。
日志对象的打印方法有很多种,我们可以先使用 info() 方法来输出日志,如下代码所示
// 2.使⽤⽇志打印⽇志 @Controller//当前类为控制器 @ResponseBody//返回的是数据,而非页面 public class UserController { private static final Logger logger= LoggerFactory.getLogger(UserController.class); @RequestMapping("Hi") public String sayHi(){ //写日志 // 2.使⽤⽇志打印⽇志 logger.info("--------------要输出⽇志的内容----------------"); return "Hi,Spring Boot"; } }
打印信息 :
控制台打印:
浏览器打印(使用的是生产环境,生产环境设置的端口号为:7777):
日志级别的顺序:
越往上接收到的消息就越少,如设置了 warn 就只能收到 warn、error、fatal 级别的日志了。
下面我们来看一下下面的代码,来更深入了解一下日志的级别:
@Controller//当前类为控制器 @ResponseBody//返回的是数据,而非页面 public class UserController { private static final Logger logger= LoggerFactory.getLogger(UserController.class); @RequestMapping("Hi") public String sayHi(){ //写日志 // 2.使⽤⽇志打印⽇志 logger.trace("我是trace"); logger.debug("我是debug"); logger.info("我是info"); logger.warn("我是warn"); logger.error("我是error"); return "Hi,Spring Boot"; } }
控制台打印:
我们发现只打印了三个,我们不是还打印了trace还有debug吗?
这是因为日志设置的默认级别是info,所以只能打印info级别下面的日志。
日志级别配置只需要在配置文件中设置“logging.level”配置项即可:
#开发模式 #设置默认端口号 server: port: 7777 #设置默认日志等级 logging: level: root: trace
我们设置默认级别为:trace。看控制台打印:
我们看到设置为trace后,我们要求打印都打印了。但设置为trace之后,可能会导致日志文件过大或者打印输出过长,这可能会给查看和分析日志带来一些困难。
为了解决这个问题,可以考虑以下几个方法:
调整日志级别:将日志级别设置为更高的级别,例如将级别从trace调整为debug、info或者warn。这样可以减少不必要的日志输出,只保留关键信息。
筛选日志输出:通过使用日志过滤器或者正则表达式,只打印特定关键字或者模式匹配的日志信息。这样可以减少无关的日志输出,只保留需要的部分。
分割日志文件:设置日志文件大小限制或者定期将日志文件进行分割,可以防止单个日志文件过大。这样可以方便查看和管理日志文件。
使用日志分析工具:使用专门的日志分析工具,可以对大量的日志进行快速搜索、过滤和分析。这样可以更方便地查找和定位问题。
所以在通常,默认 默认级别为info即可,看warn日志和error日志即可。对于warn和error级别的日志消息,你也可以选择查看。
日志级别的设置是特别灵活的,我们还可以针对不同的目录设置不同的日志级别
#开发模式 #设置默认端口号 server: port: 7777 #设置默认日志等级 logging: level: root: info com: example: springboard:info
有人说:我打印可以使用System.out.println()啊,为什么一定要使用日志呢?下面我们来比较一下
灵活性:使用日志框架可以方便地控制日志的输出级别,从而在不同环境中灵活地开启或关闭日志输出。而使用System.out.println()则需要手动添加或删除代码。
可配置性:日志框架可以通过配置文件来设置日志的输出格式、输出位置等信息,而System.out.println()则只能将日志输出到控制台。
性能优化:日志框架会对日志进行缓冲和异步处理,以提高程序的性能。而System.out.println()会直接将日志输出到控制台,可能会对程序的性能造成一定的影响。
可扩展性:使用日志框架可以方便地扩展和替换日志实现,例如切换到其他日志框架或自定义日志输出方式。而使用System.out.println()则需要手动修改代码。
System.out.println() 不能被持久化(可接着看后面便知晓了)。
以上的日志都是输出在控制台上的,然而在生产环境上咱们需要将日志保存下来,以便出现问题之后追溯问题,把日志保存下来的过程就叫做持久化。
想要将日志进行持久化,只需要在配置文件中指定日志的存储目录或者是指定日志保存文件名之后, Spring Boot 就会将控制台的日志写到相应的目录或文件下了。
#开发模式 #设置默认端口号 server: port: 7777 #设置默认日志等级 logging: level: root: error com: example: springbootdemo: info # 设置⽇志⽂件的⽬录 file: path: C:\logs
在C盘创建应该logs文件夹:
我们可以自己定义.log的文件名:
# 设置⽇志⽂件的⽂件名 logging: file: name: C:\logs\spring-1.log
#开发模式 #设置默认端口号 server: port: 7777 #设置默认日志等级 logging: level: root: error com: example: springbootdemo: info # 设置⽇志⽂件的⽬录 file: name: spring-1.log
如果直接指点文件名,那它就会直接在项目文件下直接生成.log文件:
@Controller//当前类为控制器 @ResponseBody//返回的是数据,而非页面 public class UserController { private static final Logger logger= LoggerFactory.getLogger(UserController.class); @RequestMapping("Hi") public String sayHi(){ //写日志 // 2.使⽤⽇志打印⽇志 logger.trace("我是trace"); logger.debug("我是debug"); logger.info("我是info"); logger.warn("我是warn"); logger.error("我是error"); System.out.println("我是System。"); return "Hi,Spring Boot"; } }
运行代码:
打开控制台:
打开logs:
打开这spring.log:
可以发现这和控制台打印的一模一样。但是没有打印 System.out.println(),这是因为日志的持久化只会保存日志信息,其他信息是不会去保存的。
如果我们重新运行代码,这个spring.log里面的内容是被覆盖还是被追加呢?
现在我们重新运行代码,打开spring.log看看:
可以看到日志的内容是追加的,所以不用担心日志会被覆盖或者消失,但是如果一直把它放在一个.log文件里面,那它越来越大,这怎么办啊?这时候就应该去查看一下官方文档:
官方文档
可以看到,日志持久化文件最大为10M,当超过10M是它会重新创建一个新的持久化文件。还有其他持久化设置,感兴趣的可以去了解一下。
每次都使用 LoggerFactory.getLogger(xxx.class) 很繁琐,且每个类都添加⼀遍,也很麻烦,这里讲⼀ 种更好用的日志输出方式,使用 lombok 来更简单的输出。
org.projectlombok lombok1.18.20 true
但是我们在创建Spring Boot时就已经导入了Lombok框架了:
pom.xml:
安装EditStarters:
然后在pom.xml里面右键选择 Generate
选择Edit Starters
点击OK
添加需要添加的依赖:
添加完成之后,重新reload就行了。
package com.example.springbootdemo; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller//当前类为控制器 @ResponseBody//返回的是数据,而非页面 @Slf4j public class ArticleController { @RequestMapping("art") public String sayHi(){ //写日志 // 2.使⽤⽇志打印⽇志 log.trace("我是trace"); log.debug("我是debug"); log.info("我是info"); log.warn("我是warn"); log.error("我是error"); return "Hi,Article"; } }
注意:使用 @Slf4j 注解,在程序中使用 log 对象即可输入日志,并且只能用 log 对象才能输出这是 lombok 提供的对象名
控制台打印:
lombok 能够打印日志的密码就在 target 目录里面,target 为项目最终执行的代码,查看 target 目录。如下:
自己所写的代码:
在target目录中,您可以找到编译后的项目代码
可以看到lombok会直接给你生成注释对应的代码 ,这就特别省事了。
Java 程序的运行原理
Lombok 的作⽤如下图所示:
基本注解
注解 | 作用 |
@Getter | 自动添加getter方法 |
@Setter | 自动添加setter方法 |
@ToString | 自动添加toString 方法 |
@EqualsAndHashCode | 自动添加equals 和hashCode 方法 |
@NoArgsConstructor | 自动添加无参构造方法 |
@AllArgsConstructor | 自动添加全属性构造方法,顺序按照属性的定义顺序 |
@NonNull | 属性不能为null |
@RequiredArgsConstructor | 自动添加必需属性的构造方法,final +@NonNull的属性为必需 |
组合注解
注解 | 作用 |
@Data | @Getter + @Setter +@ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor |
⽇志注解
注解 | 作⽤ |
@Slf4j | 添加一个名为 log 的日志,使用slf4j |