为spring2.5中的jpetstore增加perf4j监控

perf4j是一款类似于log4j的性能检测工具.

 

它的基本操作就是封装我们常用的通过System.currentTimeMillis();来计算执行时间.如下:

Java代码
  1. long  start = System.currentTimeMillis();  
  2.   
  3. // execute the block of code to be timed   
  4.   
  5. System.out.println("ms for block n was: "  + (System.currentTimeMillis() - start));  
long start = System.currentTimeMillis();

// execute the block of code to be timed

System.out.println("ms for block n was: " + (System.currentTimeMillis() - start));

 

它的最大优势是可以根据这些数据对要检测的代码块的执行进行数字以及图形化统计.

 

下面是通过AOP方式为jpetstore添加的perf4j步骤.

 

1.在pom文件中增加如下依赖

 

Xml代码
  1. < dependency >   
  2.     < groupId > org.perf4j </ groupId >   
  3.     < artifactId > perf4j </ artifactId >   
  4.     < version > 0.9.12-SNAPSHOT </ version >   
  5. </ dependency >   
  6. < dependency >   
  7.     < groupId > commons-jexl </ groupId >   
  8.     < artifactId > commons-jexl </ artifactId >   
  9.     < version > 1.1 </ version >   
  10.     < type > jar </ type >   
  11. </ dependency >   
  12. < dependency >   
  13.     < groupId > log4j </ groupId >   
  14.     < artifactId > log4j </ artifactId >   
  15.     < version > 1.2.14 </ version >   
  16.     < type > jar </ type >   
  17. </ dependency >   
    <dependency>
        <groupId>org.perf4j</groupId>
        <artifactId>perf4j</artifactId>
        <version>0.9.12-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>commons-jexl</groupId>
        <artifactId>commons-jexl</artifactId>
        <version>1.1</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
        <type>jar</type>
    </dependency>
 

 

2.增加编译插件如下:

Xml代码
  1. < build >   
  2.     < finalName > jpetstore </ finalName >   
  3.     < defaultGoal > package </ defaultGoal >   
  4.     < plugins >   
  5.         < plugin >   
  6.             < groupId > org.apache.maven.plugins </ groupId >   
  7.             < artifactId > maven-compiler-plugin </ artifactId >   
  8.             < version > 2.0.2 </ version >   
  9.             < configuration >   
  10.                 < source > 1.5 </ source >   
  11.                 < target > 1.5 </ target >   
  12.                 < encoding > UTF-8 </ encoding >   
  13.             </ configuration >   
  14.         </ plugin >   
  15.     </ plugins >   
  16.   </ build >   
<build>
    <finalName>jpetstore</finalName>
    <defaultGoal>package</defaultGoal>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>2.0.2</version>
			<configuration>
				<source>1.5</source>
				<target>1.5</target>
				<encoding>UTF-8</encoding>
			</configuration>
		</plugin>
	</plugins>
  </build>

 3.为需要进行检测的方法增加注解@Profiled

  譬如PetStoreImpl类中

Java代码
  1. @Profiled   
  2. public  Category getCategory(String categoryId) {  
  3.     return   this .categoryDao.getCategory(categoryId);  
  4. }  
@Profiled
public Category getCategory(String categoryId) {
	return this.categoryDao.getCategory(categoryId);
}

 4.在spring配置文件中增加Aspectj的支持以及perf4j的支持

Xml代码
  1. < aop:aspectj-autoproxy />   
  2.   
  3. < bean   id = "timingAspect"   class = "org.perf4j.log4j.aop.TimingAspect" />   
<aop:aspectj-autoproxy/>

<bean id="timingAspect" class="org.perf4j.log4j.aop.TimingAspect"/>

 5.为了能够在页面上进行定制统计图表的实时查看,需要在web.xml中增加如下配置

