Permalink
Browse files

OpenTracing To Zipkin via Brave Bridge

Design:
 - All spans are created with the local tracer.
 - CS+CR and SR+SS annotations are done around the inject and extract methods.
 - tracer.extract never returns null. A NoopSpanBuilder is returned if nothing is extracted.
 - tracer.extract returns a new span, with a parent matching the spanId extracted.
 - TextMapExtractorImpl and TextMapInjectorImpl has been added again.
 - These two classes, along with abstract methods AbstractTracer.getTraceState, AbstractSpanBuilder.withStateItem, and
AbstractSpanBuilder.isTraceState, allow to automate much around the separation and extraction of a span's required propated state and its
optional baggage.

Other Changes:
 - lots of stuff made final and/or less visible.
 - Span and SpanContext are both implemented by AbstractSpan to keep things simple.
 - update AbstractTracer.PropagationRegistry so that it stores the injectors and extractors by the format instances, not the carrier types.

ref: #25
  • Loading branch information...
1 parent 0d805d6 commit 99a0c6add9b769cb54693756cfc58b6817205b84 @michaelsembwever michaelsembwever committed Mar 28, 2016
Showing with 1,465 additions and 175 deletions.
  1. +1 −0 .gitignore
  2. +3 −2 opentracing-api/src/main/java/io/opentracing/Tracer.java
  3. +1 −1 opentracing-api/src/main/java/io/opentracing/propagation/Format.java
  4. +1 −1 opentracing-api/src/main/java/io/opentracing/propagation/TextMap.java
  5. +3 −4 opentracing-api/src/main/java/io/opentracing/propagation/TextMapExtractAdapter.java
  6. +3 −4 opentracing-api/src/main/java/io/opentracing/propagation/TextMapInjectAdapter.java
  7. +108 −0 opentracing-brave/pom.xml
  8. +142 −0 opentracing-brave/src/main/java/io/opentracing/BraveSpanBuilderImpl.java
  9. +78 −0 opentracing-brave/src/main/java/io/opentracing/BraveSpanImpl.java
  10. +92 −0 opentracing-brave/src/main/java/io/opentracing/BraveTracerImpl.java
  11. +161 −0 opentracing-brave/src/test/java/io/opentracing/BraveSpanBuilderImplTest.java
  12. +148 −0 opentracing-brave/src/test/java/io/opentracing/BraveSpanImplTest.java
  13. +460 −0 opentracing-brave/src/test/java/io/opentracing/BraveTracerImplTest.java
  14. +26 −2 opentracing-impl-java8/src/main/java/io/opentracing/AbstractSpan.java
  15. +29 −10 opentracing-impl-java8/src/main/java/io/opentracing/AbstractSpanBuilder.java
  16. +33 −46 opentracing-impl-java8/src/main/java/io/opentracing/AbstractTracer.java
  17. +43 −0 opentracing-impl-java8/src/main/java/io/opentracing/TextMapExtractorImpl.java
  18. +47 −0 opentracing-impl-java8/src/main/java/io/opentracing/TextMapInjectorImpl.java
  19. +23 −9 opentracing-impl-java8/src/test/java/io/opentracing/AbstractTracerTest.java
  20. +23 −6 ...g/NoopSpanContext.java → opentracing-impl-java8/src/test/java/io/opentracing/TestSpanBuilder.java
  21. +0 −52 opentracing-impl-java8/src/test/java/io/opentracing/TestSpanContextImpl.java
  22. +0 −17 opentracing-impl-java8/src/test/java/io/opentracing/TestSpanImpl.java
  23. +10 −9 opentracing-impl-java8/src/test/java/io/opentracing/{propagation → }/TestTextMapExtractorImpl.java
  24. +5 −5 opentracing-impl-java8/src/test/java/io/opentracing/{propagation → }/TestTextMapInjectorImpl.java
  25. +11 −2 opentracing-impl/src/main/java/io/opentracing/NoopSpan.java
  26. +10 −2 opentracing-impl/src/main/java/io/opentracing/NoopSpanBuilder.java
  27. +1 −1 opentracing-impl/src/main/java/io/opentracing/NoopTracer.java
  28. +2 −2 opentracing-impl/src/main/java/io/opentracing/propagation/Extractor.java
  29. +1 −0 pom.xml
