59. 自定义

59.1 HTTP

如果需要自定义 client/server 解析 HTTP 相关 spans,只需注册或brave.http.HttpServerParser类型的 bean。如果需要 client /server sampling,只需注册一个类型为brave.http.HttpSampler的 bean,name 为 client 采样器的 bean sleuthClientSampler,为服务器采样器注册sleuthServerSampler。为方便起见,@ClientSampler@ServerSampler 注释可用于注入正确的 beans 或通过其静态 String NAME字段引用 bean 名称。

查看 Brave 的 code 以查看如何制作 path-based 采样器的示例https://github.com/openzipkin/brave/tree/master/instrumentation/http#sampling-policy

如果要完全__rite bean,可以使用SkipPatternProvider接口检索应该未采样的_sp的 URL Pattern。您可以在下面看到服务器端SkipPatternProvider的使用_示例HttpSampler

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

59.2 TracingFilter

您还可以修改TracingFilter的行为,TracingFilter是负责处理输入 HTTP 请求并基于 HTTP 响应添加标记的 component。您可以通过注册自己的TracingFilter bean 实例来自定义标记或修改响应 headers。

在下面的示例中,我们注册TracingFilter bean,添加包含当前 Span 的跟踪 ID 的ZIPKIN-TRACE-ID响应头,并将 key custom和 value tag添加到 span。

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

59.3 自定义服务 name

默认情况下,Sleuth 假设,当您将 span 发送到 Zipkin 时,您希望 span 的服务 name 等于spring.application.name property 的 value。但情况并非总是如此。在某些情况下,您希望为来自 application 的所有 spans 显式提供不同的服务 name。为此,您可以将以下 property 传递给 application 以覆盖该 value(example 用于名为myService的服务):

spring.zipkin.service.name: myService

59.4 报告 Spans 的自定义

在报告 spans(对于 example,到 Zipkin)之前,您可能希望以某种方式修改 span。您可以使用SpanAdjuster接口执行此操作。

在 Sleuth 中,我们生成带有固定 name 的 spans。有些用户希望根据标签的值修改 name。您可以实现SpanAdjuster接口来更改该 name。

以下 example 显示了如何注册实现SpanAdjuster的两个 beans:

@Bean SpanAdjuster adjusterOne() {
	return span -> span.toBuilder().name("foo").build();
}

@Bean SpanAdjuster adjusterTwo() {
	return span -> span.toBuilder().name(span.name() + " bar").build();
}

前面的 example 导致在报告之前将报告的 span 的 name 更改为foo bar(对于 example,为 Zipkin)。

59.5 Host Locator

本节介绍如何从服务发现中定义host。通过服务发现找到 Zipkin 并不是**。

要定义与特定 span 对应的 host,我们需要解析 host name 和 port。默认方法是从服务器 properties 中获取这些值。如果没有设置,我们尝试从网络接口检索 host name。

如果您启用了发现 client 并且更喜欢从服务注册表中的已注册实例检索 host 地址,则必须设置spring.zipkin.locator.discovery.enabled property(它适用于 HTTP-based 和 Stream-based span 报告),如下所示:

spring.zipkin.locator.discovery.enabled: true