001
014
015 package com.liferay.portal.monitoring.statistics.service;
016
017 import com.liferay.portal.kernel.exception.SystemException;
018 import com.liferay.portal.kernel.messaging.MessageBusUtil;
019 import com.liferay.portal.kernel.monitoring.MonitoringProcessor;
020 import com.liferay.portal.kernel.monitoring.RequestStatus;
021 import com.liferay.portal.kernel.monitoring.statistics.DataSampleThreadLocal;
022 import com.liferay.portal.kernel.util.AutoResetThreadLocal;
023 import com.liferay.portal.kernel.util.MethodKey;
024 import com.liferay.portal.spring.aop.ChainableMethodAdvice;
025
026 import java.lang.reflect.Method;
027
028 import java.util.HashSet;
029 import java.util.Set;
030
031 import org.aopalliance.intercept.MethodInvocation;
032
033
036 public class ServiceMonitorAdvice extends ChainableMethodAdvice {
037
038
041 public static ServiceMonitorAdvice getInstance() {
042 return new ServiceMonitorAdvice();
043 }
044
045 public void addMonitoredClass(String className) {
046 _monitoredClasses.add(className);
047 }
048
049 public void addMonitoredMethod(
050 String className, String methodName, String[] parameterTypes)
051 throws SystemException {
052
053 try {
054 MethodKey methodKey = new MethodKey(
055 className, methodName, parameterTypes);
056
057 _monitoredMethods.add(methodKey);
058 }
059 catch (ClassNotFoundException cnfe) {
060 throw new SystemException("Unable to add method", cnfe);
061 }
062 }
063
064 @Override
065 public void afterReturning(MethodInvocation methodInvocation, Object result)
066 throws Throwable {
067
068 ServiceRequestDataSample serviceRequestDataSample =
069 _serviceRequestDataSampleThreadLocal.get();
070
071 if (serviceRequestDataSample != null) {
072 serviceRequestDataSample.capture(RequestStatus.SUCCESS);
073 }
074 }
075
076 @Override
077 public boolean afterThrowing(
078 MethodInvocation methodInvocation, Throwable throwable)
079 throws Throwable {
080
081 ServiceRequestDataSample serviceRequestDataSample =
082 _serviceRequestDataSampleThreadLocal.get();
083
084 if (serviceRequestDataSample != null) {
085 serviceRequestDataSample.capture(RequestStatus.ERROR);
086 }
087
088 return true;
089 }
090
091 @Override
092 public Object before(MethodInvocation methodInvocation) throws Throwable {
093 if (!_active) {
094 return null;
095 }
096
097 Object thisObject = methodInvocation.getThis();
098
099 Class<?> clazz = thisObject.getClass();
100
101 Class<?>[] interfaces = clazz.getInterfaces();
102
103 for (int i = 0; i < interfaces.length; i++) {
104 if (interfaces[i].isAssignableFrom(MonitoringProcessor.class)) {
105 return null;
106 }
107 }
108
109 if (!_permissiveMode && !isMonitored(methodInvocation)) {
110 return null;
111 }
112
113 ServiceRequestDataSample serviceRequestDataSample =
114 new ServiceRequestDataSample(methodInvocation);
115
116 serviceRequestDataSample.prepare();
117
118 _serviceRequestDataSampleThreadLocal.set(serviceRequestDataSample);
119
120 return null;
121 }
122
123 @Override
124 public void duringFinally(MethodInvocation methodInvocation) {
125 ServiceRequestDataSample serviceRequestDataSample =
126 _serviceRequestDataSampleThreadLocal.get();
127
128 if (serviceRequestDataSample != null) {
129 _serviceRequestDataSampleThreadLocal.remove();
130
131 DataSampleThreadLocal.addDataSample(serviceRequestDataSample);
132
133 MessageBusUtil.sendMessage(
134 _monitoringDestinationName, serviceRequestDataSample);
135 }
136 }
137
138 public Set<String> getMonitoredClasses() {
139 return _monitoredClasses;
140 }
141
142 public Set<MethodKey> getMonitoredMethods() {
143 return _monitoredMethods;
144 }
145
146 public String getMonitoringDestinationName() {
147 return _monitoringDestinationName;
148 }
149
150 public boolean isActive() {
151 return _active;
152 }
153
154 public boolean isPermissiveMode() {
155 return _permissiveMode;
156 }
157
158 public void setActive(boolean active) {
159 _active = active;
160 }
161
162 public void setMonitoredClasses(Set<String> monitoredClasses) {
163 _monitoredClasses = monitoredClasses;
164 }
165
166 public void setMonitoredMethods(Set<MethodKey> monitoredMethods) {
167 _monitoredMethods = monitoredMethods;
168 }
169
170 public void setMonitoringDestinationName(String monitoringDestinationName) {
171 _monitoringDestinationName = monitoringDestinationName;
172 }
173
174 public void setPermissiveMode(boolean permissiveMode) {
175 _permissiveMode = permissiveMode;
176 }
177
178 protected boolean isMonitored(MethodInvocation methodInvocation) {
179 Method method = methodInvocation.getMethod();
180
181 Class<?> declaringClass = method.getDeclaringClass();
182
183 String className = declaringClass.getName();
184
185 if (_monitoredClasses.contains(className)) {
186 return true;
187 }
188
189 String methodName = method.getName();
190 Class<?>[] parameterTypes = method.getParameterTypes();
191
192 MethodKey methodKey = new MethodKey(
193 className, methodName, parameterTypes);
194
195 if (_monitoredMethods.contains(methodKey)) {
196 return true;
197 }
198
199 return false;
200 }
201
202 private static ThreadLocal<ServiceRequestDataSample>
203 _serviceRequestDataSampleThreadLocal =
204 new AutoResetThreadLocal<ServiceRequestDataSample>(
205 ServiceRequestDataSample.class +
206 "._serviceRequestDataSampleThreadLocal");
207
208 private static boolean _active;
209 private static Set<String> _monitoredClasses = new HashSet<String>();
210 private static Set<MethodKey> _monitoredMethods = new HashSet<MethodKey>();
211 private static String _monitoringDestinationName;
212 private static boolean _permissiveMode;
213
214 }