View
@@ -11,3 +11,4 @@ _site/
.idea
*.iml
*.swp
+/opentracing-brave/nbproject/
@@ -78,15 +78,16 @@
* @param format the Format of the carrier
* @param carrier the carrier for the SpanContext state. All Tracer.extract() implementations must support
* io.opentracing.propagation.TextMap and java.nio.ByteBuffer.
- * @returns the SpanContext instance extracted from the carrier
+ *
+ * @return the SpanContext instance holding context to create a Span.
*
* @see io.opentracing.propagation.Format
* @see io.opentracing.propagation.Format.Builtin
*/
<C> SpanContext extract(Format<C> format, C carrier);
- interface SpanBuilder {
+ interface SpanBuilder extends SpanContext {
/**
* A shorthand for addReference(References.CHILD_OF, parent).
@@ -34,7 +34,7 @@
* @see Tracer#extract(Format, Object)
*/
public interface Format<C> {
- class Builtin<C> implements Format<C> {
+ final class Builtin<C> implements Format<C> {
/**
* The TEXT_MAP format allows for arbitrary String->String map encoding of SpanContext state for Tracer.inject
* and Tracer.extract.
@@ -14,8 +14,8 @@
package io.opentracing.propagation;
import io.opentracing.SpanContext;
-
import java.util.Iterator;
+
import java.util.Map;
/**
@@ -14,8 +14,8 @@
package io.opentracing.propagation;
import io.opentracing.Tracer;
-
import java.util.Iterator;
+
import java.util.Map;
/**
@@ -26,7 +26,7 @@
*
* @see Tracer#extract(Format, Object)
*/
-public class TextMapExtractAdapter implements TextMap {
+public final class TextMapExtractAdapter implements TextMap {
private final Map<String,String> map;
public TextMapExtractAdapter(final Map<String,String> map) {
@@ -40,7 +40,6 @@ public TextMapExtractAdapter(final Map<String,String> map) {
@Override
public void put(String key, String value) {
- throw new UnsupportedOperationException(
- "TextMapInjectAdapter should only be used with Tracer.extract()");
+ throw new UnsupportedOperationException("TextMapInjectAdapter should only be used with Tracer.extract()");
}
}
@@ -15,8 +15,8 @@
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
-
import java.util.Iterator;
+
import java.util.Map;
/**
@@ -27,7 +27,7 @@
*
* @see Tracer#inject(SpanContext, Format, Object)
*/
-public class TextMapInjectAdapter implements TextMap {
+public final class TextMapInjectAdapter implements TextMap {
private final Map<String,String> map;
public TextMapInjectAdapter(final Map<String,String> map) {
@@ -36,8 +36,7 @@ public TextMapInjectAdapter(final Map<String,String> map) {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
- throw new UnsupportedOperationException(
- "TextMapInjectAdapter should only be used with Tracer.inject()");
+ throw new UnsupportedOperationException("TextMapInjectAdapter should only be used with Tracer.inject()");
}
@Override
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2016 The OpenTracing 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>io.opentracing</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.13-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>opentracing-brave</artifactId>
+ <name>OpenTracing-brave</name>
+ <description>OpenTracing Brave bridge</description>
+
+ <properties>
+ <main.basedir>${project.basedir}/..</main.basedir>
+ <animal-sniffer-maven-plugin.version>1.14</animal-sniffer-maven-plugin.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.opentracing</groupId>
+ <artifactId>opentracing-impl-java8</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.zipkin.brave</groupId>
+ <artifactId>brave-core</artifactId>
+ <version>3.9.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.kristofa</groupId>
+ <artifactId>brave-http</artifactId>
+ <version>3.5.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.10.8</version>
+ <scope>test</scope>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- Ensure main source tree compiles to Java 7 bytecode. This allows higher
+ reuse, including android, which doesn't support Java 8 features. -->
+ <plugin>
+ <inherited>true</inherited>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- Language-level aside, make sure Java 8 types and methods aren't used -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <version>${animal-sniffer-maven-plugin.version}</version>
+ <configuration>
+ <signature>
+ <groupId>org.codehaus.mojo.signature</groupId>
+ <artifactId>java18</artifactId>
+ <version>1.0</version>
+ </signature>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
@@ -0,0 +1,142 @@
+/**
+ * Copyright 2016 The OpenTracing 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 io.opentracing;
+
+import java.util.Optional;
+
+import com.github.kristofa.brave.Brave;
+import com.github.kristofa.brave.IdConversion;
+import com.github.kristofa.brave.ServerTracer;
+import com.github.kristofa.brave.http.BraveHttpHeaders;
+
+
+final class BraveSpanBuilderImpl extends AbstractSpanBuilder {
+
+ Long traceId = null;
+ Long parentSpanId = null;
+ ServerTracer serverTracer = null;
+ SpanContext spanContext = null;
+
+ private final Brave brave;
+
+ static BraveSpanBuilderImpl create(Brave brave, String operationName) {
+ return new BraveSpanBuilderImpl(brave, operationName);
+ }
+
+ private BraveSpanBuilderImpl(Brave brave, String operationName) {
+ super(operationName);
+ this.brave = brave;
+ }
+
+ @Override
+ protected BraveSpanImpl createSpan() {
+ BraveSpanImpl parent = getParent();
+ if (null != parent) {
+ traceId = parent.spanId.getTraceId();
+ parentSpanId = parent.spanId.getSpanId();
+
+ // push this into the serverSpanState as the current span as that is where new localSpans find their parents
+ brave.serverTracer()
+ .setStateCurrentTrace(traceId, parentSpanId, parent.spanId.parentId, parent.operationName);
+ }
+ if (null == traceId && null == parentSpanId) {
+ brave.serverTracer().clearCurrentSpan();
+ }
+
+ BraveSpanImpl span = BraveSpanImpl.create(brave,
+ operationName,
+ Optional.ofNullable(parent),
+ start,
+ Optional.ofNullable(serverTracer));
+
+ // push this into the serverSpanState as the current span as that is where new localSpans find their parents
+ brave.serverTracer().setStateCurrentTrace(
+ span.spanId.traceId,
+ span.spanId.spanId,
+ span.spanId.parentId,
+ span.operationName);
+
+ assert (null == traceId && null == parentSpanId) || (null != traceId && null != parentSpanId);
+ assert null == traceId || span.spanId.getTraceId() == traceId;
+ assert null == parentSpanId || parentSpanId.equals(span.spanId.getParentSpanId());
+
+ if (null == traceId && null == parentSpanId) {
+ // called through tracer.buildSpan(..), as opposed to builder.extract(..)
+ brave.serverTracer().setStateCurrentTrace(
+ span.spanId.getTraceId(),
+ span.spanId.getSpanId(),
+ span.spanId.getParentSpanId(),
+ operationName);
+ }
+
+ return span;
+ }
+
+ BraveSpanBuilderImpl withServerTracer(ServerTracer serverTracer) {
+ this.serverTracer = serverTracer;
+ return this;
+ }
+
+ /** @Nullable **/
+ private BraveSpanImpl getParent() {
+ for (Reference reference : references) {
+ if (References.CHILD_OF.equals(reference.getReferenceType())) {
+ return (BraveSpanImpl) reference.getReferredTo();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ boolean isTraceState(String key, Object value) {
+ return null != valueOf(key);
+ }
+
+ private static BraveHttpHeaders valueOf(String key) {
+ for (BraveHttpHeaders header : BraveHttpHeaders.values()) {
+ if (header.getName().equals(key)) {
+ return header;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ BraveSpanBuilderImpl withStateItem(String key, Object value) {
+ BraveHttpHeaders header = valueOf(key);
+ if (null == header) {
+ throw new IllegalArgumentException(key + " is not a valid brave header");
+ }
+ switch (header) {
+ case TraceId:
+ traceId = value instanceof Number
+ ? ((Number)value).longValue()
+ : IdConversion.convertToLong(value.toString());
+ break;
+ case SpanId:
+ parentSpanId = value instanceof Number
+ ? ((Number)value).longValue()
+ : IdConversion.convertToLong(value.toString());
+ break;
+ case ParentSpanId:
+ if (null == parentSpanId) {
+ parentSpanId = value instanceof Number
+ ? ((Number)value).longValue()
+ : IdConversion.convertToLong(value.toString());
+ }
+ break;
+ }
+ return this;
+ }
+}
Oops, something went wrong.

0 comments on commit 99a0c6a

Please sign in to comment.