...
| Code Block |
|---|
|
<bean id="braveFeature" class="org.apache.cxf.tracing.brave.BraveFeature"><!-- JAX-WS server feature -->
<constructor-arg ref="httpTracing" />
</bean>
<bean id="httpTracing" class="brave.spring.beans.HttpTracingFactoryBean">
<property name="tracing">
<bean class="brave.spring.beans.TracingFactoryBean">
<property name="localServiceName" value="myService"/>
<property name="reporter">
<bean class="brave.spring.beans.AsyncReporterFactoryBean">
<property name="sender">
<bean class="zipkin.reporter.urlconnection.URLConnectionSender" factory-method="create">
<constructor-arg value="http://localhost:9411/api/v1/spans"/>
</bean>
</property>
</bean>
</property>
<property name="currentTraceContext">
<bean class="brave.context.slf4j.MDCCurrentTraceContext" factory-method="create"/>
</property>
</bean>
</property>
<property name="clientParser">
<bean class="org.apache.cxf.tracing.brave.HttpClientSpanParser" />
</property>
<property name="serverParser">
<bean class="org.apache.cxf.tracing.brave.HttpServerSpanParser" />
</property>
</bean> |
Using non-JAX-RS clients
The Apache CXF uses native OpenZipkin Brave capabilities so the existing instrumentations for different HTTP clients work as expected. The usage of only JAX-RS client is not required. For example, the following snippet demonstrates the usage of traceble OkHttp client to call JAX-RS resources, backed by Apache CXF .
| Code Block |
|---|
|
final Tracing brave = Tracing
.newBuilder()
.localServiceName("web-client")
.reporter(AsyncReporter.builder(sender).build())
.traceSampler(Sampler.ALWAYS_SAMPLE) /* or any other Sampler */
.build();
final OkHttpClient client = new OkHttpClient();
final Call.Factory factory = TracingCallFactory.create(brave, client);
final Request request = new Request.Builder()
.url("http://localhost:9000/catalog")
.header("Accept", "application/json")
.build();
try (final Response response = factory.newCall(request).execute()) {
// Do something with response.body()
} |
Accessing Brave APIs
The Apache CXF abstracts as much of the tracer-specific APIs behind TracerContext as possible. However, sometimes there is a need to get access to OpenZipkin Brave APIs in order to leverages the rich set of available instrumentations. To make it possible, TracerContext has a dedicated unwrap method which returns underlying HttpTracing, Tracer or Tracing instances. The snippet below shows off how to use this API and use OpenZipkin Brave instrumentation for Apache HttpClient.
| Code Block |
|---|
|
@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();
}
} |
The usage of tracer-specific APIs is not generally advisable (because of portability reasons) but in case there are no other options available, it is available.