1
14
15 package com.liferay.portal.monitoring.statistics.service;
16
17 import com.liferay.portal.SystemException;
18 import com.liferay.portal.kernel.messaging.MessageBusUtil;
19 import com.liferay.portal.kernel.util.AutoResetThreadLocal;
20 import com.liferay.portal.kernel.util.MethodKey;
21 import com.liferay.portal.monitoring.MonitoringProcessor;
22 import com.liferay.portal.monitoring.RequestStatus;
23 import com.liferay.portal.monitoring.statistics.DataSampleThreadLocal;
24 import com.liferay.portal.spring.aop.ChainableMethodAdvice;
25
26 import java.lang.reflect.Method;
27
28 import java.util.HashSet;
29 import java.util.Set;
30
31 import org.aopalliance.intercept.MethodInvocation;
32
33
38 public class ServiceMonitorAdvice extends ChainableMethodAdvice {
39
40
43 public static ServiceMonitorAdvice getInstance() {
44 return new ServiceMonitorAdvice();
45 }
46
47 public void addMonitoredClass(String className) {
48 _monitoredClasses.add(className);
49 }
50
51 public void addMonitoredMethod(
52 String className, String methodName, String[] parameterTypes)
53 throws SystemException {
54
55 try {
56 MethodKey methodKey = new MethodKey(
57 className, methodName, parameterTypes);
58
59 _monitoredMethods.add(methodKey);
60 }
61 catch (ClassNotFoundException cnfe) {
62 throw new SystemException("Unable to add method", cnfe);
63 }
64 }
65
66 public void afterReturning(MethodInvocation methodInvocation, Object result)
67 throws Throwable {
68
69 ServiceRequestDataSample serviceRequestDataSample =
70 _serviceRequestDataSampleThreadLocal.get();
71
72 if (serviceRequestDataSample != null) {
73 serviceRequestDataSample.capture(RequestStatus.SUCCESS);
74 }
75 }
76
77 public void afterThrowing(
78 MethodInvocation methodInvocation, Throwable throwable)
79 throws Throwable {
80
81 ServiceRequestDataSample serviceRequestDataSample =
82 _serviceRequestDataSampleThreadLocal.get();
83
84 if (serviceRequestDataSample != null) {
85 serviceRequestDataSample.capture(RequestStatus.ERROR);
86 }
87 }
88
89 public Object before(MethodInvocation methodInvocation) throws Throwable {
90 if (!_active) {
91 return null;
92 }
93
94 Class<?> classObj = methodInvocation.getThis().getClass();
95
96 Class<?>[] interfaces = classObj.getInterfaces();
97
98 for (int i = 0; i < interfaces.length; i++) {
99 if (interfaces[i].isAssignableFrom(MonitoringProcessor.class)) {
100 return null;
101 }
102 }
103
104 if (!_permissiveMode && !isMonitored(methodInvocation)) {
105 return null;
106 }
107
108 ServiceRequestDataSample serviceRequestDataSample =
109 new ServiceRequestDataSample(methodInvocation);
110
111 serviceRequestDataSample.prepare();
112
113 _serviceRequestDataSampleThreadLocal.set(serviceRequestDataSample);
114
115 return null;
116 }
117
118 public void duringFinally(MethodInvocation methodInvocation) {
119 ServiceRequestDataSample serviceRequestDataSample =
120 _serviceRequestDataSampleThreadLocal.get();
121
122 if (serviceRequestDataSample != null) {
123 _serviceRequestDataSampleThreadLocal.remove();
124
125 DataSampleThreadLocal.addDataSample(serviceRequestDataSample);
126
127 MessageBusUtil.sendMessage(
128 _monitoringDestinationName, serviceRequestDataSample);
129 }
130 }
131
132 public Set<String> getMonitoredClasses() {
133 return _monitoredClasses;
134 }
135
136 public Set<MethodKey> getMonitoredMethods() {
137 return _monitoredMethods;
138 }
139
140 public String getMonitoringDestinationName() {
141 return _monitoringDestinationName;
142 }
143
144 public boolean isActive() {
145 return _active;
146 }
147
148 public boolean isPermissiveMode() {
149 return _permissiveMode;
150 }
151
152 public void setActive(boolean active) {
153 _active = active;
154 }
155
156 public void setMonitoredClasses(Set<String> monitoredClasses) {
157 _monitoredClasses = monitoredClasses;
158 }
159
160 public void setMonitoredMethods(Set<MethodKey> monitoredMethods) {
161 _monitoredMethods = monitoredMethods;
162 }
163
164 public void setMonitoringDestinationName(String monitoringDestinationName) {
165 _monitoringDestinationName = monitoringDestinationName;
166 }
167
168 public void setPermissiveMode(boolean permissiveMode) {
169 _permissiveMode = permissiveMode;
170 }
171
172 protected boolean isMonitored(MethodInvocation methodInvocation) {
173 Method method = methodInvocation.getMethod();
174
175 Class<?> declaringClass = method.getDeclaringClass();
176
177 String className = declaringClass.getName();
178
179 if (_monitoredClasses.contains(className)) {
180 return true;
181 }
182
183 String methodName = method.getName();
184 Class<?>[] parameterTypes = method.getParameterTypes();
185
186 MethodKey methodKey = new MethodKey(
187 className, methodName, parameterTypes);
188
189 if (_monitoredMethods.contains(methodKey)) {
190 return true;
191 }
192
193 return false;
194 }
195
196 private static ThreadLocal<ServiceRequestDataSample>
197 _serviceRequestDataSampleThreadLocal =
198 new AutoResetThreadLocal<ServiceRequestDataSample>();
199
200 private static boolean _active;
201 private static Set<String> _monitoredClasses = new HashSet<String>();
202 private static Set<MethodKey> _monitoredMethods = new HashSet<MethodKey>();
203 private static String _monitoringDestinationName;
204 private static boolean _permissiveMode;
205
206 }