21

线上排障技巧 | 动态修改LOGGER级别

 3 years ago
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级别,从而免去打包再部署的繁杂手续,更快的定位线上问题。」

「效果演示:」

vMBRRvv.png!mobile

本地测试:实时修改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,效果如下图:

uymieqV.png!mobile

全局Logger信息

使用命令:

<code>logger
</code><button>复制</button>

ZnQF7f.png!mobile

可以看到所有logger的信息,包括其中每个appenders。

使用如下命令,修改名称为ROOT的logger的日志级别至debug级别:

<code>logger --name ROOT --level debug
</code><button>复制</button>

QzUriqv.png!mobile

可以看到多出了debug级别的输出。

指定类名的logger信息

在有多个logger的情况下,可以查找指定名称的logger

<code>logger -n ROOT
</code><button>复制</button>

BNR3muF.png!mobile

指定classloader的logger信息

如果需要改变指定类的输出级别,先要定位到该类的classLoader,然后修改该clasLoader的logger。

使用sc命令查看你需要改变的类信息:

<code>sc -d cn.monitor4all.miaoshaweb.DynamicLoggerTest | grep classLoaderHash
</code><button>复制</button>

6zQJNfm.png!mobile

随后可以通过classLoader找到其对应的logger:

logger -c 18b4aac2
复制

NJbYrqn.png!mobile

然后就可以调整对应的logger日志级别:

logger -c 18b4aac2 --name ROOT --level debug
复制

vUvU323.png!mobile

RRBvMnJ.png!mobile

使用 ongl 命令

此外,Arthas还支持使用ognl来修改日志级别。但是这种方法对log4j不友好,修改会报错。并且就算支持的logback/slf4j,也需要复杂的形如ognl -c @org.slf4j.LoggerFactory@getLogger(“root”).setLevel()的命令才能修改,并不是一个很好的办法。

线上实战:实时打印MyBatis SQL语句

容器内启动arthas

我的线上容器,是没有外网访问权限的(这种情况蛮常见的),我将全量包解压在容器内运行:

raMriu.png!mobile

打印DEBUG级别的SQL日志

下图是没有DEBUG信息的一条请求日志,可以看到只有入参出参的拦截器信息(INFO级别):

3I77FrJ.png!mobile

使用 logger --name ROOT --level debug ,将SQL语句输出出来:

riy2Ev7.png!mobile

毕竟,很多时候线上的bug是不小心拼错SQL导致。

总结

文章简单总结了使用Arthas来动态调整日志级别的使用方法。在线上环境,能够有效的提升排查问题的效率。当然Arthas能做的还远不止于此,更多有趣并且「实用」的功能等待大家的发掘。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK