下面列出了org.springframework.http.converter.xml.SourceHttpMessageConverter#brave.http.HttpTracing 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void run(TranslationServiceConfiguration configuration,
Environment environment) {
/* START TRACING INSTRUMENTATION */
final var sender = URLConnectionSender.newBuilder()
.endpoint(configuration.getZipkinEndpoint()).build();
final var reporter = AsyncReporter.builder(sender).build();
final var tracing = Tracing.newBuilder().localServiceName("translation-service")
.sampler(Sampler.ALWAYS_SAMPLE).spanReporter(reporter).build();
final var httpTracing = HttpTracing.newBuilder(tracing).build();
final var jerseyTracingFilter = TracingApplicationEventListener
.create(httpTracing);
environment.jersey().register(jerseyTracingFilter);
/* END TRACING INSTRUMENTATION */
final var repository = new TranslationRepository();
final var translationResource = new TranslationResource(repository);
environment.jersey().register(translationResource);
final var healthCheck = new TranslationServiceHealthCheck();
environment.healthChecks().register("translation-service", healthCheck);
}
/**
* Shows bean aliases work to configure the same instance for both client and server
*/
@Test
public void configuresUserProvidedHttpClientAndServerParser() {
contextRunner().withUserConfiguration(HttpParserConfig.class).run((context) -> {
HttpRequestParser serverRequestParser = context.getBean(HttpTracing.class)
.serverRequestParser();
HttpResponseParser serverResponseParser = context.getBean(HttpTracing.class)
.serverResponseParser();
HttpRequestParser clientRequestParser = context.getBean(HttpTracing.class)
.clientRequestParser();
HttpResponseParser clientResponseParser = context.getBean(HttpTracing.class)
.clientResponseParser();
then(clientRequestParser).isSameAs(HttpParserConfig.REQUEST_PARSER);
then(clientResponseParser).isSameAs(HttpParserConfig.RESPONSE_PARSER);
then(serverRequestParser).isSameAs(HttpParserConfig.REQUEST_PARSER);
then(serverResponseParser).isSameAs(HttpParserConfig.RESPONSE_PARSER);
});
}
@Test public void clientParser() {
context = new XmlBeans(""
+ "<bean id=\"httpTracing\" class=\"brave.spring.beans.HttpTracingFactoryBean\">\n"
+ " <property name=\"tracing\">\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".TRACING\"/>\n"
+ " </property>\n"
+ " <property name=\"clientParser\">\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".CLIENT_PARSER\"/>\n"
+ " </property>\n"
+ "</bean>"
);
assertThat(context.getBean("httpTracing", HttpTracing.class))
.extracting("clientParser")
.isEqualTo(CLIENT_PARSER);
}
@Test public void customizers() {
context = new XmlBeans(""
+ "<bean id=\"httpTracing\" class=\"brave.spring.beans.HttpTracingFactoryBean\">\n"
+ " <property name=\"tracing\">\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".TRACING\"/>\n"
+ " </property>\n"
+ " <property name=\"customizers\">\n"
+ " <list>\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".CUSTOMIZER_ONE\"/>\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".CUSTOMIZER_TWO\"/>\n"
+ " </list>\n"
+ " </property>"
+ "</bean>"
);
context.getBean("httpTracing", HttpTracing.class);
verify(CUSTOMIZER_ONE).customize(any(HttpTracing.Builder.class));
verify(CUSTOMIZER_TWO).customize(any(HttpTracing.Builder.class));
}
@Override
public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {
final Optional<HttpTracing> tracing = zipkinBundle.getHttpTracing();
final Client client;
if (tracing.isPresent()) {
client =
new ZipkinClientBuilder(environment, tracing.get())
.build(configuration.getZipkinClient());
} else {
final ZipkinClientConfiguration clientConfig = configuration.getZipkinClient();
client =
new JerseyClientBuilder(environment)
.using(clientConfig)
.build(clientConfig.getServiceName());
}
// Register resources
final HelloWorldResource resource = new HelloWorldResource(client);
environment.jersey().register(resource);
}
/**
* Build a new {@link HttpTracing} instance for interfacing with Zipkin
*
* @param environment Environment
* @return Brave instance
*/
@Override
public Optional<HttpTracing> build(final Environment environment) {
if (!isEnabled()) {
LOGGER.warn("Zipkin tracing is disabled");
return Optional.empty();
}
final KafkaSender sender =
KafkaSender.newBuilder()
.bootstrapServers(bootstrapServers)
.topic(topic)
.overrides(overrides)
.build();
LOGGER.info("Sending spans to Kafka topic \"{}\" at: {}", topic, bootstrapServers);
return buildTracing(environment, sender);
}
@GET
@Path("/search")
@Produces(MediaType.APPLICATION_JSON)
public JsonObject search(@QueryParam("q") final String query, @Context final TracerContext tracing) throws Exception {
final CloseableHttpClient httpclient = TracingHttpClientBuilder
.create(tracing.unwrap(HttpTracing.class))
.build();
try {
final URI uri = new URIBuilder("https://www.googleapis.com/books/v1/volumes")
.setParameter("q", query)
.build();
final HttpGet request = new HttpGet(uri);
request.setHeader("Accept", "application/json");
final HttpResponse response = httpclient.execute(request);
final String data = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
try (final StringReader reader = new StringReader(data)) {
return Json.createReader(reader).readObject();
}
} finally {
httpclient.close();
}
}
@Test
public void createsChildFromHeadersWhenJoinUnsupported() throws Exception {
Tracing tracing = Tracing.newBuilder()
.currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
.addScopeDecorator(StrictScopeDecorator.create()).build())
.addSpanHandler(this.spans).supportsJoin(false).build();
HttpTracing httpTracing = HttpTracing.create(tracing);
this.request = builder().header("b3", "0000000000000014-000000000000000a")
.buildRequest(new MockServletContext());
TracingFilter.create(httpTracing).doFilter(this.request, this.response,
this.filterChain);
then(Tracing.current().tracer().currentSpan()).isNull();
then(this.spans).hasSize(1);
then(this.spans.get(0).parentId()).isEqualTo("000000000000000a");
}
@Provides @Singleton
public HttpTracing getHttpTracing(final Config config, final ServerConfig serverConfig) {
Tracing tracing = Tracing.newBuilder()
.sampler(config.sampler)
.currentTraceContext(new RatpackCurrentTraceContext())
.endpoint(buildEndpoint(config.serviceName, serverConfig.getPort(),
serverConfig.getAddress()))
.spanReporter(config.spanReporter)
.propagationFactory(config.propagationFactory)
.build();
return HttpTracing.newBuilder(tracing)
.clientParser(config.clientParser)
.serverParser(config.serverParser)
.serverSampler(config.serverSampler)
.clientSampler(config.clientSampler)
.build();
}
@Test public void clientSampler() {
context = new XmlBeans(""
+ "<bean id=\"httpTracing\" class=\"brave.spring.beans.HttpTracingFactoryBean\">\n"
+ " <property name=\"tracing\">\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".TRACING\"/>\n"
+ " </property>\n"
+ " <property name=\"clientSampler\">\n"
+ " <util:constant static-field=\"brave.http.HttpSampler.NEVER_SAMPLE\"/>\n"
+ " </property>\n"
+ "</bean>"
);
assertThat(context.getBean("httpTracing", HttpTracing.class))
.extracting("clientSampler")
.isEqualTo(HttpSampler.NEVER_SAMPLE);
}
@Test
public void notSampledHeaderAddedWhenNotSampled() {
this.tracing.close();
this.tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext)
.addSpanHandler(this.spans).sampler(Sampler.NEVER_SAMPLE).build();
this.template.setInterceptors(Arrays.<ClientHttpRequestInterceptor>asList(
TracingClientHttpRequestInterceptor.create(HttpTracing.create(tracing))));
Span span = tracing.tracer().nextSpan().name("new trace");
Map<String, String> headers;
try (Tracer.SpanInScope ws = tracing.tracer().withSpanInScope(span.start())) {
headers = this.template.getForEntity("/", Map.class).getBody();
}
finally {
span.finish();
}
then(this.spans).isEmpty();
}
@Override
public void run(HelloServiceConfiguration configuration, Environment environment) {
/* START TRACING INSTRUMENTATION */
final var sender = URLConnectionSender.newBuilder()
.endpoint(configuration.getZipkinEndpoint()).build();
final var reporter = AsyncReporter.builder(sender).build();
final var tracing = Tracing.newBuilder().localServiceName("hello-service")
.sampler(Sampler.ALWAYS_SAMPLE).spanReporter(reporter).build();
final var httpTracing = HttpTracing.newBuilder(tracing).build();
final var jerseyTracingFilter = TracingApplicationEventListener
.create(httpTracing);
environment.jersey().register(jerseyTracingFilter);
/* END TRACING INSTRUMENTATION */
// Without instrumentation
// final HttpClient httpClient =
// new
// HttpClientBuilder(environment).using(configuration.getHttpClientConfiguration())
// .build(getName());
final var httpClient = TracingHttpClientBuilder.create(httpTracing).build();
final var url = configuration.getTranslationServiceUrl() + "/translate";
final var translationServiceClient = new HelloTranslationServiceClient(httpClient,
url);
final var helloResource = new HelloResource(translationServiceClient);
environment.jersey().register(helloResource);
final var helloServiceHealthCheck = new HelloServiceHealthCheck();
environment.healthChecks().register("hello-service", helloServiceHealthCheck);
}
public Portable(final Tracing tracing) {
this(
HttpTracing
.newBuilder(tracing)
.clientParser(new HttpClientSpanParser())
.build()
);
}
private Client delegate() {
if (this.delegate == null) {
try {
this.delegate = this.beanFactory.getBean(Client.class);
}
catch (BeansException ex) {
this.delegate = TracingFeignClient.create(
beanFactory.getBean(HttpTracing.class),
new Client.Default(null, null));
}
}
return this.delegate;
}
@Test public void serverRequestSampler() {
context = new XmlBeans(""
+ "<bean id=\"httpTracing\" class=\"brave.spring.beans.HttpTracingFactoryBean\">\n"
+ " <property name=\"tracing\">\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".TRACING\"/>\n"
+ " </property>\n"
+ " <property name=\"serverSampler\">\n"
+ " <bean class=\"brave.sampler.SamplerFunctions\" factory-method=\"neverSample\"/>\n"
+ " </property>\n"
+ "</bean>"
);
assertThat(context.getBean("httpTracing", HttpTracing.class).serverRequestSampler())
.isEqualTo(SamplerFunctions.neverSample());
}
@Test
void newDecorator_shouldWorkWhenRequestContextCurrentTraceContextConfigured() {
BraveClient.newDecorator(
HttpTracing.create(
Tracing.newBuilder().currentTraceContext(RequestContextCurrentTraceContext.ofDefault())
.build()));
}
@SuppressWarnings("unchecked")
@Override
public <T> T unwrap(final Class<T> clazz) {
if (HttpTracing.class.equals(clazz)) {
return (T)brave;
} else if (Tracing.class.equals(clazz)) {
return (T)brave.tracing();
} else if (Tracer.class.equals(clazz)) {
return (T)tracer;
} else {
throw new IllegalArgumentException("The class is '" + clazz
+ "'not supported and cannot be unwrapped");
}
}
@Test public void clientRequestSampler() {
context = new XmlBeans(""
+ "<bean id=\"httpTracing\" class=\"brave.spring.beans.HttpTracingFactoryBean\">\n"
+ " <property name=\"tracing\">\n"
+ " <util:constant static-field=\"" + getClass().getName() + ".TRACING\"/>\n"
+ " </property>\n"
+ " <property name=\"clientSampler\">\n"
+ " <bean class=\"brave.sampler.SamplerFunctions\" factory-method=\"neverSample\"/>\n"
+ " </property>\n"
+ "</bean>"
);
assertThat(context.getBean("httpTracing", HttpTracing.class).clientRequestSampler())
.isEqualTo(SamplerFunctions.neverSample());
}
/**
* Creates a new tracing {@link HttpClient} decorator using the specified {@link HttpTracing} instance.
*/
public static Function<? super HttpClient, BraveClient> newDecorator(
HttpTracing httpTracing) {
try {
ensureScopeUsesRequestContext(httpTracing.tracing());
} catch (IllegalStateException e) {
logger.warn("{} - it is appropriate to ignore this warning if this client is not being used " +
"inside an Armeria server (e.g., this is a normal spring-mvc tomcat server).",
e.getMessage());
}
return delegate -> new BraveClient(delegate, httpTracing);
}
@SuppressWarnings("unchecked")
HttpServerHandler<HttpServerRequest, HttpServerResponse> handler() {
if (this.handler == null) {
this.handler = HttpServerHandler
.create(this.beanFactory.getBean(HttpTracing.class));
}
return this.handler;
}
protected XioClient newClient(int port) {
// System.out.println("newClient port: " + port);
HttpTracing httpTracing = null; // TODO(CK): remove this when the tests are fixed
state = new HttpClientTracingState(httpTracing, false);
return new XioClientBootstrap(ClientConfig.fromConfig("xio.h1TestClient"), eventLoopGroup)
.address(new InetSocketAddress("127.0.0.1", port))
.ssl(false)
.proto(Protocol.HTTP)
.handler(new ApplicationHandler())
.tracingHandler(() -> new HttpClientTracingHandler(state))
.usePool(false)
.build();
}
AbstractHttpHeadersFilter(HttpTracing httpTracing) {
this.tracer = httpTracing.tracing().tracer();
this.extractor = httpTracing.tracing().propagation()
.extractor(HttpClientRequest::header);
this.handler = HttpClientHandler.create(httpTracing);
this.httpTracing = httpTracing;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
LazyBean<HttpTracing> httpTracing = LazyBean.create(this.springContext,
HttpTracing.class);
if (bean instanceof HttpClient) {
// This adds handlers to manage the span lifecycle. All require explicit
// propagation of the current span as a reactor context property.
// This done in mapConnect, added last so that it is setup first.
// https://projectreactor.io/docs/core/release/reference/#_simple_context_examples
// In our case, we treat a normal response no differently than one in
// preparation of a redirect follow-up.
TracingDoOnResponse doOnResponse = new TracingDoOnResponse(httpTracing);
return ((HttpClient) bean)
.doOnResponseError(new TracingDoOnErrorResponse(httpTracing))
.doOnRedirect(doOnResponse).doOnResponse(doOnResponse)
.doOnRequestError(new TracingDoOnErrorRequest(httpTracing))
.doOnRequest(new TracingDoOnRequest(httpTracing))
.mapConnect(new TracingMapConnect(() -> {
HttpTracing ref = httpTracing.get();
return ref != null ? ref.tracing().currentTraceContext().get()
: null;
}));
}
return bean;
}
TracingMainExec(HttpTracing httpTracing, ClientExecChain mainExec) {
this.tracer = httpTracing.tracing().tracer();
this.currentTraceContext = httpTracing.tracing().currentTraceContext();
this.serverName = "".equals(httpTracing.serverName()) ? null : httpTracing.serverName();
this.handler = HttpClientHandler.create(httpTracing);
this.mainExec = mainExec;
}
@Override public Set<Object> getSingletons() {
return new LinkedHashSet<>(asList(new Resource(), TracingApplicationEventListener.create(
HttpTracing.create(Tracing.newBuilder()
.sampler(Sampler.NEVER_SAMPLE)
.spanReporter(Reporter.NOOP)
.build())
)));
}
TracingHttpClientBuilder(HttpTracing httpTracing) { // intentionally hidden
if (httpTracing == null) throw new NullPointerException("HttpTracing == null");
this.httpTracing = httpTracing;
}
public static Filter create(Tracing tracing) {
return new TracingFilter(HttpTracing.create(tracing));
}
@Before
public void setUp() {
brave = Tracing.newBuilder().localServiceName("myservice").build();
httpTracing = HttpTracing.create(brave);
context = new BraveTracerContext(httpTracing);
}
@Bean
HttpTracing httpTracing(Tracing tracing) {
return HttpTracing.create(tracing);
}
@Bean
Filter tracingFilter(HttpTracing httpTracing) {
return TracingFilter.create(httpTracing);
}