SpringBoot系列(三)----某程序猿竟然因为“日志”问题一夜秃头
某程序猿竟然因为“日志”问题一夜秃头。这是道德的沦丧还是因为什么。。。。
在一个夜深人静的凌晨两点。一个兢兢业业的程序猿–小张,正在面对着电脑敲着键盘。他正在开发一个公司发不下来的大型系统。由于这个系统有点大,小张每次为了调试或者测试方面,他都喜欢使用System.out.println("");
将一些关键数据打印在控制台上,以方便查看。
经过一段时间,小张以掉数不胜数的头发为代价,终于把系统开发完了。然而,有一天,老板跑过来跟小张说:“小张啊。你这个系统里面的System.out.println("");
是不是有点多了,你把他给我去掉吧。”没办法,小张为了保住饭碗,只能在老板的淫威之下把这个System.out.println("");
去掉。
小张刚把System.out.println("");
去掉,老板又跑过来说:“我觉得这个输出的还不错,我们能够通过控制台来了解项目的运行状况。” 小张当时心里把老板的家人都问候了一遍。。。。
小张抽了根烟冷静了一下。想到,我干脆直接写在一个文件不就好了吗,方便以后控制。小张想,难道又要去该System.out.println("");
了吗?不不不,太麻烦了,小张就想,我干脆直接写个框架来记录系统的信息不就好了吗。说干就干。
然后又是一段秃头的日子。小张终于把这个框架给写好了。给它命名为:zhanglogging.jar
。这个框架表现的还不错,小张对这个框架很满意。但是天有不测风云,随着时代的进步,小张觉得这个框架的功能有点简陋了,已经跟不上时代的脚步了。小张突然想到一些高大上的功能,什么异步模式、自动归档,将每天的日志放到一个文件里边,以天来分类。等等等…
接下来还是一段掉发的日子,还别说,小张凭借过硬的技术,终于把第二代日志框架给开发出来了,给它命名为:zhanglogging-good.jar
。但是小张的头发也越来越少。没过几天的美好生活,小张面临的问题又来了。小张写的那个新框架,里面的API或者一些设计可能跟之前写的老框架有点不一样了。那怎么办呢?只能将以前那个老框架卸下,换上新的框架,重新修改之前相关的API,又完善了一些功能;最终,一个完美的框架问世了,小张将之命名为:zhanglogging-prefect.jar;
。
但是问题又来了,每次换框架的时候都要改代码,太麻烦了。小张突然想到了一种模式。想到了JDBC跟数据库驱动的关系。现在我们写数据库都是面向接口编程,我们只需要把数据库的实现放进去就行了。小张说,那我的这个框架我为什么不这么设计呢?说干就干。
小张为所有的日志框架写了一个统一的接口层,就叫做日志门面(日志的抽象层),给它命名为:zhanglogging-abstract.jar
,以后进行编码的时候,只面向zhanglogging-abstract.jar
进行编程就行了,想要用哪个日志框架只需要给项目中导入具体的日志实现就行了。之前的日志框架都是实现的抽象层。小张为了公司真的是操碎了心,头发也越来越少,为小张来个一键三连吧。
接下来我们来进入今天的主题:
文章目录
- SpringBoot日志框架选择
- SLF4j使用
- 如何在系统中使用SLF4j
- 遗留问题
- SpringBoot日志关系
- 总结:
- 日志使用
- 指定配置
- 切换日志框架
SpringBoot日志框架选择
开发中存在非常多的日志框架,JUL(java.util.logging),JCL(Apche Commons Logging),Log4j, Log4j2,Logback,SLF4j,jboss-logging等。
日志门面 (日志的抽象层) | 日志实现 |
---|---|
JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for Java) jboss-logging | Log4j JUL(java.util.logging) Log4j2 Logback |
- 使用SpringBoot的日志框架,也就是说我们需要一个抽象层和一个实现层,SpringBoot选用
SLF4j
作为抽象层,logback
作为实现层。这里要说一下的是,SpringBoot底层是Spring框架,Spring框架默认的是JCL作为抽象层。
SLF4j使用
如何在系统中使用SLF4j
(我们创建新项目中已经帮我们导入了slf4j和logback
)如何在系统中使用SLF4j?以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法。
- SLF4 官方给出了简单示例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class HelloWorld {public static void main(String[] args) {Logger logger = LoggerFactory.getLogger(HelloWorld.class);logger.info("Hello World");}
}
- 下图是 SLF4J 结合各种日志框架的官方示例,从图中可以清晰的看出 SLF4J API 永远作为日志的门面,直接应用与应用程序中。slf4j官网用户手册
每一个日志的实现框架都有自己的配置文件。使用slf4j以后,配置文件还是做成日志实现框架自己本身的配置文件;
遗留问题
我们想要写一个SpringBoot项目,日志框架组合我们打算使用Slf4j+logback
,但是项目中集成了Spring,Hibernate,MyBatis等等组件依赖,这个时候会有一个问题,就是我们集成的组件框架中存在自己的日志框架,比如Spring自带commons-logging、Hibernate(jboss-logging)
等等,那么这个时候,我们的项目里面就像一个日志框架的大杂烩一样,非常的乱,那么我们就需要给我们项目中日志框架做统一,也就是说,不管我依赖的组件自带了什么日志框架,我只要配置我的Slf4j+logback
就可以了。
来看看官方文档
我们需要分别引入我们组件日志的覆盖层,因为我们想要去除组件中的日志,不可能跑去删除组件的日志框架包,这样会导致组件崩溃,底层源码都被该了还不崩溃,所以我们在删除其他组件的日志框架jar包的时候,需要导入一层覆盖层jar包,这个jar中依旧有原来组件的日志框架的API,组件运行就不会报错,就相当于多做了一层适配,我们调用Slf4j+logback
,然后通过这层适配层调用各组件的日志框架。
如何让系统中所有的日志都统一到slf4j;
1、将系统中其他日志框架先排除出去;
2、用中间包来替换原有的日志框架;
3、我们导入slf4j其他的实现
SpringBoot日志关系
- 新项目中的
pom.xm
文件中的内容自动引入的内容 - pom.xml中引入了starter启动器,其实每个启动器都会引入大量的依赖,那么我们怎么查看呢,如下图
- 双击进入到
spring-boot-starter-logging
中,可以看到如下
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId><version>2.4.3</version><scope>compile</scope></dependency>
总结:
- SpringBoot底层也是使用
slf4j+logback
的方式进行日志记录 - SpringBoot也把其他的日志都替换成了slf4j;
- 中间替换包
- 如果我们要引入其他框架。一定要把这个框架的默认日志依赖移除掉。Spring框架用的是commons-logging;
- SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架的依赖的日志框架移除掉。
日志使用
当我们直接运行新建项目的测试类,我们发现SpringBoot是帮我们配置了日志的
- 修改测试类:
@SpringBootTest
class SpringbootLoggingApplicationTests {//记录器Logger logger = LoggerFactory.getLogger(getClass());@Testvoid contextLoads() {//trace<debug<info<warn<errorlogger.trace("这是trace日志");logger.debug("这是debug日志");logger.info("这是info日志");logger.warn("这是warn日志");logger.error("这是error日志");}
}
在新版的idea中实例化Logger时
Logger logger=LoggerFactory.getLogger(getClass());
会自动导入
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
需要手动替换为
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
日志的级别:
- 由低到高
trace<debug<info<warn<error
可以调整输出的日志级别; - 日志就只会在这个级别以后的高级别生效
- SpringBoot默认给我们使用的是
info
级别的,没有指定级别的就用SpringBoot默认规定的级别;也就是说info是我们的root级别
可以看到只输出了info及以上的级别。
- 在主配置文件中修改,如下
logging.level.com.cz=trace
意思就是我们cz包下所有的类都调成
trace
级别
- 继续修改配置文件的内容,然后我会逐一讲解。
logging.level.com.cz=trace#当前项目下生成springboot.log日志
logging.file.name=springboot.log# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
#logging.file.path=/spring/log# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
logging.file.name
指定日志生成到某个文件
logging.pattern.console
- 后面的
%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
是我们自己指定的格式。
- 后面的
日志输出格式:
%d
:表示日期时间,%thread
:表示线程名,%-5level
:级别从左显示5个字符宽度%logger{50}
:表示logger名字最长50个字符,否则按照句点分割。%msg
:日志消息,%n
:是换行符
指定配置
如果我们还需要使用异步日志等功能的话,那么我们可能需要专门进行编写日志的配置文件。详细的看官方日志配置文件说明
- 给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了
Logging System | Customization |
---|---|
Logback |
logback-spring.xml , logback-spring.groovy , logback.xml or logback.groovy
|
Log4j2 |
log4j2-spring.xml or log4j2.xml
|
JDK (Java Util Logging) |
logging.properties
|
我们可以创建一个logback.xml放在resources目录下,里面写着我们日志配置的相关内容,直接创建就可以了,不需要配置什么,SpringBoot就会自动识别
logback.xml
:直接就被日志框架识别了;
logback-spring.xml
:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能
<springProfile name="staging"><!-- configuration to be enabled when the "staging" profile is active -->可以指定某段配置只在某个环境下生效
</springProfile>
如:
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"><!--日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度%logger{50} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,%n是换行符--><layout class="ch.qos.logback.classic.PatternLayout"><springProfile name="dev"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern></springProfile><springProfile name="!dev"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern></springProfile></layout></appender>
如果使用logback.xml
作为日志配置文件,还要使用profile功能,会有以下错误
no applicable action for [springProfile]
切换日志框架
但是不建议切换,人家经过多年的测试才有了现在的日志框架,下面东西看看就好了。
然后在依赖中就会被排除掉,这个时候我们只要在pom.xml中引入我们想要换的那个日志实现层就可以了
SpringBoot系列(三)----某程序猿竟然因为“日志”问题一夜秃头相关推荐
- 【j360-boot】Spring-boot系列三(崩溃模式,不是你崩就是电脑崩)
2019独角兽企业重金招聘Python工程师标准>>> j360-boot spring-boot入门工程之j360-boot:(欢迎star.fork) https://githu ...
- 毕业之际,而我也快了-------一位准大三的程序猿
活动地址:毕业季·进击的技术er 大二已经过去 自己学习经历从大一到大二,让自己学习到什么? 本人现在是个准大三的物联网工程技术专业学生,大二专业课有单片机.zigbee无线传感器.java.嵌入式L ...
- 一个三本程序猿的大厂逆袭之路
作者 | 神技圈子 来源 | CSDN 博客 外包公司的艰苦岁月 一哥们这里暂且称他为A君,毕业于东北一个三本学校,出生于一个西南地区贫困的小村庄.由于负担不起高昂的学费差点不能上学,最后只得到处找身 ...
- 一名奔三的程序猿的困惑
一名在IT行业做了3年半的程序员,在他即将奔三的时候在论坛上写了下面这段话: "下个月就奔三了,有时在编程的时候会感到心力交瘁,失去热情.另外也担心如果一直在做技术,到了30以后会不会真的很 ...
- 惊!十二星座程序猿竟然这样写代码
摘要: 水瓶座 大概只有水瓶座的程序猿可以做到代码神秘到无人能解. 水瓶座,属于风系星座.常被称为"天才星座"或"未来星座".他们较着重于精神层次的提升,是很好 ...
- 从零开始搭建SpringBoot项目(三)——小程序Uni-app项目搭建(详细教程和实战)
前情回顾 从零开始搭建SpringBoot项目(一)--开发环境搭建 从零开始搭建SpringBoot项目(二)--Swagger接口测试平台搭建 目录 前情回顾 一.前置条件 二.本篇介绍 三.获取 ...
- SpringBoot系列三:SpringBoot基本概念(统一父 pom 管理、SpringBoot 代码测试、启动注解分析、配置访问路径、使用内置对象、项目打包发布)...
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.了解SpringBoot的基本概念 2.具体内容 在之前所建立的 SpringBoot 项目只是根据官方文档实现的一个基础程 ...
- springboot系列(三十一):如何实现excel模板导出成pdf文件?这你得会 | 超级详细,建议收藏
- 漫谈程序猿系列:怎么告别“混日子”
我在"漫谈程序猿系列:咦,你也在混日子啊"一文中描写叙述了一种混日子的现状,有朋友说该文仅仅提到了设置目标告别混日子而没有展开论述"怎样设立目标"." ...
最新文章
- 用聚类方法结合卷积网络,实现无监督端到端图像分类
- Linux系统下活用History命令
- poj3352(强连通分量)
- Bash,Vim,gdbgit常用命令
- 大数据教程(13.6)sqoop使用教程
- Adobe pixel Bender toolkit
- two sum 3道题
- 据说,80%的人没有真正理解了Spring的依赖注入
- 年底各类年会邀请函也要美美的设计
- vmware esxi 4.0 上安装postfix,mailx发送邮件
- HTML实现简单注册页面
- acunetix导出html,关于Acunetix v11 WebUI下不得不说的事情!
- 主板检测卡c5_主板检测卡代码(常见)及解决方法
- 仓库管理软件中的账套是什么意思
- Javascript验证身份证号码:正则表达式
- matlab保存nii_Matlab实现NIfTI(ANALYZE)核磁共振图像读写
- WSL关闭与windows的互交互(解决PATH等环境变量问题
- 下载、预览PDF报错问题排查
- 第五十八章 SQL函数 FLOOR
- 计算机显示没有可以的ip地址,w7电脑提示没有有效ip地址怎么处理