一般动作
登录
Wiki: BROPEN ▼: Document Index
»
Space: FAQ ▼: Document Index
»
Page: 如何使用调试工具 DebutUtils
搜索
zh
页面动作
导出 ▼: 以PDF格式导出 以RTF格式导出 以HTML格式导出
更多动作 ▼: 打印预览 察看源码
欢迎进入Wiki » FAQ » 如何使用调试工具 DebugUtils?

# 如何使用调试工具 DebugUtils?

在2014-01-20 10:59上被李小翔修改
评论 (0) · 附件 (0) · 记录 · 信息

BroToolkit 中有一个用于调试的 DebugUtils 工具类，下面对里面的几个常用的API做些简单介绍，更多方法参见API文档。

# 性能调试

DebugUtils 里包含了两个很简单的性能调试方法 ps 和 pm，可以用来打印代码的执行时间，比如下面代码：

DebugUtils.ps("start");
sleep 1000;
DebugUtils.pm("111");
sleep 2000;
DebugUtils.pm("222");

将输出：

0: start
1002: 111
2000: 222

也就是说从 “start” 到 “111” 之间的代码段运行了1002ms，而从 “111” 到 “222”，运行了 2000ms。

当发现某段代码执行缓慢、存在性能问题的时候，就可以将这段代码分成多个段，然后通过这种简单的打日志的方式，定位到最耗时间的代码，然后各个击破。

不过，ps、pm 方面只支持单线程。

# 动态设置log4j的日志级别

setLogLevel 方法可以用来动态设置日志级别，而不仅仅局限于启动时在 Config 中的限制。比如下面的代码：

// 输出所有通过 hibernate 执行的 sql 语句，可以用来调试 hql 的错误，或者是不是有重复执行、需要优化的数据库代码
DebugUtils.setLogLevel( "org.hibernate.SQL", "DEBUG")

# 打印堆栈信息

调试问题代码的时候，如果仅仅局限于问题发生点，而不进行追溯，很容易发生只见树木、不见森林的情况，无法从源头解决问题；或者调试一些未知代码时，由于对代码结构不了接，经常会无从下手。

此时，可以通过 printStacktrace 方法打印出代码的整个调用堆栈信息，以便更好的跟踪调试，日志信息如：

1: java_lang_Thread$getStackTrace.call(Unknown Source)
2: org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
3: org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
4: org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
5: bropen.toolkit.utils.DebugUtils.printStacktrace(DebugUtils.groovy:56)
6: bropen.toolkit.utils.DebugUtils$printStacktrace.call(Unknown Source)
7: org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
8: org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
9: org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
10: Script1.run(Script1.groovy:1)
11: groovy.lang.GroovyShell.evaluate(GroovyShell.java:518)
12: groovy.lang.GroovyShell.evaluate(GroovyShell.java:556)
13: groovy.lang.GroovyShell.evaluate(GroovyShell.java:527)
14: groovy.lang.GroovyShell$evaluate.call(Unknown Source)
15: org.grails.plugins.console.ConsoleService.eval(ConsoleService.groovy:58)
......

# 存取私有变量、执行私有方法

java中，将成员变量、方法设置为 private、protected 目的就是为了不让别人访问，但是，调试问题、或者想要对开源组件进行定制的时候，getInaccessibleField、setInaccessibleField、invokeInaccessibleMethod 这几个无底线的方法却能发挥意想不到的作用。示例如下：

// 调用没有参数的方法 foo
DebugUtils.invokeInaccessibleMethod( foobar, "foo", null, null );
// 使用java调用有一个int类型参数的静态方法 bar
DebugUtils.invokeInaccessibleMethod( Foobar.class, "bar", (List) Arrays.asList(Integer.class), (List) Arrays.asList(200));
// 获得私有变量的值
DebugUtils.getInaccessibleField( Foobar.class, "bar", int.class );
// 设置私有变量的值
DebugUtils.setInaccessibleField( this, "excludePackageNames", List.class, newValue );
标签： BroToolkit
在2014-01-19 14:07上被李小翔创建

- 评论 （0）
- 附件 （0）
- 记录
- 信息

# 快速链接

- 首页
- 新闻动态
- FAQ

Copyright © 2013 北京博瑞开源软件有限公司
京ICP备12048974号