文档章节

Alibaba Java诊断利器Arthas实践--使用redefine排查应用奇怪的日志来源

 横云断岭
发布于 2018/10/24 00:49
字数 787
阅读 177
收藏 12

背景

随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如:

[] [] [] No credential found

那么怎样排查这些奇怪的日志从哪里打印出来的呢?因为搞不清楚是什么logger打印出来的,所以想定位就比较头疼。

下面介绍用arthas的redefine命令快速定位奇怪日志来源。

修改StringBuilder

首先在java代码里,字符串拼接基本都是通过StringBuilder来实现的。比如下面的代码:

    public static String hello(String world) {
        return "hello " + world;
    }

实际上生成的字节码也是用StringBuilder来拼接的:

  public static java.lang.String hello(java.lang.String);
    descriptor: (Ljava/lang/String;)Ljava/lang/String;
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=1, args_size=1
         0: new           #22                 // class java/lang/StringBuilder
         3: dup
         4: ldc           #24                 // String hello
         6: invokespecial #26                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
         9: aload_0
        10: invokevirtual #29                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        13: invokevirtual #33                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        16: areturn

在java的logger系统里,输出日志时通常也是StringBuilder来实现的,最终会调用StringBuilder.toString(),那么我们可以修改StringBuilder的代码来检测到日志来源。

StringBuilder.toString() 的原生实现是:

    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

修改为:

    @Override
    public String toString() {
        // Create a copy, don't share the array
        String result = new String(value, 0, count);
        if(result.contains("No credential found")) {
            System.err.println(result);
            new Throwable().printStackTrace();
        }
        return result;
    }

增加的逻辑是:当String里包含No credential found时打印出当前栈,这样子就可以定位日志输出来源了。

编绎修改过的StringBuilder

其实很简单,在IDE里把StringBuilder的代码复制一份,然后贴到任意一个工程里,然后编绎即可。

也可以直接用javac来编绎:

javac StringBuilder.java

启动应用,使用Arthas redefine修改过的StringBuilder

启动应用后,在奇怪日志输出之前,先使用arthas attach应用,再redefine StringBuilder:

$ redefine -p /tmp/StringBuilder.class
redefine success, size: 1

当执行到输出[] [] [] No credential found的logger代码时,会打印当前栈。实际运行结果是:

[] [] [] No credential found
java.lang.Throwable
    at java.lang.StringBuilder.toString(StringBuilder.java:410)
    at com.taobao.middleware.logger.util.MessageUtil.getMessage(MessageUtil.java:26)
    at com.taobao.middleware.logger.util.MessageUtil.getMessage(MessageUtil.java:15)
    at com.taobao.middleware.logger.slf4j.Slf4jLogger.info(Slf4jLogger.java:77)
    at com.taobao.spas.sdk.common.log.SpasLogger.info(SpasLogger.java:18)
    at com.taobao.spas.sdk.client.identity.CredentialWatcher.loadCredential(CredentialWatcher.java:128)
    at com.taobao.spas.sdk.client.identity.CredentialWatcher.access$200(CredentialWatcher.java:18)
    at com.taobao.spas.sdk.client.identity.CredentialWatcher$1.run(CredentialWatcher.java:58)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

可以看到是spas.sdk打印出了[] [] [] No credential found的日志。

总结

  • logger最终会用StringBuilder来输出
  • 修改StringBuilder来定位输出特定日志的地方
  • 使用Arthas redefine命令来加载修改过的StringBuilder
  • redefine命令实际上实现了任意代码线上debug的功能,可以随意本地修改代码重新编绎,然后线上redefine加载
  • redefine的功能过于强大,所以请小心使用:)

© 著作权归作者所有

共有 人打赏支持
粉丝 14
博文 8
码字总数 9532
作品 3
深圳
私信 提问
Arthas实践--使用redefine排查应用奇怪的日志来源

背景 随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如: 那么怎样排查这些奇怪的日志从哪里打印出来的呢?因为搞不清楚是什么logger打印出来的,所以...

阿里云云栖社区
2018/10/25
0
0
阿里内部的那个牛逼带闪电的Java诊断工具终于开源了

在阿里巴巴内部,有很多自研工具供开发者使用,其中有一款工具,是几乎每个Java开发都使用过的工具,那就是Arthas,这是一款Java诊断工具,是一款牛逼带闪电的工具。该工具已于2018年9月份开...

Java填坑路
2018/12/20
0
0
当DUBBO遇上Arthas - 排查问题的实践

Apache Dubbo是Alibaba开源的高性能RPC框架,在国内有非常多的用户。 Github: https://github.com/apache/incubator-dubbo 文档:http://dubbo.incubator.apache.org/zh-cn/ Arthas是Alibaba......

hengyunabc
2018/12/07
0
0
Arthas实践--快速排查Spring Boot应用404/401问题

背景 在Java Web/Spring Boot开发时,很常见的问题是: 网页访问404了,为什么访问不到? 登陆失败了,请求返回401,到底是哪个Filter拦截了我的请求? 碰到这种问题时,通常很头痛,特别是在...

横云断岭
01/07
0
0
深入Spring Boot:利用Arthas排查NoSuchMethodError

前言 有时spring boot应用会遇到的问题,下面以具体的demo来说明怎样利用arthas来排查。 Demo: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-NoSuchMethodError 在应...

阿里云云栖社区
2018/09/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

从 JVM 分析 hibernate-validator NoClassDefFoundError

最近排查一个spring boot应用抛出hibernate.validator NoClassDefFoundError的问题,异常信息如下: Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.hibernat......

微笑向暖wx
18分钟前
1
0
c++指针和字符串

==============================

天王盖地虎626
23分钟前
2
0
从 JVM 分析 hibernate-validator NoClassDefFoundError

最近排查一个spring boot应用抛出hibernate.validator NoClassDefFoundError的问题,异常信息如下: Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.hibernat......

java菜分享
28分钟前
2
0
超500款社交APP对标微信,细分未来社交领域

“微信之父”张小龙在2019微信公开课PRO活动上透露,截止2018年8月,微信的日登录量已超过10亿。腾讯2018年三季度财报显示,QQ智能终端月活跃账户达6.98亿人。 当前微信和QQ无疑是中国最大且...

ThinkSNS账号
35分钟前
1
0
Fiddler 抓包工具总结

序章 Fiddler是一个蛮好用的抓包工具,可以将网络传输发送与接受的数据包进行截获、重发、编辑、转存等操作。也可以用来检测网络安全。反正好处多多,举之不尽呀!当年学习的时候也蛮费劲,一...

javaer
37分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部