Perf4j 可以对自定义监控范围的java代码进行日志记录,再经统计分析生成所需性能数据。Perf4j 提供了对常用日志工具log4j的扩展以方便与产品集成,它产生的性能数据可被用于生成可视化的性能图表。
Perf4j是一款专门用于java服务器端代码计时,记录日志和监控结果的开源工具包。Per4j对常用日志工具包进行了扩展,能够将得到的原始性能数据进行统计并发布到可定制的输出源,如控制台、日志文件、JMX等。
本文主要面向JAVA EE项目,来说明Perf4j集成log4j来进行性能的的分析。
首先要在项目中加入perf4j和log4j的jar包。
然后修改log4j.xml,使得支持perf4j
    <!-- perf4j的Logger及Appender -->
    <!-- Perf4J appenders -->
    <!-- AsyncCoalescingStatisticsAppender收集StopWatch的日志信息并传送到下游的文件appenders。 -->
    <appender name="CoalescingStatistics"
        class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
        <!-- TimeSlice配置多少时间间隔去做一次汇总写入文件中 默认值是 30000 ms ,设置为10分钟-->
        <param name="TimeSlice" value="3600000" />
        <appender-ref ref="performanceAppenderCSV" /><appender-ref ref="performanceAppenderLOG" />
    </appender>
    <!-- 把汇总的perf4j的日志信息写到${web.XxxWeb.root}/WEB-INF/logs/perfmance/perfmance.log文件中去 -->
    <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>
    <!-- 11、perf4j日志记录器org.perf4j.TimingLogger 日志记录在${web.XxxWeb.root}/WEB-INF/logs/performance/目录下 -->
    <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<String, StopWatch> watches = new HashMap<String, StopWatch>();
 
 
    // 在服务中得方法执行之前加入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
    <!-- 定义Perf4jInterceptor的bean -->
    <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>fydmbService</value> -->
                <value>dmService</value>
                <value>xzqdmbService</value>
                <value>gjService</value>
                <value>xxxService</value>
                <value>gjXxxGxService</value>
                <value>gzService</value>
                <value>sxgzService</value>
                <value>xtyhService</value>
                <value>xtjsService</value>
                <value>qxService</value>
                <value>xtdxService</value>
                <value>bmbService</value>
                <value>gzbwlService</value>
                <value>executionService</value>
                <value>repositoryService</value>
                <value>taskService</value>
                <value>aydmbService</value>
                <value>hytglService</value>
                <value>hytcyService</value>
                <value>sftjPzxxbService</value>
            </list>
        </property>
        <property name="interceptorNames">
            <list>
                <value>perf4jInterceptor</value>
            </list>
        </property>

</bean>

至此为止,java EE的项目中就可以使用perf4j来统计各种service的性能了
 
 

