Make span name and process id properly optional
This commit is contained in:
@@ -53,9 +53,8 @@ public interface Trace {
|
||||
|
||||
String SPAN_ID_NAME = "X-Span-Id";
|
||||
String TRACE_ID_NAME = "X-Trace-Id";
|
||||
String SPAN_NAME_NAME = "X-Span-Name";
|
||||
String PARENT_ID_NAME = "X-Parent-Id";
|
||||
String PROCESS_ID_NAME = "X-Process-Id";
|
||||
String NOT_SAMPLED_NAME = "X-Not-Sampled";
|
||||
|
||||
/**
|
||||
* Creates a trace scope wrapping a new span.
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import static org.springframework.cloud.sleuth.Trace.NOT_SAMPLED_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PARENT_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PROCESS_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_NAME_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.TRACE_ID_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -37,27 +36,28 @@ import org.springframework.messaging.Message;
|
||||
public class SpanMessageHeaders {
|
||||
|
||||
public static Message<?> addSpanHeaders(Message<?> message, Span span) {
|
||||
if (span==null) {
|
||||
if (span == null) {
|
||||
if (!message.getHeaders().containsKey(NOT_SAMPLED_NAME)) {
|
||||
return MessageBuilder.fromMessage(message).setHeader(NOT_SAMPLED_NAME, "")
|
||||
.build();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
Map<String, String> headers = new HashMap<String, String>();
|
||||
addHeader(headers, TRACE_ID_NAME, span.getTraceId());
|
||||
addHeader(headers, SPAN_ID_NAME, span.getSpanId());
|
||||
addHeader(headers, PARENT_ID_NAME, getFirst(span.getParents()));
|
||||
addHeader(headers, SPAN_NAME_NAME, span.getName());
|
||||
addHeader(headers, PROCESS_ID_NAME, span.getProcessId());
|
||||
return MessageBuilder.fromMessage(message).copyHeaders(headers).build();
|
||||
}
|
||||
|
||||
private static void addHeader(Map<String, String> headers, String name, String value) {
|
||||
if (value!=null) {
|
||||
if (value != null) {
|
||||
headers.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getFirst(List<String> parents) {
|
||||
return parents==null || parents.isEmpty() ? null : parents.get(0);
|
||||
return parents == null || parents.isEmpty() ? null : parents.get(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import static org.springframework.cloud.sleuth.Trace.NOT_SAMPLED_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PARENT_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PROCESS_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_NAME_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.TRACE_ID_NAME;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
@@ -47,7 +46,7 @@ public class TraceChannelInterceptor extends ChannelInterceptorAdapter {
|
||||
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
if (TraceContextHolder.isTracing()) {
|
||||
if (TraceContextHolder.isTracing() || message.getHeaders().containsKey(NOT_SAMPLED_NAME)) {
|
||||
return SpanMessageHeaders.addSpanHeaders(message, TraceContextHolder.getCurrentSpan());
|
||||
}
|
||||
String spanId = getHeader(message, SPAN_ID_NAME);
|
||||
@@ -60,14 +59,6 @@ public class TraceChannelInterceptor extends ChannelInterceptorAdapter {
|
||||
|
||||
MilliSpanBuilder span = MilliSpan.builder().traceId(traceId).spanId(spanId);
|
||||
String parentId = getHeader(message, PARENT_ID_NAME);
|
||||
String processId = getHeader(message, PROCESS_ID_NAME);
|
||||
String spanName = getHeader(message, SPAN_NAME_NAME);
|
||||
if (spanName != null) {
|
||||
span.name(spanName);
|
||||
}
|
||||
if (processId != null) {
|
||||
span.processId(processId);
|
||||
}
|
||||
if (parentId != null) {
|
||||
span.parent(parentId);
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import static org.springframework.cloud.sleuth.Trace.PARENT_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PROCESS_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_NAME_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.TRACE_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.TraceContextHolder.getCurrentSpan;
|
||||
import static org.springframework.cloud.sleuth.TraceContextHolder.setCurrentSpan;
|
||||
@@ -144,15 +142,10 @@ implements ExecutorChannelInterceptor {
|
||||
|
||||
setHeader(headers, SPAN_ID_NAME, this.span.getSpanId());
|
||||
setHeader(headers, TRACE_ID_NAME, this.span.getTraceId());
|
||||
setHeader(headers, SPAN_NAME_NAME, this.span.getName());
|
||||
String parentId = getParentId(getCurrentSpan());
|
||||
if (parentId != null) {
|
||||
setHeader(headers, PARENT_ID_NAME, parentId);
|
||||
}
|
||||
String processId = this.span.getProcessId();
|
||||
if (processId != null) {
|
||||
setHeader(headers, PROCESS_ID_NAME, processId);
|
||||
}
|
||||
this.messageHeaders = new MessageHeaders(headers);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import static org.springframework.cloud.sleuth.Trace.NOT_SAMPLED_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PARENT_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PROCESS_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_NAME_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.TRACE_ID_NAME;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
@@ -82,13 +81,15 @@ public class TraceFilter extends OncePerRequestFilter {
|
||||
throws ServletException, IOException {
|
||||
|
||||
String uri = this.urlPathHelper.getPathWithinApplication(request);
|
||||
boolean skip = this.skipPattern.matcher(uri).matches();
|
||||
boolean skip = this.skipPattern.matcher(uri).matches() || getHeader(request, response, NOT_SAMPLED_NAME)!=null;
|
||||
|
||||
TraceScope traceScope = (TraceScope) request.getAttribute(TRACE_REQUEST_ATTR);
|
||||
if (traceScope != null) {
|
||||
this.trace.continueSpan(traceScope.getSpan());
|
||||
}
|
||||
else if (!skip) {
|
||||
else if (skip) {
|
||||
addToResponseIfNotPresent(response, NOT_SAMPLED_NAME, "");
|
||||
} else {
|
||||
String spanId = getHeader(request, response, SPAN_ID_NAME);
|
||||
String traceId = getHeader(request, response, TRACE_ID_NAME);
|
||||
String name = "http" + uri;
|
||||
@@ -97,14 +98,6 @@ public class TraceFilter extends OncePerRequestFilter {
|
||||
MilliSpanBuilder span = MilliSpan.builder().traceId(traceId)
|
||||
.spanId(spanId);
|
||||
String parentId = getHeader(request, response, PARENT_ID_NAME);
|
||||
String processId = getHeader(request, response, PROCESS_ID_NAME);
|
||||
String parentName = getHeader(request, response, SPAN_NAME_NAME);
|
||||
if (parentName != null) {
|
||||
span.name(parentName);
|
||||
}
|
||||
if (processId != null) {
|
||||
span.processId(processId);
|
||||
}
|
||||
if (parentId != null) {
|
||||
span.parent(parentId);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
package org.springframework.cloud.sleuth.instrument.web.client;
|
||||
|
||||
import static org.springframework.cloud.sleuth.Trace.PARENT_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.PROCESS_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_NAME_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.TRACE_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.TraceContextHolder.getCurrentSpan;
|
||||
import static org.springframework.cloud.sleuth.TraceContextHolder.isTracing;
|
||||
@@ -65,9 +63,7 @@ ApplicationEventPublisherAware {
|
||||
}
|
||||
setHeader(request, SPAN_ID_NAME, getCurrentSpan().getSpanId());
|
||||
setHeader(request, TRACE_ID_NAME, getCurrentSpan().getTraceId());
|
||||
setHeader(request, SPAN_NAME_NAME, getCurrentSpan().getName());
|
||||
setHeader(request, PARENT_ID_NAME, getParentId(getCurrentSpan()));
|
||||
setHeader(request, PROCESS_ID_NAME, getCurrentSpan().getProcessId());
|
||||
publish(new ClientSentEvent(this, getCurrentSpan()));
|
||||
return new TraceHttpResponse(this, execution.execute(request, body));
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.springframework.cloud.sleuth.Trace.NOT_SAMPLED_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.SPAN_ID_NAME;
|
||||
import static org.springframework.cloud.sleuth.Trace.TRACE_ID_NAME;
|
||||
|
||||
@@ -48,7 +50,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes=App.class)
|
||||
@SpringApplicationConfiguration(classes = App.class)
|
||||
@IntegrationTest
|
||||
@DirtiesContext
|
||||
public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
@@ -78,6 +80,16 @@ public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
this.channel.unsubscribe(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSpanCreation() {
|
||||
this.channel.send(MessageBuilder.withPayload("hi").setHeader(NOT_SAMPLED_NAME, "")
|
||||
.build());
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
String spanId = this.message.getHeaders().get(SPAN_ID_NAME, String.class);
|
||||
assertNull("spanId was not null", spanId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpanCreation() {
|
||||
this.channel.send(MessageBuilder.withPayload("hi").build());
|
||||
@@ -92,7 +104,8 @@ public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
|
||||
@Test
|
||||
public void testHeaderCreation() {
|
||||
TraceScope traceScope = this.trace.startSpan("testSendMessage", new AlwaysSampler(), null);
|
||||
TraceScope traceScope = this.trace.startSpan("testSendMessage",
|
||||
new AlwaysSampler(), null);
|
||||
this.channel.send(MessageBuilder.withPayload("hi").build());
|
||||
traceScope.close();
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
@@ -88,7 +88,7 @@ public class TraceRestTemplateInterceptorTests {
|
||||
public Map<String, String> home(@RequestHeader HttpHeaders headers) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
addHeaders(map, headers, Trace.SPAN_ID_NAME, Trace.TRACE_ID_NAME,
|
||||
Trace.PARENT_ID_NAME, Trace.SPAN_NAME_NAME, Trace.PROCESS_ID_NAME);
|
||||
Trace.PARENT_ID_NAME);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.cloud.sleuth.event.SpanStartedEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanStoppedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.github.kristofa.brave.SpanCollector;
|
||||
import com.twitter.zipkin.gen.Annotation;
|
||||
@@ -64,7 +65,7 @@ public class ZipkinSpanListener {
|
||||
@EventListener
|
||||
@Order(0)
|
||||
public void start(SpanStartedEvent event) {
|
||||
if (event.getParent()!=null && event.getParent().isRemote()) {
|
||||
if (event.getParent() != null && event.getParent().isRemote()) {
|
||||
event.getParent().addTimelineAnnotation(zipkinCoreConstants.SERVER_RECV);
|
||||
}
|
||||
event.getSpan().addTimelineAnnotation("start");
|
||||
@@ -85,7 +86,7 @@ public class ZipkinSpanListener {
|
||||
@EventListener
|
||||
@Order(0)
|
||||
public void stop(SpanStoppedEvent event) {
|
||||
if (event.getParent()!=null && event.getParent().isRemote()) {
|
||||
if (event.getParent() != null && event.getParent().isRemote()) {
|
||||
event.getParent().addTimelineAnnotation(zipkinCoreConstants.SERVER_SEND);
|
||||
this.spanCollector.collect(convert(event.getParent()));
|
||||
}
|
||||
@@ -110,17 +111,20 @@ public class ZipkinSpanListener {
|
||||
|
||||
Endpoint ep = new Endpoint(address, port.shortValue(), serviceName);
|
||||
List<Annotation> annotationList = createZipkinAnnotations(span, ep);
|
||||
List<BinaryAnnotation> binaryAnnotationList = createZipkinBinaryAnnotations(span, ep);
|
||||
List<BinaryAnnotation> binaryAnnotationList = createZipkinBinaryAnnotations(span,
|
||||
ep);
|
||||
zipkinSpan.setTrace_id(hash(span.getTraceId()));
|
||||
if (span.getParents().size() > 0) {
|
||||
if (span.getParents().size() > 1) {
|
||||
log.error("zipkin doesn't support spans with multiple parents. Omitting " +
|
||||
"other parents for " + span);
|
||||
log.error("zipkin doesn't support spans with multiple parents. Omitting "
|
||||
+ "other parents for " + span);
|
||||
}
|
||||
zipkinSpan.setParent_id(hash(span.getParents().get(0)));
|
||||
}
|
||||
zipkinSpan.setId(hash(span.getSpanId()));
|
||||
zipkinSpan.setName(span.getName());
|
||||
if (StringUtils.hasText(span.getName())) {
|
||||
zipkinSpan.setName(span.getName());
|
||||
}
|
||||
zipkinSpan.setAnnotations(annotationList);
|
||||
zipkinSpan.setBinary_annotations(binaryAnnotationList);
|
||||
return zipkinSpan;
|
||||
@@ -130,8 +134,9 @@ public class ZipkinSpanListener {
|
||||
Integer port;
|
||||
if (this.serverProperties.getPort() != null) {
|
||||
port = this.serverProperties.getPort();
|
||||
} else {
|
||||
port = 8080; //TODO: support random port
|
||||
}
|
||||
else {
|
||||
port = 8080; // TODO: support random port
|
||||
}
|
||||
return port;
|
||||
}
|
||||
@@ -140,8 +145,9 @@ public class ZipkinSpanListener {
|
||||
String address;
|
||||
if (this.serverProperties.getAddress() != null) {
|
||||
address = this.serverProperties.getAddress().getHostAddress();
|
||||
} else {
|
||||
address = "127.0.0.1"; //TODO: get address from config
|
||||
}
|
||||
else {
|
||||
address = "127.0.0.1"; // TODO: get address from config
|
||||
}
|
||||
return ipAddressToInt(address);
|
||||
}
|
||||
@@ -150,18 +156,19 @@ public class ZipkinSpanListener {
|
||||
String serviceName;
|
||||
if (span.getProcessId() != null) {
|
||||
serviceName = span.getProcessId().toLowerCase();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
serviceName = this.appName;
|
||||
}
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
|
||||
private int ipAddressToInt(final String ip) {
|
||||
InetAddress inetAddress = null;
|
||||
try {
|
||||
inetAddress = InetAddress.getByName(ip);
|
||||
} catch (final UnknownHostException e) {
|
||||
}
|
||||
catch (final UnknownHostException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return ByteBuffer.wrap(inetAddress.getAddress()).getInt();
|
||||
@@ -170,25 +177,27 @@ public class ZipkinSpanListener {
|
||||
/**
|
||||
* Add annotations from the sleuth Span.
|
||||
*/
|
||||
private List<Annotation> createZipkinAnnotations(Span span,
|
||||
Endpoint endpoint) {
|
||||
private List<Annotation> createZipkinAnnotations(Span span, Endpoint endpoint) {
|
||||
List<Annotation> annotationList = new ArrayList<>();
|
||||
|
||||
long srTime = 0, csTime = 0;
|
||||
// add sleuth time annotation
|
||||
for (TimelineAnnotation ta : span.getTimelineAnnotations()) {
|
||||
Annotation zipkinAnnotation = createZipkinAnnotation(ta.getMsg(), ta.getTime(), 0, endpoint, true);
|
||||
Annotation zipkinAnnotation = createZipkinAnnotation(ta.getMsg(),
|
||||
ta.getTime(), 0, endpoint, true);
|
||||
if (zipkinCoreConstants.SERVER_RECV.equals(ta.getMsg())) {
|
||||
srTime = ta.getTime();
|
||||
}
|
||||
if (zipkinCoreConstants.SERVER_SEND.equals(ta.getMsg()) && srTime!=0) {
|
||||
zipkinAnnotation.setDuration(new Long(ta.getTime() - srTime).intValue()*1000);
|
||||
if (zipkinCoreConstants.SERVER_SEND.equals(ta.getMsg()) && srTime != 0) {
|
||||
zipkinAnnotation
|
||||
.setDuration(new Long(ta.getTime() - srTime).intValue() * 1000);
|
||||
}
|
||||
if (zipkinCoreConstants.CLIENT_SEND.equals(ta.getMsg())) {
|
||||
csTime = ta.getTime();
|
||||
}
|
||||
if (zipkinCoreConstants.CLIENT_RECV.equals(ta.getMsg()) && csTime!=0) {
|
||||
zipkinAnnotation.setDuration(new Long(ta.getTime() - csTime).intValue()*1000);
|
||||
if (zipkinCoreConstants.CLIENT_RECV.equals(ta.getMsg()) && csTime != 0) {
|
||||
zipkinAnnotation
|
||||
.setDuration(new Long(ta.getTime() - csTime).intValue() * 1000);
|
||||
}
|
||||
annotationList.add(zipkinAnnotation);
|
||||
}
|
||||
@@ -209,7 +218,8 @@ public class ZipkinSpanListener {
|
||||
binaryAnn.setKey(e.getKey());
|
||||
try {
|
||||
binaryAnn.setValue(e.getValue().getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
log.error("Error encoding string as UTF-8", ex);
|
||||
}
|
||||
binaryAnn.setHost(endpoint);
|
||||
@@ -221,20 +231,21 @@ public class ZipkinSpanListener {
|
||||
/**
|
||||
* Create an annotation with the correct times and endpoint.
|
||||
*
|
||||
* @param value Annotation value
|
||||
* @param time timestamp will be extracted
|
||||
* @param endpoint the endpoint this annotation will be associated with.
|
||||
* @param value Annotation value
|
||||
* @param time timestamp will be extracted
|
||||
* @param endpoint the endpoint this annotation will be associated with.
|
||||
* @param sendRequest use the first or last timestamp.
|
||||
*/
|
||||
private static Annotation createZipkinAnnotation(String value, long time, int duration,
|
||||
Endpoint endpoint, boolean sendRequest) {
|
||||
private static Annotation createZipkinAnnotation(String value, long time,
|
||||
int duration, Endpoint endpoint, boolean sendRequest) {
|
||||
Annotation annotation = new Annotation();
|
||||
annotation.setHost(endpoint);
|
||||
|
||||
// Zipkin is in microseconds
|
||||
if (sendRequest) {
|
||||
annotation.setTimestamp(time * 1000);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
annotation.setTimestamp(time * 1000);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user