赞
踩
日志实际上只是一种按照时间顺序存储记录的数据表或文件它记录了什么时间发生了什么事情。而对分布式数据系统,在许多方面,这是要解决的问题的真正核心。
⽇志是程序的重要组成部分,想象⼀下,如果程序报错了,不让你打开控制台看⽇志,那么你能找到报 错的原因吗? 答案是否定的,写程序不是买彩票,不能完全靠猜,因此⽇志对于我们来说,最主要的⽤途就是排除和 定位问题。
在springboot中当我们运行程序时候,在控制台就会生成一系列的日志文件。日志文件具体有什么用呢?
1.如果程序报错,控制台就会进行报错日志,写着代码第几行出现了问题帮助我们快速的排查定位问题出现在哪里,方便我们快速的解决问题
2.记录用户信息,及时发现用户的不正常行为,比如作为系统后台,如果我们发现某一个账号一直在尝试不同的密码登录,我们可以认定该程序可能存在被盗号的风险,通过日志查看捕捉到这一信息,并且可以尝试封号处理,再比如,发现某一账号一直在不同的地方登录或者一天之内的登陆次数特别多,那么通过日志文件可以查看到,那么也可以认定该账号可能存在风险,可以进行一些处理
3.记录操作信息,在团队开发中,可能由于某些人的误操作,或者恶意操作,对程序造成一些损失,如果很多人都对该程序有操作的权限的话,询问无果的情况下,就可以通过日志文件查看定位责任人,并且日志还记录了操作的过程,可以帮助我们恢复数据
4.记录程序的执行时间,帮助我们分析程序的运行,可以进行程序的优化和分析
以上这些都是⽇志提供的⾮常实⽤的功能
⽇志真实使⽤案例:
关键节点上的关键数据⽇志记录举例:例如,我们学校的教务系统,在注册时候不⽌要在教务系统添加 ⼀条⽤户记录,同时也会给学校论坛添加⼀条⼀模⼀样的⽤户记录,这样做的⽬的是为了实现⼀次注 册,多处使⽤的⽬的。不需要⽤户在两边系统注册了,等于在程序中以极低的成本实现的⽤户数据的同 步,但这样设计有⼀个致命的问题,⽤户在教务系统注册信息的时候,如果论坛挂了,那么⽤户的注册 ⾏为就会失败?因为⽤户在注册的时候需要同步注册到论坛系统,但论坛现在挂了,这个时候怎么办 呢? 最简单的解决⽅案,教务系统在注册的时候,不管论坛是否注册成功,都给⽤户返回成功,那这个时候 如果论坛注册失败了怎么办?⾮常简单,如果注册失败了,记录⼀下⽇志,等论坛恢复正常之后,把⽇ 志给论坛的管理⼈员,让他⼿动将注册失败的⽤户同步到论坛系统,这样就最低成本的解决了问题。这 就是⽇志的重要作⽤。
Spring Boot 项⽬在启动的时候默认就有⽇志输出,如下图所示
首先是spring启动的一个logo,再就是一些info信息,info就是日志等级,下面会总结
通过上述⽇志信息我们能发现以下 3 个问题:
1.spring默认自带日志框架
2.默认情况下,输出的⽇志并⾮是开发者定义和打印的,那开发者怎么在程序中⾃定义打印⽇志呢?
3.⽇志默认是打印在控制台上的,⽽控制台的⽇志是不能被保存的,就类似于sout打印操作一样输出在控制台上的,那么怎么把⽇志永久的保存下来 呢?
开发者⾃定义打印⽇志的实现步骤:
1.在程序中得到⽇志对象。
2.使⽤⽇志对象的相关语法输出要打印的内容。
接下来我们分别来看
- // 1.得到⽇志对象
- private static Logger logger =
- LoggerFactory.getLogger(UserController.class);
⽇志⼯⼚需要将每个类的类型传递进去,这样我们才知道⽇志的归属类,才能更⽅便、更直观的定位 到问题类。
!!!注意:Logger 对象是属于 org.slf4j 包下的,不要导⼊错包。
日志门面:通常对于简单的项目,我们会使用单独的日志门面进行实现日志相关操作,随着开发的进行,会更新迭代使用不同的日志框架,此时若是一开始使用单个日志实现框架,再使用其他日志框架时难以统一与管理,造成日志体系的混乱。此时我们需要借鉴JDBC的思想,为日志系统提供一套门面,通过面向接口规范来进行开发,避免了直接依赖具体的日志框架,可轻松切换不同的日志实现框架并且不需要改动代码,这就是日志门面存在的意义。日志门面就相当于是一个代理,具体指向的日志实现,是完成具体日志工作的。
日志实现:具体的日志功能实现。框架有JUL
、log4j
、log4j2
、logback
⽇志对象的打印⽅法有很多种,我们可以先使⽤ info() ⽅法来输出⽇志,如下代码所示:
- @PostConstruct
- public void UserController() {
- log.error("我是construct的error日志");
- }
- }
具体的实现如图
⽇志的级别就是为了筛选符合⽬标的⽇志信息的。试想⼀下这样的场景,假设你⼀家 2 万⼈公司的⽼ 板,那么每⼈员⼯的⽇常⼯作和琐碎的信息都要反馈给你吗?⼀定不会,因为你根本没有那么多经历。 于是就有了组织架构,⽽组织架构就会分级,有很多的级别设置,老板每天可能只看他的下一级的汇报,日志也是同样如此,当我们设置了日志级别的时候,比如设置日志等级为info,那么就会进行筛选,只会出现打印保存比 info等级高的日志,筛选过滤了比他等级低的日志,因此日志等级可以认为是一个筛选等级(只是方便理解,可以认为是筛选等级)。
fatal:致命的,因为代码异常导致程序退出执⾏的事件,等级最高且为系统级别不受程序员的控制
error:错误信息,级别较⾼的错误⽇志信息;
warn:警告,不影响使⽤,但需要注意的问题;
info:普通的打印信息;
debug:需要调试时候的关键信息打印
trace:微量,少许的意思,级别最低
上述排列就是等级由高到低的顺序进行排列的,等级越高接受的消息越少,这也就是班主任委托课代表,课代表委托组长,组长委托小组长检查作业的例子一样,越往上获取的消息越少
设置日志级别的目的,还有一个用,在最开始时候使用syso打印来记录日志,但是其实不适用syso进行保存日志,首先使用日志的方式更加专业,在不同的操作环境下对日志输出的内容进行控制,syso打印是一定会打印的,而在实际开发中我们在不同生产环境下,比如在调试环境下,我们只需要观察程序会不会报错之类的,因此设置日志级别高一点,在生产环境下,我们要观察所有的程序运行的时间方便做出优化和相应的记录,那么日志的级别就应该低,方便我们记录完整的信息
⽇志级别配置只需要在配置⽂件中设置“logging.level”配置项即可,如下所示
- logging:
- level:
- root: error
配置跟路径的⽇志级别
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- @RequestMapping("/user")
- public class UserController {
- // 1.得到⽇志对象
- private static Logger logger =
- LoggerFactory.getLogger(UserController.class);
- @Value("${server.port}")
- private String port;
- @Value("${spring.datasource.url}")
- private String url;
- @RequestMapping("/sayhi")
- public String sayHi() {
- // 2.使⽤⽇志打印⽇志
- logger.trace("================= trace ===============");
- logger.debug("================= debug ===============");
- logger.info("================= info ===============");
- logger.warn("================= warn ===============");
- logger.error("================= error ===============");
- return "Hi," + url;
- }
- }
以上的⽇志都是输出在控制台上的,然⽽在⽣产环境上咱们需要将⽇志保存下来,以便出现问题之后追 溯问题,把⽇志保存下来的过程就叫做持久化。想要将⽇志进⾏持久化,只需要在配置⽂件中指定⽇志的存储⽬录或者是指定⽇志保存⽂件名之后, Spring Boot 就会将控制台的⽇志写到相应的⽬录或⽂件下了。
配置⽇志⽂件的保存路径:
- # 设置⽇志⽂件的⽬录
- logging:
- file:
- path: D:\home\ruoyi
配置⽇志⽂件的⽂件名:
- # 设置⽇志⽂件的⽂件名
- logging:
- file:
- name: D:\home\ruoyi\spring-1204.log
每次都使⽤ LoggerFactory.getLogger(xxx.class) 很繁琐,且每个类都添加⼀遍,也很麻烦,这⾥有⼀ 种更好⽤的⽇志输出⽅式,使⽤ lombok 来更简单的输出。
1. 添加 lombok 框架⽀持
2. 使⽤ @slf4j 注解输出⽇志
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.20</version>
- <optional>true</optional>
- </dependency>
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- @RequestMapping("/p")
- @Slf4j
- public class PersonController {
- @RequestMapping("/log")
- public void loggerTest() {
- log.error("------------------- error -----------------");
- }
- }
注意:使⽤ @Slf4j 注解,在程序中使⽤ log 对象即可输⼊⽇志,并且只能使⽤ log 对象才能输出,这 是 lombok 提供的对象名。这还是springboot使用中,约定大于配置
lombok 能够打印⽇志的密码就在 target ⽬录⾥⾯,target 为项⽬最终执⾏的代码,查看 target ⽬录如 下:
这是我们的代码
这是target文件中的字节码
Lombok 的作⽤如下图所示:
⽇志是程序中的重要组成部分,使⽤⽇志可以快速的发现和定位问题,Spring Boot 内容了⽇志框架, 默认情况下使⽤的是 info ⽇志级别将⽇志输出到控制台的,我们可以通过 lombok 提供的 @Slf4j 注解 和 log 对象快速的打印⾃定义⽇志。
⽇志包含 6 个级别: trace:微量,少许的意思,级别最低; info:普通的打印信息; debug:需要调试时候的关键信息打印; warn:警告,不影响使⽤,但需要注意的问题; error:错误信息,级别较⾼的错误⽇志信息; fatal:致命的,因为代码异常导致程序退出执⾏的事件。
⽇志级别依次提升,⽽⽇志界别越⾼,收到的⽇志信息也就越少,我们可以通过配置⽇志的保存名称或 保存⽬录来将⽇志永久地保存下来
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。