Skip to content
This repository has been archived by the owner on Jul 1, 2022. It is now read-only.

Commit

Permalink
Add a ActiveSpanSource backed TraceContext (#266)
Browse files Browse the repository at this point in the history
- use `ActiveSpanSource` for propagation instead of `ThreadLocalTraceContext`.
  • Loading branch information
vprithvi authored Oct 11, 2017
1 parent 37bd37f commit 20573d0
Show file tree
Hide file tree
Showing 17 changed files with 291 additions and 68 deletions.
1 change: 1 addition & 0 deletions jaeger-apachehttpclient/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies {
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: apacheHttpComponentsVersion
compile group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: apacheHttpComponentsVersion

testCompile project(path: ':jaeger-core', configuration: 'tests')
testCompile group: 'org.mock-server', name: 'mockserver-netty', version: '3.10.4'
testCompile group: 'junit', name: 'junit', version: junitVersion
testCompile group: 'org.mockito', name: 'mockito-core', version: mockitoVersion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.uber.jaeger.reporters.InMemoryReporter;
import com.uber.jaeger.samplers.ConstSampler;
import com.uber.jaeger.samplers.Sampler;
import com.uber.jaeger.utils.TestUtils;
import io.opentracing.util.GlobalTracer;
import java.util.List;
import org.apache.http.HttpHost;
import org.apache.http.concurrent.FutureCallback;
Expand All @@ -32,6 +34,7 @@
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.message.BasicHttpRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -64,6 +67,7 @@ public void setUp() {
reporter = new InMemoryReporter();
Sampler sampler = new ConstSampler(true);
tracer = new Tracer.Builder("test_service", reporter, sampler).build();
GlobalTracer.register(tracer);

parentSpan = (Span) tracer.buildSpan("parent_operation").startManual();
parentSpan.setBaggageItem(BAGGAGE_KEY, BAGGAGE_VALUE);
Expand All @@ -72,6 +76,11 @@ public void setUp() {
TracingUtils.getTraceContext().push(parentSpan);
}

@After
public void tearDown() throws Exception {
TestUtils.resetGlobalTracer();
}

@Test
public void testAsyncHttpClientTracing() throws Exception {
HttpAsyncClientBuilder clientBuilder = HttpAsyncClients.custom();
Expand Down
3 changes: 3 additions & 0 deletions jaeger-context/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ description = 'A library for thread-local context and utility methods for propag

dependencies {
compile group: 'io.opentracing', name: 'opentracing-api', version: opentracingVersion
compile group: 'io.opentracing', name: 'opentracing-util', version: opentracingVersion

// Testing Frameworks
testCompile group: 'junit', name: 'junit', version: junitVersion
testCompile group: 'org.mockito', name: 'mockito-core', version: mockitoVersion
testCompile project(path: ':jaeger-core')
testCompile project(path: ':jaeger-core', configuration: 'tests')

signature 'org.codehaus.mojo.signature:java16:1.1@signature'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2017, Uber Technologies, Inc
*
* Licensed 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 com.uber.jaeger.context;

import io.opentracing.ActiveSpan;
import io.opentracing.ActiveSpanSource;
import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;
import io.opentracing.util.ThreadLocalActiveSpan;

import java.lang.reflect.Field;

/**
* This is a {@link TraceContext} that relies on the {@link ActiveSpanSource} registered with {@link
* GlobalTracer}.
*/
public class ActiveSpanSourceTraceContext implements TraceContext {

private final ActiveSpanSource activeSpanSource;
/**
* This is a hack to retrieve the span wrapped by the {@link ThreadLocalActiveSpan} implementation
* to shoehorn into the {@link TraceContext} implementation. This is being done so that
* instrumentation relying on {@link Tracer} is consistent with instrumentation using {@link
* TraceContext}. We expect to remove this when opentracing-api version 0.31 is released.
*/
private static final Field wrappedSpan;

static {
try {
wrappedSpan = ThreadLocalActiveSpan.class.getDeclaredField("wrapped");
wrappedSpan.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Unable to access ThreadLocalActiveSpan.wrapped reflectively.", e);
}
}

public ActiveSpanSourceTraceContext(ActiveSpanSource activeSpanSource) {
this.activeSpanSource = activeSpanSource;
}

/** Makes the span active. */
@Override
public void push(Span span) {
activeSpanSource.makeActive(span);
}

/** Deactivates the current active span. */
@Override
public Span pop() {
ActiveSpan activeSpan = activeSpanSource.activeSpan();
Span span = getSpan(activeSpan);
activeSpan.deactivate();
return span;
}

/** Retrieves the current active span. */
@Override
public Span getCurrentSpan() {
ActiveSpan activeSpan = activeSpanSource.activeSpan();
return getSpan(activeSpan);
}

@Override
public boolean isEmpty() {
return activeSpanSource.activeSpan() == null;
}

private Span getSpan(ActiveSpan activeSpan) {
Span span;
try {
span = (Span) wrappedSpan.get(activeSpan);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}

return span;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,28 @@

package com.uber.jaeger.context;

import io.opentracing.util.GlobalTracer;

import java.util.concurrent.ExecutorService;

public class TracingUtils {
private static final TraceContext traceContext = new ThreadLocalTraceContext();
private static TraceContext traceContext = new ActiveSpanSourceTraceContext(GlobalTracer.get());

public static TraceContext getTraceContext() {
assertGlobalTracerRegistered();
return traceContext;
}

public static ExecutorService tracedExecutor(ExecutorService wrappedExecutorService) {
assertGlobalTracerRegistered();
return new TracedExecutorService(wrappedExecutorService, traceContext);
}

private TracingUtils(){}
private static void assertGlobalTracerRegistered() {
if (!GlobalTracer.isRegistered()) {
throw new IllegalStateException("Please register a io.opentracing.util.GlobalTracer.");
}
}

private TracingUtils() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2017, The Jaeger Authors
*
* Licensed 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 com.uber.jaeger.context;

import io.opentracing.ActiveSpanSource;
import io.opentracing.Span;
import io.opentracing.util.ThreadLocalActiveSpanSource;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class ActiveSpanSourceTraceContextTest {

private ActiveSpanSource activeSpanSource = new ThreadLocalActiveSpanSource();

@Mock private Span span;

private ActiveSpanSourceTraceContext traceContext =
new ActiveSpanSourceTraceContext(activeSpanSource);

@Test
public void pushAndPop() throws Exception {
traceContext.push(span);
Span actual = traceContext.pop();
Assert.assertEquals(span, actual);
}

@Test
public void getCurrentSpan() throws Exception {
traceContext.push(span);
Span actual = traceContext.getCurrentSpan();
Assert.assertEquals(span, actual);
}

@Test
public void isEmpty() throws Exception {
Assert.assertTrue(traceContext.isEmpty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2017, The Jaeger Authors
*
* Licensed 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 com.uber.jaeger.context;

import com.uber.jaeger.Configuration;
import com.uber.jaeger.utils.TestUtils;
import io.opentracing.Tracer;
import java.util.concurrent.Executors;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;

public class TracingUtilsTest {

@After
public void tearDown() throws Exception {
TestUtils.resetGlobalTracer();
}

@Test(expected = IllegalStateException.class)
public void getTraceContextWithoutGlobalTracer() throws Exception {
TracingUtils.getTraceContext();
}

@Test
public void getTraceContext() {
Tracer tracer = new Configuration("boop").getTracer();
Assert.assertNotNull(tracer);
Assert.assertNotNull(TracingUtils.getTraceContext());
}

@Test(expected = IllegalStateException.class)
public void tracedExecutorWithoutGlobalTracer() throws Exception {
TracingUtils.tracedExecutor(null);
}

@Test()
public void tracedExecutor() throws Exception {
Tracer tracer = new Configuration("boop").getTracer();
Assert.assertNotNull(tracer);
Assert.assertNotNull(TracingUtils.tracedExecutor(Executors.newSingleThreadExecutor()));
}
}
11 changes: 11 additions & 0 deletions jaeger-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,20 @@ shadowJar {
classifier 'okhttp381'
}

task testJar(type: Jar, dependsOn: testClasses) {
baseName = "test-${project.archivesBaseName}"
from sourceSets.test.output
}

configurations {
tests
}

artifacts {
archives(shadowJar.archivePath) {
builtBy shadowJar
}
tests testJar
}

task jaegerVersion {
Expand All @@ -43,3 +53,4 @@ task jaegerVersion {
}

compileJava.dependsOn jaegerVersion

Loading

0 comments on commit 20573d0

Please sign in to comment.