Java 线上问题排查利器之 Btrace

本贴最后更新于 2918 天前,其中的信息可能已经时移世易

1 背景

我们在排查线上线下问题的时候,有时可能因为打印的日志不够,导致问题无法追踪。
我们比较通常的做法是:
1.加日志
2.重新发版

但有时问题是,问题不是必现的,重启后不一定能能浮现,btrace 这时就能不重启机器的情况下把必需的日志打印出来

2 下载 btrace

官网: https://kenai.com/projects/btrace
自己下的一个 1.3.8.3 版本: http://ogw5xyc12.bkt.clouddn.com/0c6572d6702142cd88dbcabf03187ac8.tgz

3 设置环境变量

下面的配置按照自己实际的需求去设置

export BTRACE_HOME=/home/yaochengfly/btrace
export PATH=$PATH:$BTRACE_HOME/bin
export JAVA_HOME=/usr/lib/jvm/java-8-oracle

运行 btrace 看一下
如下图就说明你配置的 ok 了

4 实战

4.1 目标代码

/**
 * Gets the specified article's author. 
 * The specified article has a property {@value Article#ARTICLE_AUTHOR_EMAIL}, this method will use this property to
 * get a user from users.
 *
 * 
 * If can't find the specified article's author (i.e. the author has been removed by administrator), returns
 * administrator.
 *
 * @param article the specified article
 * @return user, {@code null} if not found
 * @throws ServiceException service exception
 */
public JSONObject getAuthor(final JSONObject article) throws ServiceException {
    try {
        final String email = article.getString(Article.ARTICLE_AUTHOR_EMAIL);

  JSONObject ret = userRepository.getByEmail(email);

 if (null == ret) {
            LOGGER.log(Level.WARN, "Gets author of article failed, assumes the administrator is the author of this article[id={0}]",
  article.getString(Keys.OBJECT_ID));
  // This author may be deleted by admin, use admin as the author
 // of this article  ret = userRepository.getAdmin();
  }

        return ret;
  } catch (final RepositoryException e) {
        LOGGER.log(Level.ERROR, "Gets author of article[id={0}] failed", article.optString(Keys.OBJECT_ID));
 throw new ServiceException(e);
  } catch (final JSONException e) {
        LOGGER.log(Level.ERROR, "Gets author of article[id={0}] failed", article.optString(Keys.OBJECT_ID));
 throw new ServiceException(e);
  }
}

ps 代码摘自 solo 源码

4.2 btrace 脚本

import org.b3log.solo.service.ArticleQueryService;
import org.json.JSONObject;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
 
@BTrace
public class BtraceTest {
    @OnMethod(
            //  指定需要拦截的类名
            clazz = "org.b3log.solo.service.ArticleQueryService",
            //  指定需要拦截的方法名
            method = "getAuthor",
            //  指定脚本指定的位置,此处表示被拦截方法执行后执行该脚本
            location = @Location(Kind.RETURN))
    public static void getAuthor(
						  JSONObject article, 
                          @Return JSONObject result,
                          //  执行时间,单位纳秒
                          @Duration long duration) {
        println("=========btraceTest=========");
        println("input: "  + article);
        println("output: " + result);
        println("use time(ns):" + duration);
    }
}

4.3 运行

btrace  -cp /home/yaochengfly/solo_war/WEB-INF/classes:/home/yaochengfly/solo_war/WEB-INF/lib/latke-2.3.5.jar 30565 BtraceTest.java

注意 要将依赖的 jar 包加到 -cp 所指定的 classpath
运行结果如下:

ps: 使用中发现 println 追后一行由于缓冲的原因没有输出,还没有找到类似 flush 的方法,有人知道可以评论给我哦 ~

5 进阶

Btrace UserGuide
GitHub

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注
  • BTrace
    2 引用 • 2 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...