遇到的问题
目前线上的服务存在两个问题:
- 日志等级如何实时热更新
- 打印的日志缺少字段,需要修改打印日志的代码
最原始的解决方式可以通过修改配置文件修改日志等级,更新代码,重新发布来解决这两个问题。这样就会使得代码需要变更,并重新发布,效率会非常的低。
这里适用Arthas的两个命令,就能做到再不重启服务,不更新代码的情况下修改日志打印等级,以及热更新class文件。
安装Arthas服务
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
执行完java -jar命令后,根据提示选择要进入的线程编号。
Arthas - logger
进入arthas控制台后,先输入logger命令,获取当前日志信息,这里只需要关注name、classLoaderHash和level三个值就可以。
name ROOT
class ch.qos.logback.classic.Logger
classLoader org.springframework.boot.loader.LaunchedURLClassLoader@2e5d6d97
classLoaderHash 2e5d6d97
level INFO
effectiveLevel INFO
logger命令的几个关键参数:
-c: 指定classLoaderHash值--name: 指定name值--level: 指定要变更的日志等级(info / trace / debug / error ...)
这里我们执行命令:logger -c 2e5d6d97 --name ROOT --level debug,将日志等级从info修改为debug,这样再看日志,就能看到日志输出了大量的DBUG级别的日志。
至此我们实现了第一个目标,修改日志等级。
Artahs - retransform
retransform命令可以用来替换执行的.class文件
用logger命令已经实现了日志等级的切换,但在实际定位问题的过程中,可能某些日志打印的字段不全,或者没有打印日志,需要更新代码重新发布。但生产环境发布一次代码需要各种流程,并且加了日志可能并没发现问题,还需要二次添加日志,是的问题定位解决效率非常的低。此时就可以用arthas的retransform命令来替换class文件。
替换步骤:
- 再java文件中添加日志语句,编译为.class文件
- 上传.class文件到服务器
- 执行命令:
retransform <classFilePath>
注意事项:不允许新增加field/method
总结
用这两个命令可以简单的实现线上通过日志定位问题,但实际生产环境这样做还是有一定的风险和困难的,大家可以先在研发和测试环境使用此种方式定位和解决问题,结合官方文档,深入的学习一下,有条件的可以在不敏感的线上服务使用。