Skip to content

Commit f451c53

Browse files
committed
Remove activeScope() use in OpenTracing shim
This was only used to implement the deprecated 'active()' OpenTracing method. We take a best effort approach of using a 'fake' scope which lets the caller close the active scope if it matches the expected span, and otherwise logs a warning (or throws an exception in strict mode.)
1 parent 31fb383 commit f451c53

File tree

12 files changed

+154
-17
lines changed

12 files changed

+154
-17
lines changed

dd-java-agent/instrumentation/opentracing/api-0.31/src/main/java/datadog/trace/instrumentation/opentracing31/GlobalTracerInstrumentation.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public String[] helperClassNames() {
4444
packageName + ".OTTextMapSetter",
4545
packageName + ".OTScopeManager",
4646
packageName + ".OTScopeManager$OTScope",
47+
packageName + ".OTScopeManager$FakeScope",
4748
packageName + ".TypeConverter",
4849
packageName + ".OTSpan",
4950
packageName + ".OTSpanContext",

dd-java-agent/instrumentation/opentracing/api-0.31/src/main/java/datadog/trace/instrumentation/opentracing31/OTScopeManager.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package datadog.trace.instrumentation.opentracing31;
22

3+
import datadog.trace.api.Config;
34
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
45
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
56
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -8,8 +9,12 @@
89
import io.opentracing.Scope;
910
import io.opentracing.ScopeManager;
1011
import io.opentracing.Span;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
1114

1215
public class OTScopeManager implements ScopeManager {
16+
static final Logger log = LoggerFactory.getLogger(OTScopeManager.class);
17+
1318
private final TypeConverter converter;
1419
private final AgentTracer.TracerAPI tracer;
1520

@@ -33,8 +38,12 @@ public Scope activate(final Span span, final boolean finishSpanOnClose) {
3338
@Deprecated
3439
@Override
3540
public Scope active() {
41+
AgentSpan agentSpan = tracer.activeSpan();
42+
if (null == agentSpan) {
43+
return null;
44+
}
3645
// WARNING... Making an assumption about finishSpanOnClose
37-
return converter.toScope(tracer.activeScope(), false);
46+
return new OTScope(new FakeScope(agentSpan), false, converter);
3847
}
3948

4049
static class OTScope implements Scope, TraceScope {
@@ -67,4 +76,33 @@ public boolean isFinishSpanOnClose() {
6776
return finishSpanOnClose;
6877
}
6978
}
79+
80+
private final class FakeScope implements AgentScope {
81+
private final AgentSpan agentSpan;
82+
83+
FakeScope(AgentSpan agentSpan) {
84+
this.agentSpan = agentSpan;
85+
}
86+
87+
@Override
88+
public AgentSpan span() {
89+
return agentSpan;
90+
}
91+
92+
@Override
93+
public byte source() {
94+
return ScopeSource.MANUAL.id();
95+
}
96+
97+
@Override
98+
public void close() {
99+
if (agentSpan == tracer.activeSpan()) {
100+
tracer.closeActiveSpan();
101+
} else if (Config.get().isScopeStrictMode()) {
102+
throw new RuntimeException("Tried to close scope when not on top");
103+
} else {
104+
log.warn("Tried to close scope when not on top");
105+
}
106+
}
107+
}
70108
}

dd-java-agent/instrumentation/opentracing/api-0.31/src/test/groovy/OpenTracing31Test.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ class OpenTracing31Test extends AgentTestRunner {
258258
firstScope.close()
259259

260260
then:
261-
tracer.scopeManager().active().delegate == secondScope.delegate
261+
tracer.scopeManager().active().span() == secondScope.span()
262262
_ * TEST_PROFILING_CONTEXT_INTEGRATION._
263263
0 * _
264264

dd-java-agent/instrumentation/opentracing/api-0.32/src/main/java/datadog/trace/instrumentation/opentracing32/GlobalTracerInstrumentation.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public String[] helperClassNames() {
3535
packageName + ".OTTextMapInjectSetter",
3636
packageName + ".OTScopeManager",
3737
packageName + ".OTScopeManager$OTScope",
38+
packageName + ".OTScopeManager$FakeScope",
3839
packageName + ".TypeConverter",
3940
packageName + ".OTSpan",
4041
packageName + ".OTSpanContext",

dd-java-agent/instrumentation/opentracing/api-0.32/src/main/java/datadog/trace/instrumentation/opentracing32/OTScopeManager.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package datadog.trace.instrumentation.opentracing32;
22

3+
import datadog.trace.api.Config;
34
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
45
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
56
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -8,8 +9,12 @@
89
import io.opentracing.Scope;
910
import io.opentracing.ScopeManager;
1011
import io.opentracing.Span;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
1114

1215
public class OTScopeManager implements ScopeManager {
16+
static final Logger log = LoggerFactory.getLogger(OTScopeManager.class);
17+
1318
private final TypeConverter converter;
1419
private final AgentTracer.TracerAPI tracer;
1520

@@ -38,8 +43,12 @@ public Scope activate(final Span span, final boolean finishSpanOnClose) {
3843
@Deprecated
3944
@Override
4045
public Scope active() {
46+
AgentSpan agentSpan = tracer.activeSpan();
47+
if (null == agentSpan) {
48+
return null;
49+
}
4150
// WARNING... Making an assumption about finishSpanOnClose
42-
return converter.toScope(tracer.activeScope(), false);
51+
return new OTScope(new FakeScope(agentSpan), false, converter);
4352
}
4453

4554
@Override
@@ -77,4 +86,33 @@ public boolean isFinishSpanOnClose() {
7786
return finishSpanOnClose;
7887
}
7988
}
89+
90+
private final class FakeScope implements AgentScope {
91+
private final AgentSpan agentSpan;
92+
93+
FakeScope(AgentSpan agentSpan) {
94+
this.agentSpan = agentSpan;
95+
}
96+
97+
@Override
98+
public AgentSpan span() {
99+
return agentSpan;
100+
}
101+
102+
@Override
103+
public byte source() {
104+
return ScopeSource.MANUAL.id();
105+
}
106+
107+
@Override
108+
public void close() {
109+
if (agentSpan == tracer.activeSpan()) {
110+
tracer.closeActiveSpan();
111+
} else if (Config.get().isScopeStrictMode()) {
112+
throw new RuntimeException("Tried to close scope when not on top");
113+
} else {
114+
log.warn("Tried to close scope when not on top");
115+
}
116+
}
117+
}
80118
}

dd-java-agent/instrumentation/opentracing/api-0.32/src/test/groovy/OpenTracing32Test.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ class OpenTracing32Test extends AgentTestRunner {
273273
firstScope.close()
274274

275275
then:
276-
tracer.scopeManager().active().delegate == secondScope.delegate
276+
tracer.scopeManager().active().span() == secondScope.span()
277277
_ * TEST_PROFILING_CONTEXT_INTEGRATION._
278278
0 * _
279279

dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,14 @@ public AgentScope activeScope() {
972972
return scopeManager.active();
973973
}
974974

975+
@Override
976+
public void closeActiveSpan() {
977+
AgentScope activeScope = this.scopeManager.active();
978+
if (activeScope != null) {
979+
activeScope.close();
980+
}
981+
}
982+
975983
@Override
976984
public AgentSpanContext notifyExtensionStart(Object event) {
977985
return LambdaHandler.notifyStartInvocation(this, event);

dd-trace-ot/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ minimumInstructionCoverage = 0.5
1515
excludedClassesCoverage += [
1616
// This is mainly equals() and hashCode()
1717
"datadog.opentracing.OTScopeManager.OTScope",
18+
"datadog.opentracing.OTScopeManager.FakeScope",
1819
"datadog.opentracing.OTSpan",
1920
"datadog.opentracing.OTSpanContext",
2021
"datadog.opentracing.CustomScopeManagerWrapper.CustomScopeState",

dd-trace-ot/src/main/java/datadog/opentracing/OTScopeManager.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package datadog.opentracing;
22

3+
import datadog.trace.api.Config;
34
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
45
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
56
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -8,9 +9,13 @@
89
import io.opentracing.Scope;
910
import io.opentracing.ScopeManager;
1011
import io.opentracing.Span;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
1114

1215
/** One of the two possible scope managers. See CustomScopeManagerWrapper */
1316
class OTScopeManager implements ScopeManager {
17+
static final Logger log = LoggerFactory.getLogger(OTScopeManager.class);
18+
1419
private final TypeConverter converter;
1520
private final AgentTracer.TracerAPI tracer;
1621

@@ -39,8 +44,12 @@ public Scope activate(final Span span, final boolean finishSpanOnClose) {
3944
@Deprecated
4045
@Override
4146
public Scope active() {
47+
AgentSpan agentSpan = tracer.activeSpan();
48+
if (null == agentSpan) {
49+
return null;
50+
}
4251
// WARNING... Making an assumption about finishSpanOnClose
43-
return converter.toScope(tracer.activeScope(), false);
52+
return new OTScope(new FakeScope(agentSpan), false, converter);
4453
}
4554

4655
@Override
@@ -83,16 +92,45 @@ public boolean equals(final Object o) {
8392
return false;
8493
}
8594
final OTScope otScope = (OTScope) o;
86-
return delegate.equals(otScope.delegate);
95+
return delegate.span().equals(otScope.delegate.span());
8796
}
8897

8998
@Override
9099
public int hashCode() {
91-
return delegate.hashCode();
100+
return delegate.span().hashCode();
92101
}
93102

94103
boolean isFinishSpanOnClose() {
95104
return finishSpanOnClose;
96105
}
97106
}
107+
108+
private final class FakeScope implements AgentScope {
109+
private final AgentSpan agentSpan;
110+
111+
FakeScope(AgentSpan agentSpan) {
112+
this.agentSpan = agentSpan;
113+
}
114+
115+
@Override
116+
public AgentSpan span() {
117+
return agentSpan;
118+
}
119+
120+
@Override
121+
public byte source() {
122+
return ScopeSource.MANUAL.id();
123+
}
124+
125+
@Override
126+
public void close() {
127+
if (agentSpan == tracer.activeSpan()) {
128+
tracer.closeActiveSpan();
129+
} else if (Config.get().isScopeStrictMode()) {
130+
throw new RuntimeException("Tried to close scope when not on top");
131+
} else {
132+
log.warn("Tried to close scope when not on top");
133+
}
134+
}
135+
}
98136
}

dd-trace-ot/src/ot33CompatibilityTest/groovy/OT33ApiTest.groovy

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ class OT33ApiTest extends DDSpecification {
6363

6464
then:
6565
tracer.activeSpan().delegate == span.delegate
66-
coreTracer.activeScope().span() == span.delegate
6766
coreTracer.activeSpan() == span.delegate
6867

6968
cleanup:

dd-trace-ot/src/test/groovy/datadog/opentracing/IterationSpansForkedTest.groovy

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class IterationSpansForkedTest extends DDSpecification {
4040

4141
and:
4242
scope1.span() == span1
43-
scopeManager.active().delegate == scope1
43+
scopeManager.active().span().delegate == span1
4444
!spanFinished(span1)
4545

4646
when:
@@ -54,7 +54,7 @@ class IterationSpansForkedTest extends DDSpecification {
5454

5555
and:
5656
scope2.span() == span2
57-
scopeManager.active().delegate == scope2
57+
scopeManager.active().span().delegate == span2
5858
!spanFinished(span2)
5959

6060
when:
@@ -69,7 +69,7 @@ class IterationSpansForkedTest extends DDSpecification {
6969

7070
and:
7171
scope3.span() == span3
72-
scopeManager.active().delegate == scope3
72+
scopeManager.active().span().delegate == span3
7373
!spanFinished(span3)
7474

7575
when:
@@ -96,7 +96,7 @@ class IterationSpansForkedTest extends DDSpecification {
9696

9797
and:
9898
scope1.span() == span1
99-
scopeManager.active().delegate == scope1
99+
scopeManager.active().span().delegate == span1
100100
!spanFinished(span1)
101101

102102
when:
@@ -110,7 +110,7 @@ class IterationSpansForkedTest extends DDSpecification {
110110

111111
and:
112112
scope2.span() == span2
113-
scopeManager.active().delegate == scope2
113+
scopeManager.active().span().delegate == span2
114114
!spanFinished(span2)
115115

116116
when:
@@ -124,7 +124,7 @@ class IterationSpansForkedTest extends DDSpecification {
124124

125125
and:
126126
scope3.span() == span3
127-
scopeManager.active().delegate == scope3
127+
scopeManager.active().span().delegate == span3
128128
!spanFinished(span3)
129129

130130
// close and finish the surrounding (non-iteration) span to complete the trace
@@ -150,7 +150,7 @@ class IterationSpansForkedTest extends DDSpecification {
150150

151151
and:
152152
scope1.span() == span1
153-
scopeManager.active().delegate == scope1
153+
scopeManager.active().span().delegate == span1
154154
!spanFinished(span1)
155155

156156
when:
@@ -168,7 +168,7 @@ class IterationSpansForkedTest extends DDSpecification {
168168

169169
and:
170170
scope1A1.span() == span1A1
171-
scopeManager.active().delegate == scope1A1
171+
scopeManager.active().span().delegate == span1A1
172172
!spanFinished(span1A1)
173173

174174
when:
@@ -182,7 +182,7 @@ class IterationSpansForkedTest extends DDSpecification {
182182

183183
and:
184184
scope1A2.span() == span1A2
185-
scopeManager.active().delegate == scope1A2
185+
scopeManager.active().span().delegate == span1A2
186186
!spanFinished(span1A2)
187187

188188
when:

internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ public static AgentScope.Continuation captureSpan(final AgentSpan span) {
121121
return get().captureSpan(span);
122122
}
123123

124+
/**
125+
* Closes the scope for the currently active span. Prefer closing the scope returned by {@link
126+
* #activateSpan} when available.
127+
*/
128+
public static void closeActiveSpan() {
129+
get().closeActiveSpan();
130+
}
131+
124132
/**
125133
* Closes the immediately previous iteration scope. Should be called before creating a new span
126134
* for {@link #activateNext(AgentSpan)}.
@@ -318,6 +326,8 @@ AgentSpan startSpan(
318326

319327
AgentScope activeScope();
320328

329+
void closeActiveSpan();
330+
321331
default AgentSpan blackholeSpan() {
322332
final AgentSpan active = activeSpan();
323333
return new BlackHoleSpan(active != null ? active.getTraceId() : DDTraceId.ZERO);
@@ -481,6 +491,9 @@ public AgentScope activeScope() {
481491
return null;
482492
}
483493

494+
@Override
495+
public void closeActiveSpan() {}
496+
484497
@Override
485498
public AgentSpan blackholeSpan() {
486499
return NoopSpan.INSTANCE; // no-op tracer stays no-op

0 commit comments

Comments
 (0)