From cd31a3bad1ceb08a213efde5f1f3700028d45351 Mon Sep 17 00:00:00 2001 From: Ben Keith Date: Tue, 17 Apr 2018 11:08:32 -0400 Subject: [PATCH 1/3] Add ZipkinReporter to support Zipkin v2 This adds a new class called Zipkin2Reporter that adapts a Zipkin v2 reporter and converts Jaeger spans to Zipkin v2 spans. This enables us to send spans to a Zipkin v2 server using the newer protocol. This also moves the existing Thrift conversion logic to a new package `io.jaegertracing.zipkin` where it exists alongside the new v2 conversion logic. Signed-off-by: Ben Keith --- jaeger-zipkin/README.md | 31 +- jaeger-zipkin/build.gradle | 17 +- .../senders/zipkin/ZipkinSender.java | 4 +- .../jaegertracing/zipkin/ConverterUtil.java | 38 +++ .../zipkin/ThriftSpanConverter.java | 26 +- .../jaegertracing/zipkin/V2SpanConverter.java | 187 +++++++++++ .../zipkin/reporters/Zipkin2Reporter.java | 39 +++ .../senders/zipkin/ZipkinSenderTest.java | 1 + .../zipkin/ThriftSpanConverterTest.java | 10 +- .../zipkin/V2SpanConverterTest.java | 312 ++++++++++++++++++ .../zipkin/reporters/Zipkin2ReporterTest.java | 73 ++++ 11 files changed, 707 insertions(+), 31 deletions(-) create mode 100644 jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java rename jaeger-zipkin/src/main/java/io/jaegertracing/{senders => }/zipkin/ThriftSpanConverter.java (90%) create mode 100644 jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java create mode 100644 jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/Zipkin2Reporter.java rename jaeger-zipkin/src/test/java/io/jaegertracing/{senders => }/zipkin/ThriftSpanConverterTest.java (97%) create mode 100644 jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java create mode 100644 jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/Zipkin2ReporterTest.java diff --git a/jaeger-zipkin/README.md b/jaeger-zipkin/README.md index 4071f9a31..a8a165407 100644 --- a/jaeger-zipkin/README.md +++ b/jaeger-zipkin/README.md @@ -21,12 +21,39 @@ tracer = new Tracer.Builder(serviceName, reporter, sampler) ``` ## Sending data to Zipkin -Zipkin supports transports including Http and Kafka. You can configure Jaeger to send to a Zipkin server with -`ZipkinSender`. +There are two ways to send spans to a Zipkin server: + +### Thrift +If you want to send Zipkin v1 Thrift-encoded spans, you should use the `ZipkinSender` sender, which +wraps a Zipkin sender class to enable the use of various transports such as HTTP and Kafka. For example: ```java +import io.jaegertracing.senders.zipkin.ZipkinSender; + reporter = new RemoteReporter(ZipkinSender.create("http://localhost:9411/api/v1/spans")); tracer = new Tracer.Builder(serviceName, reporter, sampler) ... ``` + +### Zipkin 2 Reporters +You can reuse a Zipkin 2 reporter instance as-is by using `Zipkin2Reporter`, which adapts a Zipkin +2 reporter to the Jaeger reporter interface and deals with converting Jaeger spans to the Zipkin 2 +model. + +For example: +```java +import io.jaegertracing.zipkin.reporters.Zipkin2Reporter; +import zipkin2.reporter.AsyncReporter; +import zipkin2.reporter.urlconnection.URLConnectionSender; + +reporter = new Zipkin2Reporter( + AsyncReporter.create(URLConnectionSender.create("http://localhost:9411/api/v2/spans"))); + +tracer = new Tracer.Builder(serviceName) + .withReporter(reporter) + ... + .build() +``` + +This will send spans to the Zipkin v2 endpoint using the v2 JSON encoding. diff --git a/jaeger-zipkin/build.gradle b/jaeger-zipkin/build.gradle index cd092a3b4..7de4a113c 100644 --- a/jaeger-zipkin/build.gradle +++ b/jaeger-zipkin/build.gradle @@ -1,12 +1,23 @@ description = 'Integration library for Zipkin' dependencies { - compile group: 'io.zipkin.reporter', name: 'zipkin-reporter', version: '1.1.2' - compile group: 'io.zipkin.reporter', name: 'zipkin-sender-urlconnection', version: '1.1.2' + compile(group: 'io.zipkin.reporter', name: 'zipkin-reporter', version: '1.1.2') { + exclude group:'io.zipkin.zipkin2' + exclude group:'io.zipkin.java' + } + compile(group: 'io.zipkin.reporter', name: 'zipkin-sender-urlconnection', version: '1.1.2') { + exclude group:'io.zipkin.zipkin2' + exclude group:'io.zipkin.java' + } + + compile group: 'io.zipkin.java', name: 'zipkin', version: '2.8.1' + compile group: 'io.zipkin.reporter2', name: 'zipkin-reporter', version: '2.6.0' + compile project(path: ':jaeger-core', configuration: 'shadow') + testCompile group: 'io.zipkin.reporter2', name: 'zipkin-sender-urlconnection', version: '2.6.0' testCompile group: 'junit', name: 'junit', version: junitVersion - testCompile group: 'io.zipkin.java', name: 'zipkin-junit', version: '2.3.0' + testCompile group: 'io.zipkin.java', name: 'zipkin-junit', version: '2.7.1' testCompile group: 'com.tngtech.java', name: 'junit-dataprovider', version: junitDataProviderVersion signature 'org.codehaus.mojo.signature:java16:1.1@signature' diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java b/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java index df25acc7f..8963c2898 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java @@ -21,6 +21,7 @@ import com.twitter.zipkin.thriftjava.zipkincoreConstants; import io.jaegertracing.exceptions.SenderException; import io.jaegertracing.senders.Sender; +import io.jaegertracing.zipkin.ThriftSpanConverter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -33,7 +34,8 @@ /** * This sends (TBinaryProtocol big-endian) encoded spans to a Zipkin Collector (usually a - * zipkin-server). + * zipkin-server). If you want to send newer Zipkin V2 spans in protocols other than Thrift, + * see {@link io.jaegertracing.zipkin.reporters.Zipkin2Reporter Zipkin2Reporter}. * *

* Example usage: diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java new file mode 100644 index 000000000..e80168a0e --- /dev/null +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, 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 io.jaegertracing.zipkin; + +import io.jaegertracing.Span; +import io.opentracing.tag.Tags; + +/** + * Logic that is common to both Thrift v1 and JSON v2 senders + */ +class ConverterUtil { + static boolean isRpcServer(Span span) { + return Tags.SPAN_KIND_SERVER.equals(span.getTags().get(Tags.SPAN_KIND.getKey())); + } + + static boolean isRpc(Span span) { + return isRpcServer(span) || isRpcClient(span); + + } + + static boolean isRpcClient(Span span) { + return Tags.SPAN_KIND_CLIENT.equals(span.getTags().get(Tags.SPAN_KIND.getKey())); + } + + +} diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ThriftSpanConverter.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ThriftSpanConverter.java similarity index 90% rename from jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ThriftSpanConverter.java rename to jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ThriftSpanConverter.java index a8b199ee6..95c946581 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ThriftSpanConverter.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ThriftSpanConverter.java @@ -12,7 +12,7 @@ * the License. */ -package io.jaegertracing.senders.zipkin; +package io.jaegertracing.zipkin; import com.google.gson.Gson; import com.twitter.zipkin.thriftjava.Annotation; @@ -56,10 +56,10 @@ public static com.twitter.zipkin.thriftjava.Span convertSpan(Span span) { private static List buildAnnotations(Span span, Endpoint host) { List annotations = new ArrayList(); - if (isRpc(span)) { + if (ConverterUtil.isRpc(span)) { String startLabel = zipkincoreConstants.SERVER_RECV; String endLabel = zipkincoreConstants.SERVER_SEND; - if (isRpcClient(span)) { + if (ConverterUtil.isRpcClient(span)) { startLabel = zipkincoreConstants.CLIENT_SEND; endLabel = zipkincoreConstants.CLIENT_RECV; } @@ -87,9 +87,9 @@ private static List buildAnnotations(Span span, Endpoint host) { private static List buildBinaryAnnotations(Span span, Endpoint host) { List binaryAnnotations = new ArrayList(); Map tags = span.getTags(); - boolean isRpc = isRpc(span); - boolean isClient = isRpcClient(span); - boolean firstSpanInProcess = span.getReferences().isEmpty() || isRpcServer(span); + boolean isRpc = ConverterUtil.isRpc(span); + boolean isClient = ConverterUtil.isRpcClient(span); + boolean firstSpanInProcess = span.getReferences().isEmpty() || ConverterUtil.isRpcServer(span); if (firstSpanInProcess) { Map processTags = span.getTracer().tags(); @@ -154,20 +154,6 @@ private static BinaryAnnotation buildBinaryAnnotation(String tagKey, Object tagV return banno; } - static boolean isRpcServer(Span span) { - return Tags.SPAN_KIND_SERVER.equals(span.getTags().get(Tags.SPAN_KIND.getKey())); - } - - static boolean isRpc(Span span) { - Object spanKindValue = span.getTags().get(Tags.SPAN_KIND.getKey()); - return Tags.SPAN_KIND_CLIENT.equals(spanKindValue) || Tags.SPAN_KIND_SERVER.equals(spanKindValue); - - } - - static boolean isRpcClient(Span span) { - return Tags.SPAN_KIND_CLIENT.equals(span.getTags().get(Tags.SPAN_KIND.getKey())); - } - /** * Extract peer Endpoint from tags * diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java new file mode 100644 index 000000000..b6c7e4faf --- /dev/null +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2018, 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 io.jaegertracing.zipkin; + +import com.google.gson.Gson; +import io.jaegertracing.Constants; +import io.jaegertracing.LogData; +import io.jaegertracing.Span; +import io.jaegertracing.SpanContext; +import io.jaegertracing.Tracer; +import io.opentracing.tag.Tags; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Map; + +/** + * Converts a Jaeger span to a Zipkin2 span. + */ +public class V2SpanConverter { + + private static final Gson gson = new Gson(); + + public static zipkin2.Span convertSpan(Span span) { + Tracer tracer = span.getTracer(); + zipkin2.Endpoint host = zipkin2.Endpoint.newBuilder() + .ip(convertIp(tracer.getIpv4())) + .serviceName(tracer.getServiceName()) + .build(); + + zipkin2.Endpoint peerEndpoint = extractPeerEndpoint(span.getTags()); + + SpanContext context = span.context(); + zipkin2.Span.Builder builder = zipkin2.Span.newBuilder() + .id(Long.toHexString(context.getSpanId())) + .traceId(Long.toHexString(context.getTraceId())) + .name(span.getOperationName()) + .parentId(Long.toHexString(context.getParentId())) + .debug(context.isDebug()) + .localEndpoint(host) + .remoteEndpoint(peerEndpoint) + .kind(convertKind(span.getTags().get(Tags.SPAN_KIND.getKey()))) + .timestamp(span.getStart()) + .duration(span.getDuration()); + + buildAnnotations(span, builder); + buildTags(span, builder); + + return builder.build(); + } + + private static zipkin2.Span.Kind convertKind(Object kind) { + if (Tags.SPAN_KIND_SERVER.equals(kind)) { + return zipkin2.Span.Kind.SERVER; + } else if (Tags.SPAN_KIND_CLIENT.equals(kind)) { + return zipkin2.Span.Kind.CLIENT; + } else if (Tags.SPAN_KIND_CONSUMER.equals(kind)) { + return zipkin2.Span.Kind.CONSUMER; + } else if (Tags.SPAN_KIND_PRODUCER.equals(kind)) { + return zipkin2.Span.Kind.PRODUCER; + } else { + return null; + } + } + + private static void buildAnnotations(Span span, zipkin2.Span.Builder builder) { + if (ConverterUtil.isRpc(span)) { + String startLabel = zipkin.Constants.SERVER_RECV; + String endLabel = zipkin.Constants.SERVER_SEND; + if (ConverterUtil.isRpcClient(span)) { + startLabel = zipkin.Constants.CLIENT_SEND; + endLabel = zipkin.Constants.CLIENT_RECV; + } + + builder.addAnnotation(span.getStart(), startLabel); + builder.addAnnotation(span.getStart() + span.getDuration(), endLabel); + } + + List logs = span.getLogs(); + if (logs != null) { + for (LogData logData : logs) { + String logMessage = logData.getMessage(); + Map logFields = logData.getFields(); + if (logMessage != null) { + builder.addAnnotation(logData.getTime(), logMessage); + } else if (logFields != null) { + builder.addAnnotation(logData.getTime(), gson.toJson(logFields)); + } + } + } + } + + private static void buildTags(Span span, zipkin2.Span.Builder builder) { + Map tags = span.getTags(); + boolean isRpc = ConverterUtil.isRpc(span); + boolean firstSpanInProcess = span.getReferences().isEmpty() || ConverterUtil.isRpcServer(span); + + if (firstSpanInProcess) { + Map processTags = span.getTracer().tags(); + // add tracer tags to first zipkin span in a process but remove "ip" tag as it is + // taken care of separately. + for (Map.Entry entry : processTags.entrySet()) { + String tagKey = entry.getKey(); + if (!Constants.TRACER_IP_TAG_KEY.equals(tagKey)) { + Object tagValue = entry.getValue(); + // add a tracer. prefix to process tags for zipkin + builder.putTag("tracer." + tagKey, tagValue.toString()); + } + } + } + + if (!isRpc) { + String componentName; + Object componentTag = tags.get(Tags.COMPONENT.getKey()); + if (componentTag instanceof String) { + componentName = componentTag.toString(); + } else { + // spans always have associated tracers, and service names + componentName = span.getTracer().getServiceName(); + } + + builder.putTag(zipkin.Constants.LOCAL_COMPONENT, componentName); + } + + if (tags != null) { + for (Map.Entry entry : tags.entrySet()) { + String tagKey = entry.getKey(); + // Every value is converted to string because zipkin search doesn't + // work well with ints, and bytes. + Object tagValue = entry.getValue(); + builder.putTag(tagKey, tagValue.toString()); + } + } + } + + private static InetAddress convertIp(int ip) { + byte[] bytes = ByteBuffer.allocate(4).putInt(ip).array(); + try { + return InetAddress.getByAddress(bytes); + } catch (UnknownHostException e) { + return null; + } + } + + /** + * Extract peer Endpoint from tags + * + * @param tags tags + * @return null or peer endpoint + */ + public static zipkin2.Endpoint extractPeerEndpoint(Map tags) { + Object peerIpv4 = tags.get(Tags.PEER_HOST_IPV4.getKey()); + Object peerPort = tags.get(Tags.PEER_PORT.getKey()); + Object peerService = tags.get(Tags.PEER_SERVICE.getKey()); + + if (peerIpv4 == null && peerPort == null && peerService == null) { + return null; + } + + zipkin2.Endpoint.Builder builder = zipkin2.Endpoint.newBuilder(); + + if (peerIpv4 instanceof String) { + builder.ip((String) peerIpv4); + } + if (peerPort instanceof Number) { + builder.port(((Number) peerPort).intValue()); + } + if (peerService instanceof String) { + builder.serviceName((String) peerService); + } + + return builder.build(); + } +} diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/Zipkin2Reporter.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/Zipkin2Reporter.java new file mode 100644 index 000000000..ea2185c5f --- /dev/null +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/Zipkin2Reporter.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, 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 io.jaegertracing.zipkin.reporters; + +import io.jaegertracing.reporters.Reporter; +import io.jaegertracing.zipkin.V2SpanConverter; + +/** + * Wrapper around a zipkin v2 AsyncReporter that reports spans using the newer v2 Span class + */ +public class Zipkin2Reporter implements Reporter { + public final zipkin2.reporter.AsyncReporter reporter; + + public Zipkin2Reporter(zipkin2.reporter.AsyncReporter reporter) { + this.reporter = reporter; + } + + @Override + public void report(io.jaegertracing.Span span) { + reporter.report(V2SpanConverter.convertSpan(span)); + } + + @Override + public void close() { + reporter.close(); + } +} diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java index c4b11573b..518212961 100644 --- a/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java @@ -25,6 +25,7 @@ import io.jaegertracing.reporters.InMemoryReporter; import io.jaegertracing.reporters.Reporter; import io.jaegertracing.samplers.ConstSampler; +import io.jaegertracing.zipkin.ThriftSpanConverter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ThriftSpanConverterTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/ThriftSpanConverterTest.java similarity index 97% rename from jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ThriftSpanConverterTest.java rename to jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/ThriftSpanConverterTest.java index 2e939bb50..ac996d60d 100644 --- a/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ThriftSpanConverterTest.java +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/ThriftSpanConverterTest.java @@ -12,7 +12,7 @@ * the License. */ -package io.jaegertracing.senders.zipkin; +package io.jaegertracing.zipkin; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.assertEquals; @@ -241,8 +241,8 @@ public void testSpanDetectsIsClient() { Span span = (Span) tracer.buildSpan("test-service-operation").start(); Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); - assertTrue(ThriftSpanConverter.isRpc(span)); - assertTrue(ThriftSpanConverter.isRpcClient(span)); + assertTrue(ConverterUtil.isRpc(span)); + assertTrue(ConverterUtil.isRpcClient(span)); } @Test @@ -250,8 +250,8 @@ public void testSpanDetectsIsServer() { Span span = (Span) tracer.buildSpan("test-service-operation").start(); Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER); - assertTrue(ThriftSpanConverter.isRpc(span)); - assertFalse(ThriftSpanConverter.isRpcClient(span)); + assertTrue(ConverterUtil.isRpc(span)); + assertFalse(ConverterUtil.isRpcClient(span)); } @Test diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java new file mode 100644 index 000000000..7f78d4a4f --- /dev/null +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2018, 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 io.jaegertracing.zipkin; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import io.jaegertracing.Span; +import io.jaegertracing.SpanContext; +import io.jaegertracing.Tracer; +import io.jaegertracing.reporters.InMemoryReporter; +import io.jaegertracing.samplers.ConstSampler; +import io.opentracing.propagation.Format; +import io.opentracing.propagation.TextMap; +import io.opentracing.propagation.TextMapExtractAdapter; +import io.opentracing.propagation.TextMapInjectAdapter; +import io.opentracing.tag.Tags; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import zipkin2.Annotation; + +@RunWith(DataProviderRunner.class) +public class V2SpanConverterTest { + Tracer tracer; + + @Before + public void setUp() { + tracer = + new Tracer.Builder("test-service-name") + .withReporter(new InMemoryReporter()) + .withSampler(new ConstSampler(true)) + .withZipkinSharedRpcSpan() + .build(); + } + + // undef value is used to mark tags that should *not* be present + private static final String UNDEF = "undef"; + + // ANY value is used to mark tags that should be present but we don't care what it's value is + private static final String ANY = "any"; + + private enum SpanType { + ROOT, + CHILD, + RPC_SERVER + } + + @DataProvider + public static Object[][] dataProviderTracerTags() { + Tracer tracer = new Tracer.Builder("x").build(); + + Map rootTags = new HashMap<>(); + rootTags.put("tracer.jaeger.version", tracer.getVersion()); + rootTags.put("tracer.hostname", ANY); + rootTags.put("tracer.tag.str", "y"); + rootTags.put("tracer.tag.bool", "true"); + rootTags.put("tracer.tag.num", "1"); + rootTags.put("sampler.type", "const"); + rootTags.put("sampler.param", "true"); + + Map childTags = new HashMap<>(); + childTags.put("tracer.jaeger.version", UNDEF); + childTags.put("tracer.hostname", UNDEF); + childTags.put("tracer.tag.str", UNDEF); + childTags.put("tracer.tag.bool", UNDEF); + childTags.put("tracer.tag.num", UNDEF); + childTags.put("sampler.type", UNDEF); + childTags.put("sampler.param", UNDEF); + + Map rpcTags = new HashMap<>(); + rpcTags.put("tracer.jaeger.version", tracer.getVersion()); + rpcTags.put("tracer.hostname", ANY); + rpcTags.put("tracer.tag.str", "y"); + rpcTags.put("tracer.tag.bool", "true"); + rpcTags.put("tracer.tag.num", "1"); + rpcTags.put("sampler.type", UNDEF); + rpcTags.put("sampler.param", UNDEF); + + return new Object[][] { + { SpanType.ROOT, rootTags }, + { SpanType.CHILD, childTags }, + { SpanType.RPC_SERVER, rpcTags }, + }; + } + + @Test + @UseDataProvider("dataProviderTracerTags") + public void testTracerTags(SpanType spanType, Map expectedTags) throws Exception { + InMemoryReporter spanReporter = new InMemoryReporter(); + Tracer tracer = new Tracer.Builder("x", spanReporter, new ConstSampler(true)) + .withZipkinSharedRpcSpan() + .withTag("tag.str", "y") + .withTag("tag.bool", true) + .withTag("tag.num", 1) + .build(); + + Span span = (Span) tracer.buildSpan("root").start(); + if (spanType == SpanType.CHILD) { + span = (Span) tracer.buildSpan("child").asChildOf(span).start(); + } else if (spanType == SpanType.RPC_SERVER) { + span = + (Span) + tracer + .buildSpan("rpc-server") + .asChildOf(span) + .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) + .start(); + } + zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); + + Map zipkinTags = zipkinSpan.tags(); + for (Map.Entry entry : expectedTags.entrySet()) { + String key = entry.getKey(); + Object expectedValue = entry.getValue(); + String tagValue = zipkinTags.get(key); + if (expectedValue.equals(UNDEF)) { + assertNull("Not expecting " + key + " for " + spanType, tagValue); + } else if (expectedValue.equals(ANY)) { + assertNotNull(key, tagValue); + } else { + assertEquals("Expecting " + key + " for " + spanType, expectedValue, tagValue); + } + } + } + + @Test + public void testSpanKindServerCreatesAnnotations() { + Span span = (Span) tracer.buildSpan("operation-name").start(); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER); + + zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); + + List annotations = zipkinSpan.annotations(); + boolean serverReceiveFound = false; + boolean serverSendFound = false; + for (Annotation anno : annotations) { + if (anno.value().equals(zipkin.Constants.SERVER_RECV)) { + serverReceiveFound = true; + } + if (anno.value().equals(zipkin.Constants.SERVER_SEND)) { + serverSendFound = true; + } + } + assertTrue(serverReceiveFound); + assertTrue(serverSendFound); + } + + @Test + public void testSpanKindClientCreatesAnnotations() { + Span span = (Span) tracer.buildSpan("operation-name").start(); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); + + zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); + + List annotations = zipkinSpan.annotations(); + boolean clientReceiveFound = false; + boolean clientSendFound = false; + for (Annotation anno : annotations) { + if (anno.value().equals(zipkin.Constants.CLIENT_RECV)) { + clientReceiveFound = true; + } + + if (anno.value().equals(zipkin.Constants.CLIENT_SEND)) { + clientSendFound = true; + } + } + + assertTrue(clientReceiveFound); + assertTrue(clientSendFound); + } + + @Test + public void testSpanKindConsumerCreatesAnnotations() { + Span span = (Span) tracer.buildSpan("operation-name").start(); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CONSUMER); + + zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); + + assertEquals(zipkinSpan.kind(), zipkin2.Span.Kind.CONSUMER); + } + + @Test + public void testSpanKindProducerCreatesAnnotations() { + Span span = (Span) tracer.buildSpan("operation-name").start(); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_PRODUCER); + + zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); + + assertEquals(zipkinSpan.kind(), zipkin2.Span.Kind.PRODUCER); + } + + @Test + public void testExpectedLocalComponentNameUsed() { + String expectedComponentName = "local-name"; + Span span = (Span) tracer.buildSpan("operation-name").start(); + Tags.COMPONENT.set(span, expectedComponentName); + + zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); + + String actualComponent = zipkinSpan.tags().get(Tags.COMPONENT.getKey()); + assertEquals(expectedComponentName, actualComponent); + } + + @Test + public void testSpanDetectsEndpointTags() { + String expectedIp = "127.0.0.1"; + Integer expectedPort = 8080; + String expectedServiceName = "some-peer-service"; + Span span = (Span) tracer.buildSpan("test-service-operation").start(); + Tags.PEER_HOST_IPV4.set(span, expectedIp); + Tags.PEER_PORT.set(span, expectedPort); + Tags.PEER_SERVICE.set(span, expectedServiceName); + + assertEquals(expectedIp, V2SpanConverter.extractPeerEndpoint(span.getTags()).ipv4()); + assertEquals(expectedPort, V2SpanConverter.extractPeerEndpoint(span.getTags()).port()); + assertEquals(expectedServiceName, V2SpanConverter.extractPeerEndpoint(span.getTags()).serviceName()); + } + + @Test + public void testSpanDetectsIsClient() { + Span span = (Span) tracer.buildSpan("test-service-operation").start(); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); + + assertTrue(ConverterUtil.isRpc(span)); + assertTrue(ConverterUtil.isRpcClient(span)); + } + + @Test + public void testSpanDetectsIsServer() { + Span span = (Span) tracer.buildSpan("test-service-operation").start(); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER); + + assertTrue(ConverterUtil.isRpc(span)); + assertFalse(ConverterUtil.isRpcClient(span)); + } + + @Test + public void testRpcChildSpanHasTheSameId() { + String expectedOperation = "parent"; + Span client = (Span) tracer.buildSpan(expectedOperation) + .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) + .start(); + + Map map = new HashMap<>(); + TextMap carrier = new TextMapInjectAdapter(map); + tracer.inject(client.context(), Format.Builtin.TEXT_MAP, carrier); + + carrier = new TextMapExtractAdapter(map); + SpanContext ctx = (SpanContext) tracer.extract(Format.Builtin.TEXT_MAP, carrier); + assertEquals(client.context().getSpanId(), ctx.getSpanId()); + + Span server = (Span)tracer.buildSpan("child") + .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) + .asChildOf(ctx) + .start(); + + assertEquals("client and server must have the same span ID", + client.context().getSpanId(), server.context().getSpanId()); + } + + @Test + public void testSpanLogsCreateAnnotations() { + Span span = (Span) tracer.buildSpan("span-with-logs").start(); + + span.log("event"); + + // use sorted map for consistent ordering in test + Map fields = new TreeMap(); + fields.put("event", "structured data"); + fields.put("string", "something"); + fields.put("number", 42); + fields.put("boolean", true); + span.log(fields); + + zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); + + List annotationValues = new ArrayList(); + for (Annotation annotation : zipkinSpan.annotations()) { + annotationValues.add(annotation.value()); + } + + List expectedValues = new ArrayList(); + expectedValues.add("event"); + expectedValues.add("{\"boolean\":true,\"event\":\"structured data\",\"number\":42,\"string\":\"something\"}"); + + assertEquals("zipkin span should contain matching annotations for span logs", expectedValues, annotationValues); + } +} diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/Zipkin2ReporterTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/Zipkin2ReporterTest.java new file mode 100644 index 000000000..267ef5149 --- /dev/null +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/Zipkin2ReporterTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018, 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 io.jaegertracing.zipkin.reporters; + +import static org.junit.Assert.assertEquals; + +import io.jaegertracing.Span; +import io.jaegertracing.Tracer; +import io.jaegertracing.metrics.InMemoryMetricsFactory; +import io.jaegertracing.reporters.Reporter; +import io.jaegertracing.samplers.ConstSampler; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import zipkin.junit.ZipkinRule; +import zipkin2.codec.Encoding; +import zipkin2.reporter.Sender; +import zipkin2.reporter.urlconnection.URLConnectionSender; + + +public class Zipkin2ReporterTest { + @Rule public ZipkinRule zipkinRule = new ZipkinRule(); + + Sender sender; + Reporter reporter; + Tracer tracer; + + @Before + public void setUp() throws Exception { + sender = URLConnectionSender.newBuilder() + .encoding(Encoding.JSON) + .endpoint(zipkinRule.httpUrl() + "/api/v2/spans") + .build(); + + reporter = new Zipkin2Reporter( + zipkin2.reporter.AsyncReporter.builder(sender) + .messageTimeout(10, TimeUnit.SECONDS) + .closeTimeout(10, TimeUnit.SECONDS) + .build()); + + tracer = new Tracer.Builder("test-sender") + .withReporter(reporter) + .withSampler(new ConstSampler(true)) + .withMetricsFactory(new InMemoryMetricsFactory()) + .build(); + } + + @Test + public void testConvertsAndSendsSpan() throws Exception { + Span jaegerSpan = (Span)tracer.buildSpan("raza").start(); + jaegerSpan.finish(); + + reporter.report(jaegerSpan); + reporter.close(); + + List> spans = zipkinRule.getTraces(); + assertEquals(spans.get(0).get(0).name, "raza"); + } +} From 5730b137952efe8db18e4bcf213edf3a9c898d4a Mon Sep 17 00:00:00 2001 From: Ben Keith Date: Wed, 16 May 2018 09:56:46 -0400 Subject: [PATCH 2/3] Reverting ThriftSpanConverter to origin location Also removing Zipkin v1 special tag handling from V2SpanConverter because they are not necessary Signed-off-by: Ben Keith --- jaeger-zipkin/README.md | 6 +-- .../zipkin/ThriftSpanConverter.java | 3 +- .../senders/zipkin/ZipkinSender.java | 3 +- .../jaegertracing/zipkin/ConverterUtil.java | 11 ++-- .../jaegertracing/zipkin/V2SpanConverter.java | 26 ---------- ...in2Reporter.java => ZipkinV2Reporter.java} | 4 +- .../zipkin/ThriftSpanConverterTest.java | 3 +- .../senders/zipkin/ZipkinSenderTest.java | 1 - .../zipkin/V2SpanConverterTest.java | 50 +------------------ ...terTest.java => ZipkinV2ReporterTest.java} | 15 +++--- 10 files changed, 24 insertions(+), 98 deletions(-) rename jaeger-zipkin/src/main/java/io/jaegertracing/{ => senders}/zipkin/ThriftSpanConverter.java (98%) rename jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/{Zipkin2Reporter.java => ZipkinV2Reporter.java} (89%) rename jaeger-zipkin/src/test/java/io/jaegertracing/{ => senders}/zipkin/ThriftSpanConverterTest.java (99%) rename jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/{Zipkin2ReporterTest.java => ZipkinV2ReporterTest.java} (87%) diff --git a/jaeger-zipkin/README.md b/jaeger-zipkin/README.md index a8a165407..d622bfe0c 100644 --- a/jaeger-zipkin/README.md +++ b/jaeger-zipkin/README.md @@ -37,17 +37,17 @@ tracer = new Tracer.Builder(serviceName, reporter, sampler) ``` ### Zipkin 2 Reporters -You can reuse a Zipkin 2 reporter instance as-is by using `Zipkin2Reporter`, which adapts a Zipkin +You can reuse a Zipkin 2 reporter instance as-is by using `ZipkinV2Reporter`, which adapts a Zipkin 2 reporter to the Jaeger reporter interface and deals with converting Jaeger spans to the Zipkin 2 model. For example: ```java -import io.jaegertracing.zipkin.reporters.Zipkin2Reporter; +import io.jaegertracing.zipkin.reporters.ZipkinV2Reporter; import zipkin2.reporter.AsyncReporter; import zipkin2.reporter.urlconnection.URLConnectionSender; -reporter = new Zipkin2Reporter( +reporter = new ZipkinV2Reporter( AsyncReporter.create(URLConnectionSender.create("http://localhost:9411/api/v2/spans"))); tracer = new Tracer.Builder(serviceName) diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ThriftSpanConverter.java b/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ThriftSpanConverter.java similarity index 98% rename from jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ThriftSpanConverter.java rename to jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ThriftSpanConverter.java index 95c946581..664f1711d 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ThriftSpanConverter.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ThriftSpanConverter.java @@ -12,7 +12,7 @@ * the License. */ -package io.jaegertracing.zipkin; +package io.jaegertracing.senders.zipkin; import com.google.gson.Gson; import com.twitter.zipkin.thriftjava.Annotation; @@ -25,6 +25,7 @@ import io.jaegertracing.Span; import io.jaegertracing.SpanContext; import io.jaegertracing.Tracer; +import io.jaegertracing.zipkin.ConverterUtil; import io.opentracing.tag.Tags; import java.nio.charset.Charset; import java.util.ArrayList; diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java b/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java index 8963c2898..f443b15e7 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/senders/zipkin/ZipkinSender.java @@ -21,7 +21,6 @@ import com.twitter.zipkin.thriftjava.zipkincoreConstants; import io.jaegertracing.exceptions.SenderException; import io.jaegertracing.senders.Sender; -import io.jaegertracing.zipkin.ThriftSpanConverter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -35,7 +34,7 @@ /** * This sends (TBinaryProtocol big-endian) encoded spans to a Zipkin Collector (usually a * zipkin-server). If you want to send newer Zipkin V2 spans in protocols other than Thrift, - * see {@link io.jaegertracing.zipkin.reporters.Zipkin2Reporter Zipkin2Reporter}. + * see {@link io.jaegertracing.zipkin.reporters.ZipkinV2Reporter ZipkinV2Reporter}. * *

