Fix a tracing context leak in SpringMVC plugin (#34)
* Once the springMVC span is created in beforeMethod, it must be stopped in afterMethod. Or it may cause memory leak. Authored-by: furao <furao@didiglobal.com>
This commit is contained in:
parent
941350bbc9
commit
43839e02aa
|
|
@ -21,6 +21,8 @@ Release Notes.
|
|||
* Add benchmark result for `exception-ignore` plugin and polish plugin guide.
|
||||
* Provide Alibaba Druid database connection pool plugin.
|
||||
* Provide HikariCP database connection pool plugin.
|
||||
* fix the bug that springMVC plugin will not stop span when exception throws.
|
||||
|
||||
|
||||
#### Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -198,56 +198,58 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
|
|||
Object request = runtimeContext.get(REQUEST_KEY_IN_RUNTIME_CONTEXT);
|
||||
|
||||
if (request != null) {
|
||||
StackDepth stackDepth = (StackDepth) runtimeContext.get(CONTROLLER_METHOD_STACK_DEPTH);
|
||||
if (stackDepth == null) {
|
||||
throw new IllegalMethodStackDepthException();
|
||||
} else {
|
||||
stackDepth.decrement();
|
||||
}
|
||||
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
|
||||
if (stackDepth.depth() == 0) {
|
||||
Object response = runtimeContext.get(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
if (response == null) {
|
||||
throw new ServletResponseNotFoundException();
|
||||
try {
|
||||
StackDepth stackDepth = (StackDepth) runtimeContext.get(CONTROLLER_METHOD_STACK_DEPTH);
|
||||
if (stackDepth == null) {
|
||||
throw new IllegalMethodStackDepthException();
|
||||
} else {
|
||||
stackDepth.decrement();
|
||||
}
|
||||
|
||||
Integer statusCode = null;
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
|
||||
if (IS_SERVLET_GET_STATUS_METHOD_EXIST && HttpServletResponse.class.isAssignableFrom(response.getClass())) {
|
||||
statusCode = ((HttpServletResponse) response).getStatus();
|
||||
} else if (ServerHttpResponse.class.isAssignableFrom(response.getClass())) {
|
||||
if (IS_SERVLET_GET_STATUS_METHOD_EXIST) {
|
||||
statusCode = ((ServerHttpResponse) response).getRawStatusCode();
|
||||
if (stackDepth.depth() == 0) {
|
||||
Object response = runtimeContext.get(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
if (response == null) {
|
||||
throw new ServletResponseNotFoundException();
|
||||
}
|
||||
Object context = runtimeContext.get(REACTIVE_ASYNC_SPAN_IN_RUNTIME_CONTEXT);
|
||||
if (context != null) {
|
||||
((AbstractSpan[]) context)[0] = span.prepareForAsync();
|
||||
|
||||
Integer statusCode = null;
|
||||
|
||||
if (IS_SERVLET_GET_STATUS_METHOD_EXIST && HttpServletResponse.class.isAssignableFrom(response.getClass())) {
|
||||
statusCode = ((HttpServletResponse) response).getStatus();
|
||||
} else if (ServerHttpResponse.class.isAssignableFrom(response.getClass())) {
|
||||
if (IS_SERVLET_GET_STATUS_METHOD_EXIST) {
|
||||
statusCode = ((ServerHttpResponse) response).getRawStatusCode();
|
||||
}
|
||||
Object context = runtimeContext.get(REACTIVE_ASYNC_SPAN_IN_RUNTIME_CONTEXT);
|
||||
if (context != null) {
|
||||
((AbstractSpan[]) context)[0] = span.prepareForAsync();
|
||||
}
|
||||
}
|
||||
|
||||
if (statusCode != null && statusCode >= 400) {
|
||||
span.errorOccurred();
|
||||
Tags.HTTP_RESPONSE_STATUS_CODE.set(span, statusCode);
|
||||
}
|
||||
|
||||
runtimeContext.remove(REACTIVE_ASYNC_SPAN_IN_RUNTIME_CONTEXT);
|
||||
runtimeContext.remove(REQUEST_KEY_IN_RUNTIME_CONTEXT);
|
||||
runtimeContext.remove(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
runtimeContext.remove(CONTROLLER_METHOD_STACK_DEPTH);
|
||||
}
|
||||
|
||||
// Active HTTP parameter collection automatically in the profiling context.
|
||||
if (!SpringMVCPluginConfig.Plugin.SpringMVC.COLLECT_HTTP_PARAMS && span.isProfiling()) {
|
||||
if (HttpServletRequest.class.isAssignableFrom(request.getClass())) {
|
||||
RequestUtil.collectHttpParam((HttpServletRequest) request, span);
|
||||
} else if (ServerHttpRequest.class.isAssignableFrom(request.getClass())) {
|
||||
RequestUtil.collectHttpParam((ServerHttpRequest) request, span);
|
||||
}
|
||||
}
|
||||
|
||||
if (statusCode != null && statusCode >= 400) {
|
||||
span.errorOccurred();
|
||||
Tags.HTTP_RESPONSE_STATUS_CODE.set(span, statusCode);
|
||||
}
|
||||
|
||||
runtimeContext.remove(REACTIVE_ASYNC_SPAN_IN_RUNTIME_CONTEXT);
|
||||
runtimeContext.remove(REQUEST_KEY_IN_RUNTIME_CONTEXT);
|
||||
runtimeContext.remove(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
runtimeContext.remove(CONTROLLER_METHOD_STACK_DEPTH);
|
||||
} finally {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
|
||||
// Active HTTP parameter collection automatically in the profiling context.
|
||||
if (!SpringMVCPluginConfig.Plugin.SpringMVC.COLLECT_HTTP_PARAMS && span.isProfiling()) {
|
||||
if (HttpServletRequest.class.isAssignableFrom(request.getClass())) {
|
||||
RequestUtil.collectHttpParam((HttpServletRequest) request, span);
|
||||
} else if (ServerHttpRequest.class.isAssignableFrom(request.getClass())) {
|
||||
RequestUtil.collectHttpParam((ServerHttpRequest) request, span);
|
||||
}
|
||||
}
|
||||
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
Loading…
Reference in New Issue