利用Perf4j 对java项目进行性能监控

Perf4j 可以对自定义监控范围的java代码进行日志记录,再经统计分析生成所需性能数据。Perf4j 提供了对常用日志工具log4j的扩展以方便与产品集成,它产生的性能数据可被用于生成可视化的性能图表。
Perf4j是一款专门用于java服务器端代码计时,记录日志和监控结果的开源工具包。Per4j对常用日志工具包进行了扩展,能够将得到的原始性能数据进行统计并发布到可定制的输出源,如控制台、日志文件、JMX等。
本文主要面向JAVA EE项目,来说明Perf4j集成log4j来进行性能的的分析。
首先要在项目中加入perf4j和log4j的jar包。
然后修改log4j.xml,使得支持perf4j
    
    
    
    <appender name="CoalescingStatistics"
        class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
        
        <param name="TimeSlice" value="3600000" />
        <appender-ref ref="performanceAppenderCSV" /><appender-ref ref="performanceAppenderLOG" />
    appender>
    
    <appender name="performanceAppenderLOG" class="org.apache.log4j.FileAppender">
        <param name="File" value="${web.XxxWeb.root}/WEB-INF/logs/perfmance/perfmance.log" />
        <param name="Append" value="true" />                                              
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n" />
        layout>
    appender>
    <appender name="performanceAppenderCSV" class="org.apache.log4j.FileAppender">
        <param name="File" value="${web.XxxWeb.root}/WEB-INF/logs/perfmance/perfmance.csv" />
        <param name="Append" value="true" />                                              
        <param name="DatePattern" value="'.'yyyy-MM-dd'.csv'" />
        <layout class="org.perf4j.log4j.StatisticsCsvLayout">
            <param name="ConversionPattern" value="%m%n" />
        layout>
    appender>
    
    <logger name="org.perf4j.TimingLogger" additivity="false">
        <level value="INFO" />
        <appender-ref ref="CoalescingStatistics" />
    logger>
简单的测试代码如下:
    public long add(DmModel dmModel) {
        StopWatch stopWatch = new Slf4JStopWatch("dmService.add",
                "textArgs");
        long maxbh = fydmbDao.getMaxDmbh();
        maxbh++;
        dmModel.setDqbs("1");
        dmModel.setXgsj(new Date());
        dmModel.setBh(maxbh);
        dmbDao.addFyDm(DmConvertor.modelToFydm(dmModel));
        stopWatch.stop();
        return dmModel.getBh();
    }
运行junit测试即可看到如下结果:
Performance Statistics   2013-09-06 19:00:00 - 2013-09-06 20:00:00
Tag                                                          Avg(ms)         Min         Max     Std Dev       Count
FydmService.addFy                                      181.0         181         181         0.0             1
最后,介绍perf4j在实战中的应用----借助于aop,实现对服务性能的批量记录
1、配置log4j,如上
 
2、编写 Perf4jInterceptor代码
package nju.software.XxxWeb.performance;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.perf4j.StopWatch;
import org.perf4j.slf4j.Slf4JStopWatch;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
/**
 * @author typ
 * 
 */
public class Perf4jInterceptor implements MethodBeforeAdvice,
        AfterReturningAdvice {
    /**
     * 用于存放不同服务的不同方法的stopWatch
     */
    private Map watches = new HashMap();
 
    // 在服务中得方法执行之前加入before方法中得如下逻辑,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);
        }
    }
 
    // 在服务执行完毕,返回值之前加入如下afterReturning逻辑,stopWatch结束统计
    public void afterReturning(Object returnValue, Method method,
            Object[] args, Object target) throws Throwable {
        String completeMethodName = getCompleteMethodName(target, method);
        // logger.info("After:"+completeMethodName);
        // 记录性能
        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();
    }
}
以上类是附加逻辑,用于对拦截器拦截下的服务添加before和after逻辑。即对所有的服务进行拦截,在服务方法执行之前加入before方法内的逻辑,在服务返回之后加入afterReturning方法逻辑。
 
3、配置applicationContext.xml
    
    <bean id="perf4jInterceptor" class="nju.software.XxxWeb.performance.Perf4jInterceptor">
    bean>
    
    <bean id="perf4jProxy"
        class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames">
            <list>
                
                <value>dmServicevalue>
                <value>xzqdmbServicevalue>
                <value>gjServicevalue>
                <value>xxxServicevalue>
                <value>gjXxxGxServicevalue>
                <value>gzServicevalue>
                <value>sxgzServicevalue>
                <value>xtyhServicevalue>
                <value>xtjsServicevalue>
                <value>qxServicevalue>
                <value>xtdxServicevalue>
                <value>bmbServicevalue>
                <value>gzbwlServicevalue>
                <value>executionServicevalue>
                <value>repositoryServicevalue>
                <value>taskServicevalue>
                <value>aydmbServicevalue>
                <value>hytglServicevalue>
                <value>hytcyServicevalue>
                <value>sftjPzxxbServicevalue>
            list>
        property>
        <property name="interceptorNames">
            <list>
                <value>perf4jInterceptorvalue>
            list>
        property>
    bean>
至此为止,java EE的项目中就可以使用perf4j来统计各种service的性能了
 
 

你可能感兴趣的:(总结)