线上排障技巧 | 动态修改 LOGGER 级别
前言
大多数情况下,我们会在打印日志时定义日志的LOGGER级别,用来控制输出的信息范围。
一方面,过多的输出会影响查看日志的效率,另一方面,过少的日志让问题定位变得困难。
但当线上出现问题时,线上容器通常定义在info级别,发生一些疑难问题时,光靠info级别的日志很难定位问题。
一个典型的场景:在一些需要打印MySQL语句的场景,如果你正在使用MyBatis框架,由于MyBaits中SQL语句是DEBUG级别的信息,通常在线上容器就没法看到。
一个丑陋的解决办法就是在沙箱/预发环境,将log4j.xml中的info改为debug:
然后重新打包部署,再发起请求来调试代码。
甚至在一些无法模拟请求的场景下,还需要将修改灰度至线上环境,大量的debug信息会对线上服务造成实质性的影响。
「本文简要介绍如何使用阿里巴巴开源Java调试工具Arthas,实时修改线上服务的LOGGER级别,从而免去打包再部署的繁杂手续,更快的定位线上问题。」
「效果演示:」
![](https://static001.geekbang.org/infoq/b7/b7f751d96d1089ea2b1e8e5b96ef3a0c.png)
本地测试:实时修改LOGGER级别
安装arthas
网络安装
在接通外网的环境下,可以使用快速网络安装,会从阿里的源拉去全量包。
全量安装
如果本地外网环境不通,比如某些容器内是不允许外网访问的,那么可以使用预先下载好的全量安装包,然后解压后运行包内的jar,使用命令:
启动arthas
我在本地启动arthas,效果如下图:
![](https://static001.geekbang.org/infoq/2f/2fda7200d99e4bf3739e03d0323e16e1.png)
全局Logger信息
使用命令:
![](https://static001.geekbang.org/infoq/73/732b5beec0ebd2d02c9a344eb32ab76f.png)
可以看到所有logger的信息,包括其中每个appenders。
使用如下命令,修改名称为ROOT的logger的日志级别至debug级别:
![](https://static001.geekbang.org/infoq/d5/d5358504d6d2b433a4098fd0bac6daef.png)
可以看到多出了debug级别的输出。
指定类名的logger信息
在有多个logger的情况下,可以查找指定名称的logger
![](https://static001.geekbang.org/infoq/1c/1cc6888534a45192419c720d0fc4f6c6.png)
指定classloader的logger信息
如果需要改变指定类的输出级别,先要定位到该类的classLoader,然后修改该clasLoader的logger。
使用sc命令查看你需要改变的类信息:
![](https://static001.geekbang.org/infoq/c4/c4340b0c83f860af199e9102d7edf54c.png)
随后可以通过classLoader找到其对应的logger:
![](https://static001.geekbang.org/infoq/36/361009ae7202c86c373f9ecd1ef82b63.png)
然后就可以调整对应的logger日志级别:
![](https://static001.geekbang.org/infoq/35/35f34fbd840a75d98ec1c8e138cc4c8b.png)
![](https://static001.geekbang.org/infoq/d6/d6b9c5b36bcbf535ceada0a6b917d676.png)
使用 ongl 命令
此外,Arthas还支持使用ognl来修改日志级别。但是这种方法对log4j不友好,修改会报错。并且就算支持的logback/slf4j,也需要复杂的形如ognl -c @org.slf4j.LoggerFactory@getLogger(“root”).setLevel()的命令才能修改,并不是一个很好的办法。
线上实战:实时打印MyBatis SQL语句
容器内启动arthas
我的线上容器,是没有外网访问权限的(这种情况蛮常见的),我将全量包解压在容器内运行:
![](https://static001.geekbang.org/infoq/f6/f63aba946e15ac35913e87c1edbd3705.png)
打印DEBUG级别的SQL日志
下图是没有DEBUG信息的一条请求日志,可以看到只有入参出参的拦截器信息(INFO级别):
![](https://static001.geekbang.org/infoq/bc/bc185b66f2e1a369937757dd00ddab18.png)
使用logger --name ROOT --level debug
,将SQL语句输出出来:
![](https://static001.geekbang.org/infoq/6e/6e4892140ea883022005545dff93e8a0.png)
毕竟,很多时候线上的bug是不小心拼错SQL导致。
总结
文章简单总结了使用Arthas来动态调整日志级别的使用方法。在线上环境,能够有效的提升排查问题的效率。当然Arthas能做的还远不止于此,更多有趣并且「实用」的功能等待大家的发掘。
看完三件事❤️
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
-
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
-
关注公众号 『 java烂猪皮 』,不定期分享原创知识。
-
同时可以期待后续文章ing🚀
![](https://static001.geekbang.org/infoq/34/34172ad7f3cc8e0f28bd1fc6ca2d2b68.png)
作者:后端技术漫谈
出处:https://club.perfma.com/article/1989496