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 }