Xml代码
  1. < servlet >   
  2.         < servlet-name > perf4j </ servlet-name >   
  3.         < servlet-class > org.perf4j.log4j.servlet.GraphingServlet </ servlet-class >   
  4.   
  5.         < init-param >   
  6.             < param-name > graphNames </ param-name >   
  7.             < param-value > graphExecutionTimes,graphExecutionTPS </ param-value >   
  8.         </ init-param >   
  9.     </ servlet >   
  10.   
  11.     < servlet-mapping >   
  12.         < servlet-name > perf4j </ servlet-name >   
  13.         < url-pattern > /perf4j </ url-pattern >   
  14.     </ servlet-mapping >   
<servlet>
        <servlet-name>perf4j</servlet-name>
        <servlet-class>org.perf4j.log4j.servlet.GraphingServlet</servlet-class>

        <init-param>
            <param-name>graphNames</param-name>
            <param-value>graphExecutionTimes,graphExecutionTPS</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>perf4j</servlet-name>
        <url-pattern>/perf4j</url-pattern>
    </servlet-mapping>

 此处定义的graphExecutionTimes,graphExecutionTPS为log4j配置文件中定义的appender,可增加可删除.

6.现在最重要的一步就是log4j中的设置了.

    首先将jpetstore的log4j配置文件log4j.properties更换为log4j.xml。内容如下

