提交 137b142a 编写于 作者: L li.can 提交者: wu-sheng

Support servlet 2.5 for Jetty,Tomcat,SpringMvc (#3120)

* servlet 2.5

* method exist

* update MethodUtil

* Update MethodUtil.java

Add a comment to the new core util method. @candyleer I am concerning this method will be used widely even unnecessary.
上级 f4ca4c8a
...@@ -30,6 +30,7 @@ import java.lang.reflect.Method; ...@@ -30,6 +30,7 @@ import java.lang.reflect.Method;
public class MethodUtil { public class MethodUtil {
public static String generateOperationName(Method method) { public static String generateOperationName(Method method) {
StringBuilder operationName = new StringBuilder(method.getDeclaringClass().getName() + "." + method.getName() + "("); StringBuilder operationName = new StringBuilder(method.getDeclaringClass().getName() + "." + method.getName() + "(");
Class<?>[] parameterTypes = method.getParameterTypes(); Class<?>[] parameterTypes = method.getParameterTypes();
...@@ -42,4 +43,44 @@ public class MethodUtil { ...@@ -42,4 +43,44 @@ public class MethodUtil {
operationName.append(")"); operationName.append(")");
return operationName.toString(); return operationName.toString();
} }
/**
* This is a low-performance method, recommand to use this when have to, make sure it is only executed once and the result is being cached.
*/
public static boolean isMethodExist(ClassLoader classLoader, String className, String methodName, String... parameterTypes) {
try {
Class<?> clazz = Class.forName(className, true, classLoader);
if (parameterTypes == null || parameterTypes.length == 0) {
clazz.getDeclaredMethod(methodName);
return true;
} else {
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if (declaredMethod.getName().equals(methodName) && isParameterTypesEquals(declaredMethod.getParameterTypes(), parameterTypes)) {
return true;
}
}
}
} catch (Exception e) {
//ignore
}
return false;
}
private static boolean isParameterTypesEquals(Class<?>[] parameterTypeClazz, String[] parameterTypeString) {
if (parameterTypeClazz == null) {
return false;
}
if (parameterTypeClazz.length != parameterTypeString.length) {
return false;
}
for (int i = 0; i < parameterTypeClazz.length; i++) {
if (!parameterTypeClazz[i].getName().equals(parameterTypeString[i])) {
return false;
}
}
return true;
}
} }
...@@ -31,10 +31,20 @@ import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; ...@@ -31,10 +31,20 @@ import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.agent.core.util.MethodUtil;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpChannel;
public class HandleInterceptor implements InstanceMethodsAroundInterceptor { public class HandleInterceptor implements InstanceMethodsAroundInterceptor {
private static boolean IS_SERVLET_GET_STATUS_METHOD_EXIST;
private static final String SERVLET_RESPONSE_CLASS = "javax.servlet.http.HttpServletResponse";
private static final String GET_STATUS_METHOD = "getStatus";
static {
IS_SERVLET_GET_STATUS_METHOD_EXIST = MethodUtil.isMethodExist(HandleInterceptor.class.getClassLoader(), SERVLET_RESPONSE_CLASS, GET_STATUS_METHOD);
}
@Override @Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable { MethodInterceptResult result) throws Throwable {
...@@ -62,7 +72,7 @@ public class HandleInterceptor implements InstanceMethodsAroundInterceptor { ...@@ -62,7 +72,7 @@ public class HandleInterceptor implements InstanceMethodsAroundInterceptor {
HttpChannel httpChannel = (HttpChannel)objInst; HttpChannel httpChannel = (HttpChannel)objInst;
HttpServletResponse servletResponse = httpChannel.getResponse(); HttpServletResponse servletResponse = httpChannel.getResponse();
AbstractSpan span = ContextManager.activeSpan(); AbstractSpan span = ContextManager.activeSpan();
if (servletResponse.getStatus() >= 400) { if (IS_SERVLET_GET_STATUS_METHOD_EXIST && servletResponse.getStatus() >= 400) {
span.errorOccurred(); span.errorOccurred();
Tags.STATUS_CODE.set(span, Integer.toString(servletResponse.getStatus())); Tags.STATUS_CODE.set(span, Integer.toString(servletResponse.getStatus()));
} }
......
...@@ -46,6 +46,15 @@ import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESP ...@@ -46,6 +46,15 @@ import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESP
* the abstract method interceptor * the abstract method interceptor
*/ */
public abstract class AbstractMethodInterceptor implements InstanceMethodsAroundInterceptor { public abstract class AbstractMethodInterceptor implements InstanceMethodsAroundInterceptor {
private static boolean IS_SERVLET_GET_STATUS_METHOD_EXIST;
private static final String SERVLET_RESPONSE_CLASS = "javax.servlet.http.HttpServletResponse";
private static final String GET_STATUS_METHOD = "getStatus";
static {
IS_SERVLET_GET_STATUS_METHOD_EXIST = MethodUtil.isMethodExist(AbstractMethodInterceptor.class.getClassLoader(), SERVLET_RESPONSE_CLASS, GET_STATUS_METHOD);
}
public abstract String getRequestURL(Method method); public abstract String getRequestURL(Method method);
public abstract String getAcceptedMethodTypes(Method method); public abstract String getAcceptedMethodTypes(Method method);
...@@ -151,7 +160,7 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround ...@@ -151,7 +160,7 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
throw new ServletResponseNotFoundException(); throw new ServletResponseNotFoundException();
} }
if (response.getStatus() >= 400) { if (IS_SERVLET_GET_STATUS_METHOD_EXIST && response.getStatus() >= 400) {
span.errorOccurred(); span.errorOccurred();
Tags.STATUS_CODE.set(span, Integer.toString(response.getStatus())); Tags.STATUS_CODE.set(span, Integer.toString(response.getStatus()));
} }
......
...@@ -32,6 +32,7 @@ import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; ...@@ -32,6 +32,7 @@ import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.agent.core.util.MethodUtil;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
/** /**
...@@ -41,6 +42,14 @@ import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; ...@@ -41,6 +42,14 @@ import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
*/ */
public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor { public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor {
private static boolean IS_SERVLET_GET_STATUS_METHOD_EXIST;
private static final String SERVLET_RESPONSE_CLASS = "javax.servlet.http.HttpServletResponse";
private static final String GET_STATUS_METHOD = "getStatus";
static {
IS_SERVLET_GET_STATUS_METHOD_EXIST = MethodUtil.isMethodExist(TomcatInvokeInterceptor.class.getClassLoader(), SERVLET_RESPONSE_CLASS, GET_STATUS_METHOD);
}
/** /**
* * The {@link TraceSegment#refs} of current trace segment will reference to the * * The {@link TraceSegment#refs} of current trace segment will reference to the
* trace segment id of the previous level if the serialized context is not null. * trace segment id of the previous level if the serialized context is not null.
...@@ -76,7 +85,7 @@ public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor ...@@ -76,7 +85,7 @@ public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor
HttpServletResponse response = (HttpServletResponse)allArguments[1]; HttpServletResponse response = (HttpServletResponse)allArguments[1];
AbstractSpan span = ContextManager.activeSpan(); AbstractSpan span = ContextManager.activeSpan();
if (response.getStatus() >= 400) { if (IS_SERVLET_GET_STATUS_METHOD_EXIST && response.getStatus() >= 400) {
span.errorOccurred(); span.errorOccurred();
Tags.STATUS_CODE.set(span, Integer.toString(response.getStatus())); Tags.STATUS_CODE.set(span, Integer.toString(response.getStatus()));
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册