[#146] Introduced SpanName
- Added aspect to provide better naming for @Async fixes #146
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
// Do not edit this file (e.g. go instead to src/main/asciidoc)
|
||||
|
||||
image::https://api.travis-ci.org/spring-cloud/spring-cloud-sleuth.svg?branch=master[Build Status, link=https://travis-ci.org/spring-cloud/spring-cloud-sleuth]
|
||||
image::https://badges.gitter.im/spring-cloud/spring-cloud-sleuth.svg[Gitter, link="https://gitter.im/spring-cloud/spring-cloud-sleuth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
|
||||
image::https://api.travis-ci.org/spring-cloud/spring-cloud-sleuth.svg?branch=master[Build Status, link=https://travis-ci.org/spring-cloud/spring-cloud-sleuth] image::https://badges.gitter.im/spring-cloud/spring-cloud-sleuth.svg[Gitter, link="https://gitter.im/spring-cloud/spring-cloud-sleuth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
|
||||
== Spring Cloud Sleuth
|
||||
|
||||
Spring Cloud Sleuth implements a distributed tracing solution for http://cloud.spring.io[Spring Cloud].
|
||||
|
||||
@@ -61,7 +61,7 @@ public class Span {
|
||||
|
||||
private final long begin;
|
||||
private long end = 0;
|
||||
private final String name;
|
||||
private final SpanName name;
|
||||
private final long traceId;
|
||||
@Singular
|
||||
private List<Long> parents = new ArrayList<>();
|
||||
@@ -93,18 +93,18 @@ public class Span {
|
||||
this.savedSpan = savedSpan;
|
||||
}
|
||||
|
||||
public Span(long begin, long end, String name, long traceId, List<Long> parents,
|
||||
public Span(long begin, long end, SpanName name, long traceId, List<Long> parents,
|
||||
long spanId, boolean remote, boolean exportable, String processId) {
|
||||
this(begin, end, name, traceId, parents, spanId, remote, exportable, processId,
|
||||
null);
|
||||
}
|
||||
|
||||
public Span(long begin, long end, String name, long traceId, List<Long> parents,
|
||||
public Span(long begin, long end, SpanName name, long traceId, List<Long> parents,
|
||||
long spanId, boolean remote, boolean exportable, String processId,
|
||||
Span savedSpan) {
|
||||
this.begin = begin <= 0 ? System.currentTimeMillis() : begin;
|
||||
this.end = end;
|
||||
this.name = name;
|
||||
this.name = name != null ? name : SpanName.NO_NAME;
|
||||
this.traceId = traceId;
|
||||
this.parents = parents;
|
||||
this.spanId = spanId;
|
||||
@@ -117,7 +117,7 @@ public class Span {
|
||||
// for serialization
|
||||
private Span() {
|
||||
this.begin = 0;
|
||||
this.name = null;
|
||||
this.name = SpanName.NO_NAME;
|
||||
this.traceId = 0;
|
||||
this.spanId = 0;
|
||||
this.processId = null;
|
||||
@@ -210,7 +210,7 @@ public class Span {
|
||||
* A human-readable name assigned to this span instance.
|
||||
* <p>
|
||||
*/
|
||||
public String getName() {
|
||||
public SpanName getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or 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 org.springframework.cloud.sleuth;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Class representing a name of the span.
|
||||
* It consists of
|
||||
* <li>
|
||||
* <ul>component - means of communication e.g. http, message</ul>
|
||||
* <ul>address - what the span is addressing e.g. /some/http/address, someQueueName</ul>
|
||||
* <ul>fragment - additional label e.g. async</ul>
|
||||
* </li>
|
||||
*
|
||||
* The template of the span name is
|
||||
*
|
||||
* <pre>component:address#fragment</pre>
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class SpanName {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
public static final SpanName NO_NAME = new SpanName("", "");
|
||||
|
||||
public final String component;
|
||||
public final String address;
|
||||
public final String fragment;
|
||||
|
||||
// serialization
|
||||
SpanName() {
|
||||
this("", "", "");
|
||||
}
|
||||
|
||||
public SpanName(String component, String address) {
|
||||
this(component, address, "");
|
||||
}
|
||||
|
||||
public SpanName(String component, String address, String fragment) {
|
||||
this.component = component;
|
||||
this.address = address;
|
||||
this.fragment = fragment;
|
||||
}
|
||||
|
||||
public static SpanName fromString(String name) {
|
||||
String[] splitString = name.split(":");
|
||||
if (splitString.length < 2) {
|
||||
log.debug("Can't parse [{}]. Returning 'unknown' component and passing name to address", name);
|
||||
return new SpanName("unknown", name);
|
||||
}
|
||||
String protocol = splitString[0];
|
||||
String address = name.substring(name.indexOf(":") + 1);
|
||||
String fragment = "";
|
||||
if (address.contains("#")) {
|
||||
String[] splitSecondArg = address.split("#");
|
||||
fragment = address.substring(address.indexOf("#") + 1);
|
||||
address = splitSecondArg[0];
|
||||
}
|
||||
return new SpanName(protocol, address, fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.equals(NO_NAME)) {
|
||||
return "";
|
||||
}
|
||||
String baseName = this.component + ":" + this.address;
|
||||
if (StringUtils.hasText(this.fragment)) {
|
||||
return baseName + "#" + this.fragment;
|
||||
}
|
||||
return baseName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
SpanName spanName = (SpanName) o;
|
||||
return Objects.equals(this.component, spanName.component) &&
|
||||
Objects.equals(this.address, spanName.address) &&
|
||||
Objects.equals(this.fragment, spanName.fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.component, this.address, this.fragment);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public interface Tracer extends SpanAccessor {
|
||||
*
|
||||
* @param name The name field for the new span to create.
|
||||
*/
|
||||
Span startTrace(String name);
|
||||
Span startTrace(SpanName name);
|
||||
|
||||
/**
|
||||
* Creates a new Span with a specific parent. The parent might be in another
|
||||
@@ -67,7 +67,7 @@ public interface Tracer extends SpanAccessor {
|
||||
*
|
||||
* @param name The name field for the new span to create.
|
||||
*/
|
||||
Span joinTrace(String name, Span parent);
|
||||
Span joinTrace(SpanName name, Span parent);
|
||||
|
||||
/**
|
||||
* Start a new span if the sampler allows it or if we are already tracing in this
|
||||
@@ -75,7 +75,7 @@ public interface Tracer extends SpanAccessor {
|
||||
* @param name the name of the span
|
||||
* @param sampler a sampler to decide whether to create the span or not
|
||||
*/
|
||||
Span startTrace(String name, Sampler sampler);
|
||||
Span startTrace(SpanName name, Sampler sampler);
|
||||
|
||||
/**
|
||||
* Pick up an existing span from another thread.
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.AsyncConfigurer;
|
||||
@@ -47,4 +48,9 @@ public class AsyncDefaultAutoConfiguration extends AsyncConfigurerSupport {
|
||||
return new LazyTraceExecutor(this.beanFactory, new SimpleAsyncTaskExecutor());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TraceAsyncAspect traceAsyncAspect(Tracer tracer) {
|
||||
return new TraceAsyncAspect(tracer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or 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 org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
/**
|
||||
* Aspect that creates a new Span for running threads executing methods annotated with
|
||||
* {@link org.springframework.scheduling.annotation.Async} annotation.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*
|
||||
* @see Tracer
|
||||
*/
|
||||
@Aspect
|
||||
public class TraceAsyncAspect {
|
||||
|
||||
private static final String ASYNC_COMPONENT = "async";
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
public TraceAsyncAspect(Tracer tracer) {
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
@Around("execution (@org.springframework.scheduling.annotation.Async * *.*(..))")
|
||||
public Object traceBackgroundThread(final ProceedingJoinPoint pjp) throws Throwable {
|
||||
SpanName spanName = new SpanName(ASYNC_COMPONENT,
|
||||
pjp.getTarget().getClass().getSimpleName(),
|
||||
"method=" + pjp.getSignature().getName());
|
||||
Span span = this.tracer.startTrace(spanName);
|
||||
try {
|
||||
return pjp.proceed();
|
||||
}
|
||||
finally {
|
||||
this.tracer.close(span);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,11 +18,11 @@ package org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -35,7 +35,7 @@ public class TraceCallable<V> extends TraceDelegate<Callable<V>> implements Call
|
||||
super(tracer, delegate);
|
||||
}
|
||||
|
||||
public TraceCallable(Tracer tracer, Callable<V> delegate, String name) {
|
||||
public TraceCallable(Tracer tracer, Callable<V> delegate, SpanName name) {
|
||||
super(tracer, delegate, name);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
import lombok.Getter;
|
||||
@@ -27,16 +28,18 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public abstract class TraceDelegate<T> {
|
||||
|
||||
private static final String ASYNC_COMPONENT = "async";
|
||||
|
||||
private final Tracer tracer;
|
||||
private final T delegate;
|
||||
private final String name;
|
||||
private final SpanName name;
|
||||
private final Span parent;
|
||||
|
||||
public TraceDelegate(Tracer tracer, T delegate) {
|
||||
this(tracer, delegate, null);
|
||||
}
|
||||
|
||||
public TraceDelegate(Tracer tracer, T delegate, String name) {
|
||||
public TraceDelegate(Tracer tracer, T delegate, SpanName name) {
|
||||
this.tracer = tracer;
|
||||
this.delegate = delegate;
|
||||
this.name = name;
|
||||
@@ -51,8 +54,10 @@ public abstract class TraceDelegate<T> {
|
||||
return this.tracer.joinTrace(getSpanName(), this.parent);
|
||||
}
|
||||
|
||||
protected String getSpanName() {
|
||||
return this.name == null ? Thread.currentThread().getName() : this.name;
|
||||
protected SpanName getSpanName() {
|
||||
return this.name == null ?
|
||||
new SpanName(ASYNC_COMPONENT, Thread.currentThread().getName())
|
||||
: this.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -33,7 +33,7 @@ public class TraceRunnable extends TraceDelegate<Runnable> implements Runnable {
|
||||
super(tracer, delegate);
|
||||
}
|
||||
|
||||
public TraceRunnable(Tracer tracer, Runnable delegate, String name) {
|
||||
public TraceRunnable(Tracer tracer, Runnable delegate, SpanName name) {
|
||||
super(tracer, delegate, name);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
/**
|
||||
* A decorator class for {@link ExecutorService} to support tracing in Executors
|
||||
@@ -33,15 +34,21 @@ import org.springframework.cloud.sleuth.Tracer;
|
||||
public class TraceableExecutorService implements ExecutorService {
|
||||
final ExecutorService delegate;
|
||||
final Tracer tracer;
|
||||
private final SpanName spanName;
|
||||
|
||||
public TraceableExecutorService(final ExecutorService delegate, final Tracer tracer) {
|
||||
this(delegate, tracer, null);
|
||||
}
|
||||
|
||||
public TraceableExecutorService(final ExecutorService delegate, final Tracer tracer, SpanName spanName) {
|
||||
this.delegate = delegate;
|
||||
this.tracer = tracer;
|
||||
this.spanName = spanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
final Runnable r = new TraceRunnable(this.tracer, command);
|
||||
final Runnable r = new TraceRunnable(this.tracer, command, this.spanName);
|
||||
this.delegate.execute(r);
|
||||
}
|
||||
|
||||
@@ -72,19 +79,19 @@ public class TraceableExecutorService implements ExecutorService {
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
Callable<T> c = new TraceCallable<>(this.tracer, task);
|
||||
Callable<T> c = new TraceCallable<>(this.tracer, task, this.spanName);
|
||||
return this.delegate.submit(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Runnable task, T result) {
|
||||
Runnable r = new TraceRunnable(this.tracer, task);
|
||||
Runnable r = new TraceRunnable(this.tracer, task, this.spanName);
|
||||
return this.delegate.submit(r, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> submit(Runnable task) {
|
||||
Runnable r = new TraceRunnable(this.tracer, task);
|
||||
Runnable r = new TraceRunnable(this.tracer, task, this.spanName);
|
||||
return this.delegate.submit(r);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package org.springframework.cloud.sleuth.instrument.hystrix;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.netflix.hystrix.strategy.HystrixPlugins;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
@Slf4j
|
||||
public class SleuthHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
|
||||
|
||||
private static final String HYSTRIX_COMPONENT = "hystrix";
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
public SleuthHystrixConcurrencyStrategy(Tracer tracer) {
|
||||
@@ -62,7 +62,8 @@ public class SleuthHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy
|
||||
span = this.tracer.continueSpan(span);
|
||||
}
|
||||
else {
|
||||
span = this.tracer.startTrace(Thread.currentThread().getName());
|
||||
span = this.tracer.startTrace(new SpanName(HYSTRIX_COMPONENT,
|
||||
Thread.currentThread().getName()));
|
||||
created = true;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.sleuth.instrument.hystrix;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
@@ -33,6 +34,8 @@ import com.netflix.hystrix.HystrixCommand;
|
||||
*/
|
||||
public abstract class TraceCommand<R> extends HystrixCommand<R> {
|
||||
|
||||
private static final String HYSTRIX_COMPONENT = "hystrix";
|
||||
|
||||
private final Tracer tracer;
|
||||
private final Span parentSpan;
|
||||
|
||||
@@ -44,7 +47,8 @@ public abstract class TraceCommand<R> extends HystrixCommand<R> {
|
||||
|
||||
@Override
|
||||
protected R run() throws Exception {
|
||||
Span span = this.tracer.joinTrace(getCommandKey().name(), this.parentSpan);
|
||||
SpanName spanName = new SpanName(HYSTRIX_COMPONENT, getCommandKey().name());
|
||||
Span span = this.tracer.joinTrace(spanName, this.parentSpan);
|
||||
try {
|
||||
return doRun();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
@@ -20,7 +21,7 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
abstract class AbstractTraceChannelInterceptor extends ChannelInterceptorAdapter implements ExecutorChannelInterceptor {
|
||||
|
||||
protected static final String MESSAGE_NAME_PREFIX = "message/";
|
||||
protected static final String MESSAGE_COMPONENT = "message";
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
@@ -64,7 +65,7 @@ abstract class AbstractTraceChannelInterceptor extends ChannelInterceptorAdapter
|
||||
String processId = getHeader(message, Span.PROCESS_ID_NAME);
|
||||
String spanName = getHeader(message, Span.SPAN_NAME_NAME);
|
||||
if (spanName != null) {
|
||||
span.name(spanName);
|
||||
span.name(SpanName.fromString(spanName));
|
||||
}
|
||||
if (processId != null) {
|
||||
span.processId(processId);
|
||||
@@ -106,8 +107,8 @@ abstract class AbstractTraceChannelInterceptor extends ChannelInterceptorAdapter
|
||||
return name;
|
||||
}
|
||||
|
||||
String getMessageChannelName(MessageChannel channel) {
|
||||
return MESSAGE_NAME_PREFIX + getChannelName(channel);
|
||||
SpanName getMessageChannelName(MessageChannel channel) {
|
||||
return new SpanName(MESSAGE_COMPONENT, getChannelName(channel));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class SpanMessageHeaders {
|
||||
if (parentId != null) {
|
||||
addHeader(headers, Span.PARENT_ID_NAME, Span.toHex(parentId));
|
||||
}
|
||||
addHeader(headers, Span.SPAN_NAME_NAME, span.getName());
|
||||
addHeader(headers, Span.SPAN_NAME_NAME, span.getName().toString());
|
||||
addHeader(headers, Span.PROCESS_ID_NAME, span.getProcessId());
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.sampler.NeverSampler;
|
||||
@@ -45,12 +46,12 @@ public class TraceChannelInterceptor extends AbstractTraceChannelInterceptor {
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
Span parentSpan = getTracer().isTracing() ? getTracer().getCurrentSpan()
|
||||
: buildSpan(message);
|
||||
String name = getMessageChannelName(channel);
|
||||
SpanName name = getMessageChannelName(channel);
|
||||
Span span = startSpan(parentSpan, name, message);
|
||||
return SpanMessageHeaders.addSpanHeaders(getTraceKeys(), message, span);
|
||||
}
|
||||
|
||||
private Span startSpan(Span span, String name, Message<?> message) {
|
||||
private Span startSpan(Span span, SpanName name, Message<?> message) {
|
||||
if (span != null) {
|
||||
return getTracer().joinTrace(name, span);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
/**
|
||||
@@ -37,6 +38,8 @@ import org.springframework.cloud.sleuth.Tracer;
|
||||
@Aspect
|
||||
public class TraceSchedulingAspect {
|
||||
|
||||
private static final String SCHEDULED_COMPONENT = "scheduled";
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
public TraceSchedulingAspect(Tracer tracer) {
|
||||
@@ -45,7 +48,10 @@ public class TraceSchedulingAspect {
|
||||
|
||||
@Around("execution (@org.springframework.scheduling.annotation.Scheduled * *.*(..))")
|
||||
public Object traceBackgroundThread(final ProceedingJoinPoint pjp) throws Throwable {
|
||||
Span span = this.tracer.startTrace(pjp.toShortString());
|
||||
SpanName spanName = new SpanName(SCHEDULED_COMPONENT,
|
||||
pjp.getTarget().getClass().getSimpleName(),
|
||||
"method=" + pjp.getSignature().getName());
|
||||
Span span = this.tracer.startTrace(spanName);
|
||||
try {
|
||||
return pjp.proceed();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Span.SpanBuilder;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.ServerReceivedEvent;
|
||||
import org.springframework.cloud.sleuth.event.ServerSentEvent;
|
||||
@@ -57,7 +58,7 @@ import org.springframework.web.util.UrlPathHelper;
|
||||
*
|
||||
* @see Tracer
|
||||
* @see TraceKeys
|
||||
* @see TraceWebAutoConfiguration#traceWebFilter(TraceFilter)
|
||||
* @see TraceWebAutoConfiguration#traceFilter(TraceFilter)
|
||||
*
|
||||
* @author Jakub Nabrdalik, 4financeIT
|
||||
* @author Tomasz Nurkiewicz, 4financeIT
|
||||
@@ -117,7 +118,9 @@ public class TraceFilter extends OncePerRequestFilter
|
||||
addToResponseIfNotPresent(response, Span.NOT_SAMPLED_NAME, "");
|
||||
}
|
||||
|
||||
String name = "http" + uri;
|
||||
String protocol = "http";
|
||||
String address = uri;
|
||||
SpanName name = new SpanName(protocol, address);
|
||||
if (spanFromRequest == null) {
|
||||
if (hasHeader(request, response, Span.TRACE_ID_NAME)) {
|
||||
long traceId = Span
|
||||
@@ -133,10 +136,10 @@ public class TraceFilter extends OncePerRequestFilter
|
||||
String processId = getHeader(request, response, Span.PROCESS_ID_NAME);
|
||||
String parentName = getHeader(request, response, Span.SPAN_NAME_NAME);
|
||||
if (StringUtils.hasText(parentName)) {
|
||||
span.name(parentName);
|
||||
span.name(SpanName.fromString(parentName));
|
||||
}
|
||||
else {
|
||||
span.name("parent/" + name);
|
||||
span.name(new SpanName(protocol, "/parent" + uri));
|
||||
}
|
||||
if (StringUtils.hasText(processId)) {
|
||||
span.processId(processId);
|
||||
@@ -272,7 +275,6 @@ public class TraceFilter extends OncePerRequestFilter
|
||||
private String getFullUrl(HttpServletRequest request) {
|
||||
StringBuffer requestURI = request.getRequestURL();
|
||||
String queryString = request.getQueryString();
|
||||
|
||||
if (queryString == null) {
|
||||
return requestURI.toString();
|
||||
}
|
||||
|
||||
@@ -16,13 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -33,6 +35,8 @@ public class TraceHandlerInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
private final UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
|
||||
public TraceHandlerInterceptor(Tracer tracer) {
|
||||
this.tracer = tracer;
|
||||
}
|
||||
@@ -42,7 +46,9 @@ public class TraceHandlerInterceptor implements HandlerInterceptor {
|
||||
Object handler) throws Exception {
|
||||
// TODO: get trace data from request?
|
||||
// TODO: what is the description?
|
||||
Span span = this.tracer.startTrace("traceHandlerInterceptor");
|
||||
String uri = this.urlPathHelper.getPathWithinApplication(request);
|
||||
SpanName spanName = new SpanName("http", uri, "interceptor=traceHandlerInterceptor");
|
||||
Span span = this.tracer.startTrace(spanName);
|
||||
request.setAttribute(ATTR_NAME, span);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,18 +16,20 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.cloud.sleuth.SpanAccessor;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.async.TraceCallable;
|
||||
import org.springframework.web.context.request.async.WebAsyncTask;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.Callable;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* Aspect that adds correlation id to
|
||||
@@ -61,6 +63,8 @@ import java.util.concurrent.Callable;
|
||||
@CommonsLog
|
||||
public class TraceWebAspect {
|
||||
|
||||
private static final String ASYNC_COMPONENT = "async";
|
||||
|
||||
private final Tracer tracer;
|
||||
private final SpanAccessor accessor;
|
||||
|
||||
@@ -100,13 +104,19 @@ public class TraceWebAspect {
|
||||
if (this.accessor.isTracing()) {
|
||||
log.debug("Wrapping callable with span ["
|
||||
+ this.accessor.getCurrentSpan() + "]");
|
||||
return new TraceCallable<>(this.tracer, callable);
|
||||
return new TraceCallable<>(this.tracer, callable, spanName(pjp));
|
||||
}
|
||||
else {
|
||||
return callable;
|
||||
}
|
||||
}
|
||||
|
||||
private SpanName spanName(ProceedingJoinPoint pjp) {
|
||||
return new SpanName(ASYNC_COMPONENT,
|
||||
pjp.getTarget().getClass().getSimpleName(),
|
||||
"method=" + pjp.getSignature().getName());
|
||||
}
|
||||
|
||||
@Around("anyControllerOrRestControllerWithPublicWebAsyncTaskMethod()")
|
||||
public Object wrapWebAsyncTaskWithCorrelationId(ProceedingJoinPoint pjp) throws Throwable {
|
||||
final WebAsyncTask<?> webAsyncTask = (WebAsyncTask<?>) pjp.proceed();
|
||||
@@ -116,7 +126,8 @@ public class TraceWebAspect {
|
||||
+ this.accessor.getCurrentSpan() + "]");
|
||||
Field callableField = WebAsyncTask.class.getDeclaredField("callable");
|
||||
callableField.setAccessible(true);
|
||||
callableField.set(webAsyncTask, new TraceCallable<>(this.tracer, webAsyncTask.getCallable()));
|
||||
callableField.set(webAsyncTask, new TraceCallable<>(this.tracer,
|
||||
webAsyncTask.getCallable(), spanName(pjp)));
|
||||
} catch (NoSuchFieldException ex) {
|
||||
log.warn("Cannot wrap webAsyncTask's callable with TraceCallable", ex);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class TraceFeignClientAutoConfiguration {
|
||||
return;
|
||||
}
|
||||
template.header(Span.TRACE_ID_NAME, Span.toHex(span.getTraceId()));
|
||||
setHeader(template, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(template, Span.SPAN_NAME_NAME, span.getName().toString());
|
||||
setHeader(template, Span.SPAN_ID_NAME, Span.toHex(span.getSpanId()));
|
||||
if (!span.isExportable()) {
|
||||
setHeader(template, Span.NOT_SAMPLED_NAME, "true");
|
||||
@@ -152,18 +152,12 @@ public class TraceFeignClientAutoConfiguration {
|
||||
}
|
||||
|
||||
public void setHeader(RequestTemplate request, String name, String value) {
|
||||
if (value != null && !request.headers().containsKey(name)
|
||||
if (StringUtils.hasText(value) && !request.headers().containsKey(name)
|
||||
&& this.accessor.isTracing()) {
|
||||
request.header(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHeader(RequestTemplate request, String name, Long value) {
|
||||
if (value != null) {
|
||||
setHeader(request, name, Span.toHex(value));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Collection<String>> headersWithTraceId(
|
||||
Map<String, Collection<String>> headers) {
|
||||
Map<String, Collection<String>> newHeaders = new HashMap<>();
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Interceptor that verifies whether the trance and span id has been set on the request
|
||||
@@ -68,7 +69,7 @@ public class TraceRestTemplateInterceptor
|
||||
if (!span.isExportable()) {
|
||||
setHeader(request, Span.NOT_SAMPLED_NAME, "true");
|
||||
}
|
||||
setHeader(request, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(request, Span.SPAN_NAME_NAME, span.getName().toString());
|
||||
setHeader(request, Span.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(request, Span.PROCESS_ID_NAME, span.getProcessId());
|
||||
publish(new ClientSentEvent(this, span));
|
||||
@@ -93,7 +94,7 @@ public class TraceRestTemplateInterceptor
|
||||
}
|
||||
|
||||
public void setHeader(HttpRequest request, String name, String value) {
|
||||
if (value!=null && !request.getHeaders().containsKey(name) && this.accessor.isTracing()) {
|
||||
if (StringUtils.hasText(value) && !request.getHeaders().containsKey(name) && this.accessor.isTracing()) {
|
||||
request.getHeaders().add(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -68,7 +69,7 @@ public class TracePreZuulFilter extends ZuulFilter
|
||||
try {
|
||||
setHeader(response, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(response, Span.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(response, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(response, Span.SPAN_NAME_NAME, span.getName().toString());
|
||||
if (!span.isExportable()) {
|
||||
setHeader(response, Span.NOT_SAMPLED_NAME, "true");
|
||||
}
|
||||
@@ -92,7 +93,7 @@ public class TracePreZuulFilter extends ZuulFilter
|
||||
}
|
||||
|
||||
public void setHeader(Map<String, String> request, String name, String value) {
|
||||
if (value != null && !request.containsKey(name) && this.accessor.isTracing()) {
|
||||
if (StringUtils.hasText(value) && !request.containsKey(name) && this.accessor.isTracing()) {
|
||||
request.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand
|
||||
}
|
||||
setHeader(requestBuilder, Span.TRACE_ID_NAME, Span.toHex(span.getTraceId()));
|
||||
setHeader(requestBuilder, Span.SPAN_ID_NAME, Span.toHex(span.getSpanId()));
|
||||
setHeader(requestBuilder, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(requestBuilder, Span.SPAN_NAME_NAME, span.getName().toString());
|
||||
setHeader(requestBuilder, Span.PARENT_ID_NAME,
|
||||
Span.toHex(getParentId(span)));
|
||||
setHeader(requestBuilder, Span.PROCESS_ID_NAME,
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.SpanAcquiredEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanContinuedEvent;
|
||||
@@ -49,7 +50,7 @@ public class DefaultTracer implements Tracer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Span joinTrace(String name, Span parent) {
|
||||
public Span joinTrace(SpanName name, Span parent) {
|
||||
if (parent == null) {
|
||||
return startTrace(name);
|
||||
}
|
||||
@@ -57,12 +58,12 @@ public class DefaultTracer implements Tracer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Span startTrace(String name) {
|
||||
public Span startTrace(SpanName name) {
|
||||
return this.startTrace(name, this.defaultSampler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Span startTrace(String name, Sampler sampler) {
|
||||
public Span startTrace(SpanName name, Sampler sampler) {
|
||||
Span span;
|
||||
if (isTracing()) {
|
||||
span = createChild(getCurrentSpan(), name);
|
||||
@@ -128,7 +129,7 @@ public class DefaultTracer implements Tracer {
|
||||
return savedSpan;
|
||||
}
|
||||
|
||||
protected Span createChild(Span parent, String name) {
|
||||
protected Span createChild(Span parent, SpanName name) {
|
||||
long id = createId();
|
||||
if (parent == null) {
|
||||
Span span = Span.builder().begin(System.currentTimeMillis()).name(name)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.springframework.cloud.sleuth;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class SpanNameTest {
|
||||
|
||||
@Test
|
||||
public void should_return_span_name_wihout_fragment_when_no_fragment_is_passed() {
|
||||
then(new SpanName("component", "address").toString())
|
||||
.isEqualTo("component:address");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_return_span_name_together_with_fragment_when_fragment_was_passed() {
|
||||
then(new SpanName("component", "address", "fragment").toString())
|
||||
.isEqualTo("component:address#fragment");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_return_empty_string_if_there_is_no_span_name() {
|
||||
then(SpanName.NO_NAME.toString()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_build_span_from_valid_string_name() {
|
||||
then(SpanName.fromString("http:/a/b/c#async"))
|
||||
.hasComponentEqualTo("http")
|
||||
.hasAddressEqualTo("/a/b/c")
|
||||
.hasFragmentEqualTo("async");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_build_span_from_a_string_with_missing_protocol() {
|
||||
then(SpanName.fromString("/a/b/c").toString())
|
||||
.isEqualTo("unknown:/a/b/c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_build_span_from_a_string_name_with_many_separators() {
|
||||
then(SpanName.fromString("http:/a/b:/c#async:asd=123#4444"))
|
||||
.hasComponentEqualTo("http")
|
||||
.hasAddressEqualTo("/a/b:/c")
|
||||
.hasFragmentEqualTo("async:asd=123#4444");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package org.springframework.cloud.sleuth;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
/**
|
||||
@@ -37,14 +37,14 @@ public class SpanTest {
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class) public void getAnnotationsReadOnly() {
|
||||
Span span = new Span(1, 2, "name", 1L, Collections.<Long>emptyList(), 2L, true,
|
||||
Span span = new Span(1, 2, new SpanName("http", "name"), 1L, Collections.<Long>emptyList(), 2L, true,
|
||||
true, "process");
|
||||
|
||||
span.tags().put("a", "b");
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class) public void getTimelineAnnotationsReadOnly() {
|
||||
Span span = new Span(1, 2, "name", 1L, Collections.<Long>emptyList(), 2L, true,
|
||||
Span span = new Span(1, 2, new SpanName("http", "name"), 1L, Collections.<Long>emptyList(), 2L, true,
|
||||
true, "process");
|
||||
|
||||
span.logs().add(new Log(1, "1"));
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.springframework.cloud.sleuth.assertions;
|
||||
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
|
||||
public class SleuthAssertions extends BDDAssertions {
|
||||
|
||||
@@ -13,4 +14,12 @@ public class SleuthAssertions extends BDDAssertions {
|
||||
return new SpanAssert(actual);
|
||||
}
|
||||
|
||||
public static SpanNameAssert then(SpanName actual) {
|
||||
return assertThat(actual);
|
||||
}
|
||||
|
||||
public static SpanNameAssert assertThat(SpanName actual) {
|
||||
return new SpanNameAssert(actual);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.assertj.core.api.AbstractAssert;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
|
||||
@Slf4j
|
||||
public class SpanAssert extends AbstractAssert<SpanAssert, Span> {
|
||||
@@ -28,7 +29,7 @@ public class SpanAssert extends AbstractAssert<SpanAssert, Span> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanAssert hasNameNotEqualTo(String name) {
|
||||
public SpanAssert hasNameNotEqualTo(SpanName name) {
|
||||
isNotNull();
|
||||
if (Objects.equals(this.actual.getName(), name)) {
|
||||
String message = String.format("Expected span's name not to be <%s> but was <%s>", name, this.actual.getName());
|
||||
@@ -38,7 +39,7 @@ public class SpanAssert extends AbstractAssert<SpanAssert, Span> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanAssert hasNameEqualTo(String name) {
|
||||
public SpanAssert hasNameEqualTo(SpanName name) {
|
||||
isNotNull();
|
||||
if (!Objects.equals(this.actual.getName(), name)) {
|
||||
String message = String.format("Expected span's name to be <%s> but it was <%s>", name, this.actual.getName());
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or 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 org.springframework.cloud.sleuth.assertions;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class SpanNameAssert extends AbstractAssert<SpanNameAssert, SpanName> {
|
||||
|
||||
public SpanNameAssert(SpanName actual) {
|
||||
super(actual, SpanNameAssert.class);
|
||||
}
|
||||
|
||||
public static SpanNameAssert then(SpanName actual) {
|
||||
return new SpanNameAssert(actual);
|
||||
}
|
||||
|
||||
public SpanNameAssert hasComponentEqualTo(String protocol) {
|
||||
isNotNull();
|
||||
if (!Objects.equals(this.actual.component, protocol)) {
|
||||
String message = String.format("Expected span name's component to be <%s> but was <%s>", protocol, this.actual.component);
|
||||
log.error(message);
|
||||
failWithMessage(message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanNameAssert hasAddressEqualTo(String address) {
|
||||
isNotNull();
|
||||
if (!Objects.equals(this.actual.address, address)) {
|
||||
String message = String.format("Expected span name's address to be <%s> but was <%s>", address, this.actual.address);
|
||||
log.error(message);
|
||||
failWithMessage(message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanNameAssert hasFragmentEqualTo(String fragment) {
|
||||
isNotNull();
|
||||
if (!Objects.equals(this.actual.fragment, fragment)) {
|
||||
String message = String.format("Expected span name's fragment to be <%s> but was <%s>", fragment, this.actual.fragment);
|
||||
log.error(message);
|
||||
failWithMessage(message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
package org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.async.TraceCallable;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
@@ -13,11 +19,6 @@ import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -72,7 +73,7 @@ public class TraceCallableTests {
|
||||
}
|
||||
|
||||
private Span givenSpanIsAlreadyActive() {
|
||||
return this.tracer.startTrace("parent");
|
||||
return this.tracer.startTrace(new SpanName("http", "parent"));
|
||||
}
|
||||
|
||||
private Callable<Span> thatRetrievesTraceFromThreadLocal() {
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
package org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.async.TraceableExecutorService;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
@@ -24,6 +9,22 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.async.TraceableExecutorService;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@@ -55,7 +56,7 @@ public class TraceableExecutorServiceTests {
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void should_propagate_trace_id_and_set_new_span_when_traceable_executor_service_is_executed() {
|
||||
Span span = this.tracer.startTrace("PARENT");
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "PARENT"));
|
||||
CompletableFuture.allOf(runnablesExecutedViaTraceManagerableExecutorService()).get();
|
||||
this.tracer.close(span);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
@@ -57,7 +58,7 @@ public class HystrixAnnotationsIntegrationTests {
|
||||
}
|
||||
|
||||
private Span givenASpanInCurrentThread() {
|
||||
Span span = this.tracer.startTrace("existing");
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "existing"));
|
||||
this.tracer.continueSpan(span);
|
||||
return span;
|
||||
}
|
||||
@@ -111,11 +112,11 @@ public class HystrixAnnotationsIntegrationTests {
|
||||
return this.spanCaughtFromHystrixThread.get().getTraceId();
|
||||
}
|
||||
|
||||
public String getSpanName() {
|
||||
public SpanName getSpanName() {
|
||||
if (this.spanCaughtFromHystrixThread == null
|
||||
|| (this.spanCaughtFromHystrixThread.get() != null
|
||||
&& this.spanCaughtFromHystrixThread.get()
|
||||
.getName() == null)) {
|
||||
&& this.spanCaughtFromHystrixThread.get()
|
||||
.getName() == null)) {
|
||||
return null;
|
||||
}
|
||||
return this.spanCaughtFromHystrixThread.get().getName();
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package org.springframework.cloud.sleuth.instrument.hystrix;
|
||||
|
||||
import static com.netflix.hystrix.HystrixCommand.Setter.withGroupKey;
|
||||
import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -11,6 +7,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
@@ -21,6 +18,10 @@ import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
||||
import com.netflix.hystrix.strategy.HystrixPlugins;
|
||||
|
||||
import static com.netflix.hystrix.HystrixCommand.Setter.withGroupKey;
|
||||
import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
public class TraceCommandTests {
|
||||
|
||||
static final long EXPECTED_TRACE_ID = 1L;
|
||||
@@ -63,7 +64,7 @@ public class TraceCommandTests {
|
||||
}
|
||||
|
||||
private Span givenATraceIsPresentInTheCurrentThread() {
|
||||
return this.tracer.joinTrace("test",
|
||||
return this.tracer.joinTrace(new SpanName("http", "test"),
|
||||
Span.builder().traceId(EXPECTED_TRACE_ID).build());
|
||||
}
|
||||
|
||||
@@ -72,8 +73,8 @@ public class TraceCommandTests {
|
||||
withGroupKey(asKey("group"))
|
||||
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties
|
||||
.Setter().withCoreSize(1).withMaxQueueSize(1))
|
||||
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
|
||||
.withExecutionTimeoutEnabled(false))) {
|
||||
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
|
||||
.withExecutionTimeoutEnabled(false))) {
|
||||
@Override
|
||||
public Span doRun() throws Exception {
|
||||
return TestSpanContextHolder.getCurrentSpan();
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
@@ -38,7 +39,7 @@ public class SpanMessageHeadersTests {
|
||||
|
||||
@Test
|
||||
public void spanHeadersAdded() {
|
||||
Span span = Span.builder().name("foo").spanId(1L).traceId(2L).build();
|
||||
Span span = Span.builder().name(new SpanName("http", "foo")).spanId(1L).traceId(2L).build();
|
||||
Message<?> message = new GenericMessage<>("Hello World");
|
||||
message = SpanMessageHeaders.addSpanHeaders(this.traceKeys, message, span);
|
||||
assertThat(message.getHeaders()).containsKey(Span.SPAN_ID_NAME);
|
||||
@@ -46,7 +47,7 @@ public class SpanMessageHeadersTests {
|
||||
|
||||
@Test
|
||||
public void nativeSpanHeadersAdded() {
|
||||
Span span = Span.builder().name("foo").spanId(1L).traceId(2L).build();
|
||||
Span span = Span.builder().name(new SpanName("http", "foo")).spanId(1L).traceId(2L).build();
|
||||
MessageHeaderAccessor accessor = SimpMessageHeaderAccessor.create();
|
||||
Message<?> message = MessageBuilder.createMessage("Hello World", accessor.getMessageHeaders());
|
||||
message = SpanMessageHeaders.addSpanHeaders(this.traceKeys, message, span);
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -35,6 +29,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
|
||||
import org.springframework.cloud.sleuth.instrument.messaging.TraceChannelInterceptorTests.App;
|
||||
@@ -52,6 +47,12 @@ import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -138,7 +139,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
|
||||
@Test
|
||||
public void headerCreation() {
|
||||
Span span = this.tracer.startTrace("testSendMessage", new AlwaysSampler());
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "testSendMessage"), new AlwaysSampler());
|
||||
this.channel.send(MessageBuilder.withPayload("hi").build());
|
||||
this.tracer.close(span);
|
||||
assertNotNull("message was null", this.message);
|
||||
@@ -154,7 +155,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
// TODO: Refactor to parametrized test together with sending messages via channel
|
||||
@Test
|
||||
public void headerCreationViaMessagingTemplate() {
|
||||
Span span = this.tracer.startTrace("testSendMessage", new AlwaysSampler());
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "testSendMessage"), new AlwaysSampler());
|
||||
this.messagingTemplate.send(MessageBuilder.withPayload("hi").build());
|
||||
this.tracer.close(span);
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.messaging.TraceContextPropagationChannelInterceptorTests.App;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
@@ -65,7 +66,7 @@ public class TraceContextPropagationChannelInterceptorTests {
|
||||
@Test
|
||||
public void testSpanPropagation() {
|
||||
|
||||
Span span = this.tracer.startTrace("testSendMessage", new AlwaysSampler());
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "testSendMessage"), new AlwaysSampler());
|
||||
this.channel.send(MessageBuilder.withPayload("hi").build());
|
||||
Long expectedSpanId = span.getSpanId();
|
||||
this.tracer.close(span);
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import com.jayway.awaitility.Awaitility;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
@@ -17,7 +19,7 @@ import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import com.jayway.awaitility.Awaitility;
|
||||
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
@@ -39,7 +41,7 @@ public class TraceAsyncIntegrationTests {
|
||||
}
|
||||
|
||||
private Span givenASpanInCurrentThread() {
|
||||
Span span = this.tracer.startTrace("existing");
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "existing"));
|
||||
this.tracer.continueSpan(span);
|
||||
return span;
|
||||
}
|
||||
@@ -55,6 +57,8 @@ public class TraceAsyncIntegrationTests {
|
||||
then(span)
|
||||
.hasTraceIdEqualTo(TraceAsyncIntegrationTests.this.classPerformingAsyncLogic.getTraceId())
|
||||
.hasNameNotEqualTo(TraceAsyncIntegrationTests.this.classPerformingAsyncLogic.getSpanName());
|
||||
then(TraceAsyncIntegrationTests.this.classPerformingAsyncLogic.getSpanName()).
|
||||
isEqualTo(SpanName.fromString("async:ClassPerformingAsyncLogic#method=invokeAsynchronousLogic"));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -92,7 +96,7 @@ public class TraceAsyncIntegrationTests {
|
||||
return this.span.get().getTraceId();
|
||||
}
|
||||
|
||||
public String getSpanName() {
|
||||
public SpanName getSpanName() {
|
||||
if (this.span.get() != null && this.span.get().getName() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -16,21 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
@@ -46,7 +40,13 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -113,8 +113,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void continuesSpanInRequestAttr() throws Exception {
|
||||
|
||||
Span span = this.tracer.startTrace("foo");
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "foo"));
|
||||
this.request.setAttribute(TraceFilter.TRACE_REQUEST_ATTR, span);
|
||||
// It should have been removed from the thread local context so simulate that
|
||||
TestSpanContextHolder.removeCurrentSpan();
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.ArrayListSpanAccumulator;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
@@ -44,9 +45,11 @@ public class MultipleHopsIntegrationTests extends AbstractMvcIntegrationTest {
|
||||
MockMvcResultMatchers.status().isOk());
|
||||
|
||||
await().until(() -> {
|
||||
then(this.arrayListSpanAccumulator.getSpans().stream().map(Span::getName).collect(
|
||||
toList())).containsAll(asList("http/greeting", "message/greetings",
|
||||
"message/words", "message/counts"));
|
||||
then(this.arrayListSpanAccumulator.getSpans().stream().map(Span::getName)
|
||||
.map(SpanName::toString)
|
||||
.collect(
|
||||
toList())).containsAll(asList("http:/greeting", "message:greetings",
|
||||
"message:words", "message:counts"));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,22 +16,22 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.zuul;
|
||||
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -55,7 +55,7 @@ public class TracePostZuulFilterTests {
|
||||
@Test
|
||||
public void filterPublishesEvent() throws Exception {
|
||||
this.filter.setApplicationEventPublisher(this.publisher);
|
||||
this.tracer.startTrace("start");
|
||||
this.tracer.startTrace(new SpanName("http", "start"));
|
||||
this.filter.run();
|
||||
verify(this.publisher).publishEvent(isA(ClientReceivedEvent.class));
|
||||
}
|
||||
|
||||
@@ -16,25 +16,25 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.zuul;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.sampler.NeverSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -59,7 +59,7 @@ public class TracePreZuulFilterTests {
|
||||
|
||||
@Test
|
||||
public void filterAddsHeaders() throws Exception {
|
||||
this.tracer.startTrace("start");
|
||||
this.tracer.startTrace(new SpanName("http", "start"));
|
||||
this.filter.run();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
assertThat(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME),
|
||||
@@ -70,7 +70,7 @@ public class TracePreZuulFilterTests {
|
||||
|
||||
@Test
|
||||
public void notSampledIfNotExportable() throws Exception {
|
||||
this.tracer.startTrace("start", NeverSampler.INSTANCE);
|
||||
this.tracer.startTrace(new SpanName("http", "start"), NeverSampler.INSTANCE);
|
||||
this.filter.run();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
assertThat(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME),
|
||||
|
||||
@@ -16,15 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.trace;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
@@ -34,6 +25,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.SpanAcquiredEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
|
||||
@@ -42,14 +34,25 @@ import org.springframework.cloud.sleuth.sampler.NeverSampler;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DefaultTracerTests {
|
||||
|
||||
public static final String CREATE_SIMPLE_TRACE = "createSimpleTrace";
|
||||
public static final String IMPORTANT_WORK_1 = "important work 1";
|
||||
public static final String IMPORTANT_WORK_2 = "important work 2";
|
||||
public static final String CREATE_SIMPLE_TRACE_SPAN_NAME = "createSimpleTrace";
|
||||
public static final SpanName CREATE_SIMPLE_TRACE = new SpanName("http",
|
||||
CREATE_SIMPLE_TRACE_SPAN_NAME);
|
||||
public static final SpanName IMPORTANT_WORK_1 = new SpanName("http", "important work 1");
|
||||
public static final SpanName IMPORTANT_WORK_2 = new SpanName("http", "important work 2");
|
||||
public static final int NUM_SPANS = 3;
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
@@ -126,7 +129,7 @@ public class DefaultTracerTests {
|
||||
this.publisher);
|
||||
Span span = tracer.startTrace(CREATE_SIMPLE_TRACE, NeverSampler.INSTANCE);
|
||||
assertThat(span.isExportable(), is(false));
|
||||
Span child = tracer.joinTrace(CREATE_SIMPLE_TRACE + "/child", span);
|
||||
Span child = tracer.joinTrace(new SpanName("http", CREATE_SIMPLE_TRACE_SPAN_NAME + "/child"), span);
|
||||
assertThat(child.isExportable(), is(false));
|
||||
}
|
||||
|
||||
@@ -163,7 +166,7 @@ public class DefaultTracerTests {
|
||||
assertThat(tracer.getCurrentSpan(), is(equalTo(grandParent)));
|
||||
}
|
||||
|
||||
private Span assertSpan(List<Span> spans, Long parentId, String name) {
|
||||
private Span assertSpan(List<Span> spans, Long parentId, SpanName name) {
|
||||
List<Span> found = findSpans(spans, parentId);
|
||||
assertThat("more than one span with parentId " + parentId, found.size(), is(1));
|
||||
Span span = found.get(0);
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import integration.MessagingApplicationTests.IntegrationSpanCollectorConfig;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -33,6 +32,8 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import integration.MessagingApplicationTests.IntegrationSpanCollectorConfig;
|
||||
import sample.SampleMessagingApplication;
|
||||
import tools.AbstractIntegrationTest;
|
||||
import zipkin.Constants;
|
||||
@@ -116,7 +117,7 @@ public class MessagingApplicationTests extends AbstractIntegrationTest {
|
||||
|
||||
private Optional<Span> findLastHttpSpan() {
|
||||
return this.integrationTestSpanCollector.hashedSpans.stream()
|
||||
.filter(span -> "http/foo".equals(span.name)).findFirst();
|
||||
.filter(span -> "http:/foo".equals(span.name)).findFirst();
|
||||
}
|
||||
|
||||
private Optional<Span> findSpanWithAnnotation(List<Span> eventSpans, String annotationName) {
|
||||
@@ -128,13 +129,13 @@ public class MessagingApplicationTests extends AbstractIntegrationTest {
|
||||
|
||||
private List<Span> findAllEventRelatedSpans() {
|
||||
return this.integrationTestSpanCollector.hashedSpans.stream()
|
||||
.filter(span -> "message/messages".equals(span.name) && span.parentId != null).collect(
|
||||
.filter(span -> "message:messages".equals(span.name) && span.parentId != null).collect(
|
||||
Collectors.toList());
|
||||
}
|
||||
|
||||
private Optional<Span> findFirstHttpRequestSpan() {
|
||||
return this.integrationTestSpanCollector.hashedSpans.stream()
|
||||
.filter(span -> "http/".equals(span.name) && span.parentId != null).findFirst();
|
||||
.filter(span -> "http:/".equals(span.name) && span.parentId != null).findFirst();
|
||||
}
|
||||
|
||||
private void thenAllSpansArePresent(Optional<Span> firstHttpSpan,
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
package sample;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanAccessor;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -29,9 +33,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -93,7 +94,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
@SneakyThrows
|
||||
@RequestMapping("/traced")
|
||||
public String traced() {
|
||||
Span span = this.tracer.startTrace("customTraceEndpoint",
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "customTraceEndpoint"),
|
||||
new AlwaysSampler());
|
||||
int millis = this.random.nextInt(1000);
|
||||
log.info("Sleeping for {} millis", millis);
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package integration;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import example.ZipkinStreamServerApplication;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -25,6 +28,7 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.WebIntegrationTest;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.stream.Host;
|
||||
import org.springframework.cloud.sleuth.stream.SleuthSink;
|
||||
import org.springframework.cloud.sleuth.stream.Spans;
|
||||
@@ -36,9 +40,6 @@ import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import tools.AbstractIntegrationTest;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = { TestSupportBinderAutoConfiguration.class,
|
||||
ZipkinStreamServerApplication.class })
|
||||
@@ -62,7 +63,7 @@ public class ZipkinStreamTests extends AbstractIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void should_propagate_spans_to_zipkin() {
|
||||
Span span = Span.builder().traceId(this.traceId).spanId(this.spanId).name("test").build();
|
||||
Span span = Span.builder().traceId(this.traceId).spanId(this.spanId).name(new SpanName("http", "test")).build();
|
||||
span.tag(getRequiredBinaryAnnotationName(), "10131");
|
||||
|
||||
this.input.send(messageWithSpan(span));
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanAccessor;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -96,7 +97,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
@SneakyThrows
|
||||
@RequestMapping("/traced")
|
||||
public String traced() {
|
||||
Span span = this.tracer.startTrace("customTraceEndpoint",
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "customTraceEndpoint"),
|
||||
new AlwaysSampler());
|
||||
int millis = this.random.nextInt(1000);
|
||||
log.info("Sleeping for {} millis", millis);
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
package sample;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanAccessor;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -29,9 +33,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -93,7 +94,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
@SneakyThrows
|
||||
@RequestMapping("/traced")
|
||||
public String traced() {
|
||||
Span span = this.tracer.startTrace("customTraceEndpoint",
|
||||
Span span = this.tracer.startTrace(new SpanName("http", "customTraceEndpoint"),
|
||||
new AlwaysSampler());
|
||||
int millis = this.random.nextInt(1000);
|
||||
log.info("Sleeping for {} millis", millis);
|
||||
|
||||
@@ -16,18 +16,19 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ServerPropertiesHostLocatorTests {
|
||||
Span span = new Span(1, 3, "name", 1L, Collections.<Long>emptyList(), 2L, true, true,
|
||||
Span span = new Span(1, 3, new SpanName("http", "name"), 1L, Collections.<Long>emptyList(), 2L, true, true,
|
||||
"process");
|
||||
|
||||
@Test
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
@@ -75,16 +76,16 @@ public class StreamSpanListenerTests {
|
||||
|
||||
@Test
|
||||
public void acquireAndRelease() {
|
||||
Span context = this.tracer.startTrace("foo");
|
||||
Span context = this.tracer.startTrace(new SpanName("http", "foo"));
|
||||
this.tracer.close(context);
|
||||
assertEquals(1, this.test.spans.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rpcAnnotations() {
|
||||
Span parent = Span.builder().traceId(1L).name("parent").remote(true)
|
||||
Span parent = Span.builder().traceId(1L).name(new SpanName("http", "parent")).remote(true)
|
||||
.build();
|
||||
Span context = this.tracer.joinTrace("child", parent);
|
||||
Span context = this.tracer.joinTrace(new SpanName("http", "child"), parent);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context));
|
||||
this.application
|
||||
.publishEvent(new ServerReceivedEvent(this, parent, context));
|
||||
@@ -107,7 +108,7 @@ public class StreamSpanListenerTests {
|
||||
|
||||
@Test
|
||||
public void shouldIncreaseNumberOfAcceptedSpans() {
|
||||
Span context = this.tracer.startTrace("foo");
|
||||
Span context = this.tracer.startTrace(new SpanName("http", "foo"));
|
||||
this.tracer.close(context);
|
||||
this.listener.poll();
|
||||
|
||||
|
||||
@@ -18,13 +18,12 @@ package org.springframework.cloud.sleuth.zipkin.stream;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.stream.Host;
|
||||
import org.springframework.cloud.sleuth.stream.SleuthSink;
|
||||
import org.springframework.cloud.sleuth.stream.Spans;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import zipkin.BinaryAnnotation;
|
||||
import zipkin.Constants;
|
||||
import zipkin.Endpoint;
|
||||
@@ -37,6 +36,8 @@ import zipkin.Span.Builder;
|
||||
@CommonsLog
|
||||
final class SamplingZipkinSpanIterator implements Iterator<zipkin.Span> {
|
||||
|
||||
private static final String MESSAGE_COMPONENT = "message";
|
||||
|
||||
private final Sampler sampler;
|
||||
private final Iterator<Span> delegate;
|
||||
private final Host host;
|
||||
@@ -75,7 +76,7 @@ final class SamplingZipkinSpanIterator implements Iterator<zipkin.Span> {
|
||||
* returns a converted span or null if it is invalid or unsampled.
|
||||
*/
|
||||
zipkin.Span convertAndSample(Span input, Host host) {
|
||||
if (!input.getName().equals("message/" + SleuthSink.INPUT)) {
|
||||
if (!protocolWithAddressMatch(input)) {
|
||||
zipkin.Span result = SamplingZipkinSpanIterator.convert(input, host);
|
||||
if (this.sampler.isSampled(result.traceId)) {
|
||||
return result;
|
||||
@@ -87,6 +88,12 @@ final class SamplingZipkinSpanIterator implements Iterator<zipkin.Span> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean protocolWithAddressMatch(Span input) {
|
||||
SpanName spanName = input.getName();
|
||||
return SamplingZipkinSpanIterator.MESSAGE_COMPONENT.equals(spanName.component) &&
|
||||
("/" + SleuthSink.INPUT).equals(spanName.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given Sleuth span to a Zipkin Span.
|
||||
* <ul>
|
||||
@@ -128,8 +135,8 @@ final class SamplingZipkinSpanIterator implements Iterator<zipkin.Span> {
|
||||
zipkinSpan.parentId(span.getParents().get(0));
|
||||
}
|
||||
zipkinSpan.id(span.getSpanId());
|
||||
if (StringUtils.hasText(span.getName())) {
|
||||
zipkinSpan.name(span.getName());
|
||||
if (!SpanName.NO_NAME.equals(span.getName())) {
|
||||
zipkinSpan.name(span.getName().toString());
|
||||
}
|
||||
return zipkinSpan.build();
|
||||
}
|
||||
|
||||
@@ -15,18 +15,19 @@
|
||||
*/
|
||||
package org.springframework.cloud.sleuth.zipkin.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.stream.Host;
|
||||
import org.springframework.cloud.sleuth.stream.Spans;
|
||||
import zipkin.Sampler;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.stream.Host;
|
||||
import org.springframework.cloud.sleuth.stream.Spans;
|
||||
import zipkin.Sampler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class SamplingZipkinSpanIteratorTests {
|
||||
@@ -36,7 +37,7 @@ public class SamplingZipkinSpanIteratorTests {
|
||||
@Test
|
||||
public void skipsInputSpans() {
|
||||
Spans spans = new Spans(this.host,
|
||||
Collections.singletonList(span("message/sleuth")));
|
||||
Collections.singletonList(span("sleuth")));
|
||||
|
||||
Iterator<zipkin.Span> result = new SamplingZipkinSpanIterator(
|
||||
Sampler.create(1.0f), spans);
|
||||
@@ -52,7 +53,8 @@ public class SamplingZipkinSpanIteratorTests {
|
||||
Iterator<zipkin.Span> result = new SamplingZipkinSpanIterator(
|
||||
Sampler.create(1.0f), spans);
|
||||
|
||||
assertThat(result).extracting(s -> s.name).containsExactly("foo", "bar", "baz");
|
||||
assertThat(result).extracting(s -> s.name).containsExactly(
|
||||
"message:/foo", "message:/bar", "message:/baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,12 +73,13 @@ public class SamplingZipkinSpanIteratorTests {
|
||||
Iterator<zipkin.Span> result = new SamplingZipkinSpanIterator(everyOtherSampler,
|
||||
spans);
|
||||
|
||||
assertThat(result).extracting(s -> s.name).containsExactly("foo", "baz");
|
||||
assertThat(result).extracting(s -> s.name).containsExactly(
|
||||
"message:/foo", "message:/baz");
|
||||
}
|
||||
|
||||
Span span(String name) {
|
||||
Long id = new Random().nextLong();
|
||||
return new Span(1, 3, name, id, Collections.<Long>emptyList(), id, true, true,
|
||||
return new Span(1, 3, new SpanName("message", "/" + name), id, Collections.<Long>emptyList(), id, true, true,
|
||||
"process");
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.springframework.cloud.sleuth.zipkin.stream;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import zipkin.BinaryAnnotation;
|
||||
import zipkin.Endpoint;
|
||||
|
||||
@@ -27,7 +29,7 @@ import org.springframework.cloud.sleuth.stream.Host;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ZipkinMessageListenerTests {
|
||||
Span span = new Span(1, 3, "name", 1L, Collections.<Long>emptyList(), 2L, true, true,
|
||||
Span span = new Span(1, 3, new SpanName("http", "name"), 1L, Collections.<Long>emptyList(), 2L, true, true,
|
||||
"process");
|
||||
Host host = new Host("myservice", "1.2.3.4", 8080);
|
||||
Endpoint endpoint = Endpoint.create("myservice", 1 << 24 | 2 << 16 | 3 << 8 | 4, 8080);
|
||||
@@ -80,7 +82,7 @@ public class ZipkinMessageListenerTests {
|
||||
// TODO: "unknown" bc process id, documented as not nullable, is null in some tests.
|
||||
@Test
|
||||
public void nullProcessIdCoercesToUnknownServiceName() {
|
||||
Span noProcessId = Span.builder().traceId(1L).name("parent").remote(true).build();
|
||||
Span noProcessId = Span.builder().traceId(1L).name(new SpanName("http", "parent")).remote(true).build();
|
||||
|
||||
zipkin.Span result = SamplingZipkinSpanIterator.convert(noProcessId, this.host);
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ package org.springframework.cloud.sleuth.zipkin;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import org.springframework.cloud.sleuth.Log;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
import org.springframework.cloud.sleuth.event.ClientSentEvent;
|
||||
import org.springframework.cloud.sleuth.event.ServerReceivedEvent;
|
||||
@@ -29,9 +31,6 @@ import org.springframework.cloud.sleuth.event.SpanAcquiredEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import zipkin.Annotation;
|
||||
import zipkin.BinaryAnnotation;
|
||||
import zipkin.Constants;
|
||||
@@ -150,8 +149,8 @@ public class ZipkinSpanListener {
|
||||
zipkinSpan.parentId(span.getParents().get(0));
|
||||
}
|
||||
zipkinSpan.id(span.getSpanId());
|
||||
if (StringUtils.hasText(span.getName())) {
|
||||
zipkinSpan.name(span.getName());
|
||||
if (!SpanName.NO_NAME.equals(span.getName())) {
|
||||
zipkinSpan.name(span.getName().toString());
|
||||
}
|
||||
return zipkinSpan.build();
|
||||
}
|
||||
|
||||
@@ -16,14 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -31,6 +27,7 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
@@ -45,6 +42,9 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -70,7 +70,7 @@ public class ZipkinSpanListenerTests {
|
||||
this.test.spans.clear();
|
||||
}
|
||||
|
||||
Span parent = Span.builder().traceId(1L).name("parent").remote(true).build();
|
||||
Span parent = Span.builder().traceId(1L).name(new SpanName("http", "parent")).remote(true).build();
|
||||
|
||||
/** Sleuth timestamps are millisecond granularity while zipkin is microsecond. */
|
||||
@Test
|
||||
@@ -118,7 +118,7 @@ public class ZipkinSpanListenerTests {
|
||||
*/
|
||||
@Test
|
||||
public void spanWithoutAnnotationsLogsComponent() {
|
||||
Span context = this.tracer.startTrace("foo");
|
||||
Span context = this.tracer.startTrace(new SpanName("http", "foo"));
|
||||
this.tracer.close(context);
|
||||
assertEquals(1, this.test.spans.size());
|
||||
assertThat(this.test.spans.get(0).binaryAnnotations.get(0).endpoint.serviceName)
|
||||
@@ -127,7 +127,7 @@ public class ZipkinSpanListenerTests {
|
||||
|
||||
@Test
|
||||
public void rpcAnnotations() {
|
||||
Span context = this.tracer.joinTrace("child", this.parent);
|
||||
Span context = this.tracer.joinTrace(new SpanName("http", "child"), this.parent);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context));
|
||||
this.application.publishEvent(new ServerReceivedEvent(this, this.parent, context));
|
||||
this.application.publishEvent(new ServerSentEvent(this, this.parent, context));
|
||||
|
||||
Reference in New Issue
Block a user