Adding the spring.instance_id tag
without this tag it's impossible to discern from which server was the given span originated
with this change we're adding a tag in which we're passing the instance id value. The value can be taken either from Cloud Foundry or from a concatanation of some local properties like instance_id / application name / application port etc.
fixes #369
This commit is contained in:
@@ -36,6 +36,10 @@
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-feign</artifactId>
|
||||
|
||||
@@ -134,6 +134,11 @@ public class Span {
|
||||
*/
|
||||
public static final String SPAN_PEER_SERVICE_TAG_NAME = "peer.service";
|
||||
|
||||
/**
|
||||
* ID of the instance from which the span was originated.
|
||||
*/
|
||||
public static final String INSTANCEID = "spring.instance_id";
|
||||
|
||||
private final long begin;
|
||||
private long end = 0;
|
||||
private final String name;
|
||||
|
||||
@@ -183,6 +183,7 @@ public class DefaultTracerTests {
|
||||
then(span).hasATag("key", "value").hasLoggedAnEvent("event");
|
||||
then(continuedSpan).hasATag("key", "value").hasLoggedAnEvent("event");
|
||||
then(span).isEqualTo(continuedSpan);
|
||||
tracer.close(span);
|
||||
}
|
||||
|
||||
private Span assertSpan(List<Span> spans, Long parentId, String name) {
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.integration.config.GlobalChannelInterceptor;
|
||||
import org.springframework.integration.scheduling.PollerMetadata;
|
||||
import org.springframework.messaging.support.ChannelInterceptor;
|
||||
@@ -76,8 +77,8 @@ public class SleuthStreamAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public StreamSpanReporter sleuthStreamSpanReporter(HostLocator endpointLocator,
|
||||
SpanMetricReporter spanMetricReporter) {
|
||||
return new StreamSpanReporter(endpointLocator, spanMetricReporter);
|
||||
SpanMetricReporter spanMetricReporter, Environment environment) {
|
||||
return new StreamSpanReporter(endpointLocator, spanMetricReporter, environment);
|
||||
}
|
||||
|
||||
@Bean(name = StreamSpanReporter.POLLER)
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
package org.springframework.cloud.sleuth.stream;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.commons.util.IdUtils;
|
||||
import org.springframework.cloud.sleuth.Log;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanReporter;
|
||||
import org.springframework.cloud.sleuth.metric.SpanMetricReporter;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.integration.annotation.InboundChannelAdapter;
|
||||
import org.springframework.integration.annotation.MessageEndpoint;
|
||||
import org.springframework.integration.annotation.Poller;
|
||||
@@ -41,7 +44,11 @@ import org.springframework.integration.annotation.Poller;
|
||||
@MessageEndpoint
|
||||
public class StreamSpanReporter implements SpanReporter {
|
||||
|
||||
private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass());
|
||||
private static final org.apache.commons.logging.Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass());
|
||||
|
||||
private static final List<String> RPC_EVENTS = Arrays.asList(
|
||||
Span.CLIENT_RECV, Span.CLIENT_SEND, Span.SERVER_RECV, Span.SERVER_SEND
|
||||
);
|
||||
|
||||
/**
|
||||
* Bean name for the
|
||||
@@ -53,10 +60,19 @@ public class StreamSpanReporter implements SpanReporter {
|
||||
private BlockingQueue<Span> queue = new LinkedBlockingQueue<>(1000);
|
||||
private final HostLocator endpointLocator;
|
||||
private final SpanMetricReporter spanMetricReporter;
|
||||
private final Environment environment;
|
||||
|
||||
public StreamSpanReporter(HostLocator endpointLocator, SpanMetricReporter spanMetricReporter) {
|
||||
@Deprecated
|
||||
public StreamSpanReporter(HostLocator endpointLocator,
|
||||
SpanMetricReporter spanMetricReporter) {
|
||||
this(endpointLocator, spanMetricReporter, null);
|
||||
}
|
||||
|
||||
public StreamSpanReporter(HostLocator endpointLocator,
|
||||
SpanMetricReporter spanMetricReporter, Environment environment) {
|
||||
this.endpointLocator = endpointLocator;
|
||||
this.spanMetricReporter = spanMetricReporter;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public void setQueue(BlockingQueue<Span> queue) {
|
||||
@@ -84,6 +100,9 @@ public class StreamSpanReporter implements SpanReporter {
|
||||
public void report(Span span) {
|
||||
if (span.isExportable()) {
|
||||
try {
|
||||
if (this.environment != null) {
|
||||
processLogs(span);
|
||||
}
|
||||
this.queue.add(span);
|
||||
} catch (Exception e) {
|
||||
this.spanMetricReporter.incrementDroppedSpans(1);
|
||||
@@ -97,4 +116,13 @@ public class StreamSpanReporter implements SpanReporter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processLogs(Span span) {
|
||||
for (Log spanLog : span.logs()) {
|
||||
if (RPC_EVENTS.contains(spanLog.getEvent())) {
|
||||
span.tag(Span.INSTANCEID, IdUtils.getDefaultInstanceId(this.environment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,27 +16,34 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.stream;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.metric.SpanMetricReporter;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class StreamSpanReporterTests {
|
||||
|
||||
@Mock HostLocator endpointLocator;
|
||||
@Mock SpanMetricReporter spanMetricReporter;
|
||||
@InjectMocks StreamSpanReporter reporter;
|
||||
HostLocator endpointLocator = Mockito.mock(HostLocator.class);
|
||||
SpanMetricReporter spanMetricReporter = Mockito.mock(SpanMetricReporter.class);
|
||||
MockEnvironment mockEnvironment = new MockEnvironment();
|
||||
StreamSpanReporter reporter;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.reporter = new StreamSpanReporter(this.endpointLocator, this.spanMetricReporter, this.mockEnvironment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_not_throw_an_exception_when_queue_size_is_exceeded() throws Exception {
|
||||
@@ -46,7 +53,43 @@ public class StreamSpanReporterTests {
|
||||
|
||||
this.reporter.report(Span.builder().name("bar").exportable(true).build());
|
||||
|
||||
then(spanMetricReporter).should().incrementDroppedSpans(1);
|
||||
then(this.spanMetricReporter).should().incrementDroppedSpans(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void should_append_client_serviceid_when_span_has_rpc_event() throws Exception {
|
||||
LinkedBlockingQueue<Span> queue = new LinkedBlockingQueue<>(1000);
|
||||
this.reporter.setQueue(queue);
|
||||
this.mockEnvironment.setProperty("vcap.application.instance_id", "foo");
|
||||
Span span = Span.builder().name("bar").exportable(true).build();
|
||||
span.logEvent(Span.CLIENT_RECV);
|
||||
|
||||
this.reporter.report(span);
|
||||
|
||||
assertThat(queue).isNotEmpty();
|
||||
assertThat(queue.poll())
|
||||
.extracting(Span::tags)
|
||||
.extracting(o -> ((Map<String, String>) o).get(Span.INSTANCEID))
|
||||
.containsExactly("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void should_not_append_server_serviceid_when_span_has_rpc_event_and_there_is_no_environment() throws Exception {
|
||||
this.reporter = new StreamSpanReporter(this.endpointLocator, this.spanMetricReporter, null);
|
||||
LinkedBlockingQueue<Span> queue = new LinkedBlockingQueue<>(1000);
|
||||
this.reporter.setQueue(queue);
|
||||
Span span = Span.builder().name("bar").exportable(true).build();
|
||||
span.logEvent(Span.CLIENT_SEND);
|
||||
|
||||
this.reporter.report(span);
|
||||
|
||||
assertThat(queue).isNotEmpty();
|
||||
assertThat(queue.poll())
|
||||
.extracting(Span::tags)
|
||||
.filteredOn(o -> ((Map<String, String>) o).containsKey(Span.INSTANCEID))
|
||||
.isNullOrEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,7 +34,7 @@ import org.springframework.cloud.sleuth.sampler.PercentageBasedSampler;
|
||||
import org.springframework.cloud.sleuth.sampler.SamplerProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration Auto-configuration}
|
||||
@@ -64,8 +64,9 @@ public class ZipkinAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SpanReporter zipkinSpanListener(ZipkinSpanReporter reporter, EndpointLocator endpointLocator) {
|
||||
return new ZipkinSpanListener(reporter, endpointLocator);
|
||||
public SpanReporter zipkinSpanListener(ZipkinSpanReporter reporter, EndpointLocator endpointLocator,
|
||||
Environment environment) {
|
||||
return new ZipkinSpanListener(reporter, endpointLocator, environment);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -21,9 +21,11 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.commons.util.IdUtils;
|
||||
import org.springframework.cloud.sleuth.Log;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanReporter;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import zipkin.Annotation;
|
||||
@@ -41,13 +43,17 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
private static final List<String> ZIPKIN_START_EVENTS = Arrays.asList(
|
||||
Constants.CLIENT_RECV, Constants.SERVER_RECV
|
||||
);
|
||||
private static final List<String> RPC_EVENTS = Arrays.asList(
|
||||
Constants.CLIENT_RECV, Constants.CLIENT_SEND, Constants.SERVER_RECV, Constants.SERVER_SEND
|
||||
);
|
||||
|
||||
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
|
||||
.getLog(ZipkinSpanListener.class);
|
||||
private static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
private static final byte[] UNKNOWN_BYTES = "unknown".getBytes(UTF_8);
|
||||
|
||||
private ZipkinSpanReporter reporter;
|
||||
private final ZipkinSpanReporter reporter;
|
||||
private final Environment environment;
|
||||
/**
|
||||
* Endpoint is the visible IP address of this service, the port it is listening on and
|
||||
* the service name from discovery.
|
||||
@@ -55,9 +61,16 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
// Visible for testing
|
||||
EndpointLocator endpointLocator;
|
||||
|
||||
@Deprecated
|
||||
public ZipkinSpanListener(ZipkinSpanReporter reporter, EndpointLocator endpointLocator) {
|
||||
this(reporter, endpointLocator, null);
|
||||
}
|
||||
|
||||
public ZipkinSpanListener(ZipkinSpanReporter reporter, EndpointLocator endpointLocator,
|
||||
Environment environment) {
|
||||
this.reporter = reporter;
|
||||
this.endpointLocator = endpointLocator;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,15 +89,10 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
zipkin.Span convert(Span span) {
|
||||
zipkin.Span.Builder zipkinSpan = zipkin.Span.builder();
|
||||
|
||||
// A zipkin span without any annotations cannot be queried, add special "lc" to avoid that.
|
||||
if (notClientOrServer(span)) {
|
||||
ensureLocalComponent(span, zipkinSpan);
|
||||
}
|
||||
addZipkinAnnotations(zipkinSpan, span, this.endpointLocator.local());
|
||||
addZipkinBinaryAnnotations(zipkinSpan, span, this.endpointLocator.local());
|
||||
if (hasClientSend(span)) {
|
||||
ensureServerAddr(span, zipkinSpan);
|
||||
}
|
||||
Endpoint endpoint = this.endpointLocator.local();
|
||||
processLogs(span, zipkinSpan, endpoint);
|
||||
addZipkinAnnotations(zipkinSpan, span, endpoint);
|
||||
addZipkinBinaryAnnotations(zipkinSpan, span, endpoint);
|
||||
// In the RPC span model, the client owns the timestamp and duration of the span. If we
|
||||
// were propagated an id, we can assume that we shouldn't report timestamp or duration,
|
||||
// rather let the client do that. Worst case we were propagated an unreported ID and
|
||||
@@ -134,22 +142,40 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean notClientOrServer(Span span) {
|
||||
// Instead of going through the list of logs multiple times we're doing it only once
|
||||
private void processLogs(Span span, zipkin.Span.Builder zipkinSpan, Endpoint endpoint) {
|
||||
boolean notClientOrServer = true;
|
||||
boolean hasClientSend = false;
|
||||
boolean instanceIdToTag = false;
|
||||
for (Log log : span.logs()) {
|
||||
if (RPC_EVENTS.contains(log.getEvent())) {
|
||||
instanceIdToTag = true;
|
||||
}
|
||||
if (ZIPKIN_START_EVENTS.contains(log.getEvent())) {
|
||||
return false;
|
||||
notClientOrServer = false;
|
||||
}
|
||||
if (Constants.CLIENT_SEND.equals(log.getEvent())) {
|
||||
hasClientSend = !span.tags().containsKey(Constants.SERVER_ADDR);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (notClientOrServer) {
|
||||
// A zipkin span without any annotations cannot be queried, add special "lc" to avoid that.
|
||||
ensureLocalComponent(span, zipkinSpan);
|
||||
}
|
||||
if (hasClientSend) {
|
||||
ensureServerAddr(span, zipkinSpan);
|
||||
}
|
||||
if (instanceIdToTag && this.environment != null) {
|
||||
setInstanceIdIfPresent(zipkinSpan, endpoint, Span.INSTANCEID);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasClientSend(Span span) {
|
||||
for (Log log : span.logs()) {
|
||||
if (Constants.CLIENT_SEND.equals(log.getEvent())) {
|
||||
return !span.tags().containsKey(Constants.SERVER_ADDR);
|
||||
}
|
||||
private void setInstanceIdIfPresent(zipkin.Span.Builder zipkinSpan,
|
||||
Endpoint endpoint, String key) {
|
||||
String property = IdUtils.getDefaultInstanceId(this.environment);
|
||||
if (StringUtils.hasText(property)) {
|
||||
addZipkinBinaryAnnotation(key, property, endpoint, zipkinSpan);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,15 +198,20 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
private void addZipkinBinaryAnnotations(zipkin.Span.Builder zipkinSpan,
|
||||
Span span, Endpoint ep) {
|
||||
for (Map.Entry<String, String> e : span.tags().entrySet()) {
|
||||
BinaryAnnotation binaryAnn = BinaryAnnotation.builder()
|
||||
.type(BinaryAnnotation.Type.STRING)
|
||||
.key(e.getKey())
|
||||
.value(e.getValue().getBytes(UTF_8))
|
||||
.endpoint(ep).build();
|
||||
zipkinSpan.addBinaryAnnotation(binaryAnn);
|
||||
addZipkinBinaryAnnotation(e.getKey(), e.getValue(), ep, zipkinSpan);
|
||||
}
|
||||
}
|
||||
|
||||
private void addZipkinBinaryAnnotation(String key, String value, Endpoint ep,
|
||||
zipkin.Span.Builder zipkinSpan) {
|
||||
BinaryAnnotation binaryAnn = BinaryAnnotation.builder()
|
||||
.type(BinaryAnnotation.Type.STRING)
|
||||
.key(key)
|
||||
.value(value.getBytes(UTF_8))
|
||||
.endpoint(ep).build();
|
||||
zipkinSpan.addBinaryAnnotation(binaryAnn);
|
||||
}
|
||||
|
||||
/**
|
||||
* There could be instrumentation delay between span creation and the
|
||||
* semantic start of the span (client send). When there's a difference,
|
||||
|
||||
@@ -34,6 +34,8 @@ import org.springframework.cloud.sleuth.zipkin.ZipkinSpanListenerTests.TestConfi
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import zipkin.Constants;
|
||||
@@ -52,7 +54,10 @@ public class ZipkinSpanListenerTests {
|
||||
@Autowired Tracer tracer;
|
||||
@Autowired ApplicationContext application;
|
||||
@Autowired TestConfiguration test;
|
||||
@Autowired ZipkinSpanListener spanReporter;
|
||||
@Autowired ZipkinSpanListener spanListener;
|
||||
@Autowired ZipkinSpanReporter spanReporter;
|
||||
@Autowired MockEnvironment mockEnvironment;
|
||||
@Autowired EndpointLocator endpointLocator;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
@@ -69,7 +74,7 @@ public class ZipkinSpanListenerTests {
|
||||
span.logEvent("hystrix/retry"); // System.currentTimeMillis
|
||||
span.stop();
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(span);
|
||||
zipkin.Span result = this.spanListener.convert(span);
|
||||
|
||||
assertThat(result.timestamp)
|
||||
.isEqualTo(span.getBegin() * 1000);
|
||||
@@ -90,7 +95,7 @@ public class ZipkinSpanListenerTests {
|
||||
Thread.sleep(20);
|
||||
span.stop();
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(span);
|
||||
zipkin.Span result = this.spanListener.convert(span);
|
||||
|
||||
assertThat(result.timestamp)
|
||||
.isEqualTo(span.getBegin() * 1000);
|
||||
@@ -107,7 +112,7 @@ public class ZipkinSpanListenerTests {
|
||||
@Test
|
||||
public void doesntSetDurationWhenStillRunning() {
|
||||
Span span = Span.builder().traceId(1L).name("http:api").build();
|
||||
zipkin.Span result = this.spanReporter.convert(span);
|
||||
zipkin.Span result = this.spanListener.convert(span);
|
||||
|
||||
assertThat(result.timestamp)
|
||||
.isGreaterThan(0); // sanity check it did start
|
||||
@@ -124,7 +129,7 @@ public class ZipkinSpanListenerTests {
|
||||
@Test
|
||||
public void doesntSetTimestampOrDurationWhenRemote() {
|
||||
this.parent.stop();
|
||||
zipkin.Span result = this.spanReporter.convert(this.parent);
|
||||
zipkin.Span result = this.spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.timestamp)
|
||||
.isNull();
|
||||
@@ -138,10 +143,10 @@ public class ZipkinSpanListenerTests {
|
||||
this.parent.logEvent("hystrix/retry");
|
||||
this.parent.tag("spring-boot/version", "1.3.1.RELEASE");
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(this.parent);
|
||||
zipkin.Span result = this.spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.annotations.get(0).endpoint)
|
||||
.isEqualTo(this.spanReporter.endpointLocator.local());
|
||||
.isEqualTo(this.spanListener.endpointLocator.local());
|
||||
assertThat(result.binaryAnnotations.get(0).endpoint)
|
||||
.isEqualTo(result.annotations.get(0).endpoint);
|
||||
}
|
||||
@@ -149,7 +154,7 @@ public class ZipkinSpanListenerTests {
|
||||
/** zipkin's Endpoint.serviceName should never be null. */
|
||||
@Test
|
||||
public void localEndpointIncludesServiceName() {
|
||||
assertThat(this.spanReporter.endpointLocator.local().serviceName)
|
||||
assertThat(this.spanListener.endpointLocator.local().serviceName)
|
||||
.isNotEmpty();
|
||||
}
|
||||
|
||||
@@ -172,7 +177,7 @@ public class ZipkinSpanListenerTests {
|
||||
Span context = this.tracer.createSpan("http:child", this.parent);
|
||||
context.logEvent(Span.CLIENT_SEND);
|
||||
logServerReceived(this.parent);
|
||||
logServerSent(this.spanReporter, this.parent);
|
||||
logServerSent(this.spanListener, this.parent);
|
||||
this.tracer.close(context);
|
||||
assertEquals(2, this.test.zipkinSpans.size());
|
||||
}
|
||||
@@ -195,7 +200,7 @@ public class ZipkinSpanListenerTests {
|
||||
this.parent.logEvent("hystrix/retry");
|
||||
this.parent.stop();
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(this.parent);
|
||||
zipkin.Span result = this.spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.binaryAnnotations)
|
||||
.extracting(input -> input.key)
|
||||
@@ -208,7 +213,7 @@ public class ZipkinSpanListenerTests {
|
||||
this.parent.tag(Span.SPAN_PEER_SERVICE_TAG_NAME, "fooservice");
|
||||
this.parent.stop();
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(this.parent);
|
||||
zipkin.Span result = this.spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.binaryAnnotations)
|
||||
.filteredOn("key", Constants.SERVER_ADDR)
|
||||
@@ -220,7 +225,7 @@ public class ZipkinSpanListenerTests {
|
||||
this.parent.logEvent(Constants.CLIENT_SEND);
|
||||
this.parent.stop();
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(this.parent);
|
||||
zipkin.Span result = this.spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.binaryAnnotations)
|
||||
.filteredOn("key", Constants.SERVER_ADDR)
|
||||
@@ -231,7 +236,7 @@ public class ZipkinSpanListenerTests {
|
||||
public void converts128BitTraceId() {
|
||||
Span span = Span.builder().traceIdHigh(1L).traceId(2L).spanId(3L).name("foo").build();
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(span);
|
||||
zipkin.Span result = this.spanListener.convert(span);
|
||||
|
||||
assertThat(result.traceIdHigh).isEqualTo(span.getTraceIdHigh());
|
||||
assertThat(result.traceId).isEqualTo(span.getTraceId());
|
||||
@@ -243,7 +248,7 @@ public class ZipkinSpanListenerTests {
|
||||
this.parent.tag(Span.SPAN_PEER_SERVICE_TAG_NAME, "fooservice");
|
||||
this.parent.stop();
|
||||
|
||||
zipkin.Span result = this.spanReporter.convert(this.parent);
|
||||
zipkin.Span result = this.spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.binaryAnnotations)
|
||||
.filteredOn("key", Constants.SERVER_ADDR)
|
||||
@@ -255,11 +260,38 @@ public class ZipkinSpanListenerTests {
|
||||
public void shouldNotReportToZipkinWhenSpanIsNotExportable() {
|
||||
Span span = Span.builder().exportable(false).build();
|
||||
|
||||
this.spanReporter.report(span);
|
||||
this.spanListener.report(span);
|
||||
|
||||
assertThat(this.test.zipkinSpans).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddClientServiceIdTagWhenSpanContainsRpcEvent() {
|
||||
this.parent.logEvent(Span.CLIENT_SEND);
|
||||
this.mockEnvironment.setProperty("vcap.application.instance_id", "foo");
|
||||
|
||||
zipkin.Span result = this.spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.binaryAnnotations)
|
||||
.filteredOn("key", Span.INSTANCEID)
|
||||
.extracting(input -> input.value)
|
||||
.containsOnly("foo".getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotAddAnyServiceIdTagWhenSpanContainsRpcEventAndThereIsNoEnvironment() {
|
||||
this.parent.logEvent(Span.CLIENT_RECV);
|
||||
ZipkinSpanListener spanListener = new ZipkinSpanListener(this.spanReporter,
|
||||
this.endpointLocator, null);
|
||||
|
||||
zipkin.Span result = spanListener.convert(this.parent);
|
||||
|
||||
assertThat(result.binaryAnnotations)
|
||||
.filteredOn("key", Span.INSTANCEID)
|
||||
.extracting(input -> input.value)
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestConfiguration {
|
||||
@@ -276,6 +308,10 @@ public class ZipkinSpanListenerTests {
|
||||
return this.zipkinSpans::add;
|
||||
}
|
||||
|
||||
@Bean @Primary MockEnvironment mockEnvironment() {
|
||||
return new MockEnvironment();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user