* Example usage: diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java index e80168a0e..426aeccb9 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/ConverterUtil.java @@ -20,19 +20,16 @@ /** * Logic that is common to both Thrift v1 and JSON v2 senders */ -class ConverterUtil { - static boolean isRpcServer(Span span) { +public class ConverterUtil { + public static boolean isRpcServer(Span span) { return Tags.SPAN_KIND_SERVER.equals(span.getTags().get(Tags.SPAN_KIND.getKey())); } - static boolean isRpc(Span span) { + public static boolean isRpc(Span span) { return isRpcServer(span) || isRpcClient(span); - } - static boolean isRpcClient(Span span) { + public static boolean isRpcClient(Span span) { return Tags.SPAN_KIND_CLIENT.equals(span.getTags().get(Tags.SPAN_KIND.getKey())); } - - } diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java index b6c7e4faf..345846d6b 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java @@ -77,18 +77,6 @@ private static zipkin2.Span.Kind convertKind(Object kind) { } private static void buildAnnotations(Span span, zipkin2.Span.Builder builder) { - if (ConverterUtil.isRpc(span)) { - String startLabel = zipkin.Constants.SERVER_RECV; - String endLabel = zipkin.Constants.SERVER_SEND; - if (ConverterUtil.isRpcClient(span)) { - startLabel = zipkin.Constants.CLIENT_SEND; - endLabel = zipkin.Constants.CLIENT_RECV; - } - - builder.addAnnotation(span.getStart(), startLabel); - builder.addAnnotation(span.getStart() + span.getDuration(), endLabel); - } - List logs = span.getLogs(); if (logs != null) { for (LogData logData : logs) { @@ -105,7 +93,6 @@ private static void buildAnnotations(Span span, zipkin2.Span.Builder builder) { private static void buildTags(Span span, zipkin2.Span.Builder builder) { Map tags = span.getTags(); - boolean isRpc = ConverterUtil.isRpc(span); boolean firstSpanInProcess = span.getReferences().isEmpty() || ConverterUtil.isRpcServer(span); if (firstSpanInProcess) { @@ -122,19 +109,6 @@ private static void buildTags(Span span, zipkin2.Span.Builder builder) { } } - if (!isRpc) { - String componentName; - Object componentTag = tags.get(Tags.COMPONENT.getKey()); - if (componentTag instanceof String) { - componentName = componentTag.toString(); - } else { - // spans always have associated tracers, and service names - componentName = span.getTracer().getServiceName(); - } - - builder.putTag(zipkin.Constants.LOCAL_COMPONENT, componentName); - } - if (tags != null) { for (Map.Entry entry : tags.entrySet()) { String tagKey = entry.getKey(); diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/Zipkin2Reporter.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/ZipkinV2Reporter.java similarity index 89% rename from jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/Zipkin2Reporter.java rename to jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/ZipkinV2Reporter.java index ea2185c5f..4657adf99 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/Zipkin2Reporter.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/reporters/ZipkinV2Reporter.java @@ -20,10 +20,10 @@ /** * Wrapper around a zipkin v2 AsyncReporter that reports spans using the newer v2 Span class */ -public class Zipkin2Reporter implements Reporter { +public class ZipkinV2Reporter implements Reporter { public final zipkin2.reporter.AsyncReporter reporter; - public Zipkin2Reporter(zipkin2.reporter.AsyncReporter reporter) { + public ZipkinV2Reporter(zipkin2.reporter.AsyncReporter reporter) { this.reporter = reporter; } diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/ThriftSpanConverterTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ThriftSpanConverterTest.java similarity index 99% rename from jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/ThriftSpanConverterTest.java rename to jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ThriftSpanConverterTest.java index ac996d60d..7a5ce4dcd 100644 --- a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/ThriftSpanConverterTest.java +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ThriftSpanConverterTest.java @@ -12,7 +12,7 @@ * the License. */ -package io.jaegertracing.zipkin; +package io.jaegertracing.senders.zipkin; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.assertEquals; @@ -30,6 +30,7 @@ import io.jaegertracing.Tracer; import io.jaegertracing.reporters.InMemoryReporter; import io.jaegertracing.samplers.ConstSampler; +import io.jaegertracing.zipkin.ConverterUtil; import io.opentracing.propagation.Format; import io.opentracing.propagation.TextMap; import io.opentracing.propagation.TextMapExtractAdapter; diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java index 518212961..c4b11573b 100644 --- a/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/senders/zipkin/ZipkinSenderTest.java @@ -25,7 +25,6 @@ import io.jaegertracing.reporters.InMemoryReporter; import io.jaegertracing.reporters.Reporter; import io.jaegertracing.samplers.ConstSampler; -import io.jaegertracing.zipkin.ThriftSpanConverter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java index 7f78d4a4f..e276a5c6b 100644 --- a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/V2SpanConverterTest.java @@ -148,53 +148,7 @@ public void testTracerTags(SpanType spanType, Map expectedTags) } @Test - public void testSpanKindServerCreatesAnnotations() { - Span span = (Span) tracer.buildSpan("operation-name").start(); - Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER); - - zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); - - List annotations = zipkinSpan.annotations(); - boolean serverReceiveFound = false; - boolean serverSendFound = false; - for (Annotation anno : annotations) { - if (anno.value().equals(zipkin.Constants.SERVER_RECV)) { - serverReceiveFound = true; - } - if (anno.value().equals(zipkin.Constants.SERVER_SEND)) { - serverSendFound = true; - } - } - assertTrue(serverReceiveFound); - assertTrue(serverSendFound); - } - - @Test - public void testSpanKindClientCreatesAnnotations() { - Span span = (Span) tracer.buildSpan("operation-name").start(); - Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); - - zipkin2.Span zipkinSpan = V2SpanConverter.convertSpan(span); - - List annotations = zipkinSpan.annotations(); - boolean clientReceiveFound = false; - boolean clientSendFound = false; - for (Annotation anno : annotations) { - if (anno.value().equals(zipkin.Constants.CLIENT_RECV)) { - clientReceiveFound = true; - } - - if (anno.value().equals(zipkin.Constants.CLIENT_SEND)) { - clientSendFound = true; - } - } - - assertTrue(clientReceiveFound); - assertTrue(clientSendFound); - } - - @Test - public void testSpanKindConsumerCreatesAnnotations() { + public void testSpanKindConsumerHasCorrectKind() { Span span = (Span) tracer.buildSpan("operation-name").start(); Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CONSUMER); @@ -204,7 +158,7 @@ public void testSpanKindConsumerCreatesAnnotations() { } @Test - public void testSpanKindProducerCreatesAnnotations() { + public void testSpanKindProducerHasCorrectKind() { Span span = (Span) tracer.buildSpan("operation-name").start(); Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_PRODUCER); diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/Zipkin2ReporterTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/ZipkinV2ReporterTest.java similarity index 87% rename from jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/Zipkin2ReporterTest.java rename to jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/ZipkinV2ReporterTest.java index 267ef5149..16a5502c4 100644 --- a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/Zipkin2ReporterTest.java +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/ZipkinV2ReporterTest.java @@ -32,10 +32,11 @@ import zipkin2.reporter.urlconnection.URLConnectionSender; -public class Zipkin2ReporterTest { +public class ZipkinV2ReporterTest { @Rule public ZipkinRule zipkinRule = new ZipkinRule(); Sender sender; + zipkin2.reporter.AsyncReporter zipkinReporter; Reporter reporter; Tracer tracer; @@ -46,11 +47,11 @@ public void setUp() throws Exception { .endpoint(zipkinRule.httpUrl() + "/api/v2/spans") .build(); - reporter = new Zipkin2Reporter( - zipkin2.reporter.AsyncReporter.builder(sender) - .messageTimeout(10, TimeUnit.SECONDS) - .closeTimeout(10, TimeUnit.SECONDS) - .build()); + zipkinReporter = zipkin2.reporter.AsyncReporter.builder(sender) + .messageTimeout(0, TimeUnit.MILLISECONDS) + .build(); + + reporter = new ZipkinV2Reporter(zipkinReporter); tracer = new Tracer.Builder("test-sender") .withReporter(reporter) @@ -65,7 +66,7 @@ public void testConvertsAndSendsSpan() throws Exception { jaegerSpan.finish(); reporter.report(jaegerSpan); - reporter.close(); + zipkinReporter.flush(); List> spans = zipkinRule.getTraces(); assertEquals(spans.get(0).get(0).name, "raza"); From ec6a465edb36833cfdc51a1734376821a27b8a9c Mon Sep 17 00:00:00 2001 From: Ben Keith Date: Thu, 17 May 2018 09:39:21 -0400 Subject: [PATCH 3/3] Misc changes from code review Signed-off-by: Ben Keith --- jaeger-zipkin/build.gradle | 10 ++-------- .../java/io/jaegertracing/zipkin/V2SpanConverter.java | 3 +++ .../zipkin/reporters/ZipkinV2ReporterTest.java | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/jaeger-zipkin/build.gradle b/jaeger-zipkin/build.gradle index 7de4a113c..4d478f1d7 100644 --- a/jaeger-zipkin/build.gradle +++ b/jaeger-zipkin/build.gradle @@ -1,14 +1,8 @@ description = 'Integration library for Zipkin' dependencies { - compile(group: 'io.zipkin.reporter', name: 'zipkin-reporter', version: '1.1.2') { - exclude group:'io.zipkin.zipkin2' - exclude group:'io.zipkin.java' - } - compile(group: 'io.zipkin.reporter', name: 'zipkin-sender-urlconnection', version: '1.1.2') { - exclude group:'io.zipkin.zipkin2' - exclude group:'io.zipkin.java' - } + compile group: 'io.zipkin.reporter', name: 'zipkin-reporter', version: '1.1.2' + compile group: 'io.zipkin.reporter', name: 'zipkin-sender-urlconnection', version: '1.1.2' compile group: 'io.zipkin.java', name: 'zipkin', version: '2.8.1' compile group: 'io.zipkin.reporter2', name: 'zipkin-reporter', version: '2.6.0' diff --git a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java index 345846d6b..1a7c0b12d 100644 --- a/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java +++ b/jaeger-zipkin/src/main/java/io/jaegertracing/zipkin/V2SpanConverter.java @@ -26,10 +26,12 @@ import java.nio.ByteBuffer; import java.util.List; import java.util.Map; +import lombok.extern.slf4j.Slf4j; /** * Converts a Jaeger span to a Zipkin2 span. */ +@Slf4j public class V2SpanConverter { private static final Gson gson = new Gson(); @@ -125,6 +127,7 @@ private static InetAddress convertIp(int ip) { try { return InetAddress.getByAddress(bytes); } catch (UnknownHostException e) { + log.error("Jaeger span IP " + ip + " could not be converted", e); return null; } } diff --git a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/ZipkinV2ReporterTest.java b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/ZipkinV2ReporterTest.java index 16a5502c4..8a4a85f24 100644 --- a/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/ZipkinV2ReporterTest.java +++ b/jaeger-zipkin/src/test/java/io/jaegertracing/zipkin/reporters/ZipkinV2ReporterTest.java @@ -41,7 +41,7 @@ public class ZipkinV2ReporterTest { Tracer tracer; @Before - public void setUp() throws Exception { + public void setup() throws Exception { sender = URLConnectionSender.newBuilder() .encoding(Encoding.JSON) .endpoint(zipkinRule.httpUrl() + "/api/v2/spans")