某程序猿竟然因为“日志”问题一夜秃头。这是道德的沦丧还是因为什么。。。。

在一个夜深人静的凌晨两点。一个兢兢业业的程序猿–小张,正在面对着电脑敲着键盘。他正在开发一个公司发不下来的大型系统。由于这个系统有点大,小张每次为了调试或者测试方面,他都喜欢使用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系列(三)----某程序猿竟然因为“日志”问题一夜秃头相关推荐

  1. 【j360-boot】Spring-boot系列三(崩溃模式,不是你崩就是电脑崩)

    2019独角兽企业重金招聘Python工程师标准>>> j360-boot spring-boot入门工程之j360-boot:(欢迎star.fork) https://githu ...

  2. 毕业之际,而我也快了-------一位准大三的程序猿

    活动地址:毕业季·进击的技术er 大二已经过去 自己学习经历从大一到大二,让自己学习到什么? 本人现在是个准大三的物联网工程技术专业学生,大二专业课有单片机.zigbee无线传感器.java.嵌入式L ...

  3. 一个三本程序猿的大厂逆袭之路

    作者 | 神技圈子 来源 | CSDN 博客 外包公司的艰苦岁月 一哥们这里暂且称他为A君,毕业于东北一个三本学校,出生于一个西南地区贫困的小村庄.由于负担不起高昂的学费差点不能上学,最后只得到处找身 ...

  4. 一名奔三的程序猿的困惑

    一名在IT行业做了3年半的程序员,在他即将奔三的时候在论坛上写了下面这段话: "下个月就奔三了,有时在编程的时候会感到心力交瘁,失去热情.另外也担心如果一直在做技术,到了30以后会不会真的很 ...

  5. 惊!十二星座程序猿竟然这样写代码

    摘要: 水瓶座 大概只有水瓶座的程序猿可以做到代码神秘到无人能解. 水瓶座,属于风系星座.常被称为"天才星座"或"未来星座".他们较着重于精神层次的提升,是很好 ...

  6. 从零开始搭建SpringBoot项目(三)——小程序Uni-app项目搭建(详细教程和实战)

    前情回顾 从零开始搭建SpringBoot项目(一)--开发环境搭建 从零开始搭建SpringBoot项目(二)--Swagger接口测试平台搭建 目录 前情回顾 一.前置条件 二.本篇介绍 三.获取 ...

  7. SpringBoot系列三:SpringBoot基本概念(统一父 pom 管理、SpringBoot 代码测试、启动注解分析、配置访问路径、使用内置对象、项目打包发布)...

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.了解SpringBoot的基本概念 2.具体内容 在之前所建立的 SpringBoot 项目只是根据官方文档实现的一个基础程 ...

  8. springboot系列(三十一):如何实现excel模板导出成pdf文件?这你得会 | 超级详细,建议收藏

  9. 漫谈程序猿系列:怎么告别“混日子”

    我在"漫谈程序猿系列:咦,你也在混日子啊"一文中描写叙述了一种混日子的现状,有朋友说该文仅仅提到了设置目标告别混日子而没有展开论述"怎样设立目标"." ...

最新文章

  1. 用聚类方法结合卷积网络,实现无监督端到端图像分类
  2. Linux系统下活用History命令
  3. poj3352(强连通分量)
  4. Bash,Vim,gdbgit常用命令
  5. 大数据教程(13.6)sqoop使用教程
  6. Adobe pixel Bender toolkit
  7. two sum 3道题
  8. 据说,80%的人没有真正理解了Spring的依赖注入
  9. 年底各类年会邀请函也要美美的设计
  10. vmware esxi 4.0 上安装postfix,mailx发送邮件
  11. HTML实现简单注册页面
  12. acunetix导出html,关于Acunetix v11 WebUI下不得不说的事情!
  13. 主板检测卡c5_主板检测卡代码(常见)及解决方法
  14. 仓库管理软件中的账套是什么意思
  15. Javascript验证身份证号码:正则表达式
  16. matlab保存nii_Matlab实现NIfTI(ANALYZE)核磁共振图像读写
  17. WSL关闭与windows的互交互(解决PATH等环境变量问题
  18. 下载、预览PDF报错问题排查
  19. 第五十八章 SQL函数 FLOOR
  20. 计算机显示没有可以的ip地址,w7电脑提示没有有效ip地址怎么处理

热门文章

  1. 软件测试的4W1H(第1-2课时)
  2. https开头的网址是什么意思_网站https含义是什么?工作原理又是什么
  3. js实现简易的ATM取款机
  4. Linux中的shell到底是什么?
  5. three.js伪入门教程之旋转的九尾妖狐
  6. 使用Ranch搭建自己的TCP连接池
  7. 为什么世上没有免费午餐
  8. 仙凡幻想-你的缘分就是我
  9. zoom 实习生错失 100万$ 的故事,以及稀有前端面经流出……
  10. Go语言string包详解