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