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.util.AutoResetThreadLocal;
020 import com.liferay.portal.kernel.util.MethodKey;
021 import com.liferay.portal.monitoring.MonitoringProcessor;
022 import com.liferay.portal.monitoring.RequestStatus;
023 import com.liferay.portal.monitoring.statistics.DataSampleThreadLocal;
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 public void afterReturning(MethodInvocation methodInvocation, Object result)
065 throws Throwable {
066
067 ServiceRequestDataSample serviceRequestDataSample =
068 _serviceRequestDataSampleThreadLocal.get();
069
070 if (serviceRequestDataSample != null) {
071 serviceRequestDataSample.capture(RequestStatus.SUCCESS);
072 }
073 }
074
075 public void afterThrowing(
076 MethodInvocation methodInvocation, Throwable throwable)
077 throws Throwable {
078
079 ServiceRequestDataSample serviceRequestDataSample =
080 _serviceRequestDataSampleThreadLocal.get();
081
082 if (serviceRequestDataSample != null) {
083 serviceRequestDataSample.capture(RequestStatus.ERROR);
084 }
085 }
086
087 public Object before(MethodInvocation methodInvocation) throws Throwable {
088 if (!_active) {
089 return null;
090 }
091
092 Class<?> classObj = methodInvocation.getThis().getClass();
093
094 Class<?>[] interfaces = classObj.getInterfaces();
095
096 for (int i = 0; i < interfaces.length; i++) {
097 if (interfaces[i].isAssignableFrom(MonitoringProcessor.class)) {
098 return null;
099 }
100 }
101
102 if (!_permissiveMode && !isMonitored(methodInvocation)) {
103 return null;
104 }
105
106 ServiceRequestDataSample serviceRequestDataSample =
107 new ServiceRequestDataSample(methodInvocation);
108
109 serviceRequestDataSample.prepare();
110
111 _serviceRequestDataSampleThreadLocal.set(serviceRequestDataSample);
112
113 return null;
114 }
115
116 public void duringFinally(MethodInvocation methodInvocation) {
117 ServiceRequestDataSample serviceRequestDataSample =
118 _serviceRequestDataSampleThreadLocal.get();
119
120 if (serviceRequestDataSample != null) {
121 _serviceRequestDataSampleThreadLocal.remove();
122
123 DataSampleThreadLocal.addDataSample(serviceRequestDataSample);
124
125 MessageBusUtil.sendMessage(
126 _monitoringDestinationName, serviceRequestDataSample);
127 }
128 }
129
130 public Set<String> getMonitoredClasses() {
131 return _monitoredClasses;
132 }
133
134 public Set<MethodKey> getMonitoredMethods() {
135 return _monitoredMethods;
136 }
137
138 public String getMonitoringDestinationName() {
139 return _monitoringDestinationName;
140 }
141
142 public boolean isActive() {
143 return _active;
144 }
145
146 public boolean isPermissiveMode() {
147 return _permissiveMode;
148 }
149
150 public void setActive(boolean active) {
151 _active = active;
152 }
153
154 public void setMonitoredClasses(Set<String> monitoredClasses) {
155 _monitoredClasses = monitoredClasses;
156 }
157
158 public void setMonitoredMethods(Set<MethodKey> monitoredMethods) {
159 _monitoredMethods = monitoredMethods;
160 }
161
162 public void setMonitoringDestinationName(String monitoringDestinationName) {
163 _monitoringDestinationName = monitoringDestinationName;
164 }
165
166 public void setPermissiveMode(boolean permissiveMode) {
167 _permissiveMode = permissiveMode;
168 }
169
170 protected boolean isMonitored(MethodInvocation methodInvocation) {
171 Method method = methodInvocation.getMethod();
172
173 Class<?> declaringClass = method.getDeclaringClass();
174
175 String className = declaringClass.getName();
176
177 if (_monitoredClasses.contains(className)) {
178 return true;
179 }
180
181 String methodName = method.getName();
182 Class<?>[] parameterTypes = method.getParameterTypes();
183
184 MethodKey methodKey = new MethodKey(
185 className, methodName, parameterTypes);
186
187 if (_monitoredMethods.contains(methodKey)) {
188 return true;
189 }
190
191 return false;
192 }
193
194 private static ThreadLocal<ServiceRequestDataSample>
195 _serviceRequestDataSampleThreadLocal =
196 new AutoResetThreadLocal<ServiceRequestDataSample>(
197 ServiceRequestDataSample.class +
198 "._serviceRequestDataSampleThreadLocal");
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 }