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