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