JavaMelody监控spring、struts
前言
前面讲过了Javamelody的基本配置,如何使用Javamelody来监控JDBC以及SQL。
这里继续讲解一下如何监控struts和spring。
手码不易,转载请注明:xingoo
由于spring的理论并不扎实,监控spring又是依靠sring的面向切面AOP技术来做的,因此在配置的时候虽然参照官方文档,但是仍然无法获得监控数据。这里先说一下简单的struts的监控。
Struts监控
Struts的监控相对来说要简单多了,只要按照下面的步骤,肯定是没有问题的。
第一步,导入必要的jar包,需要的jar包前面已经提到过了。
一个是javamelody.jar,另一个是jrobin-x.jar
第二步,需要在web.xml中添加监控对应的过滤器
1 <filter> 2 <filter-name>monitoring</filter-name> 3 <filter-class>net.bull.javamelody.MonitoringFilter</filter-class> 4 5 <init-param> 6 <param-name>log</param-name> 7 <param-value>true</param-value> 8 </init-param> 9 </filter> 10 <filter-mapping> 11 <filter-name>monitoring</filter-name> 12 <url-pattern>/*</url-pattern> 13 </filter-mapping> 14 15 <listener> 16 <listener-class> net.bull.javamelody.SessionListener</listener-class> 17 </listener>
当然不要忘记struts自己的过滤器
1 <filter> 2 <filter-name>struts</filter-name> 3 <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> 4 5 <init-param> 6 <param-name>struts.action.extension</param-name> 7 <param-value>action</param-value> 8 </init-param> 9 </filter> 10 <filter-mapping> 11 <filter-name>struts</filter-name> 12 <url-pattern>/*</url-pattern> 13 </filter-mapping>
第三步,在struts.xml中添加默认的package,这个package提供了默认的拦截器
1 <package name= "default" extends ="struts-default,json-default" > 2 <!-- 向Struts2框架中注册拦截器或者拦截器栈,一般多用于自定义拦截器或拦截器栈的注册 --> 3 <interceptors> 4 <interceptor name ="monitoring" class ="net.bull.javamelody.StrutsInterceptor" /> 5 <interceptor-stack name ="myStack" > 6 <interceptor-ref name ="monitoring" /> 7 <interceptor-ref name ="defaultStack" /> 8 </interceptor-stack> 9 </interceptors> 10 <!--设置整个包范围内所有Action所要应用的默认拦截器信息 --> 11 <default-interceptor-ref name ="myStack" /> 12 </package>
其他的package比如sttuts的包,都要继承这个default的包。
1 <package name="test" extends="default"> 2 <action name="login" class="com.test.LoginAction"> 3 <result name="error">/error.jsp</result> 4 <result name="success">/success.jsp</result> 5 </action> 6 7 <action name="search" class="com.test.SearchAction"> 8 <result name="error">/error.jsp</result> 9 <result name="success">/searchSuccess.jsp</result> 10 </action> 11 12 <action name="hibernatetest" class="com.test.TestHibernate"> 13 <result name="error">/error.jsp</result> 14 <result name="success">/hibernateSuccess.jsp</result> 15 </action> 16 17 </package>
上面三步,就算是配置完了。
如果不触发监控事件,比如点击某些东西进行响应跳转,使用struts,那么是监控不到数据的。虽然有显示对应的图片,但是图片上的数据都是0,Nan或者下方的表为空,这些都是没有触发监听事件的原因。
Spring监控
JavaMelody针对于spring的监控是到方法级别的,我们可以监控到某个类的某个方法,因此需要使用到AOP里面的pointcut进行监听。
下面看一下主要的监听配置:
第一步,依然是导入必备的jar包,上面说的两个,不再重复了。
第二步,加载monitoring-spring.xml以及我们自己的applicationContext.xml配置文件。
如果想要在加载web.xml的时候读取spring的配置文件,需要实现一个监听器
1 <listener> 2 <listener-class> 3 org.springframework.web.context.ContextLoaderListener 4 </listener-class> 5 </listener>
然后在web.xml中,添加spring文件路径。通过这只上下文参数来设置
1 <context-param> 2 <param-name> contextConfigLocation</param-name> 3 <param-value> 4 classpath:net/bull/javamelody/monitoring-spring.xml 5 /WEB-INF/classes/bean.xml 6 </param-value> 7 </context-param>
上面第一行,定义了监控应用的spring配置文件,下面是我们自己的spring的配置文件。
第三步,通过正则表达式,定位方法
1 <bean id="facadeMonitoringAdvisor" class="net.bull.javamelody.MonitoringSpringAdvisor"> 2 <property name="pointcut"> 3 <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut"> 4 <property name="pattern" value="com.test.*.*" /> 5 </bean> 6 </property> 7 </bean>
这里面主要是使用了JdkRegexpMethodPointcut,也就是正则表达式定位业务方法。下面的参数可能是pattern或者patterns,参数
com.test.*.* 意思是对应com.test包下的所有类的所有方法
com.test.*.doGet 意思是对应com.test包下所有类的叫doGet的方法
.*Test.* 意思是所有以Test结尾的类的所有方法
具体的配置详情,还需要去学习一下AOP中关于切入点pointcut的使用。如果不会的话,多看一下相关的知识吧。
然后就是针对想要监控的bean,添加这个拦截器:
1 <bean id="ProxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> 2 <property name="target"> 3 <ref bean="Computer" /> 4 </property> 5 <property name="interceptorNames"> 6 <list> 7 <value>facadeMonitoringAdvisor</value> 8 </list> 9 </property> 10 </bean>
这样在使用ProxyFactoryBean的时候,就会自动调用拦截器interceptorNames,定位到facadeMonitoringAdvisor中的方法,并在方法前后出发net.bull.javamelody.MonitoringSpringAdvisor,进行信息的监控。
相应切面的编程代码这里也直接附上,有兴趣的可以运行试验下,主要是理解这个思想,就可以监控自己感兴趣的业务了。
1 people.java 2 public class People{ 3 // 讲话 4 public void speak() { 5 System.out.println("Hello,我是People!"); 6 } 7 // 跑步 8 public void Running() { 9 System.out.println("我在跑……跑…………逃……"); 10 } 11 // 恋爱 12 public void Loving() { 13 System.out.println("我在和MM恋爱……别来打搅我!"); 14 } 15 // 死亡 16 public void died() { 17 System.out.println("完了,我死了"); 18 } 19 } 20 21 advice类 22 public class LogerPeople implements MethodBeforeAdvice { 23 24 public void before(Method method, Object[] args, Object target) 25 throws Throwable { 26 System.out.println(target.getClass().getSimpleName() + "正在" + 27 method.getName()+ "!"); 28 System.out.println("before!________________"); 29 30 } 31 } 32 33 TestMain 34 public class TestMain { 35 36 public static void main(String[] args) { 37 ApplicationContext ac = new ClassPathXmlApplicationContext( 38 "bean1.xml"); 39 40 //通过ProxyFactoryBean获取IComputer接口实现类的实例 41 People c = (People) ac.getBean("ProxyFactoryBean"); 42 c.speak(); 43 c.Running(); 44 c.Loving(); 45 c.died(); 46 } 47 } 48 49 50 spring配置文件 51 <bean id="Computer" class="com.test.People"></bean> 52 <bean id="LogerComputer" class="com.test.LogerPeople" /> 53 54 <bean id="ProxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> 55 <property name="target"> 56 <ref bean="Computer" /> 57 </property> 58 <property name="interceptorNames"> 59 <list> 60 <value>DefaultAdvisor</value> 61 </list> 62 </property> 63 </bean> 64 65 <bean id="DefaultAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> 66 <property name="pointcut" ref="JdkRegexpPointcut" /> 67 <property name="advice" ref="LogerComputer" /> 68 </bean> 69 <bean id="JdkRegexpPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> 70 <property name="patterns"> 71 <list> 72 <value>.*spea.*</value> 73 <value>.*ing</value> 74 <value>.*di.*</value> 75 </list> 76 </property> 77 <property name="excludedPattern" value=".*Run.*" /> 78 </bean>
我捣鼓了一天半的时间,一直都监控不到数据,就是因为虽然配置了默认的拦截器,但是一直都没有对拦截器进行触发响应。因此一直都没有调用到这个监控类,也就当然没有监控信息出现了。
总结起来,还是因为没有理解spring AOP的原理,以后会补上spring的相关学习。