Warning |
---|
The Apache HTrace project has retired on 2018-04-11 and is not developed anymore. The Apache CXF retired the Apache HTrace integration, starting from 3.3.0 release. |
Overview
Apache HTrace is a tracing framework intended for use with distributed systems written in java. Since version 3.1.3, Apache CXF fully supports integration with Apache HTrace, both on client side and server side. This section gives a complete overview on how distributed tracing support is supported in JAX-RS applications built on top of Apache CXF.
...
Code Block |
---|
|
final Map<String, String> properties = new HashMap<String, String>();
properties.put(Tracer.SPAN_RECEIVER_CLASSES_KEY, ...);
properties.put(Tracer.SAMPLER_CLASSES_KEY, ...);
/**
* For example:
*
* properties.put(Tracer.SPAN_RECEIVER_CLASSES_KEY, StandardOutSpanReceiver.class.getName());
* properties.put(Tracer.SAMPLER_CLASSES_KEY, AlwaysSampler.class.getName());
*/
final Tracer tracer = new Tracer.Builder("jaxrs-client")
.conf(HTraceConfiguration.fromMap(properties))
.build();
final HTraceClientProvider provider = new HTraceClientProvider(tracer);
final Client client = ClientBuilder.newClient().register(provider);
final Response response = client
.target("http://localhost:82829000/catalog")
.request()
.accept(MediaType.APPLICATION_JSON)
.get(); |
...
Code Block |
---|
|
final Map<String, String> properties = new HashMap<String, String>();
properties.put(Tracer.SPAN_RECEIVER_CLASSES_KEY, ...);
properties.put(Tracer.SAMPLER_CLASSES_KEY, ...);
final JAXRSServerFactoryBean factory =
RuntimeDelegate.getInstance().createEndpoint(/* application instance */, JAXRSServerFactoryBean.class);
factory.setFeatures(Arrays.< Feature >asList(new HTraceFeature(HTraceConfiguration.fromMap(properties), "tracer")));
...
return factory.create(); |
...
In the following subsections we are going to walk through many different scenarios to illustrate the distributed tracing in action, starting from the simplest ones and finishing with asynchronous JAX-RS services. All examples assume that configuration has been done (see please Configuring Client and Configuring Server sections above).
Example #1: Client and Server with default distributed tracing configured
...
Info |
---|
Configuring right phases for interceptors is very important. The recommended phase for in-interceptor is PRE_INVOKE while for out-interceptor is PREPOST_MARSHAL. If wrong phases are being used, response or/and request headers, status code, etc could be ignored or not processed. |
...
Code Block |
---|
|
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
...
factory.getOutInterceptors().add(new HTraceClientStartInterceptor(sampler));
factory.getInInterceptors().add(new HTraceClientStopInterceptor());
...
factory.create(); |
Propagating Trace Details To Logs
In order to have better correlation between ongoing traces and logs, Apache CXF since 3.1.11 / 3.2.0 releases distributes a helpful extension for Logback users, LogbackSpanConverter. This converter can be used to complement log records with current trace details, such as tracer id and span id. For example, here is a simple logback.xml configuration file.
Code Block |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="5 seconds">
<conversionRule conversionWord="trace" converterClass="org.apache.cxf.tracing.htrace.ext.LogbackSpanConverter" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%level] [%trace] %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration> |
In this case the tracing details will be propagated to each log record in following format: <tracer_id>, span: <span id>. For example:
Code Block |
---|
|
[INFO] [-, -] 2017-03-11 14:40:13.603 org.eclipse.jetty.server.Server Started @2731ms
[INFO] [tracer-server/192.168.0.101, span: 6d3e0d975d4c883cce12aee1fd8f3e7e]
2017-03-11 14:40:24.013 com.example.rs.PeopleRestService Getting all employees
[INFO] [tracer-server/192.168.0.101, span: 6d3e0d975d4c883c7592f4c2317dec22]
2017-03-11 14:40:28.017 com.example.rs.PeopleRestService Looking up manager in the DB database |
The special [-, -] placeholder indicates that no trace details are being available at the moment of logging the record.
Accessing Apache HTrace 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 Apache HTrace APIs in order to leverages the available instrumentations. To make it possible, TracerContext has a dedicated unwrap method which returns underlying Tracer instance.
Code Block |
---|
|
@GET
@Path("/search")
@Produces(MediaType.APPLICATION_JSON)
public JsonObject search(@QueryParam("q") final String query, @Context final TracerContext tracing) throws Exception {
final Tracer tracer = tracing.unwrap(Tracer.class);
// ...
} |
Future Work
The Apache CXF is very proud to offer Apache HTrace integration. At the current stage, it was a conscious decision to keep the minimal API and provide the set of necessary features only. However, there is a strong commitment to evolve not only Apache HTrace integration, but the distributed tracing support in general.