From 233cce5bb6341a62811807696bc172b2d340d566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=99=9F=20Wu=20Sheng?= Date: Fri, 25 Mar 2022 18:58:11 +0800 Subject: [PATCH] Make sure the parent endpoint from existing first ENTRY span (#129) * Make sure the parent endpoint in tracing context from existing first ENTRY span, rather than first span only. --- CHANGES.md | 1 + .../agent/core/context/TracingContext.java | 50 ++++++++++++++----- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6ed0bacb7..08b137781 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -33,6 +33,7 @@ Release Notes. * The namespace and cluster would be reported as instance properties, keys are `namespace` and `cluster`. Notice, if instance_properties_json includes these two keys, they would be overrided by the agent core. * [Breaking Change] Remove the namespace from `cross process propagation` key. +* Make sure the parent endpoint in tracing context from existing first ENTRY span, rather than first span only. #### Documentation 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 ec9c4e182..5e60b4cff 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 @@ -78,12 +78,11 @@ public class TracingContext implements AbstractTracerContext { * LinkedList#getLast()} instead of {@link #pop()}, {@link #push(AbstractSpan)}, {@link #peek()} */ private LinkedList activeSpanStack = new LinkedList<>(); + /** - * @since 7.0.0 SkyWalking support lazy injection through {@link ExitTypeSpan#inject(ContextCarrier)}. Due to that, - * the {@link #activeSpanStack} could be blank by then, this is a pointer forever to the first span, even the main - * thread tracing has been finished. + * @since 8.10.0 replace the removed "firstSpan"(before 8.10.0) reference. see {@link PrimaryEndpoint} for more details. */ - private AbstractSpan firstSpan = null; + private PrimaryEndpoint primaryEndpoint = null; /** * A counter for the next span. @@ -175,7 +174,7 @@ public class TracingContext implements AbstractTracerContext { carrier.setSpanId(exitSpan.getSpanId()); carrier.setParentService(Config.Agent.SERVICE_NAME); carrier.setParentServiceInstance(Config.Agent.INSTANCE_NAME); - carrier.setParentEndpoint(first().getOperationName()); + carrier.setParentEndpoint(primaryEndpoint.getName()); carrier.setAddressUsedAtClient(peer); this.correlationContext.inject(carrier); @@ -212,7 +211,7 @@ public class TracingContext implements AbstractTracerContext { segment.getTraceSegmentId(), activeSpan().getSpanId(), getPrimaryTraceId(), - first().getOperationName(), + primaryEndpoint.getName(), this.correlationContext, this.extensionContext ); @@ -527,8 +526,10 @@ public class TracingContext implements AbstractTracerContext { * @param span the {@code span} to push */ private AbstractSpan push(AbstractSpan span) { - if (firstSpan == null) { - firstSpan = span; + if (primaryEndpoint == null) { + primaryEndpoint = new PrimaryEndpoint(span); + } else { + primaryEndpoint.set(span); } activeSpanStack.addLast(span); this.extensionContext.handle(span); @@ -545,10 +546,6 @@ public class TracingContext implements AbstractTracerContext { return activeSpanStack.getLast(); } - private AbstractSpan first() { - return firstSpan; - } - private boolean isLimitMechanismWorking() { if (spanIdGenerator >= spanLimitWatcher.getSpanLimit()) { long currentTimeMillis = System.currentTimeMillis(); @@ -572,4 +569,33 @@ public class TracingContext implements AbstractTracerContext { public ProfileStatusReference profileStatus() { return this.profileStatus; } + + /** + * Primary endpoint name is used for endpoint dependency. The name pick policy according to priority is + * 1. Use the first entry span's operation name + * 2. Use the first span's operation name + * + * @since 8.10.0 + */ + private class PrimaryEndpoint { + @Getter + private AbstractSpan span; + + private PrimaryEndpoint(final AbstractSpan span) { + this.span = span; + } + + /** + * Set endpoint name according to priority + */ + private void set(final AbstractSpan span) { + if (!this.span.isEntry() && span.isEntry()) { + this.span = span; + } + } + + private String getName() { + return span.getOperationName(); + } + } }