性能文章>线上排障技巧 | 动态修改LOGGER级别>

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

7102119

前言

大多数情况下,我们会在打印日志时定义日志的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级别,从而免去打包再部署的繁杂手续,更快的定位线上问题。」

「效果演示:」
image.png

本地测试:实时修改LOGGER级别

安装arthas

网络安装
在接通外网的环境下,可以使用快速网络安装,会从阿里的源拉去全量包。

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

全量安装
如果本地外网环境不通,比如某些容器内是不允许外网访问的,那么可以使用预先下载好的全量安装包,然后解压后运行包内的jar,使用命令:

java -jar arthas-boot.jar

启动arthas

我在本地启动arthas,效果如下图:
image.png

全局Logger信息
使用命令:

logger

image.png

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

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

logger --name ROOT --level debug

image.png

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

指定类名的logger信息

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

logger -n ROOT

image.png

指定classloader的logger信息

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

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

sc -d cn.monitor4all.miaoshaweb.DynamicLoggerTest | grep classLoaderHash

image.png

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

logger -c 18b4aac2

image.png

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

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

image.png

image.png

使用 ongl 命令

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

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

容器内启动arthas

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

image.png

打印DEBUG级别的SQL日志

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

image.png

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

image.png

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

总结

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

请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

字符串字面量长度是有限制的
前言 偶然在一次单元测试中写了一个非常长的字符串字面量。 正文 在一次单元测试中,我写了一个很长的字符串字面量,大概10万个字符左右,编译时,编译器给出了异常告警 `java: constant
多次字符串相加一定要用StringBuilder而不用-吗?
今天在写一个读取Java class File并进行分析的Demo时,偶然发现了下面这个场景(基于oracle jdk 1.8.0_144): ``` package test; public c
如何通过反射获得方法的真实参数名(以及扩展研究)
前段时间,在做一个小的工程时,遇到了需要通过反射获得方法真实参数名的场景,在这里我遇到了一些小小的问题,后来在部门老大的指导下,我解决了这个问题。通过解决这个问题,附带着我了解到了很多新的知识,我觉得
高吞吐、低延迟 Java 应用的 GC 优化实践
本篇原文作者是 LinkedIn 的 Swapnil Ghike,这篇文章讲述了 LinkedIn 的 Feed 产品的 GC 优化过程,虽然文章写作于 April 8, 2014,但其中的很多内容和
「每日五分钟,玩转 JVM」:久识你名,初居我心
聊聊 JVMJVM,一个熟悉又陌生的名词,从认识Java的第一天起,我们就会听到这个名字,在参加工作的前一两年,面试的时候还会经常被问到JDK,JRE,JVM这三者的区别。JVM可以说和我们是老朋友了
据说99.99%的人都会答错的类加载的问题
概述首先还是把问题抛给大家,这个问题也是我厂同学在做一个性能分析产品的时候碰到的一个问题。 同一个类加载器对象是否可以加载同一个类文件多次并且得到多个Class对象而都可以被java层使用吗请仔细注意
Java多线程——并发测试
编写并发程序时候,可以采取和串行程序相同的编程方式。唯一的难点在于,并发程序存在不确定性,这种不确定性会令程序出错的地方远比串行程序多,出现的方式也没有固定规则。那么如何在测试中,尽可能的暴露出这些问
Java多线程知识小抄集(一)
本文主要整理笔者遇到的Java多线程的相关知识点,适合速记,故命名为“小抄集”。本文没有特别重点,每一项针对一个多线程知识做一个概要性总结,也有一些会带一点例子,习题方便理解和记忆。 1.interr