Skip to main content

Tracing Overview

ActivePivot provides a tracing API built on top of Spring Cloud Sleuth which borrows Dapper's terminology. Spring Cloud Sleuth provides a tracing facade that can integrates with OpenZipkin Brave tracer, OpenTracing, or any other Custom tracer implementing the contract org.springframework.cloud.sleuth.Tracer. An example of how Brave tracer is bridged to the Sleuth's API can be found in the org.springframework.cloud.sleuth.brave.bridge module.

By default, ActivePivot enables tracing for the CSV source and every query execution, including distributed queries (i.e. all queries endpoint are traced).

Tracing Setup

Dependencies Versions

<spring-sleuth.version>                   3.1.3            </spring-sleuth.version>
<zipkin.brave.version>                    5.13.9           </zipkin.brave.version>

Dependencies Setup

Tracing configuration can be accomplished simply by importing the following dependencies:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<version>${spring-sleuth.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
<version>${spring-sleuth.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-spring-webmvc</artifactId>
<version>${zipkin.brave.version}</version>
</dependency>

The above dependencies use Spring Boot auto-configuration to automatically configure the tracing stack. The dependency spring-cloud-starter-sleuth automatically uses Brave as the tracing library and consequently import any necessary Beans required by the tracer (for mor details see BraveAutoConfiguration).

Similarly, the dependency spring-cloud-sleuth-zipkin configures the necessary beans allowing to send span to a zipkin server (for more details see ZipkinAutoConfiguration).

The brave-instrumentation-spring-webmvc dependency automatically uses TracingFilter to extract trace state from incoming requests. Then, it reports Zipkin how long each request takes, along with relevant tags like the http url (for more details see brave-instrumentation-spring-webmvc)

Zipkin API is available at Swagger UI - Zipkin.

properties

To define the required properties for tracing, you may create a configuration file tracing.properties. A typical configuration of such file may be as follows:

spring.zipkin.baseUrl=http://127.0.0.1:9411
spring.zipkin.api-path=api/v2/spans
spring.zipkin.service.name=pivot
spring.zipkin.sender.type=web
spring.sleuth.traceId128=true
activeviam.apm.zipkin.span.level=specific

For spring based properties please refer to the Spring Cloud Sleuth Reference Documentation.

Tracing granularity can be configured within ActivePivot using the property activeviam.apm.zipkin.span.level. This configuration is used to define the tracing granularity for ForkJoinTasks. There are three possibilities :

  • NONE : continues the parent span.
  • SPECIFIC : mode creates new child span when some significant tasks are being invoked, specified in Tracing#IMPORTANT_TASKS.
  • TASK : mode creates new child span whenever a new ForkJoinTask is being called.

Please refer the SpanLevel for more details.

Sometimes spring sleuth default sampling rate is not sufficient to capture all traces.
This default is set at 10 spans per second. It could be increased with spring.sleuth.sampler.rate.

Of course, you can add/remove properties to meet your needs.

Configuration Class

You also need the configuration class TracingConfig, which you may include in your application configuration class. This class will look in your classpath for the tracing.properties and will map the required properties to set up the tracing.

It will also look for a org.springframework.cloud.sleuth.Tracer tracer bean in your classpath and wire it into the core tracing API. The default tracer defined within ActivePivot is a NoopTracer which does no tracing. By importing the configuration class TracingConfig, and by using the above brave dependency, a BraveTracer will automatically override the NoopTracer.

Users are encouraged to implement their own tracing configuration for a better control and customization

Brave Additional Configuration

You can define additional configuration for the brave tracer. For instance, in the sandbox project, we define a default trace sampling policy and enable tracing for servlet.

These configurations can be found in BraveTracingConfig class which is imported in the SandboxConfig class:

@Configuration
@ConditionalOnClass({Tracer.class})
public class BraveTracingConfig {
@Bean
public Sampler defaultSampler() {
return Sampler.ALWAYS_SAMPLE;
}
@Bean
public ServletContextInitializer servletTracing() {
return servletContext -> {
// Enables tracing for servlet
final DelegatingTracingFilter filter = new DelegatingTracingFilter();
final String filterName = Conventions.getVariableName(filter);
final FilterRegistration.Dynamic registration = servletContext.addFilter(filterName, filter);
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
};
}
}

You can add more configuration, for example to define custom error handling, etc.

Disable Tracing

If you decide to deactivate tracing, use these properties:

spring.sleuth.enabled=false
spring.zipkin.enabled=false

Logging Integration

Spring Cloud Sleuth configures the logging context with variables including the service name (%{spring.zipkin.service.name} or %{spring.application.name} if the previous one was not set), span ID (%{spanId}) and the trace ID (%{traceId}). These help you connect logs with distributed traces and allow you to group execution traces in further troubleshoot service such as ElasticSearch.

The default sandbox logging configuration (using logback) is:

<encoder>
<pattern>%d{dd/MM/yyyy HH:mm:ss.SSS} %-51([%X{traceId:-}/%X{spanId:-}]) %-5level %-70(%logger{5} %method %line) - %msg%n</pattern>
</encoder>

Usage

A complete usage guide is available in the Spring Cloud Sleuth usage documentation.

ActivePivot com.activeviam.tracing.tracer.ITracer interface provides additional syntactic method for creating and starting spans. Furthermore, the API provides the following two extra methods:

  • Span startNextSpan(Object ownerObject, TraceContext traceContext, Span parentSpan) : for starting span for ForkJoinTask based on the aforementioned SpanLevel
  • Span startNextSpanWithParentContext(TraceContext parentContext) : for starting span with a given parent context

Both methods return a Spring Span and their usage remain the same as any other tracing method.