1 package com.atlassian.performance;
2
3 import java.lang.reflect.Method;
4
5 import org.aopalliance.intercept.MethodInterceptor;
6 import org.aopalliance.intercept.MethodInvocation;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import org.slf4j.MarkerFactory;
10
11 public class TimeMethodInterceptor implements MethodInterceptor
12 {
13 private static final String PERF_MARKER_TOKEN = "com.atlassian.performance.TestMarker";
14
15 Logger log = LoggerFactory.getLogger("com.atlassian.performance.");
16
17 public Object invoke(MethodInvocation invocation) throws Throwable {
18 TimedMethodInvocation tmi = new TimedMethodInvocation(invocation);
19 EventTime et = EventTime.timeEvent(eventKey(invocation), false, tmi);
20
21 if(et.getTime() > 1) {
22 log.debug(MarkerFactory.getMarker(PERF_MARKER_TOKEN),
23 "{}, {}", new Object[]{argsToString(invocation.getArguments()), et.getTime()});
24 }
25
26 if(tmi.throwable == null) {
27 return tmi.val;
28 } else {
29 throw tmi.throwable;
30 }
31 }
32
33 private static String eventKey(MethodInvocation invocation)
34 {
35 return trimMethod(invocation.getMethod()) + " " + argsToString(invocation.getArguments());
36 }
37
38 private static String trimMethod(Method method) {
39 String rawMethStr = method.toString();
40 int methodStart = rawMethStr.lastIndexOf(" ");
41 if(methodStart > -1)
42 {
43 return rawMethStr.substring(methodStart);
44 } else {
45 return rawMethStr;
46 }
47 }
48
49 private static String argsToString(Object[] args)
50 {
51 StringBuffer buf = new StringBuffer();
52 for(Object arg : args)
53 {
54 buf.append(arg);
55 buf.append("*");
56 }
57 return buf.toString();
58 }
59
60
61 public class TimedMethodInvocation implements EventTime.TimedEvent
62 {
63 Object val;
64 Throwable throwable;
65 MethodInvocation invocation;
66
67 TimedMethodInvocation(MethodInvocation invocation)
68 {
69 this.invocation = invocation;
70 }
71
72 public boolean run()
73 {
74 try
75 {
76 val = invocation.proceed();
77 }
78 catch (Throwable t)
79 {
80 throwable = t;
81 }
82 finally
83 {
84 return true;
85 }
86 }
87
88 }
89
90 }