线上排障技巧 | 动态修改LOGGER级别
source link: https://club.perfma.com/article/1989496
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
前言
大多数情况下,我们会在打印日志时定义日志的LOGGER级别,用来控制输出的信息范围。
一方面,过多的输出会影响查看日志的效率,另一方面,过少的日志让问题定位变得困难。
但当线上出现问题时,线上容器通常定义在info级别,发生一些疑难问题时,光靠info级别的日志很难定位问题。
一个典型的场景:在一些需要打印MySQL语句的场景,如果你正在使用MyBatis框架,由于MyBaits中SQL语句是DEBUG级别的信息,通常在线上容器就没法看到。
一个丑陋的解决办法就是在沙箱/预发环境,将log4j.xml中的info改为debug:
<Root level="info">
<AppenderRef ref="detail"/>
<AppenderRef level="error" ref="error"/>
</Root>
复制
然后重新打包部署,再发起请求来调试代码。
甚至在一些无法模拟请求的场景下,还需要将修改灰度至线上环境,大量的debug信息会对线上服务造成实质性的影响。
「本文简要介绍如何使用阿里巴巴开源Java调试工具Arthas,实时修改线上服务的LOGGER级别,从而免去打包再部署的繁杂手续,更快的定位线上问题。」
「效果演示:」
本地测试:实时修改LOGGER级别
安装arthas
网络安装
在接通外网的环境下,可以使用快速网络安装,会从阿里的源拉去全量包。
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
复制
全量安装
如果本地外网环境不通,比如某些容器内是不允许外网访问的,那么可以使用预先下载好的全量安装包,然后解压后运行包内的jar,使用命令:
<code>java -jar arthas-boot.jar </code><button>复制</button>
启动arthas
我在本地启动arthas,效果如下图:
全局Logger信息
使用命令:
<code>logger </code><button>复制</button>
可以看到所有logger的信息,包括其中每个appenders。
使用如下命令,修改名称为ROOT的logger的日志级别至debug级别:
<code>logger --name ROOT --level debug </code><button>复制</button>
可以看到多出了debug级别的输出。
指定类名的logger信息
在有多个logger的情况下,可以查找指定名称的logger
<code>logger -n ROOT </code><button>复制</button>
指定classloader的logger信息
如果需要改变指定类的输出级别,先要定位到该类的classLoader,然后修改该clasLoader的logger。
使用sc命令查看你需要改变的类信息:
<code>sc -d cn.monitor4all.miaoshaweb.DynamicLoggerTest | grep classLoaderHash </code><button>复制</button>
随后可以通过classLoader找到其对应的logger:
logger -c 18b4aac2
复制
然后就可以调整对应的logger日志级别:
logger -c 18b4aac2 --name ROOT --level debug
复制
使用 ongl 命令
此外,Arthas还支持使用ognl来修改日志级别。但是这种方法对log4j不友好,修改会报错。并且就算支持的logback/slf4j,也需要复杂的形如ognl -c @org.slf4j.LoggerFactory@getLogger(“root”).setLevel()的命令才能修改,并不是一个很好的办法。
线上实战:实时打印MyBatis SQL语句
容器内启动arthas
我的线上容器,是没有外网访问权限的(这种情况蛮常见的),我将全量包解压在容器内运行:
打印DEBUG级别的SQL日志
下图是没有DEBUG信息的一条请求日志,可以看到只有入参出参的拦截器信息(INFO级别):
使用 logger --name ROOT --level debug
,将SQL语句输出出来:
毕竟,很多时候线上的bug是不小心拼错SQL导致。
总结
文章简单总结了使用Arthas来动态调整日志级别的使用方法。在线上环境,能够有效的提升排查问题的效率。当然Arthas能做的还远不止于此,更多有趣并且「实用」的功能等待大家的发掘。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK