刚开始的jar包版本如下,因为选择jar包版本不同导致的一些坑,踩过了就记录下来:

<spring.version>3.1.0.RELEASE</spring.version>
<slf4j.version>1.7.25</slf4j.version>
<logback.version>1.2.3</logback.version>
<logback.ext.version>0.1.1</logback.ext.version>

commons-logging:scope为provided,这样是为了打包时不会被带上,也就是不使用commons-logging而是准备使用slf4j
jcl-over-slf4j:这个是桥接包,将已经使用commons-logging记录日志又没法改变(spring默认使用的就是commons-logging)的jar包的日志桥接到slf4
slf4j-api:这就是我们要用的slf4j的日志接口,其实和commons-logging一样都是接口,不是具体实现
logback-classic:具体的日志实现,真正记录日志的jar
logback-ext-spring:为了将logback和spring集成而使用的包,如果不用这个包也可以记录日志,但会有个问题(下文会说)

<!-- log -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.logback-extensions</groupId>
<artifactId>logback-ext-spring</artifactId>
<version>${logback.ext.version}</version>
</dependency>

准备好依赖后,开始配置logback的使用环境
在web.xml中配置logback的监听器,ch.qos.logback.ext.spring.web.LogbackConfigListener类就是logback-ext-spring.jar中的
logback默认也会查找几个地方的配置文件,不过我喜欢自定义路径,毕竟并不是所有公司都会讲配置全部放到resources目录下而是统一在硬盘上进行的管理

<!-- logback -->
<context-param>
<param-name>logbackExposeWebAppRoot</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>file:/opt/config/testservice/logback.xml</param-value>
</context-param>
<listener>
<listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
</listener>

问题一:
程序正常启动,本来很开心的一件事,却遇到了转折,当改了java文件的代码并保存后,tomcat热部署reload会导致在项目重新加载过程中爆出异常——说可能导致内存泄露??纳里,表示完全是懵逼的

静下心看了看,发现居然是logback-1这个线程在重载的过程中没有被释放掉,那么每重载一次就会多出一个logback线程,当然也就会造成内存泄露了;在eclipse的debug视图的dubug窗口中查看线程,确实也是这种情况,重载前只有一个logback-1线程,重载后却有两个同名的logback-1了:

重载后如下图,报出内存泄露异常也是对的

那么什么原因造成的呢?我跟着监听器ch.qos.logback.ext.spring.web.LogbackConfigListener跟了下代码,发现是contextDestroyed执行时报错,所以也懒得深究原因了(其实就是代码写的有问题,在logback-ext-spring的0.1.2版本修复了)。

将logback-ext-spring从0.1.1替换到0.1.2(高于0.1.1就行)问题就解决了,看来这个jar包的作者也发现这个问题并修复了。我最后使用的版本就是<logback.ext.version>0.1.3</logback.ext.version>;完全看自己了最高版本目前是0.1.4而我的spring是3.1的最高只能和0.1.3的一起使用。

问题二:

当解决了问题一后,以为终于可以好好玩耍了(其实完全可以正常玩耍了,只是强迫症。。。);同样看了下debug视图的debug窗口,发现刚启动的时候只有一个logback-1线程

之后,每一分钟会多出一个logback-n线程,一共会多出到logback-8,记一个日志有必要这么多线程么?

刚开始以为是哪里代码又问题,后来一想不可能,启动后什么也没做就慢慢增加,所以猜测是logback内部有什么猫腻,然后找到了logback-core内部创建线程池的地方,果然发现指定了常驻线程池的线程数

JDK文档,明确写了“保留在池中的线程数”,这个我是觉得有点多了,所以我就开始找低版本的

发现CoreConstants类中SCHEDULED_EXECUTOR_POOL_SIZE这个常量随着版本在变化,如下:

1.1.9以上     8
1.1.8       2
1.1.7       2
1.1.6及以下   无

最终分析,个人觉得没必要开启常驻内存8个线程来记录日志,所以我选择了1.1.7(参考maven仓库使用记录,选择使用人数较多的)

最终确定jar包版本:

