欢迎进入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上被李小翔创建

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