From e249e0607d461b609eb76be48c046d114b34bfd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=99=9F=20Wu=20Sheng?= Date: Mon, 21 May 2018 22:43:48 +0800 Subject: [PATCH] Provide runtime context. (#1249) --- .../core/context/AbstractTracerContext.java | 5 ++ .../agent/core/context/ContextManager.java | 10 +++- .../core/context/IgnoredTracerContext.java | 14 ++++++ .../agent/core/context/RuntimeContext.java | 46 +++++++++++++++++++ .../agent/core/context/TracingContext.java | 17 ++++++- 5 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/RuntimeContext.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java index e3ffdace7..adc6a3f50 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java @@ -104,4 +104,9 @@ public interface AbstractTracerContext { * @param span to finish */ void stopSpan(AbstractSpan span); + + /** + * @return the runtime context from current tracing context. + */ + RuntimeContext getRuntimeContext(); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java index 61e1e9dfc..e1ce82890 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java @@ -194,7 +194,15 @@ public class ContextManager implements TracingContextListener, BootService, Igno } public static boolean isActive() { - return CONTEXT.get() != null; + return get() != null; + } + + public static RuntimeContext getRuntimeContext() { + if (isActive()) { + return get().getRuntimeContext(); + } else { + throw new IllegalStateException("No active context"); + } } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java index fd115e566..a52fd2efc 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java @@ -37,6 +37,13 @@ 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; } @@ -95,6 +102,13 @@ public class IgnoredTracerContext implements AbstractTracerContext { } } + @Override public RuntimeContext getRuntimeContext() { + if (runtimeContext == null) { + runtimeContext = new RuntimeContext(); + } + return runtimeContext; + } + public static class ListenerManager { private static List LISTENERS = new LinkedList(); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/RuntimeContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/RuntimeContext.java new file mode 100644 index 000000000..3bd79fd62 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/RuntimeContext.java @@ -0,0 +1,46 @@ +/* + * 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.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * RuntimeContext is alive during the tracing context. + * It will not be serialized to the collector, and always stays in the same context only. + * + * In most cases, it means it only stays in a single thread for context propagation. + * + * @author wusheng + */ +public class RuntimeContext { + private Map context = new ConcurrentHashMap(0); + + public void put(Object key, Object value) { + context.put(key, value); + } + + public Object get(Object key) { + return context.get(key); + } + + public T get(Object key, Class type) { + return (T)context.get(key); + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java index 1bff77743..e3d4f7c55 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java @@ -79,6 +79,11 @@ public class TracingContext implements AbstractTracerContext { */ private int spanIdGenerator; + /** + * Runtime context of the tracing context + */ + private RuntimeContext runtimeContext; + /** * Initialize all fields with default value. */ @@ -94,7 +99,7 @@ public class TracingContext implements AbstractTracerContext { * Inject the context into the given carrier, only when the active span is an exit one. * * @param carrier to carry the context for crossing process. - * @throws IllegalStateException if the active span isn't an exit one. + * @throws IllegalStateException if the active span isn't an exit one. * Ref to {@link AbstractTracerContext#inject(ContextCarrier)} */ @Override @@ -316,7 +321,7 @@ public class TracingContext implements AbstractTracerContext { * @param operationName most likely a service name of remote * @param remotePeer the network id(ip:port, hostname:port or ip1:port1,ip2,port, etc.) * @return the span represent an exit point of this segment. - * @see ExitSpan + * @see ExitSpan */ @Override public AbstractSpan createExitSpan(final String operationName, final String remotePeer) { @@ -419,6 +424,14 @@ 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}