KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > management > mbeans > PerformanceMonitorMBean


1 // Copyright 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.management.mbeans;
16
17 import java.util.ArrayList JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Set JavaDoc;
23
24 import javax.management.AttributeNotFoundException JavaDoc;
25 import javax.management.MBeanAttributeInfo JavaDoc;
26 import javax.management.MBeanException JavaDoc;
27 import javax.management.ReflectionException JavaDoc;
28
29 import org.apache.hivemind.management.impl.PerformanceCollector;
30 import org.apache.hivemind.service.MethodSignature;
31
32 /**
33  * MBean that holds and calculates the performance data for service method calls intercepted by the
34  * {@link org.apache.hivemind.management.impl.PerformanceMonitorFactory performanceMonitor}
35  * interceptor. Creates for each intercepted method 5 MBean attributes: Number of Calls, Minimum,
36  * maximum, average and last execution time
37  *
38  * @author Achim Huegen
39  * @since 1.1
40  */

41 public class PerformanceMonitorMBean extends AbstractDynamicMBean implements PerformanceCollector
42 {
43     protected static final String JavaDoc DATA_TYPE_MAXIMUM_TIME = "Maximum time";
44
45     protected static final String JavaDoc DATA_TYPE_MINIMUM_TIME = "Minimum time";
46
47     protected static final String JavaDoc DATA_TYPE_LAST_TIME = "Last time";
48
49     protected static final String JavaDoc DATA_TYPE_AVERAGE_TIME = "Average time";
50
51     protected static final String JavaDoc DATA_TYPE_COUNT = "Count";
52
53     private Set JavaDoc _methods;
54
55     private Map JavaDoc _countersByMethodSignature = new HashMap JavaDoc();
56
57     private Map JavaDoc _countersByMethodId = new HashMap JavaDoc();
58
59     private MBeanAttributeInfo JavaDoc[] _mBeanAttributeInfos;
60     
61     private Map JavaDoc _mBeanAttributeNameToCounterMap = new HashMap JavaDoc();
62
63     /**
64      * Creates a new instance
65      *
66      * @param methods
67      * Set with instances of {@link org.apache.hivemind.service.MethodSignature}.
68      * Contains the methods for that calls can be counted by this MBean
69      */

70     public PerformanceMonitorMBean(Set JavaDoc methods)
71     {
72         _methods = methods;
73         initCounters();
74     }
75
76     /**
77      * Builds two maps for accessing the counters by method signature and method id
78      */

79     protected void initCounters()
80     {
81         List JavaDoc mBeanAttributeInfoList = new ArrayList JavaDoc();
82         for (Iterator JavaDoc methodIterator = _methods.iterator(); methodIterator.hasNext();)
83         {
84             MethodSignature method = (MethodSignature) methodIterator.next();
85             Counter counter = new Counter();
86             _countersByMethodSignature.put(method, counter);
87             _countersByMethodId.put(method.getUniqueId(), counter);
88             
89             initAttributes(mBeanAttributeInfoList, counter, method);
90         }
91         _mBeanAttributeInfos = (MBeanAttributeInfo JavaDoc[]) mBeanAttributeInfoList
92             .toArray(new MBeanAttributeInfo JavaDoc[mBeanAttributeInfoList.size()]);
93     }
94
95     /**
96      * Creates for a intercepted method 5 MBean attributes: Number of Calls, Minimum, maximum,
97      * average and last execution time
98      */

99     protected void initAttributes(List JavaDoc mBeanAttributeInfoList, Counter counter, MethodSignature method)
100     {
101         addAttribute(
102                 mBeanAttributeInfoList, counter,
103                 method,
104                 Long JavaDoc.class,
105                 DATA_TYPE_COUNT,
106                 "Number of method calls for method " + method);
107         addAttribute(
108                 mBeanAttributeInfoList, counter,
109                 method,
110                 Long JavaDoc.class,
111                 DATA_TYPE_AVERAGE_TIME,
112                 "Average execution time in ms of method " + method);
113         addAttribute(
114                 mBeanAttributeInfoList, counter,
115                 method,
116                 Long JavaDoc.class,
117                 DATA_TYPE_LAST_TIME,
118                 "Last execution time in ms of method " + method);
119         addAttribute(
120                 mBeanAttributeInfoList, counter,
121                 method,
122                 Long JavaDoc.class,
123                 DATA_TYPE_MINIMUM_TIME,
124                 "Minimum execution time in ms of method " + method);
125         addAttribute(
126                 mBeanAttributeInfoList, counter,
127                 method,
128                 Long JavaDoc.class,
129                 DATA_TYPE_MAXIMUM_TIME,
130                 "Maximum execution time in ms of method " + method);
131
132     }
133
134     /**
135      * Creates a new MBean Attribute for a performance counter
136      */

137     private void addAttribute(List JavaDoc mBeanAttributeInfoList, Counter counter, MethodSignature method,
138             Class JavaDoc attributeType, String JavaDoc performanceDataType, String JavaDoc description)
139     {
140         String JavaDoc attributeName = null;
141         MBeanAttributeInfo JavaDoc attributeInfo = null;
142         try
143         {
144             attributeName = buildAttributeName(method, performanceDataType);
145             attributeInfo = new MBeanAttributeInfo JavaDoc(attributeName, attributeType.getName(), description,
146                     true, false, false);
147         }
148         catch (IllegalArgumentException JavaDoc e)
149         {
150             // Some jmx implementations (jboss 3.2.7) don't accept spaces and braces
151
// in attribute names. In this case a fallback is executed, that replaces
152
// invalid chars by underscores.
153
attributeName = buildAttributeNameDefensive(method, performanceDataType);
154             attributeInfo = new MBeanAttributeInfo JavaDoc(attributeName, attributeType.getName(), description,
155                     true, false, false);
156         }
157         mBeanAttributeInfoList.add(attributeInfo);
158         AttributeToCounterLink atcLink = new AttributeToCounterLink(counter, performanceDataType);
159         _mBeanAttributeNameToCounterMap.put(attributeName, atcLink);
160     }
161
162     /**
163      * Replaces all chars in a string which are not valid in a java identifier with underscores
164      */

165     private String JavaDoc makeValidJavaIdentifier(String JavaDoc attributeName)
166     {
167         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
168         for (int i = 0; i < attributeName.length(); i++)
169         {
170             char currentChar = attributeName.charAt(i);
171             if (Character.isJavaIdentifierPart(currentChar))
172                 result.append(currentChar);
173             else result.append('_');
174         }
175         return result.toString();
176     }
177
178     /**
179      * Builds the attribute name that holds the measurement data of type
180      * <code>performanceDataType</code> for the method.
181      */

182     protected String JavaDoc buildAttributeName(MethodSignature method, String JavaDoc performanceDataType)
183     {
184         String JavaDoc attributeName = method.getUniqueId() + " : " + performanceDataType;
185         return attributeName;
186     }
187
188     /**
189      * Builds the attribute name that holds the measurement data of type.
190      * <code>performanceDataType</code> for the method.
191      * Some jmx implementations (jboss 3.2.7) don't accept spaces and braces in attribute names.
192      * Unlike {@link #buildAttributeName(MethodSignature, String)} this method doesn't
193      * use chars that are not accepted by {@link Character#isJavaIdentifierPart(char)}.
194      */

195     protected String JavaDoc buildAttributeNameDefensive(MethodSignature method, String JavaDoc performanceDataType)
196     {
197         String JavaDoc attributeName = method.getUniqueId() + "$[" + performanceDataType;
198         return makeValidJavaIdentifier(attributeName);
199     }
200
201     /**
202      * @see PerformanceCollector#addMeasurement(MethodSignature, long)
203      */

204     public void addMeasurement(MethodSignature method, long executionTime)
205     {
206         Counter counter = (Counter) _countersByMethodSignature.get(method);
207         counter.addMeasurement(executionTime);
208     }
209
210     protected MBeanAttributeInfo JavaDoc[] createMBeanAttributeInfo()
211     {
212         return _mBeanAttributeInfos;
213     }
214
215     /**
216      * @see AbstractDynamicMBean#getAttribute(java.lang.String)
217      */

218     public Object JavaDoc getAttribute(String JavaDoc attribute) throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc,
219             ReflectionException JavaDoc
220     {
221         // Split the attribute to get method id and performance data type separately
222
AttributeToCounterLink atcLink = (AttributeToCounterLink) _mBeanAttributeNameToCounterMap.get(attribute);
223         if (atcLink == null)
224             throw new AttributeNotFoundException JavaDoc("Attribute '" + attribute + "' not found");
225         
226         String JavaDoc type = atcLink.type;
227         Counter counter = atcLink.counter;
228         if (type.equals(DATA_TYPE_COUNT))
229             return new Long JavaDoc(counter.count);
230         else if (type.equals(DATA_TYPE_AVERAGE_TIME))
231             return new Long JavaDoc(counter.average);
232         else if (type.equals(DATA_TYPE_LAST_TIME))
233             return new Long JavaDoc(counter.last);
234         else if (type.equals(DATA_TYPE_MINIMUM_TIME))
235             return new Long JavaDoc(counter.min);
236         else if (type.equals(DATA_TYPE_MAXIMUM_TIME))
237             return new Long JavaDoc(counter.max);
238         else
239             throw new IllegalArgumentException JavaDoc("Unknown performance data type");
240     }
241
242 }
243
244 /**
245  * Class that holds and calculates the performance data for a single method
246  */

247
248 class Counter
249 {
250     long count = 0;
251
252     long last = 0;
253
254     long average = 0;
255
256     long max = 0;
257
258     long min = 0;
259
260     public String JavaDoc toString()
261     {
262         return "" + count;
263     }
264
265     /**
266      * Should be synchronized, but this could slow things really down
267      *
268      * @param executionTime
269      */

270     public void addMeasurement(long executionTime)
271     {
272         count++;
273         last = executionTime;
274         // not an exact value without a complete history and stored as long
275
average = (average * (count - 1) + executionTime) / count;
276         if (executionTime < min || min == 0)
277             min = executionTime;
278         if (executionTime > max || max == 0)
279             max = executionTime;
280     }
281 }
282
283 class AttributeToCounterLink
284 {
285     Counter counter;
286
287     String JavaDoc type;
288
289     public AttributeToCounterLink(Counter counter, String JavaDoc type)
290     {
291         this.counter = counter;
292         this.type = type;
293     }
294 }
295
Popular Tags