Using Request Tracing in Applications
Request Tracing in Azul Payara is done either automatically, for JAX-RS endpoints and MicroProfile REST Client calls, or explicitly by annotating CDI bean methods with the OpenTelemetry @WithSpan annotation or by using the OpenTelemetry Tracer API directly. This chapter covers manually decorating your applications to enable explicit Request Tracing.
|
Important
|
The MicroProfile OpenTracing @Traced annotation and the OpenTracing Tracer API (including the startActive / buildSpan style) were removed in Azul Payara Community 7.2026.8. Applications must migrate to the OpenTelemetry @WithSpan annotation and the io.opentelemetry.api.trace.Tracer API described in this page. See OpenTelemetry Support for configuration details.
|
Terminology
Traces & Spans
A Span is a named, timed operation that represents an individual unit of work, such as the execution of a JAX-RS method. Since a Span is a unit of work, they typically contain references to other Spans to represent the work in its entirety.
A Trace is the term used to describe the collection of Spans that make up an entire request’s lifecycle from the viewpoint of Azul Payara: from the request hitting the server to it leaving. A Trace can be made up of simply one Span.
References
The references between Spans are of one of two types: "Child of" or "Follows from":
-
"Child of" references are used to denote that a Span is the child of another Span, e.g. a sub-unit of work.
-
"Follows from" references are used to denote that a Span was spawned by another Span, but is not a subunit of work of the parent Span (the parent Span does not depend on the child Span).
Tags and Logs
A Span Tag is simply a key:value pair that is added to a Span to provide details about the unit of work. For example, JAX-RS methods automatically set the http.url tag to provide information about the URL traced.
A Span Log is a Tag that is paired with a timestamp. As denoted by the name, this is typically used to add information to a Span about an event happening at a specific time during the duration of the Span (e.g. an error).
Using the @WithSpan Annotation
The io.opentelemetry.instrumentation.annotations.WithSpan annotation can be placed on CDI bean methods to automatically create a tracing span for each invocation of that method.
The @WithSpan annotation accepts one optional parameter:
value: defines the name of the span. If left blank it defaults to ClassName.methodName.
import io.opentelemetry.instrumentation.annotations.WithSpan;
@RequestScoped
public class TracedExample {
@WithSpan
public String method1() {
return "anon1";
}
@WithSpan("tracingTest")
public String method2() {
return "anon2";
}
}
The @WithSpan annotation operates as a CDI Interceptor, so for the decorated methods to be traced they must be a) not static or private, and b) invoked through the CDI proxy (i.e. accessed from an injected reference, not via new or this). In the following example, method1 of the above class would be traced and method2 would not:
@Path("/")
@RequestScoped
public class JaxrsEndpoints {
@Inject
TracedExample tracedExample;
@GET
public String method1Traced() {
return tracedExample.method1(); // traced — invoked via CDI proxy
}
@GET
public String method2NotTraced() {
return new TracedExample().method2(); // NOT traced — bypasses CDI proxy
}
}
|
Tip
|
You can annotate the class itself with @WithSpan to trace all eligible methods, and override individual methods by annotating them directly — method-level annotations take precedence.
|
Disabling @WithSpan for a Specific Method
A @WithSpan-annotated method can be disabled at runtime without code changes via MicroProfile Config. Set the following property to false:
[fully.qualified.ClassName]/[methodName]/WithSpan/enabled=false
For example, to disable tracing for TracedExample.method1 in package fish.example:
fish.example.TracedExample/method1/WithSpan/enabled=false
|
Note
|
If multiple overloaded methods share the same name, disabling one disables all overloads with that name. |
Using the OpenTelemetry Tracer API
The OpenTelemetry io.opentelemetry.api.trace.Tracer API allows you to manually start, finish, and add information to Spans for fine-grained control over span boundaries and attributes.
To access the tracer in your application, inject it from the CDI container:
import io.opentelemetry.api.trace.Tracer;
@RequestScoped
public class TracedComponent {
@Inject
Tracer tracer;
}
Starting a Span, making it the active (current) Span, and ending it is done with a try-with-resources scope block:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
@RequestScoped
public class TracedComponent {
@Inject
Tracer tracer;
public void tracedMethod() {
var span = tracer.spanBuilder("tracedTask").startSpan();
try (var scope = span.makeCurrent()) {
// do work, add attributes or events to span
if (span.isRecording()) {
// compute expensive attributes only if the span is being sampled
span.setAttribute("exampleKey", "exampleValue");
}
} finally {
span.setStatus(StatusCode.OK);
span.end();
}
}
}
The Tracer API also gives you access to context propagation across threads and processes. For asynchronous tasks it is recommended to use a Managed Executor Service; for outbound JAX-RS calls use the default JAX-RS client implementation or MicroProfile REST Client, as these propagate trace context automatically.
For more information on configuring OpenTelemetry in your application, see OpenTelemetry Support and Server-Emitted Telemetry Signals.
Disabling Automatic Tracing of JAX-RS Methods and MicroProfile REST Client Calls
By default, calls to JAX-RS endpoints and any calls made through a MicroProfile REST Client are automatically traced by the server’s OpenTelemetry instrumentation.
Disabling Automatic Tracing of JAX-RS Methods
There is no per-endpoint property to suppress the automatic JAX-RS server span. The mp.opentracing.server.skip-pattern property from the old OpenTracing integration has been removed and has no equivalent in the current OpenTelemetry instrumentation.
To avoid exporting spans for specific routes you can instead configure a custom sampler (e.g. a rule-based sampler that drops spans by URL pattern) as an application or server library component. See Using Additional Components for how to supply custom OpenTelemetry components.
Disabling Automatic Tracing of MicroProfile REST Client Calls
Outbound MicroProfile REST Client calls are traced automatically via context propagation. To prevent a specific client from contributing to traces, ensure OpenTelemetry is disabled for that application context (set otel.sdk.disabled=true in MP Config for that application).