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
的方法,有人知道可以评论给我哦 ~
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于