12. 自定义

12.1. 禁用默认日志模式

Spring Cloud Sleuth设置默认的日志记录模式。要禁用它,请将spring.sleuth.default-logging-pattern-enabled属性设置为1。spring-doc.cadn.net.cn

12.2。定制程序

With Brave 5.7 you have various options of providing customizers for your project. Brave ships withspring-doc.cadn.net.cn

  • TracingCustomizer - 允许配置插件在构建 Tracing 实例时进行协作。spring-doc.cadn.net.cn

  • CurrentTraceContextCustomizer - 允许配置插件在构建 CurrentTraceContext 实例时进行协作。spring-doc.cadn.net.cn

  • ExtraFieldCustomizer - 允许配置插件在构建 ExtraFieldPropagation.Factory 实例时进行协作。spring-doc.cadn.net.cn

Sleuth 将搜索这些类型的新创建 bean,并自动应用自定义设置。spring-doc.cadn.net.cn

12.3. HTTP

12.3.1。数据策略

The default span data policy for HTTP requests is described in Brave: github.com/openzipkin/brave/tree/master/instrumentation/http#span-data-policyspring-doc.cadn.net.cn

要向span添加不同的数据,需要根据数据收集的时间注册类型为 brave.http.HttpRequestParserbrave.http.HttpResponseParser的bean。spring-doc.cadn.net.cn

bean 名称对应于请求或响应端,以及它是客户端还是服务器。例如,sleuthHttpClientRequestParser 会在客户端请求发送到服务器之前更改收集的内容。spring-doc.cadn.net.cn

为了方便起见@HttpClientRequestParser@HttpClientResponseParser和相应的服务器注释可以用来注入适当的bean或者通过它们的静态StringNAME字段引用bean名。spring-doc.cadn.net.cn

以下是除了默认值之外添加HTTP URL的示例:spring-doc.cadn.net.cn

@Configuration
class Config {
  @Bean(name = { HttpClientRequestParser.NAME, HttpServerRequestParser.NAME })
  HttpRequestParser sleuthHttpServerRequestParser() {
      return (req, context, span) -> {
          HttpRequestParser.DEFAULT.parse(req, context, span);
          String url = req.url();
          if (url != null) {
              span.tag("http.url", url);
          }
      };
  }
}

12.3.2. 采样

如果需要客户端/服务器采样,请注册一个类型为brave.sampler.SamplerFunction<HttpRequest>的bean,并将该bean命名为sleuthHttpClientSampler以进行客户端采样,sleuthHttpServerSampler用于服务器采样。spring-doc.cadn.net.cn

为了方便,@HttpClientSampler@HttpServerSampler 注解可以用于注入合适的bean,或通过其静态 String NAME 字段来引用bean名称。spring-doc.cadn.net.cn

查看 Brave 的代码以了解如何制作基于路径的采样器 github.com/openzipkin/brave/tree/master/instrumentation/http#sampling-policyspring-doc.cadn.net.cn

如果要完全重写HttpTracingbean,可以使用SkipPatternProvider接口来检索URLPattern,用于不需要采样的跨度。下面可以看到SkipPatternProvider在服务器端、Sampler<HttpRequest>中的用法示例。spring-doc.cadn.net.cn

@Configuration
class Config {
  @Bean(name = HttpServerSampler.NAME)
  SamplerFunction<HttpRequest> myHttpSampler(SkipPatternProvider provider) {
      Pattern pattern = provider.skipPattern();
      return request -> {
          String url = request.path();
          boolean shouldSkip = pattern.matcher(url).matches();
          if (shouldSkip) {
              return false;
          }
          return null;
      };
  }
}

12.4. TracingFilter

您还可以修改TracingFilter的行为,它是负责处理输入HTTP请求并将标记基于HTTP响应添加到其中的组件。您可以通过注册TracingFilterbean的自己的实例来自定义标记或修改响应标头。spring-doc.cadn.net.cn

在下面的例子中,我们注册了TracingFilter bean,在ZIPKIN-TRACE-ID响应头中添加了包含当前跨度的跟踪id,以及键为custom、值为tag的标记,添加到跨度中。spring-doc.cadn.net.cn

@Component
@Order(TraceWebServletAutoConfiguration.TRACING_FILTER_ORDER + 1)
class MyFilter extends GenericFilterBean {

    private final Tracer tracer;

    MyFilter(Tracer tracer) {
        this.tracer = tracer;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        Span currentSpan = this.tracer.currentSpan();
        if (currentSpan == null) {
            chain.doFilter(request, response);
            return;
        }
        // for readability we're returning trace id in a hex form
        ((HttpServletResponse) response).addHeader("ZIPKIN-TRACE-ID",
                currentSpan.context().traceIdString());
        // we can also add some custom tags
        currentSpan.tag("custom", "tag");
        chain.doFilter(request, response);
    }

}

12.5. 消息传递

Sleuth automatically configures the MessagingTracing bean which serves as a foundation for Messaging instrumentation such as Kafka or JMS.spring-doc.cadn.net.cn

如果需要对消息传递跟踪的生产者/使用者采样进行自定义,只需注册类型为brave.sampler.SamplerFunction<MessagingRequest>的bean,并将该bean命名为sleuthProducerSampler作为生产者采样器和sleuthConsumerSampler作为使用者采样器。
spring-doc.cadn.net.cn

