1 package org.apache.fulcrum.yaafi.interceptor.javasimon;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.OutputStreamWriter;
25 import java.io.PrintWriter;
26 import java.io.Writer;
27 import java.lang.reflect.Method;
28
29 import org.apache.avalon.framework.activity.Disposable;
30 import org.apache.avalon.framework.activity.Initializable;
31 import org.apache.avalon.framework.configuration.Configuration;
32 import org.apache.avalon.framework.configuration.ConfigurationException;
33 import org.apache.avalon.framework.configuration.Reconfigurable;
34 import org.apache.avalon.framework.thread.ThreadSafe;
35 import org.apache.fulcrum.yaafi.framework.interceptor.AvalonInterceptorContext;
36 import org.apache.fulcrum.yaafi.framework.reflection.Clazz;
37 import org.apache.fulcrum.yaafi.interceptor.baseservice.BaseInterceptorServiceImpl;
38
39
40
41
42
43
44
45
46
47 public class JavaSimonInterceptorServiceImpl extends BaseInterceptorServiceImpl
48 implements JavaSimonInterceptorService, Reconfigurable, ThreadSafe, Disposable, Initializable {
49
50 private boolean isJavaSimonAvailable;
51
52
53 private File reportFile;
54
55
56 private long reportTimeout;
57
58
59 private boolean reportOnExit;
60
61
62 private long nextReportTimestamp;
63
64
65 private String performanceMonitorClassName;
66
67
68 private Class<?> performanceMonitorClass;
69
70
71 private static final String MONITORFACTORY_CLASSNAME = "org.javasimon.SimonManager";
72
73
74 private static final String DEFAULT_PERFORMANCEMONITOR_CLASSNAME = "org.apache.fulcrum.yaafi.interceptor.javasimon.JavaSimon4PerformanceMonitorImpl";
75
76
77
78
79
80
81
82
83 public JavaSimonInterceptorServiceImpl() {
84 super();
85 }
86
87
88
89
90 public void configure(Configuration configuration) throws ConfigurationException {
91 super.configure(configuration);
92 this.reportTimeout = configuration.getChild("reportTimeout").getValueAsLong(0);
93
94
95 this.performanceMonitorClassName = configuration.getChild("performanceMonitorClassName")
96 .getValue(DEFAULT_PERFORMANCEMONITOR_CLASSNAME);
97
98
99 String reportFileName = configuration.getChild("reportFile").getValue("./javasimon.html");
100 this.reportFile = this.makeAbsoluteFile(reportFileName);
101
102
103 this.nextReportTimestamp = System.currentTimeMillis() + this.reportTimeout;
104
105
106 this.reportOnExit = configuration.getChild("reportOnExit").getValueAsBoolean(false);
107 }
108
109
110
111
112 public void initialize() throws Exception {
113 ClassLoader classLoader = this.getClassLoader();
114
115 if (!Clazz.hasClazz(classLoader, MONITORFACTORY_CLASSNAME)) {
116 String msg = "The JavaSimonInterceptorService is disabled since the JavaSimon classes are not found in the classpath";
117 this.getLogger().warn(msg);
118 this.isJavaSimonAvailable = false;
119 return;
120 }
121
122 if (!Clazz.hasClazz(classLoader, this.performanceMonitorClassName)) {
123 String msg = "The JavaSimonInterceptorService is disabled since the performance monitor class is not found in the classpath";
124 this.getLogger().warn(msg);
125 this.isJavaSimonAvailable = false;
126 return;
127 }
128
129
130 this.performanceMonitorClass = Clazz.getClazz(this.getClassLoader(), this.performanceMonitorClassName);
131
132
133 JavaSimonPerformanceMonitor testMonitor = this.createJavaSimonPerformanceMonitor(null, null, true);
134 if (testMonitor == null) {
135 String msg = "The JavaSimonInterceptorService is disabled since the performance monitor can't be instantiated";
136 this.getLogger().warn(msg);
137 this.isJavaSimonAvailable = false;
138 return;
139 }
140
141 this.getLogger().debug("The JavaSimonInterceptorService is enabled");
142 this.isJavaSimonAvailable = true;
143 }
144
145
146
147
148 public void reconfigure(Configuration configuration) throws ConfigurationException {
149 super.reconfigure(configuration);
150 this.configure(configuration);
151 }
152
153
154
155
156 public void dispose() {
157 if (this.reportOnExit) {
158 this.run();
159 }
160
161 this.reportFile = null;
162 }
163
164
165
166
167
168
169
170
171 public void onEntry(AvalonInterceptorContext interceptorContext) {
172 if (this.isJavaSimonAvailable()) {
173 this.writeReport();
174
175 String serviceShortHand = interceptorContext.getServiceShorthand();
176 Method serviceMethod = interceptorContext.getMethod();
177 boolean isEnabled = this.isServiceMonitored(interceptorContext);
178 JavaSimonPerformanceMonitor monitor = this.createJavaSimonPerformanceMonitor(serviceShortHand,
179 serviceMethod, isEnabled);
180 monitor.start();
181 interceptorContext.getRequestContext().put(this.getServiceName(), monitor);
182 }
183 }
184
185
186
187
188
189 public void onExit(AvalonInterceptorContext interceptorContext, Object result) {
190 if (this.isJavaSimonAvailable()) {
191 JavaSimonPerformanceMonitor monitor;
192 monitor = (JavaSimonPerformanceMonitor) interceptorContext.getRequestContext()
193 .remove(this.getServiceName());
194 monitor.stop();
195 }
196 }
197
198
199
200
201
202 public void onError(AvalonInterceptorContext interceptorContext, Throwable t) {
203 if (this.isJavaSimonAvailable()) {
204 JavaSimonPerformanceMonitor monitor;
205 monitor = (JavaSimonPerformanceMonitor) interceptorContext.getRequestContext()
206 .remove(this.getServiceName());
207 monitor.stop(t);
208 }
209 }
210
211
212
213
214
215
216 public void run() {
217 this.writeReport(this.reportFile);
218 }
219
220
221
222
223
224
225
226
227 protected final boolean isJavaSimonAvailable() {
228 return this.isJavaSimonAvailable;
229 }
230
231
232
233
234
235
236
237
238
239
240 @SuppressWarnings("rawtypes")
241 protected JavaSimonPerformanceMonitor createJavaSimonPerformanceMonitor(String serviceName, Method method,
242 boolean isEnabled) {
243 JavaSimonPerformanceMonitor result = null;
244
245 try {
246 Class[] signature = { String.class, Method.class, Boolean.class };
247 Object[] args = { serviceName, method, isEnabled ? Boolean.TRUE : Boolean.FALSE };
248 result = (JavaSimonPerformanceMonitor) Clazz.newInstance(this.performanceMonitorClass, signature, args);
249 } catch (Exception e) {
250 String msg = "Failed to create a performance monitor instance : " + this.performanceMonitorClassName;
251 this.getLogger().error(msg, e);
252 }
253
254 return result;
255 }
256
257
258
259
260 protected void writeReport() {
261 if (this.reportTimeout > 0) {
262 long currTimestamp = System.currentTimeMillis();
263
264 if (currTimestamp > this.nextReportTimestamp) {
265 this.nextReportTimestamp = currTimestamp + this.reportTimeout;
266 this.writeReport(this.reportFile);
267 }
268 }
269 }
270
271
272
273
274
275
276 protected void writeReport(File reportFile) {
277 PrintWriter printWriter = null;
278
279 if (this.isJavaSimonAvailable()) {
280 try {
281 if (this.getLogger().isDebugEnabled()) {
282 this.getLogger().debug("Writing JavaSimon report to " + reportFile.getAbsolutePath());
283 }
284
285
286 Writer w = new OutputStreamWriter(new FileOutputStream(reportFile), "UTF-8");
287 printWriter = new PrintWriter(w);
288
289
290
291 String report = "Not implemented yet ...";
292 printWriter.write(report);
293 printWriter.close();
294 } catch (Throwable t) {
295 String msg = "Generating the JavaSimon report failed for " + reportFile.getAbsolutePath();
296 this.getLogger().error(msg, t);
297 } finally {
298 if (printWriter != null) {
299 printWriter.close();
300 }
301 }
302 }
303 }
304 }