61. Customizations

61.1 HTTP

如果需要定制与 HTTP 相关范围的 Client 端/服务器解析,只需注册brave.http.HttpClientParserbrave.http.HttpServerParser类型的 bean。如果需要 Client 机/服务器采样,则只需注册类型为brave.http.HttpSampler的 bean,并将其命名为sleuthClientSampler代表 Client 机采样器,并将sleuthServerSampler命名为服务器采样器。为方便起见,可以使用@ClientSampler@ServerSampler注解注入适当的 bean 或通过其静态 String NAME字段引用 bean 名称。

查看 Brave 的代码,以查看有关如何制作基于路径的采样器https://github.com/openzipkin/brave/tree/master/instrumentation/http#sampling-policy的示例。

如果要完全重写HttpTracing bean,则可以使用SkipPatternProvider接口检索不应采样的 Span 的 URL Pattern。在下面,您可以看到在服务器端HttpSampler内部使用SkipPatternProvider的示例。

@Configuration
class Config {
  @Bean(name = ServerSampler.NAME)
  HttpSampler myHttpSampler(SkipPatternProvider provider) {
  	Pattern pattern = provider.skipPattern();
  	return new HttpSampler() {

  		@Override
  		public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) {
  			String url = adapter.path(request);
  			boolean shouldSkip = pattern.matcher(url).matches();
  			if (shouldSkip) {
  				return false;
  			}
  			return null;
  		}
  	};
  }
}

61.2 TracingFilter

您还可以修改TracingFilter的行为,该组件负责处理 Importing 的 HTTP 请求并基于 HTTP 响应添加标签。您可以通过注册自己的TracingFilter bean 实例来定制标签或修改响应头。

在下面的示例中,我们注册TracingFilter bean,添加包含当前 Span 跟踪 ID 的ZIPKIN-TRACE-ID响应 Headers,并向 Span 添加带有键custom和值tag的标签。

@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);
	}

}

61.3 自定义服务名称

默认情况下,Sleuth 假定,当您向 Zipkin 发送 Span 时,您希望 Span 的服务名称等于spring.application.name属性的值。但是,情况并非总是如此。在某些情况下,您想为来自应用程序的所有范围显式提供不同的服务名称。为此,可以将以下属性传递给应用程序以覆盖该值(该示例适用于名为myService的服务):

spring.zipkin.service.name: myService

61.4 自定义报告的 Span

在报告 Span 之前(例如,向 Zipkin 报告),您可能需要以某种方式修改该 Span。您可以使用FinishedSpanHandler界面进行操作。

在 Sleuth 中,我们生成具有固定名称的 Span。一些用户希望根据标签的值来修改名称。您可以实现FinishedSpanHandler接口来更改该名称。

以下示例说明如何注册两个实现FinishedSpanHandler的 bean:

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

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

前面的示例导致报告的 Span 的名称在报告之前就更改为foo bar(例如,更改为 Zipkin)。

61.5 主机定位器

Tip

本节是关于从服务发现中定义“主机”。通过服务发现来找到 Zipkin 并不是“ **”。

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

如果启用了发现 Client 端,并且希望从服务注册表中的注册实例中检索主机地址,则必须设置spring.zipkin.locator.discovery.enabled属性(该属性适用于基于 HTTP 和基于流的 Span 报告),如下所示:

spring.zipkin.locator.discovery.enabled: true