<spring.version>3.1.0.RELEASE</spring.version>
<slf4j.version>1.7.25</slf4j.version>
<logback.version>1.1.7</logback.version>
<logback.ext.version>0.1.3</logback.ext.version>

总结:jar包并不是越新越好,而是要看你用了哪些功能,以上来就使用最新的包往往会出现一些与预期不一致的效果,解决起来又比较头疼~~

最终确定jar包版本:

踩坑记(1)——使用slf4j+logback记录日志的更多相关文章

  1. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  2. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  3. 【踩坑记】从HybridApp到ReactNative

    前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...

  4. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  5. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  6. djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记

    情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...

  7. HttpWebRequest 改为 HttpClient 踩坑记-请求头设置

    HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...

  8. vue踩坑记

    vue踩坑记 易错点 语法好难啊qwq 不要把'data'写成'date' 在v-html/v-bind中使用vue变量时不需要加变量名 在非vue事件中使用vue中变量时需要加变量名 正确 < ...

  9. 【bug记录】OS Lab4 踩坑记

    OS Lab4 踩坑记 Lab4在之前Lab3的基础上,增加了系统调用,难度增加了很多.而且加上注释不详细,开玩笑的指导书,自己做起来困难较大.也遇到了大大小小的bug,调试了一整天. 本文记录笔者在 ...

随机推荐

  1. Exp8 web基础

    20155332<网络对抗>Exp5 MSF基础应用 1.实验环境搭建 1.apache的安装与配置 安装:sudo apt-get install apache2 开启:service ...

  2. 汇编 inc 和 dec 指令

    知识点: inc 加1指令 dec 减1指令 一.加一指令inc inc a 相当于 add a, //i++ 优点 速度比sub指令快,占用空间小 这条指令执行结果影响AF.OF.PF.SF.Z ...

  3. 记一次Spring的aop代理Mybatis的DAO所遇到的问题

    由来 项目中需要实现某个订单的状态改变后然后推送给第三方的功能,由于更改状态的项目和推送的项目不是同一个项目,所以为了不改变原项目的代码,我们考虑用spring的aop来实现. 项目用的是spring ...

  4. 本地navicat远程连接到云服务器数据库

    本来没有开启秘钥的远程服务器端数据库连接非常方便,就在新建连接上填入数据就ok了,但是开启SSH秘钥后的服务器连接有一个大坑,下面来详细讲讲. 其实开启了秘钥,在新建连接下,先选择SSH方式登录到远程 ...

  5. 基于.NET Standard的分布式自增ID算法--Snowflake

    概述 本篇文章主要讲述分布式ID生成算法中最出名的Snowflake算法.搞.NET开发的,数据库主键最常见的就是int类型的自增主键和GUID类型的uniqueidentifier. 那么为何还要引 ...

  6. 初级字典树查找在 Emoji、关键字检索上的运用 Part-3

    系列索引 Unicode 与 Emoji 字典树 TrieTree 与性能测试 生产实践 生产实践 我们最终要解决 Emoji 在浏览器和打印物上的显示一致. 进行了多番对比,,在显示效果和精度上,m ...

  7. 云服务器+tomcat+mysql+web项目搭建部署

    云服务器+tomcat+mysql+web项目搭建部署 1.老样子,开头墨迹两句. 作为我的第二篇文章,有很多感慨,第一篇人气好低啊,有点小丧气,不过相信我还是经验少,分享的都是浅显的,所以大家可能不 ...

  8. PS官方正式中文版(搬砖分享)

    https://pan.baidu.com/s/1c3IdQq0 PS官方正式中文版(搬砖分享) 注意事项: 1.安装开始前请先断网,在成功破解激活前请全程断网: 2.安装完成后先试运行软件一次,然后 ...

  9. docker 学习笔记(2)--doucker file命令

    FROM base       ---- imageRUN                  ---- 执行命令ADD   ---- 添加文件COPY         ---- 拷贝文件CMD    ...

  10. 详细聊聊k8s deployment的滚动更新(二)

    一.知识准备 ● 本文详细探索deployment在滚动更新时候的行为 ● 相关的参数介绍:   livenessProbe:存活性探测.判断pod是否已经停止   readinessProbe:就绪 ...