为了方便,@ProducerSampler@ConsumerSampler 注解可以用于注入合适的bean,或通过其静态 String NAME 字段来引用bean名称。spring-doc.cadn.net.cn

例如:这是一个采样器,每秒对 100 个消费者请求进行跟踪,除了“alerts”通道。其他请求将使用由 Tracing 组件提供的全局速率。spring-doc.cadn.net.cn

@Configuration
class Config {
}

12.5.1。自定义消息跨度

为了更改默认的span名称和标签,只需注册一个类型为MessageSpanCustomizer的bean。您也可以 覆盖现有的DefaultMessageSpanCustomizer以扩展现有的行为。spring-doc.cadn.net.cn

@Component
  class MyMessageSpanCustomizer extends DefaultMessageSpanCustomizer {
      @Override
      public SpanCustomizer customizeHandle(SpanCustomizer spanCustomizer,
              Message<?> message, MessageChannel messageChannel) {
          return super.customizeHandle(spanCustomizer, message, messageChannel)
                  .name("changedHandle")
                  .tag("handleKey", "handleValue")
                  .tag("channelName", channelName(messageChannel));
      }

      @Override
      public SpanCustomizer customizeSend(SpanCustomizer spanCustomizer,
              Message<?> message, MessageChannel messageChannel) {
          return super.customizeSend(spanCustomizer, message, messageChannel)
                  .name("changedSend")
                  .tag("sendKey", "sendValue")
                  .tag("channelName", channelName(messageChannel));
      }
  }

12.6. RPC

Sleuth 自动配置了 0 Bean,它是像 gRPC 或 Dubbo 这样的 RPC 仪表化的基础。 spring-doc.cadn.net.cn

如果需要自定义RPC跟踪的客户端/服务器采样, 只需注册一个类型为brave.sampler.SamplerFunction<RpcRequest>的bean,并 将该bean命名为sleuthRpcClientSampler用于客户端采样器和 sleuthRpcServerSampler用于服务器采样器。spring-doc.cadn.net.cn

为了方便,@RpcClientSampler@RpcServerSampler 注解可以用于注入合适的bean,或通过其静态 String NAME 字段来引用bean名称。spring-doc.cadn.net.cn

例如,此处的采样器会以每秒100个的速度追踪"GetUserToken"服务器请求。 这不会为健康检查服务的请求启动新的追踪。其他请求将使用全局采样配置。spring-doc.cadn.net.cn

@Configuration
class Config {
  @Bean(name = RpcServerSampler.NAME)
  SamplerFunction<RpcRequest> myRpcSampler() {
      Matcher<RpcRequest> userAuth = and(serviceEquals("users.UserService"),
              methodEquals("GetUserToken"));
      return RpcRuleSampler.newBuilder()
              .putRule(serviceEquals("grpc.health.v1.Health"), Sampler.NEVER_SAMPLE)
              .putRule(userAuth, RateLimitingSampler.create(100)).build();
  }
}

有关更多信息,请参阅github.com/openzipkin/brave/tree/master/instrumentation/rpc#sampling-policyspring-doc.cadn.net.cn

12.7. 自定义服务名

默认情况下,Sleuth 假定当您将一个跨度发送到 Zipkin 时,您希望该跨度的服务名称等于 spring.application.name 属性的值。 但情况并非总是如此。 有时您希望为来自您的应用程序的所有跨度显式提供一个不同的服务名称。 为了实现这一点,您可以将以下属性传递给您的应用程序以覆盖该值(示例针对名为 myService 的服务):spring-doc.cadn.net.cn

spring.zipkin.service.name: myService

12.8. 报告跨度的自定义

在报告跨度(例如,向 Zipkin 报告)之前,您可能希望以某种方式修改该跨度。
您可以实现一个 SpanHandler 来做到这一点。spring-doc.cadn.net.cn

在 Sleuth 中,我们使用固定名称生成跨度。一些用户希望根据标记的值来修改该名称。您可以实现 SpanHandler 接口来更改该名称。spring-doc.cadn.net.cn

以下示例展示了如何注册两个实现SpanHandler的bean:spring-doc.cadn.net.cn

@Bean
SpanHandler handlerOne() {
    return new SpanHandler() {
        @Override
        public boolean end(TraceContext traceContext, MutableSpan span,
                Cause cause) {
            span.name("foo");
            return true; // keep this span
        }
    };
}

@Bean
SpanHandler handlerTwo() {
    return new SpanHandler() {
        @Override
        public boolean end(TraceContext traceContext, MutableSpan span,
                Cause cause) {
            span.name(span.name() + " bar");
            return true; // keep this span
        }
    };
}

前面的示例会导致在报告之前(例如,到Zipkin)将报告跨度的名称更改为foo barspring-doc.cadn.net.cn

12.9. 主机定位

本节介绍如何通过服务发现来定义主机。这不是指通过服务发现寻找Zipkin。

要定义与特定跨度对应的主机,我们需要解析主机名和端口。默认方法是从服务器属性中获取这些值。如果未设置,则尝试从网络接口中检索主机名。spring-doc.cadn.net.cn

如果您启用了发现客户端并希望从服务注册表中已注册的实例获取主机地址,则必须设置spring.zipkin.locator.discovery.enabled属性(该属性适用于基于HTTP和Stream的跨度报告),如下所示:spring-doc.cadn.net.cn

spring.zipkin.locator.discovery.enabled: true