springboot项目大量打印debug日志问题
目前,java下应用最广泛的日志系统主要就是两个系列: log4j和slf4j+logback 。
其中,slf4j只包含日志的接口,logback只包括日志的具体实现,两者加起来才是一个完整的日志系统。Log4j则同时包含了日志接口和实现。
这两套日志系统之间有可以相互兼容的组件,分别是slf4j-log4j12和 log4j-over-slf4j,引入之后就可以用log4j打出slf4j接口的日志,或者用logback打出log4j接口的日志。
背景知识介绍到这里,再简单说一下标题里提到的问题。问题的现象就是我们在war包里配置了log4j的日志级别为info, 但在catalina里却一直在打大量的debug日志。初看现象肯定很诡异,前期各种研究tomcat配置也没什么头绪。直到磁盘压力太大,去看jstack发现大量进程是等待在Logback代码中,才发现之前关注错了重点。再去具体了解了java下的日志系统后,问题也就很明了了。
先把几个事实摆出来:
1. 打出的debug日志都是用slf4j写的,根据堆栈得知logback具体执行了日志打印
2. logback在无配置文件时默认debug级别
3. 我们的war包中同时包含logback,log4j和slf4j-log4j12
4. Slf4j无法主动选择具体的日志实现
想必看到这里,大家也明白了问题所在。根据我们引入的包,log4j和logback都可以实现打印slf4j日志,而具体谁来打,不是一个用正常办法可以控制的事情,在这个具体案例下,logback就成了具体的日志打印者。而因为我们其实是想用lo4j打日志,所以没有配logback配置,所以logback就按默认的debug级别打了大量日志。
解决办法也很简单,就是把logback的包全去掉。看似有些暴力,但确实是最合理的一个解决办法。
查看依赖,发现spring-boot-starter-web包含了logback依赖包,将其移除即可。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>logback-core</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.29</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
最后提供一个排查日志问题的通用套路,免得找不到方向乱看。
1. 找几行不符合自己日志配置的具体日志,翻阅对应代码,看看是哪个日志接口打的
2. 查jar包,看看这套日志框架有哪些具体实现
3. 把多的jar包去掉
参考博文:http://lichuanyang.top/posts/4433/
springboot项目大量打印debug日志问题的更多相关文章
- Springboot + SLF4j + Log4j2 打印异常日志时,耗时要5-6秒
1.使用jps -l 查看springboot项目的进程ID 2.使用命令jstack -l 进程ID > log.txt 打印堆栈信息到文件,内容如下: "http-nio-8065 ...
- SpringBoot中Mybatis打印sql日志
application.yml中加上 # springBoot+Mybatis 控制台打印SQL语句 (方式一) logging: level: com.zoctan.api.mapper : deb ...
- iOS打印Debug日志的方式
简单介绍以下几个宏: 1) __VA_ARGS__ 是一个可变参数的宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).宏前面加上##的作用在于,当可变参 ...
- Swift打印Debug日志,实现Release下不打印
OC内,我们往往做log打印时,会考虑一个Debug环境下打印,Release下控制不打印,以节约性能消耗. OC我们可以这样做: 在pch文件内,定义如下: //打印日志 #ifdef DEBUG ...
- php 打印debug日志
A lesser known trick is that mod_php maps stderr to the Apache log. And, there is a stream for that, ...
- 03篇ELK日志系统——升级版集群之ELK日志系统整合springboot项目
[ 前言:整个ELK日志系统已经搭建好了,接下来的流程就是: springboot项目中的logback日志配置通过tcp传输,把springboot项目中所有日志数据传到————>logsta ...
- SpringBoot项目的几种创建方式,启动、和访问
最常用的4种方式,但除了这些以外,还有其他方式: ①在线创建 ②STS构建 ③Intell Idea内置构建工具 ④Maven创建 STS官网:https://start.spring.io .S ...
- Springboot项目启动不了。也不打印任何日志信息。
Springboot项目启动不了.也不打印任何日志信息. <!-- 在创建Spring Boot工程时,我们引入了spring-boot-starter,其中包含了spring-boot-sta ...
- SpringBoot中使用AOP打印接口日志的方法(转载)
前言 AOP 是 Aspect Oriented Program (面向切面)的编程的缩写.他是和面向对象编程相对的一个概念.在面向对象的编程中,我们倾向于采用封装.继承.多态等概念,将一个个的功能在 ...
随机推荐
- tomcat源码分析一之getCanonicalFile和getAbsolutePath的区别
最近在看tomcat源码 1.getPath(): 返回定义时的路径,(就是你写什么路径,他就返回什么路径) 2.getAbsolutePath(): 返回绝对路径,但不会处理“.”和“..”的情况 ...
- SQL生成 C# Model
本文转自: https://www.cnblogs.com/jhli/p/11552105.html declare @TableName sysname = 'T_FakeOrderList' de ...
- ES6十大特性(转载CSDN)
1. const和let关键字 const用于定义常量. let用于定义变量.但是JavaScript中不是已经有变量了吗? 是的,这很正确,但用var声明的变量具有函数作用域,并会被提升到顶部. 这 ...
- java-day18
函数式接口在java中指:有且仅有一个抽象方法的接口 @FunctionalInterface注解:可以检测接口是否是一个函数式接口 函数式接口的使用:一般可以作为方法的参数和返回值类型 自定义函数式 ...
- vue on emit 父子之间传值应用详细代码
大概很多人都知道用这个,网上教程也一大堆,但我想说的是一定要手动敲一遍,敲一遍,敲一遍,重要的事情说三遍. 大概有些人也不知道它该何时用on,或者emit 的吧? 先说两个我项目中用到的场景吧: 项目 ...
- js 万能判断
console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toSt ...
- Linux 进程间通信 消息队列 实现两个进程间通信
例子: 通过消息队列实现两个进程间通信,一个进程从终端输入数据,通过消息队列发送,另一个进程通过消息队列接收数据 文件1 创建进程1 终端输入通过消息队列发送数据 #include <stdio ...
- Berry 指令设计
Berry 脚本源代码需要被编译为字节码指令流才能被 Berry 虚拟机执行.本文将详细地讲解 Berry 字节码指令(下面简称指令)的设计和实现.为了达到这个目的,本文由 3 部分构成:第 1 小节 ...
- UVA11427 Expect the Expected 概率dp+全概率公式
题目传送门 题意:小明每晚都玩游戏,每一盘赢的概率都是p,如果第一盘就赢了,那么就去睡觉,第二天继续玩:否则继续玩,玩到赢的比例大于p才去睡:如果一直玩了n盘还没完成,就再也不玩了:问他玩游戏天数的期 ...
- 夯实JavaScript基础之prototype, __proto__, instanceof
function New(f){ return function(){ var o = {'__proto__': f.prototype}; f.apply(o, arguments); retur ...