1 package org.apache.fulcrum.yaafi.interceptor.jamon;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.lang.reflect.Method;
23
24 import com.jamonapi.Monitor;
25 import com.jamonapi.MonitorFactory;
26 import com.jamonapi.RangeHolder;
27 import org.apache.fulcrum.yaafi.interceptor.util.MethodToStringBuilderImpl;
28
29 /**
30 * Encapsulating the JAMon 2.x related API calls. JAMon 2.x allows for a much
31 * more powerful integration with Avalon services :
32 * <ul>
33 * <li>custom ranges/units</li>
34 * <li>exception monitoring</li>
35 * <li>smooth web interface</li>
36 * </ul>
37 *
38 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
39 */
40
41 public class Jamon2PerformanceMonitorImpl implements JamonPerformanceMonitor
42 {
43 /** the default label being used */
44 private static final String MONITOR_LABEL = "ms.services";
45
46 /** our custom range definition */
47 private static RangeHolder rangeHolder;
48
49 /** is monitoring enabled */
50 private boolean isActive;
51
52 /** the method currently monitored */
53 private Method method;
54
55 /** the global JAMON monitor */
56 private Monitor monitor;
57
58 /** the time the monitoring was started */
59 private long startTime;
60
61 static
62 {
63 rangeHolder = Jamon2PerformanceMonitorImpl.createMSHolder();
64 }
65
66 /**
67 * Constructor.
68 *
69 * @param serviceName the service name of the service being monitored
70 * @param method the method to be monitored
71 * @param isActive is this an active monitor
72 */
73 public Jamon2PerformanceMonitorImpl(String serviceName, Method method, Boolean isActive)
74 {
75 this.method = method;
76 this.isActive = isActive.booleanValue();
77 }
78
79 /**
80 * Start the monitor.
81 */
82 public void start()
83 {
84 if(this.isActive)
85 {
86 // when reseting using the JAMon GUI the custom ranges are discarded
87 MonitorFactory.setRangeDefault(MONITOR_LABEL, Jamon2PerformanceMonitorImpl.rangeHolder);
88 // do the internal house-keeping
89 this.startTime = System.currentTimeMillis();
90 MethodToStringBuilderImpl methodToStringBuilder = new MethodToStringBuilderImpl(this.method, 0);
91 String methodSignature = methodToStringBuilder.toString();
92 this.monitor = MonitorFactory.getMonitor(methodSignature, MONITOR_LABEL);
93 this.monitor.start();
94 }
95 }
96
97 /**
98 * Stop the monitor
99 */
100 public void stop()
101 {
102 if(this.isActive)
103 {
104 long duration = System.currentTimeMillis() - this.startTime;
105 this.monitor.add(duration);
106 this.monitor.stop();
107 }
108 }
109
110 /**
111 * Stop the monitor
112 */
113 public void stop(Throwable throwable)
114 {
115 if(this.isActive)
116 {
117 // use a negative execution time to mark an exception for an affiliate
118 this.monitor.add(-1);
119 this.monitor.stop();
120 }
121 }
122
123 /**
124 * Create a performance report.
125 *
126 * @return the textual performance report
127 * @throws Exception generating the report failed
128 */
129 public String createReport() throws Exception
130 {
131 return MonitorFactory.getRootMonitor().getReport();
132 }
133
134 /**
135 * @return a customized range holder for measuring the execution time for services.
136 */
137 private static RangeHolder createMSHolder() {
138 RangeHolder result = new RangeHolder("<");
139 result.add("Exceptions",0);
140 result.add("0_10ms",10);
141 result.add("10_20ms",20);
142 result.add("20_40ms",40);
143 result.add("40_80ms",80);
144 result.add("80_160ms",160);
145 result.add("160_320ms",320);
146 result.add("320_640ms",640);
147 result.add("640_1280ms",1280);
148 result.add("1280_2560ms",2560);
149 result.add("2560_5120ms",5120);
150 result.add("5120_10240ms",10240);
151 result.add("10240_20480ms",20480);
152 result.addLastHeader("20480ms_");
153 // note last range is always called lastRange and is added automatically
154 return result;
155 }
156 }