001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.remoting.support;
018:
019: import java.lang.reflect.Method;
020:
021: import org.aopalliance.intercept.MethodInterceptor;
022: import org.aopalliance.intercept.MethodInvocation;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025:
026: import org.springframework.util.ClassUtils;
027:
028: /**
029: * AOP Alliance MethodInterceptor for tracing remote invocations.
030: * Automatically applied by RemoteExporter and its subclasses.
031: *
032: * <p>Logs an incoming remote call as well as the finished processing of a remote call
033: * at DEBUG level. If the processing of a remote call results in a checked exception,
034: * the exception will get logged at INFO level; if it results in an unchecked
035: * exception (or error), the exception will get logged at WARN level.
036: *
037: * <p>The logging of exceptions is particularly useful to save the stacktrace
038: * information on the server-side rather than just propagating the exception
039: * to the client (who might or might not log it properly).
040: *
041: * @author Juergen Hoeller
042: * @since 1.2
043: * @see RemoteExporter#setRegisterTraceInterceptor
044: * @see RemoteExporter#getProxyForService
045: */
046: public class RemoteInvocationTraceInterceptor implements
047: MethodInterceptor {
048:
049: protected static final Log logger = LogFactory
050: .getLog(RemoteInvocationTraceInterceptor.class);
051:
052: private final String exporterName;
053:
054: /**
055: * Create a new RemoteInvocationTraceInterceptor.
056: * @param protocolName the name of the remoting protocol
057: * (to be used as context information in log messages)
058: */
059: public RemoteInvocationTraceInterceptor(String protocolName) {
060: this .exporterName = protocolName;
061: }
062:
063: public Object invoke(MethodInvocation invocation) throws Throwable {
064: Method method = invocation.getMethod();
065: if (logger.isDebugEnabled()) {
066: logger.debug("Incoming " + this .exporterName
067: + " remote call: "
068: + ClassUtils.getQualifiedMethodName(method));
069: }
070: try {
071: Object retVal = invocation.proceed();
072: if (logger.isDebugEnabled()) {
073: logger.debug("Finished processing of "
074: + this .exporterName + " remote call: "
075: + ClassUtils.getQualifiedMethodName(method));
076: }
077: return retVal;
078: } catch (Throwable ex) {
079: if (ex instanceof RuntimeException || ex instanceof Error) {
080: if (logger.isWarnEnabled()) {
081: logger
082: .warn(
083: "Processing of "
084: + this .exporterName
085: + " remote call resulted in fatal exception: "
086: + ClassUtils
087: .getQualifiedMethodName(method),
088: ex);
089: }
090: } else {
091: if (logger.isInfoEnabled()) {
092: logger
093: .info(
094: "Processing of "
095: + this .exporterName
096: + " remote call resulted in exception: "
097: + ClassUtils
098: .getQualifiedMethodName(method),
099: ex);
100: }
101: }
102: throw ex;
103: }
104: }
105:
106: }
|