Xml代码
  1. <? xml   version = "1.0"   encoding = "UTF-8"   ?>   
  2. <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">   
  3.   
  4. < log4j:configuration   debug = "false"   xmlns:log4j = "http://jakarta.apache.org/log4j/" >   
  5.     <!--  
  6.       This default ConsoleAppender is used to log all NON perf4j messages  
  7.       to System.out  
  8.     -->   
  9.     < appender   name = "console"   class = "org.apache.log4j.ConsoleAppender" >   
  10.         < layout   class = "org.apache.log4j.PatternLayout" >   
  11.             < param   name = "ConversionPattern"   value = "%-5p %c{1} - %m%n" />   
  12.         </ layout >   
  13.     </ appender >   
  14.   
  15.     <!-- Perf4J appenders -->   
  16.     <!--  
  17.       This AsyncCoalescingStatisticsAppender groups StopWatch log messages  
  18.       into GroupedTimingStatistics messages which it sends on the  
  19.       file appender defined below  
  20.     -->   
  21.     < appender   name = "CoalescingStatistics"   
  22.               class = "org.perf4j.log4j.AsyncCoalescingStatisticsAppender" >   
  23.         <!--  
  24.           The TimeSlice option is used to determine the time window for which  
  25.           all received StopWatch logs are aggregated to create a single  
  26.           GroupedTimingStatistics log. Here we set it to 10 seconds, overriding  
  27.           the default of 30000 ms  
  28.         -->   
  29.         < param   name = "TimeSlice"   value = "10000" />   
  30.         < appender-ref   ref = "fileAppender" />   
  31.         <!--  
  32.           Note how the GraphingStatisticsAppenders have been attached to the  
  33.           CoalescingStatistics here.  
  34.         -->   
  35.         < appender-ref   ref = "graphExecutionTimes" />   
  36.         < appender-ref   ref = "graphExecutionTPS" />   
  37.     </ appender >   
  38.   
  39.     <!-- This file appender is used to output aggregated performance statistics -->   
  40.     < appender   name = "fileAppender"   class = "org.apache.log4j.FileAppender" >   
  41.         < param   name = "File"   value = "${petstore.root}/WEB-INF/perfStats.log" />   
  42.         < layout   class = "org.apache.log4j.PatternLayout" >   
  43.             < param   name = "ConversionPattern"   value = "%m%n" />   
  44.         </ layout >   
  45.     </ appender >   
  46.   
  47.     <!--  
  48.       This first GraphingStatisticsAppender graphs Mean execution times for the  
  49.       firstBlock and secondBlock tags  
  50.     -->   
  51.     < appender   name = "graphExecutionTimes"   
  52.               class = "org.perf4j.log4j.GraphingStatisticsAppender" >   
  53.         <!-- Possible GraphTypes are Mean, Min, Max, StdDev, Count and TPS -->   
  54.         < param   name = "GraphType"   value = "Mean" />   
  55.         <!-- The tags of the timed execution blocks to graph are specified here -->   
  56.         < param   name = "TagNamesToGraph"   value = "getCategory,getItem,getItemListByProduct,getProduct,getProductListByCategory,searchProductList" />   
  57.         < appender-ref   ref = "graphsFileAppender" />   
  58.     </ appender >   
  59.   
  60.     <!--  
  61.       This second GraphingStatisticsAppender graphs transactions per second  
  62.       for the firstBlock and secondBlock tags  
  63.     -->   
  64.     < appender   name = "graphExecutionTPS"   
  65.               class = "org.perf4j.log4j.GraphingStatisticsAppender" >   
  66.         < param   name = "GraphType"   value = "TPS" />   
  67.         < param   name = "TagNamesToGraph"   value = "getCategory,getItem,getItemListByProduct,getProduct,getProductListByCategory,searchProductList" />   
  68.         < appender-ref   ref = "graphsFileAppender" />   
  69.     </ appender >   
  70.   
  71.     <!--  
  72.       This file appender is used to output the graph URLs generated  
  73.       by the GraphingStatisticsAppenders  
  74.     -->   
  75.     < appender   name = "graphsFileAppender"   class = "org.apache.log4j.FileAppender" >   
  76.         < param   name = "File"   value = "${petstore.root}/WEB-INF/perfGraphs.log" />   
  77.         < layout   class = "org.apache.log4j.PatternLayout" >   
  78.             < param   name = "ConversionPattern"   value = "%m%n" />   
  79.         </ layout >   
  80.     </ appender >   
  81.   
  82.     <!-- Loggers -->   
  83.     <!--  
  84.       The Perf4J logger. Note that org.perf4j.TimingLogger is the value of the  
  85.       org.perf4j.StopWatch.DEFAULT_LOGGER_NAME constant. Also, note that  
  86.       additivity is set to false, which is usually what is desired - this means  
  87.       that timing statements will only be sent to this logger and NOT to  
  88.       upstream loggers.  
  89.     -->   
  90.     < logger   name = "org.perf4j.TimingLogger"   additivity = "false" >   
  91.         < level   value = "DEBUG" />   
  92.         < appender-ref   ref = "CoalescingStatistics" />   
  93.     </ logger >   
  94.   
  95.     <!--  
  96.       The root logger sends all log statements EXCEPT those sent to the perf4j  
  97.       logger to System.out.  
  98.     -->   
  99.     < root >   
  100.         < level   value = "INFO" />   
  101.         < appender-ref   ref = "console" />   
  102.     </ root >   
  103. </ log4j:configuration >   
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">
    <!--
      This default ConsoleAppender is used to log all NON perf4j messages
      to System.out
    -->
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
        </layout>
    </appender>

    <!-- Perf4J appenders -->
    <!--
      This AsyncCoalescingStatisticsAppender groups StopWatch log messages
      into GroupedTimingStatistics messages which it sends on the
      file appender defined below
    -->
    <appender name="CoalescingStatistics"
              class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
        <!--
          The TimeSlice option is used to determine the time window for which
          all received StopWatch logs are aggregated to create a single
          GroupedTimingStatistics log. Here we set it to 10 seconds, overriding
          the default of 30000 ms
        -->
        <param name="TimeSlice" value="10000"/>
        <appender-ref ref="fileAppender"/>
        <!--
          Note how the GraphingStatisticsAppenders have been attached to the
          CoalescingStatistics here.
        -->
        <appender-ref ref="graphExecutionTimes"/>
        <appender-ref ref="graphExecutionTPS"/>
    </appender>

    <!-- This file appender is used to output aggregated performance statistics -->
    <appender name="fileAppender" class="org.apache.log4j.FileAppender">
        <param name="File" value="${petstore.root}/WEB-INF/perfStats.log"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n"/>
        </layout>
    </appender>

    <!--
      This first GraphingStatisticsAppender graphs Mean execution times for the
      firstBlock and secondBlock tags
    -->
    <appender name="graphExecutionTimes"
              class="org.perf4j.log4j.GraphingStatisticsAppender">
        <!-- Possible GraphTypes are Mean, Min, Max, StdDev, Count and TPS -->
        <param name="GraphType" value="Mean"/>
        <!-- The tags of the timed execution blocks to graph are specified here -->
        <param name="TagNamesToGraph" value="getCategory,getItem,getItemListByProduct,getProduct,getProductListByCategory,searchProductList"/>
        <appender-ref ref="graphsFileAppender"/>
    </appender>

    <!--
      This second GraphingStatisticsAppender graphs transactions per second
      for the firstBlock and secondBlock tags
    -->
    <appender name="graphExecutionTPS"
              class="org.perf4j.log4j.GraphingStatisticsAppender">
        <param name="GraphType" value="TPS"/>
        <param name="TagNamesToGraph" value="getCategory,getItem,getItemListByProduct,getProduct,getProductListByCategory,searchProductList"/>
        <appender-ref ref="graphsFileAppender"/>
    </appender>

    <!--
      This file appender is used to output the graph URLs generated
      by the GraphingStatisticsAppenders
    -->
    <appender name="graphsFileAppender" class="org.apache.log4j.FileAppender">
        <param name="File" value="${petstore.root}/WEB-INF/perfGraphs.log"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n"/>
        </layout>
    </appender>

    <!-- Loggers -->
    <!--
      The Perf4J logger. Note that org.perf4j.TimingLogger is the value of the
      org.perf4j.StopWatch.DEFAULT_LOGGER_NAME constant. Also, note that
      additivity is set to false, which is usually what is desired - this means
      that timing statements will only be sent to this logger and NOT to
      upstream loggers.
    -->
    <logger name="org.perf4j.TimingLogger" additivity="false">
        <level value="DEBUG"/>
        <appender-ref ref="CoalescingStatistics"/>
    </logger>

    <!--
      The root logger sends all log statements EXCEPT those sent to the perf4j
      logger to System.out.
    -->
    <root>
        <level value="INFO"/>
        <appender-ref ref="console"/>
    </root>
