用Perf4j做全局性能统计
来源:互联网 发布:js如何定义二维数组 编辑:程序博客网 时间:2024/05/21 10:48
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://fallenlord.blogbus.com/logs/40439940.html
今天下午听Kevin提到Perf4j,想起昨晚在InfoQ瞟到过这个名词,晚上回家改完系统,等着看数据更新状况,百般无聊,于是决定下载Perf4j玩玩,聊以解闷
(前言:不知道怎么搞的,codehaus.org在公司访问好好的,回家来就访问不了了,显然是被墙间了,只好翻墙上了perf4j.codehaus.org下载jar包,又找了半天的HTTP PROXY配到SVN里下载了源码——始筑墙者,其无后乎?)
首先试用了下perf4j直接写代码的方式:
public UserDTO getUserByUsername(String username) {
StopWatch stopWatch = new Slf4JStopWatch("getUserByUsername", username);
User user = userService.getUserByUsername(username);
logger.debug("Supported user {}", user);
stopWatch.stop();
return user == null ? null : mapper.map(user, UserDTO.class);
}
其中getUserByUsername是我的方法名,作为tag,username是方法参数作为message。跑了一下,slf4j出结果了,OK一切正常。
但是这种方法实在是太累赘了,每个方法都得去加代码,而且最后一行的性能还统计不到-_-(除非改代码)
遂改用@Profiled注解方式,方法里改成:
@Profiled
public UserDTO getUserByUsername(String username) {
User user = userService.getUserByUsername(username);
logger.debug("Supported user {}", user);
return user == null ? null : mapper.map(user, UserDTO.class);
}
同时在Spring配置文件里配置上AOP自动代理与perf4j:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:aspectj-autoproxy/>
<bean id="timingAspect" class="org.perf4j.slf4j.aop.TimingAspect"/>
</beans>
这回舒服多了,@Profile可以携带多个参数,甚至包含el表达式,不过我感觉默认就挺够用的了,呵呵,具体使用可以参见源码的Javadoc,里面写的很详细。执行代码,pass
于是着手开始改项目,结果发现。。。要加注释的方法太多了-_-。想起Spring的@Transactional,可惜@Profiled不能加在类上
身为一个慵懒的程序员,这种Annotation的方式显然还不够适合我,于是删掉Annotation们重新来搞
先在Spring的applicationContext里加一个AOP的bean:
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*RemoteImpl</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>perf4jInterceptor</value>
</list>
</property>
</bean>
其中*RemoteImpl是我需要统计用的类,类名都是以RemoteImpl结尾;perf4jInterceptor是用于拦截的拦截器bean,代码如下:
@Service
public class Perf4jInterceptor implements MethodBeforeAdvice, AfterReturningAdvice {
private Map<String, StopWatch> watches = new HashMap<String, StopWatch>();
public void before(Method method, Object[] args, Object target) throws Throwable {
String completeMethodName = getCompleteMethodName(target, method);
// 创建性能日志记录器
StopWatch stopWatch;
if (watches.containsKey(completeMethodName)) {
stopWatch = watches.get(completeMethodName);
stopWatch.start();
} else {
stopWatch = new Slf4JStopWatch(completeMethodName, Arrays.toString(args));
watches.put(completeMethodName, stopWatch);
}
}
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
String completeMethodName = getCompleteMethodName(target, method);
// 记录性能
if (watches.containsKey(completeMethodName)) {
StopWatch stopWatch = watches.get(completeMethodName);
stopWatch.stop();
}
}
/**
* 根据目标对象与方法获取方法完整名称.
* @param target 目标对象
* @param method 方法
* @return 方法完整名称
*/
private String getCompleteMethodName(Object target, Method method) {
String className = "";
if (target != null) {
className = target.toString();
int loc = className.indexOf("@");
if (loc >= 0) {
className = className.substring(0, loc);
}
}
return className + "." + method.getName();
}
}
OK,这样项目中所有以RemoteImpl结尾的类的所有方法均被列入了性能记录行列
再次执行代码调用方法进行测试,pass
最后将系统日志文件拷贝出来,执行:
grep perf4j publication.log > a
java -jar perf4j-0.9.10.jar -g g.html a
即可看到统计结果:
Performance Statistics 02:47:00 - 02:47:30
Tag Avg(ms) Min Max Std Dev Count
com.baidu.uic.publication.remoting.impl.UserRemoteImpl.getAllUsersByContactWithPage 2098.0 94 14625 4088.8 11
com.baidu.uic.publication.remoting.impl.UserRemoteImpl.getUserByUsername 153.3 0 1297 382.6 10
Performance Statistics 02:47:30 - 02:48:00
Tag Avg(ms) Min Max Std Dev Count
com.baidu.uic.publication.remoting.impl.UserRemoteImpl.getAllUsersByContactWithPage 2985.8 63 7406 2979.8 10
com.baidu.uic.publication.remoting.impl.UserRemoteImpl.getUserByUsername 1.6 0 16 4.8 10
下面是生成的图表:
OK,这是第一次接触Perf4j,看了下Perf4j的代码,比较简单,不过相比自己实现还是省了不少事儿,更有日志分析和统计图形生成器,用起来还是比较舒服的,呵呵
- 用Perf4j做全局性能统计
- perf4j 性能日志
- 利用 perf4j 做服务监控
- perf4j+SpringMvc监测代码性能
- perf4j
- 使用Perf4J进行性能分析和监控
- 使用Perf4J进行性能分析和监控
- 利用Perf4j 对java项目进行性能监控
- perf4j使用
- Centreon数据库数据规整做月度性能统计
- 用excel做考核统计
- 用newlisp做数学统计
- 用c++做性能测试
- 全局内存性能测试
- 用php做统计出错心得
- spring2.5 配置Perf4J
- Perf4j的使用
- 用psutil库统计系统性能
- hibernate的两种映射
- strtok函数的用法示例
- 将年月日时分秒都保存进数据库
- 黑客快速入门
- 排序算法复习(Java实现): 插入,冒泡,选择,Shell,快速排序
- 用Perf4j做全局性能统计
- C/C++与汇编混编时的内嵌汇编调用C/C++写的函数的演示
- tomcat总是访问旧的页面
- sqlserver date format(SqlServer常用日期格式)
- Windows 系统 运行命令 合集
- Java中对Date的format
- 理解并使用 JSPWiki 中的权限控制
- 牙菌斑、牙垢、牙结石、龋齿需要怎么来清洁
- java.sql.Timestamp cannot be cast to java.sql.Date求助