Fix RuntimeContext cannot store anything when the trace is not creat (#1480)
* Fix RuntimeContext cannot store anything when the trace is not create * Add RuntimecontextSnapshot and remove debug info
This commit is contained in:
parent
8635fd3bc6
commit
56d7fe4ed7
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.agent.core.conf;
|
||||
|
||||
public class RuntimeContextConfiguration {
|
||||
|
||||
public static String[] NEED_PROPAGATE_CONTEXT_KEY = new String[] {
|
||||
"SW_REQUEST",
|
||||
"SW_RESPONSE"
|
||||
};
|
||||
}
|
||||
|
|
@ -105,8 +105,4 @@ public interface AbstractTracerContext {
|
|||
*/
|
||||
void stopSpan(AbstractSpan span);
|
||||
|
||||
/**
|
||||
* @return the runtime context from current tracing context.
|
||||
*/
|
||||
RuntimeContext getRuntimeContext();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.apache.skywalking.apm.util.StringUtil;
|
|||
public class ContextManager implements TracingContextListener, BootService, IgnoreTracerContextListener {
|
||||
private static final ILog logger = LogManager.getLogger(ContextManager.class);
|
||||
private static ThreadLocal<AbstractTracerContext> CONTEXT = new ThreadLocal<AbstractTracerContext>();
|
||||
private static ThreadLocal<RuntimeContext> RUNTIME_CONTEXT = new ThreadLocal<RuntimeContext>();
|
||||
private static ContextManagerExtendService EXTEND_SERVICE;
|
||||
|
||||
private static AbstractTracerContext getOrCreate(String operationName, boolean forceSampling) {
|
||||
|
|
@ -198,11 +199,12 @@ public class ContextManager implements TracingContextListener, BootService, Igno
|
|||
}
|
||||
|
||||
public static RuntimeContext getRuntimeContext() {
|
||||
if (isActive()) {
|
||||
return get().getRuntimeContext();
|
||||
} else {
|
||||
throw new IllegalStateException("No active context");
|
||||
RuntimeContext runtimeContext = RUNTIME_CONTEXT.get();
|
||||
if (runtimeContext == null) {
|
||||
runtimeContext = new RuntimeContext(RUNTIME_CONTEXT);
|
||||
RUNTIME_CONTEXT.set(runtimeContext);
|
||||
}
|
||||
}
|
||||
|
||||
return runtimeContext;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,13 +37,6 @@ public class IgnoredTracerContext implements AbstractTracerContext {
|
|||
|
||||
private int stackDepth;
|
||||
|
||||
/**
|
||||
* Runtime context of the ignored context
|
||||
*
|
||||
* The context should work even no trace, in order to avoid the unexpected status.
|
||||
*/
|
||||
private RuntimeContext runtimeContext;
|
||||
|
||||
public IgnoredTracerContext() {
|
||||
this.stackDepth = 0;
|
||||
}
|
||||
|
|
@ -102,13 +95,6 @@ public class IgnoredTracerContext implements AbstractTracerContext {
|
|||
}
|
||||
}
|
||||
|
||||
@Override public RuntimeContext getRuntimeContext() {
|
||||
if (runtimeContext == null) {
|
||||
runtimeContext = new RuntimeContext();
|
||||
}
|
||||
return runtimeContext;
|
||||
}
|
||||
|
||||
public static class ListenerManager {
|
||||
private static List<IgnoreTracerContextListener> LISTENERS = new LinkedList<IgnoreTracerContextListener>();
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,11 @@
|
|||
|
||||
package org.apache.skywalking.apm.agent.core.context;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.apache.skywalking.apm.agent.core.conf.RuntimeContextConfiguration;
|
||||
|
||||
/**
|
||||
* RuntimeContext is alive during the tracing context.
|
||||
|
|
@ -27,11 +30,16 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
*
|
||||
* In most cases, it means it only stays in a single thread for context propagation.
|
||||
*
|
||||
* @author wusheng
|
||||
* @author wusheng, ascrutae
|
||||
*/
|
||||
public class RuntimeContext {
|
||||
private final ThreadLocal<RuntimeContext> contextThreadLocal;
|
||||
private Map context = new ConcurrentHashMap(0);
|
||||
|
||||
public RuntimeContext(ThreadLocal<RuntimeContext> contextThreadLocal) {
|
||||
this.contextThreadLocal = contextThreadLocal;
|
||||
}
|
||||
|
||||
public void put(Object key, Object value) {
|
||||
context.put(key, value);
|
||||
}
|
||||
|
|
@ -43,4 +51,32 @@ public class RuntimeContext {
|
|||
public <T> T get(Object key, Class<T> type) {
|
||||
return (T)context.get(key);
|
||||
}
|
||||
|
||||
public void remove(Object key) {
|
||||
context.remove(key);
|
||||
|
||||
if (context.isEmpty()) {
|
||||
contextThreadLocal.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public RuntimeContextSnapshot capture() {
|
||||
Map runtimeContextMap = new HashMap();
|
||||
for (String key : RuntimeContextConfiguration.NEED_PROPAGATE_CONTEXT_KEY) {
|
||||
Object value = this.get(key);
|
||||
if (value != null) {
|
||||
runtimeContextMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return new RuntimeContextSnapshot(runtimeContextMap);
|
||||
}
|
||||
|
||||
public void accept(RuntimeContextSnapshot snapshot) {
|
||||
Iterator<Map.Entry> iterator = snapshot.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry runtimeContextItem = iterator.next();
|
||||
ContextManager.getRuntimeContext().put(runtimeContextItem.getKey(), runtimeContextItem.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.agent.core.context;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class RuntimeContextSnapshot {
|
||||
private final Map map;
|
||||
|
||||
public RuntimeContextSnapshot(Map map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public Iterator<Map.Entry> iterator() {
|
||||
return map.entrySet().iterator();
|
||||
}
|
||||
}
|
||||
|
|
@ -79,11 +79,6 @@ public class TracingContext implements AbstractTracerContext {
|
|||
*/
|
||||
private int spanIdGenerator;
|
||||
|
||||
/**
|
||||
* Runtime context of the tracing context
|
||||
*/
|
||||
private RuntimeContext runtimeContext;
|
||||
|
||||
/**
|
||||
* Initialize all fields with default value.
|
||||
*/
|
||||
|
|
@ -424,14 +419,6 @@ public class TracingContext implements AbstractTracerContext {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeContext getRuntimeContext() {
|
||||
if (runtimeContext == null) {
|
||||
runtimeContext = new RuntimeContext();
|
||||
}
|
||||
return runtimeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish this context, and notify all {@link TracingContextListener}s, managed by {@link
|
||||
* TracingContext.ListenerManager}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.apache.skywalking.apm.plugin.hystrix.v1;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
|
||||
|
|
@ -28,8 +27,6 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM
|
|||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.hystrix.v1.Constants.ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT;
|
||||
|
||||
public class HystrixCommandRunInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
|
|
@ -46,8 +43,6 @@ public class HystrixCommandRunInterceptor implements InstanceMethodsAroundInterc
|
|||
}
|
||||
// Because of `fall back` method running in other thread. so we need capture concurrent span for tracing.
|
||||
enhanceRequireObjectCache.setContextSnapshot(ContextManager.capture());
|
||||
|
||||
ContextManager.getRuntimeContext().put(ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT, ((HystrixCommand)objInst).getProperties().executionIsolationStrategy().get().name().toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.hystrix.v1;
|
||||
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
import java.lang.reflect.Method;
|
||||
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.MethodInterceptResult;
|
||||
|
||||
public class HystrixConcurrencyStrategyInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
return new SWHystrixConcurrencyStrategyWrapper((HystrixConcurrencyStrategy)ret);
|
||||
}
|
||||
|
||||
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.hystrix.v1;
|
||||
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
import java.util.concurrent.Callable;
|
||||
import org.apache.skywalking.apm.agent.core.conf.RuntimeContextConfiguration;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.RuntimeContextSnapshot;
|
||||
|
||||
public class SWHystrixConcurrencyStrategyWrapper extends HystrixConcurrencyStrategy {
|
||||
|
||||
private final HystrixConcurrencyStrategy delegate;
|
||||
|
||||
public SWHystrixConcurrencyStrategyWrapper(
|
||||
HystrixConcurrencyStrategy delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Callable<T> wrapCallable(Callable<T> callable) {
|
||||
return new WrappedCallable<T>(ContextManager.getRuntimeContext().capture(), super.wrapCallable(callable));
|
||||
}
|
||||
|
||||
static class WrappedCallable<T> implements Callable<T> {
|
||||
|
||||
private final RuntimeContextSnapshot contextSnapshot;
|
||||
private final Callable<T> target;
|
||||
|
||||
WrappedCallable(RuntimeContextSnapshot contextSnapshot, Callable<T> target) {
|
||||
this.contextSnapshot = contextSnapshot;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override public T call() throws Exception {
|
||||
try {
|
||||
ContextManager.getRuntimeContext().accept(contextSnapshot);
|
||||
return target.call();
|
||||
} finally {
|
||||
for (String key : RuntimeContextConfiguration.NEED_PROPAGATE_CONTEXT_KEY) {
|
||||
ContextManager.getRuntimeContext().remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -32,6 +32,8 @@ public class HystrixPluginsInstrumentation extends ClassInstanceMethodsEnhancePl
|
|||
|
||||
public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.hystrix.v1.HystrixPluginsInterceptor";
|
||||
public static final String ENHANCE_METHOD = "getCommandExecutionHook";
|
||||
public static final String GET_CONCURRENCY_STRATEGY_METHOD = "getConcurrencyStrategy";
|
||||
public static final String GET_CONCURRENCY_STRATEGY_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.hystrix.v1.HystrixConcurrencyStrategyInterceptor";
|
||||
public static final String ENHANCE_CLASS = "com.netflix.hystrix.strategy.HystrixPlugins";
|
||||
|
||||
@Override
|
||||
|
|
@ -51,6 +53,19 @@ public class HystrixPluginsInstrumentation extends ClassInstanceMethodsEnhancePl
|
|||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(GET_CONCURRENCY_STRATEGY_METHOD);
|
||||
}
|
||||
|
||||
@Override public String getMethodsInterceptor() {
|
||||
return GET_CONCURRENCY_STRATEGY_INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jetty.v9.server;
|
||||
|
||||
public class Constants {
|
||||
public static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG";
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM
|
|||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
|
||||
public class ForwardInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor {
|
||||
private static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG";
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
|
|
@ -40,7 +39,7 @@ public class ForwardInterceptor implements InstanceMethodsAroundInterceptor, Ins
|
|||
Map<String, String> eventMap = new HashMap<String, String>();
|
||||
eventMap.put("forward-url", (String)objInst.getSkyWalkingDynamicField());
|
||||
abstractTracingSpan.log(System.currentTimeMillis(), eventMap);
|
||||
ContextManager.getRuntimeContext().put(FORWARD_REQUEST_FLAG, true);
|
||||
ContextManager.getRuntimeContext().put(Constants.FORWARD_REQUEST_FLAG, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ public class HandleInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
Tags.STATUS_CODE.set(span, Integer.toString(servletResponse.getStatus()));
|
||||
}
|
||||
ContextManager.stopSpan();
|
||||
ContextManager.getRuntimeContext().remove(Constants.FORWARD_REQUEST_FLAG);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@
|
|||
package org.apache.skywalking.apm.plugin.spring.mvc.v3;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
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.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT;
|
||||
|
||||
/**
|
||||
* {@link HandlerMethodInvokerInterceptor} pass the {@link NativeWebRequest} object into the {@link
|
||||
* org.springframework.stereotype.Controller} object.
|
||||
|
|
@ -37,7 +39,7 @@ public class HandlerMethodInvokerInterceptor implements InstanceMethodsAroundInt
|
|||
MethodInterceptResult result) throws Throwable {
|
||||
Object handler = allArguments[1];
|
||||
if (handler instanceof EnhancedInstance) {
|
||||
((EnhanceRequireObjectCache)((EnhancedInstance)handler).getSkyWalkingDynamicField()).setNativeWebRequest((NativeWebRequest)allArguments[2]);
|
||||
ContextManager.getRuntimeContext().put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, ((NativeWebRequest)allArguments[2]).getNativeResponse());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,12 +61,4 @@ public class GetBeanInterceptorTest {
|
|||
|
||||
verify(enhanceRet, times(0)).setSkyWalkingDynamicField(Matchers.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultIsEnhanceInstance() throws Throwable {
|
||||
interceptor.afterMethod(enhancedInstance, null, null, null, enhanceRet);
|
||||
|
||||
verify(enhanceRet, times(0)).setSkyWalkingDynamicField(Matchers.any());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,8 +175,6 @@ public class RequestMappingMethodInterceptorTest {
|
|||
@Override
|
||||
public Object getSkyWalkingDynamicField() {
|
||||
value.setPathMappingCache(new PathMappingCache("/test"));
|
||||
value.setHttpResponse(response);
|
||||
value.setNativeWebRequest(nativeWebRequest);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,8 +306,6 @@ public class RestMappingMethodInterceptorTest {
|
|||
@Override
|
||||
public Object getSkyWalkingDynamicField() {
|
||||
value.setPathMappingCache(new PathMappingCache("/test"));
|
||||
value.setHttpResponse(response);
|
||||
value.setNativeWebRequest(nativeWebRequest);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,15 @@ package org.apache.skywalking.apm.plugin.spring.mvc.v4;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants;
|
||||
|
||||
public final class SpringTestCaseHelper {
|
||||
|
||||
public final static void createCaseHandler(HttpServletRequest request, HttpServletResponse response,
|
||||
CaseHandler a) throws Throwable {
|
||||
ContextManager.createLocalSpan("For-Test");
|
||||
ContextManager.getRuntimeContext().put(Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT, request);
|
||||
ContextManager.getRuntimeContext().put(Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT, response);
|
||||
a.handleCase();
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ public class Constants {
|
|||
|
||||
public static final String REST_MAPPING_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor.RestMappingMethodInterceptor";
|
||||
|
||||
public static final String HYSTRIX_COMMAND_ANNOTATION = "com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand";
|
||||
public static final String REQUEST_KEY_IN_RUNTIME_CONTEXT = "SW_REQUEST";
|
||||
|
||||
public static final String ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT = "ISOLATE_STRATEGY";
|
||||
public static final String RESPONSE_KEY_IN_RUNTIME_CONTEXT = "SW_RESPONSE";
|
||||
|
||||
public static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,28 +18,15 @@
|
|||
|
||||
package org.apache.skywalking.apm.plugin.spring.mvc.commons;
|
||||
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class EnhanceRequireObjectCache {
|
||||
private PathMappingCache pathMappingCache;
|
||||
private ThreadLocal<NativeWebRequest> nativeWebRequest = new ThreadLocal<NativeWebRequest>();
|
||||
private ThreadLocal<HttpServletResponse> httpResponse = new ThreadLocal<HttpServletResponse>();
|
||||
|
||||
public void setPathMappingCache(PathMappingCache pathMappingCache) {
|
||||
this.pathMappingCache = pathMappingCache;
|
||||
}
|
||||
|
||||
public HttpServletResponse getHttpServletResponse() {
|
||||
return httpResponse.get() == null ? (HttpServletResponse) nativeWebRequest.get().getNativeResponse() : httpResponse.get();
|
||||
}
|
||||
|
||||
public void setNativeWebRequest(NativeWebRequest nativeWebRequest) {
|
||||
this.nativeWebRequest.set(nativeWebRequest);
|
||||
}
|
||||
|
||||
public String findPathMapping(Method method) {
|
||||
return pathMappingCache.findPathMapping(method);
|
||||
}
|
||||
|
|
@ -51,14 +38,4 @@ public class EnhanceRequireObjectCache {
|
|||
public PathMappingCache getPathMappingCache() {
|
||||
return pathMappingCache;
|
||||
}
|
||||
|
||||
public void setHttpResponse(HttpServletResponse httpResponse) {
|
||||
this.httpResponse.set(httpResponse);
|
||||
}
|
||||
|
||||
public void clearRequestAndResponse() {
|
||||
setNativeWebRequest(null);
|
||||
setHttpResponse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,11 +32,10 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM
|
|||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.FORWARD_REQUEST_FLAG;
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT;
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT;
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT;
|
||||
|
||||
/**
|
||||
* the abstract method inteceptor
|
||||
|
|
@ -65,12 +64,8 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
|
|||
requestURL = pathMappingCache.findPathMapping(method);
|
||||
}
|
||||
|
||||
String hystrixIsolateStrategy = (String)ContextManager.getRuntimeContext().get(ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT);
|
||||
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
|
||||
if (hystrixIsolateStrategy != null) {
|
||||
ContextManager.createLocalSpan(requestURL);
|
||||
} else if (request != null) {
|
||||
HttpServletRequest request = (HttpServletRequest)ContextManager.getRuntimeContext().get(REQUEST_KEY_IN_RUNTIME_CONTEXT);
|
||||
if (request != null) {
|
||||
ContextCarrier contextCarrier = new ContextCarrier();
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
|
|
@ -98,12 +93,9 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
|
|||
return ret;
|
||||
}
|
||||
|
||||
String hystrixIsolateStrategy = (String)ContextManager.getRuntimeContext().get(ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT);
|
||||
HttpServletResponse response = ((EnhanceRequireObjectCache)objInst.getSkyWalkingDynamicField()).getHttpServletResponse();
|
||||
HttpServletResponse response = (HttpServletResponse)ContextManager.getRuntimeContext().get(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
try {
|
||||
if (hystrixIsolateStrategy != null) {
|
||||
ContextManager.stopSpan();
|
||||
} else if (response != null) {
|
||||
if (response != null) {
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
if (response.getStatus() >= 400) {
|
||||
span.errorOccurred();
|
||||
|
|
@ -112,7 +104,8 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
|
|||
ContextManager.stopSpan();
|
||||
}
|
||||
} finally {
|
||||
((EnhanceRequireObjectCache)objInst.getSkyWalkingDynamicField()).clearRequestAndResponse();
|
||||
ContextManager.getRuntimeContext().remove(REQUEST_KEY_IN_RUNTIME_CONTEXT);
|
||||
ContextManager.getRuntimeContext().remove(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -19,11 +19,15 @@
|
|||
package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
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.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT;
|
||||
|
||||
/**
|
||||
* {@link GetBeanInterceptor} pass the {@link NativeWebRequest} object into the {@link
|
||||
|
|
@ -41,7 +45,7 @@ public class GetBeanInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
if (ret instanceof EnhancedInstance) {
|
||||
((EnhanceRequireObjectCache)((EnhancedInstance)ret).getSkyWalkingDynamicField()).setNativeWebRequest((NativeWebRequest)objInst.getSkyWalkingDynamicField());
|
||||
ContextManager.getRuntimeContext().put(REQUEST_KEY_IN_RUNTIME_CONTEXT, ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,15 @@
|
|||
package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
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.MethodInterceptResult;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT;
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT;
|
||||
|
||||
/**
|
||||
* {@link InvokeForRequestInterceptor} pass the {@link NativeWebRequest} object into the {@link
|
||||
* org.springframework.stereotype.Controller} object.
|
||||
|
|
@ -34,12 +38,15 @@ public class InvokeForRequestInterceptor implements InstanceMethodsAroundInterce
|
|||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
objInst.setSkyWalkingDynamicField(allArguments[0]);
|
||||
ContextManager.getRuntimeContext().put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, ((NativeWebRequest)allArguments[0]).getNativeResponse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
ContextManager.getRuntimeContext().remove(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
// clear request in this method
|
||||
ContextManager.getRuntimeContext().remove(REQUEST_KEY_IN_RUNTIME_CONTEXT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,24 +19,29 @@
|
|||
package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
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.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT;
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT;
|
||||
|
||||
public class InvokeHandlerMethodInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
if (allArguments[2] instanceof EnhancedInstance) {
|
||||
((EnhanceRequireObjectCache)((EnhancedInstance)allArguments[2]).getSkyWalkingDynamicField()).setHttpResponse((HttpServletResponse)allArguments[1]);
|
||||
ContextManager.getRuntimeContext().put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, allArguments[1]);
|
||||
ContextManager.getRuntimeContext().put(REQUEST_KEY_IN_RUNTIME_CONTEXT, allArguments[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
ContextManager.getRuntimeContext().remove(RESPONSE_KEY_IN_RUNTIME_CONTEXT);
|
||||
ContextManager.getRuntimeContext().remove(REQUEST_KEY_IN_RUNTIME_CONTEXT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.tomcat78x;
|
||||
|
||||
public class Constants {
|
||||
public static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG";
|
||||
}
|
||||
|
|
@ -31,8 +31,6 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInt
|
|||
|
||||
public class ForwardInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor {
|
||||
|
||||
private static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG";
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
|
|
@ -41,7 +39,7 @@ public class ForwardInterceptor implements InstanceMethodsAroundInterceptor, Ins
|
|||
Map<String, String> eventMap = new HashMap<String, String>();
|
||||
eventMap.put("forward-url", (String)objInst.getSkyWalkingDynamicField());
|
||||
abstractTracingSpan.log(System.currentTimeMillis(), eventMap);
|
||||
ContextManager.getRuntimeContext().put(FORWARD_REQUEST_FLAG, true);
|
||||
ContextManager.getRuntimeContext().put(Constants.FORWARD_REQUEST_FLAG, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor
|
|||
Tags.STATUS_CODE.set(span, Integer.toString(response.getStatus()));
|
||||
}
|
||||
ContextManager.stopSpan();
|
||||
ContextManager.getRuntimeContext().remove(Constants.FORWARD_REQUEST_FLAG);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue