/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.monitoring.statistics.service; import com.liferay.portal.kernel.monitoring.DataSample; import com.liferay.portal.kernel.monitoring.DataSampleThreadLocal; import com.liferay.portal.kernel.monitoring.MethodSignature; import com.liferay.portal.kernel.monitoring.RequestStatus; import com.liferay.portal.kernel.monitoring.ServiceMonitoringControl; import com.liferay.portal.kernel.util.AutoResetThreadLocal; import com.liferay.portal.spring.aop.ChainableMethodAdvice; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.aopalliance.intercept.MethodInvocation; /** * @author Michael C. Han */ public class ServiceMonitorAdvice extends ChainableMethodAdvice implements ServiceMonitoringControl { @Override public void addServiceClass(String className) { _serviceClasses.add(className); } @Override public void addServiceClassMethod( String className, String methodName, String[] parameterTypes) { MethodSignature methodSignature = new MethodSignature( className, methodName, parameterTypes); _serviceClassMethods.add(methodSignature); } @Override public void afterReturning(MethodInvocation methodInvocation, Object result) throws Throwable { DataSample dataSample = _dataSampleThreadLocal.get(); if (dataSample != null) { dataSample.capture(RequestStatus.SUCCESS); } } @Override public void afterThrowing( MethodInvocation methodInvocation, Throwable throwable) throws Throwable { DataSample dataSample = _dataSampleThreadLocal.get(); if (dataSample != null) { dataSample.capture(RequestStatus.ERROR); } } @Override public Object before(MethodInvocation methodInvocation) throws Throwable { if (!_monitorServiceRequest) { serviceBeanAopCacheManager.removeMethodInterceptor( methodInvocation, this); return null; } boolean included = isIncluded(methodInvocation); if ((!_inclusiveMode && included) || (_inclusiveMode && !included)) { return null; } MethodSignature methodSignature = new MethodSignature( methodInvocation.getMethod()); DataSample dataSample = DataSampleFactoryUtil.createServiceRequestDataSample( methodSignature); dataSample.prepare(); _dataSampleThreadLocal.set(dataSample); DataSampleThreadLocal.initialize(); return null; } @Override public void duringFinally(MethodInvocation methodInvocation) { DataSample dataSample = _dataSampleThreadLocal.get(); if (dataSample != null) { _dataSampleThreadLocal.remove(); DataSampleThreadLocal.addDataSample(dataSample); } } @Override public Set<String> getServiceClasses() { return Collections.unmodifiableSet(_serviceClasses); } @Override public Set<MethodSignature> getServiceClassMethods() { return Collections.unmodifiableSet(_serviceClassMethods); } @Override public boolean isInclusiveMode() { return _inclusiveMode; } @Override public boolean isMonitorServiceRequest() { return _monitorServiceRequest; } @Override public void setInclusiveMode(boolean inclusiveMode) { _inclusiveMode = inclusiveMode; } @Override public void setMonitorServiceRequest(boolean monitorServiceRequest) { if (monitorServiceRequest && !_monitorServiceRequest) { serviceBeanAopCacheManager.reset(); } _monitorServiceRequest = monitorServiceRequest; } protected boolean isIncluded(MethodInvocation methodInvocation) { Method method = methodInvocation.getMethod(); Class<?> declaringClass = method.getDeclaringClass(); String className = declaringClass.getName(); if (_serviceClasses.contains(className)) { return true; } MethodSignature methodSignature = new MethodSignature(method); if (_serviceClassMethods.contains(methodSignature)) { return true; } return false; } private static final ThreadLocal<DataSample> _dataSampleThreadLocal = new AutoResetThreadLocal<>( ServiceMonitorAdvice.class + "._dataSampleThreadLocal"); private static boolean _inclusiveMode = true; private static boolean _monitorServiceRequest; private static final Set<String> _serviceClasses = new HashSet<>(); private static final Set<MethodSignature> _serviceClassMethods = new HashSet<>(); }