</log4j:configuration>

 

最后启动服务器,点击petstore上面的链接,就可以看到项目WEB-INF/下面的perfStats.log,perfGraphs.log已经有数据了。

现在查看http://localhost:8080/jpetstore/perf4j,就可以查看perf4j对各个检测方法的图形统计了,如下:


为spring2.5中的jpetstore增加perf4j监控_第1张图片
 
为spring2.5中的jpetstore增加perf4j监控_第2张图片

上面我们是采用的AOP方式,另外也可以采用更具侵入性的方法来实现,在SqlMapProductDao代码块的开始和结尾增加如下代码:

Java代码
  1. public  List searchProductList(String keywords)  throws  DataAccessException {  
  2.     StopWatch stopWatch = new  LoggingStopWatch();  
  3.     Object parameterObject = new  ProductSearch(keywords);  
  4.     List aaa = getSqlMapClientTemplate().queryForList("searchProductList" , parameterObject);  
  5.     stopWatch.stop("searchProductList" );  
  6.     return  aaa;  
  7. }  
public List searchProductList(String keywords) throws DataAccessException {
	StopWatch stopWatch = new LoggingStopWatch();
    Object parameterObject = new ProductSearch(keywords);
    List aaa = getSqlMapClientTemplate().queryForList("searchProductList", parameterObject);
    stopWatch.stop("searchProductList");
    return aaa;
}

 

最后,perf4j在检测方式上还提供其他一些特性,譬如可以自定义TAG。。。可以查阅其相关文档http://perf4j.codehaus.org/devguide.html

 

 

 

来自:http://eddysheng.iteye.com/blog/434913

你可能感兴趣的:(apache,AOP,maven,log4j,servlet)