利用Perf4j 对java项目进行性能监控的更多相关文章

  1. 性能调优之Java系统级性能监控及优化

    性能调优之Java系统级性能监控及优化   对于性能调优而言,通常我们需要经过以下三个步骤:1,性能监控:2,性能剖析:3,性能调优 性能调优:通过分析影响Application性能问题根源,进行优化 ...

  2. java虚拟机之性能监控与故障处理工具

    sun jdk性能监控与故障处理工具 jps: 可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一id. jstat: 用于监视虚拟机各种运行状态信息的命令航工具.它可 ...

  3. 深入理解JAVA虚拟机 虚拟机性能监控和故障处理工具

    jre的bin目录下的工具,都非常小.它都是tools.jar下面的代码的一层封装而已.tools.jar不是java标准,是Hotspot实现的. 名称 作用 jps JVM Process Sta ...

  4. 利用Docker搭建java项目开发环境

    一.需求 一台 Ubuntu 16.0.4 LTS ,安装了Docker服务,Rancher服务,也制作了Tomcat相关的image,接下来我们就来说一下如何快速的构建一个开发环境和测试环境 二.步 ...

  5. Java虚拟机之性能监控

    一.jstat:虚拟机统计信息监控工具监视虚拟机各种运行状态 图中,S0.S1(Survivor0.Survivor1)代表两个Survivor区,其中一个值为57.60%.另一个为0.E(Eden) ...

  6. 利用IDEA把Java项目打成jar包

    第一步:按如下步骤或Ctrl+Shift+Alt+S打开 Project Structure第二步:第三步:选择要执行的文件,  依次选择项目, main方法所在的文件, 保存如果出现以下错误:则根据 ...

  7. Java生产环境下性能监控与调优详解视频教程 百度云 网盘

    集数合计:9章Java视频教程详情描述:A0193<Java生产环境下性能监控与调优详解视频教程>软件开发只是第一步,上线后的性能监控与调优才是更为重要的一步本课程将为你讲解如何在生产环境 ...

  8. 使用Memcached改进Java企业级应用性能:架构和设置

    Memcached由Danga Interactive开发.用来提升LiveJournal.com站点性能. Memcached分布式架构支持众多的社交网络应用,Twitter.Facebook还有W ...

  9. JVM-Java程序性能监控-初级篇

    前篇 - 小伙们都知道,java程序的性能监控主要是针对jvm中heap的监控~ 那么在做压力测试时如何对heap.线程等一系列的指标进行的监控的呢? 首先-你若不懂命令,那么就需要了解一套Java程 ...

随机推荐

  1. itextSharp 对pdf的每个页面添加footer/header

    static void SetAllHeaderFooter(string inputPath) { PdfReader reader=new PdfReader(inputPath); PdfSta ...

  2. Ch05 视图模型

    5.1  什么是视图模型 5.1.1  在线商店示例 5.1.2  建立视图模型 5.1.3  交付表现模型 5.1.4  ViewData.Model 5.2  表现用户输入 5.2.1  设计(输 ...

  3. delphi如何加上spliter分割条,任意调整大小

    如题1:如何把一个panel分割成四个小的panle 2:也就是如何加上spliter,分割条,任意调整大小 3.如何有独立的handle使用多个总共5个为什么呢,你放4个panel 然后放split ...

  4. UIViewController加载过程

    UIViewController是视图和数据的桥梁,UIViewController是所有controller的基类,ios内置了很多试图控制器,如导航控制器,tableViewController等 ...

  5. 一则 ORA-00471 处理方法

    公司新上架一台服务到机房,硬件是IBM X3850 X5,硬件配置算是好的,内存有128GB.SA安装好系统--(版本sule 32bit)后通知我可以安装数据库了.忙活半天,安装好oracle 92 ...

  6. Android异步载入全解析之使用多线程

    异步载入之使用多线程 初次尝试 异步.异步,事实上说白了就是多任务处理.也就是多线程执行.多线程那就会有各种问题,我们一步步来看.首先.我们创建一个class--ImageLoaderWithoutC ...

  7. 图片热区——axure线框图部件库介绍

    首先,我们将图片热区组建拖动到axure页面编辑区域 1. 图片热区为页面图片或者其他部件添加热区,添加交互 我们一般在做专题的时候,会遇到一些组合商品,但是又需要单独分别设置连接,如果是2张图片还好 ...

  8. 14.10.2 File Space Management 文件空间管理:

    14.10.2 File Space Management 文件空间管理: 数据文件 你定义在配置文件形成了InnoDB的系统表空间, 文件是逻辑连接形成表空间,没有条带化使用. 你不能定义你的表在表 ...

  9. linux(readhat) yum源安装

    在安装測试环境的时候遇到了一个问题,/etc/yum/repos.d中不存在文件或目录,无法更新yum源. 解决方法: (一.配置网络yum源) 1.首先在/etc/yum/repos.d/文件夹下创 ...

  10. Servlet过滤器——使用过滤器禁止浏览器缓存页面

    1.概述 IE缓存虽然能提高已储存网站的访问速度,但是过度的IE缓存会影响浏览器的响应速度.同时还可能为网站的运行带来一些不必要的麻烦.例如:可能会因为浏览器缓存的应用,而导致Web服务器不能准确的计 ...