diff --git a/spring-cloud-sleuth.html b/spring-cloud-sleuth.html index ba05e91bf..6088fd6b9 100644 --- a/spring-cloud-sleuth.html +++ b/spring-cloud-sleuth.html @@ -446,8 +446,12 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • toString() method
  • -
  • Span Data as Messages +
  • Span Data as Messages
  • +
  • Customizations @@ -767,6 +771,11 @@ latency in your applications. Sleuth is written to not log too much, and to not rest template, scheduled actions, message channels, zuul filters, feign client).

  • +

    Sleuth includes default logic to join a trace across http or messaging boundaries. For example, http propagation +works via Zipkin-compatible request headers. This propagation logic is defined and customized via +SpanInjector and SpanExtractor implementations.

    +
  • +
  • Provides simple metrics of accepted / dropped spans.

  • @@ -803,7 +812,7 @@ If using Zipkin or Stream, configure the percentage of spans exported using the SLF4J MDC is always set and logback users will immediately see the trace and span ids in logs per the example above. Other logging systems have to configure their own formatter to get the same result. The default is - logging.pattern.level set to %clr(%5p) %clr([${spring.application.name:},%X{X-Trace-Id:-},%X{X-Span-Id:-},%X{X-Span-Export:-}]){yellow} + logging.pattern.level set to %clr(%5p) %clr([${spring.application.name:},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]){yellow} (this is a Spring Boot feature for logback users). This means that if you’re not using SLF4J this pattern WILL NOT be automatically applied. @@ -1190,6 +1199,151 @@ adding a Channel Binder implementation automatically turn your app into a producer of messages with payload type Spans.

    + + +
    +

    Customizations

    +
    +
    +

    Thanks to the SpanInjector and SpanExtractor you can customize the way spans +are created and propagated.

    +
    +
    +

    There are currently two built-in ways to pass tracing information between processes:

    +
    +
    +
      +
    • +

      via Spring Integration

      +
    • +
    • +

      via HTTP

      +
    • +
    +
    +
    +

    Span ids are extracted from Zipkin-compatible (B3) headers (either Message +or HTTP headers), to start or join an existing trace. Trace information is +injected into any outbound requests so the next hop can extract them.

    +
    +
    +

    Spring Integration

    +
    +

    For Spring Integration these are the beans responsible for creation of a Span from a Message + and filling in the MessageBuilder with tracing information.

    +
    +
    +
    +
    	@Bean
    +	public SpanExtractor<Message> messagingSpanExtractor() {
    +		...
    +	}
    +
    +	@Bean
    +	public SpanInjector<MessageBuilder> messagingSpanInjector() {
    +		...
    +	}
    +
    +
    +
    +

    You can override them by providing your own implementation and by adding a @Primary annotation +to your bean definition.

    +
    +
    +
    +

    HTTP

    +
    +

    For HTTP these are the beans responsible for creation of a Span from a HttpServletRequest + and filling in the HttpServletResponse with tracing information.

    +
    +
    +
    +
    @Bean
    +public SpanExtractor<HttpServletRequest> httpServletRequestSpanExtractor() {
    +    ...
    +}
    +
    +@Bean
    +public SpanInjector<HttpServletResponse> httpServletResponseSpanInjector() {
    +	...
    +}
    +
    +
    +
    +

    You can override them by providing your own implementation and by adding a @Primary annotation +to your bean definition.

    +
    +
    +
    +

    Example

    +
    +

    Let’s assume that instead of the standard Zipkin compatible tracing HTTP header names +you have

    +
    +
    +
      +
    • +

      for trace id - correlationId

      +
    • +
    • +

      for span id - mySpanId

      +
    • +
    +
    +
    +

    This is a an example of a SpanExtractor

    +
    +
    +
    +
    static class CustomHttpServletRequestSpanExtractor implements SpanExtractor<HttpServletRequest> {
    +
    +	@Override
    +	public Span joinTrace(HttpServletRequest carrier) {
    +		long traceId = Span.hexToId(carrier.getHeader("correlationId"));
    +		long spanId = Span.hexToId(carrier.getHeader("mySpanId"));
    +		// extract all necessary headers
    +		Span.SpanBuilder builder = Span.builder().traceId(traceId).spanId(spanId);
    +		// build rest of the Span
    +		return builder.build();
    +	}
    +}
    +
    +
    +
    +

    The following SpanInjector could be created

    +
    +
    +
    +
    static class CustomHttpServletResponseSpanInjector implements SpanInjector<HttpServletResponse> {
    +
    +	@Override
    +	public void inject(Span span, HttpServletResponse carrier) {
    +		carrier.addHeader("correlationId", Span.idToHex(span.getTraceId()));
    +		carrier.addHeader("mySpanId", Span.idToHex(span.getSpanId()));
    +		// inject the rest of Span values to the header
    +	}
    +}
    +
    +
    +
    +

    And you could register them like this:

    +
    +
    +
    +
    @Bean
    +@Primary
    +SpanExtractor<HttpServletRequest> customHttpServletRequestSpanExtractor() {
    +	return new CustomHttpServletRequestSpanExtractor();
    +}
    +
    +@Bean
    +@Primary
    +SpanInjector<HttpServletResponse> customHttpServletResponseSpanInjector() {
    +	return new CustomHttpServletResponseSpanInjector();
    +}
    +
    +
    +

    Zipkin Consumer

    @@ -1534,7 +1688,7 @@ To disable Zuul support set the spring.sleuth.zuul.enabled property