View Javadoc

1   /*
2    ~ Copyright 2006-2007 Nicolas De Loof.
3    ~
4    ~ Licensed under the Apache License, Version 2.0 (the "License");
5    ~ you may not use this file except in compliance with the License.
6    ~ You may obtain a copy of the License at
7    ~
8    ~      http://www.apache.org/licenses/LICENSE-2.0
9    ~
10   ~ Unless required by applicable law or agreed to in writing, software
11   ~ distributed under the License is distributed on an "AS IS" BASIS,
12   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   ~ See the License for the specific language governing permissions and
14   ~ limitations under the License.
15   */
16  package org.jmonit.support.aop;
17  
18  import org.aopalliance.intercept.MethodInterceptor;
19  import org.aopalliance.intercept.MethodInvocation;
20  import org.jmonit.Monitor;
21  import org.jmonit.Monitoring;
22  import org.jmonit.Repository;
23  import org.jmonit.Stopwatch;
24  
25  /**
26   * AOP-alliance interceptor to evaluate component performances using an
27   * intercpetor. Typically used with spring-aop.
28   * 
29   * @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
30   */
31  public class PerformanceInterceptor
32      implements MethodInterceptor
33  {
34      /** The jMonit repository */
35      private Repository repository;
36  
37      /**
38       * {@inheritDoc}
39       * 
40       * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
41       */
42      public final Object invoke( MethodInvocation invocation )
43          throws Throwable
44      {
45          String name = getMonitorName( invocation );
46          if ( name == null )
47          {
48              return invocation.proceed();
49          }
50          Monitor monitor = getRepository().getMonitor( name );
51          Stopwatch stopwatch = Stopwatch.start( monitor );
52  
53          Throwable error = null;
54          try
55          {
56              return invocation.proceed();
57          }
58          catch ( Throwable t )
59          {
60              error = t;
61              throw t;
62          }
63          finally
64          {
65              beforeReturning( monitor, error, stopwatch.getElapsedTime() );
66          }
67      }
68  
69      /**
70       * @param monitor the monitor associated to the method invocation
71       * @param error Throwable trowed by the method invocation if any
72       * @param duration the duration of the method invocation
73       */
74      private void beforeReturning( Monitor monitor, Throwable error, long duration )
75      {
76          Monitor detail;
77          if ( error != null )
78          {
79              detail = getFailureMonitor( monitor, error );
80          }
81          else
82          {
83              detail = getSuccessMonitor( monitor );
84          }
85          if ( detail != null )
86          {
87              detail.add( duration );
88          }
89      }
90  
91      /**
92       * Select a monitor for successful method invocations. Application can
93       * override this method for custom usage.
94       * 
95       * @param monitor the monitor associated to this mehod invocation
96       * @return a monitor, or <code>null</code> if no monitoring is expected
97       */
98      protected Monitor getSuccessMonitor( Monitor monitor )
99      {
100         String name = monitor.getName() + "~" + "success";
101         return getRepository().getMonitor( name );
102     }
103 
104     /**
105      * Select a monitor for method invocation failures. Application can override
106      * this method for custom usage.
107      * 
108      * @param monitor the monitor associated to this mehod invocation
109      * @return a monitor, or <code>null</code> if no monitoring is expected
110      */
111     protected Monitor getFailureMonitor( Monitor monitor, Throwable error )
112     {
113         String name = monitor.getName() + "~" + error.getClass().getSimpleName();
114         return getRepository().getMonitor( name );
115     }
116 
117     /**
118      * Compute the monitor name associated to this mehod invocation
119      * 
120      * @param invocation method beeing invoked
121      * @return monitor name. If <code>null</code>, nothing will be monitored
122      */
123     protected String getMonitorName( MethodInvocation invocation )
124     {
125         return invocation.getClass().getSimpleName() + "." + invocation.getMethod().getName();
126     }
127 
128     /**
129      * Set a custom application-defined repository
130      * 
131      * @param repository
132      */
133     public void setRepository( Repository repository )
134     {
135         this.repository = repository;
136     }
137 
138     /**
139      * Get the current repository
140      * 
141      * @return
142      */
143     protected Repository getRepository()
144     {
145         if ( repository == null )
146         {
147             return Monitoring.getRepository();
148         }
149         return repository;
150     }
151 
152 }