001 package org.apache.fulcrum.yaafi.interceptor.jamon;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import com.jamonapi.Monitor;
023 import com.jamonapi.MonitorFactory;
024 import com.jamonapi.RangeHolder;
025 import org.apache.fulcrum.yaafi.interceptor.util.MethodToStringBuilderImpl;
026
027 import java.lang.reflect.Method;
028
029 /**
030 * Ecapsulating the JAMon 2.x related API calls. JAMon 2.x allows for a much
031 * more powerful integration with Avalon services :
032 * <ul>
033 * <li>custom ranges/units</li>
034 * <li>exception monitoring</li>
035 * <li>smooth web interface</li>
036 * </ul>
037 *
038 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
039 */
040
041 public class Jamon2PerformanceMonitorImpl implements JamonPerformanceMonitor
042 {
043 /** the default label being used */
044 private static final String MONITOR_LABEL = "ms.services";
045
046 /** our custom range definition */
047 private static RangeHolder rangeHolder;
048
049 /** is monitoring enabled */
050 private boolean isActive;
051
052 /** the method currenty monitored */
053 private Method method;
054
055 /** the global JAMON monitor */
056 private Monitor monitor;
057
058 /** the time the monitoring was started */
059 private long startTime;
060
061 static
062 {
063 rangeHolder = Jamon2PerformanceMonitorImpl.createMSHolder();
064 }
065
066 /**
067 * Constructor.
068 *
069 * @param serviceName the service name of the service being monitored
070 * @param method the method to be monitored
071 * @param isActive is this an active monitor
072 */
073 public Jamon2PerformanceMonitorImpl(String serviceName, Method method, Boolean isActive)
074 {
075 this.method = method;
076 this.isActive = isActive.booleanValue();
077 }
078
079 /**
080 * Start the monitor.
081 */
082 public void start()
083 {
084 if(this.isActive)
085 {
086 // when reseting using the JAMon GUI the custom ranges are discarded
087 MonitorFactory.setRangeDefault(MONITOR_LABEL, Jamon2PerformanceMonitorImpl.rangeHolder);
088 // do the internal house-keeping
089 this.startTime = System.currentTimeMillis();
090 MethodToStringBuilderImpl methodToStringBuilder = new MethodToStringBuilderImpl(this.method, 0);
091 String methodSignature = methodToStringBuilder.toString();
092 this.monitor = MonitorFactory.getMonitor(methodSignature, MONITOR_LABEL);
093 this.monitor.start();
094 }
095 }
096
097 /**
098 * Stop the monitor
099 */
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 /**
125 * Create a performance report.
126 *
127 * @return the textual performance report
128 * @throws Exception generating the report failed
129 */
130 public String createReport() throws Exception
131 {
132 return MonitorFactory.getRootMonitor().getReport();
133 }
134
135 /**
136 * @return a customized range holder for measuring the execution time for services.
137 */
138 private static RangeHolder createMSHolder() {
139 RangeHolder result = new RangeHolder("<");
140 result.add("Exceptions",0);
141 result.add("0_10ms",10);
142 result.add("10_20ms",20);
143 result.add("20_40ms",40);
144 result.add("40_80ms",80);
145 result.add("80_160ms",160);
146 result.add("160_320ms",320);
147 result.add("320_640ms",640);
148 result.add("640_1280ms",1280);
149 result.add("1280_2560ms",2560);
150 result.add("2560_5120ms",5120);
151 result.add("5120_10240ms",10240);
152 result.add("10240_20480ms",20480);
153 result.addLastHeader("20480ms_");
154 // note last range is always called lastRange and is added automatically
155 return result;
156 }
157 }