REST request tracing
jeap-spring-boot-rest-request-tracing provides low-level servlet request/response tracing with header
masking. Request tracing helps understand what happens on a system: for each incoming HTTP call it
records who called what and how the service responded, and routes that information to trace listeners.
It is the technology-neutral core consumed by the higher-level REST request logging in
jeap-spring-boot-logging-starter, which turns the trace events
into the structured RestRequestTracer log statements.
A traced response carries: HTTP method, request URI and matched URI pattern, status code, the calling
application (caller), the authenticated user, elapsed time (dt/ms), remote address, the (filtered)
request and response headers, and whitelisted request attributes.
How it works
TracerConfiguration (@AutoConfiguration, @ConditionalOnWebApplication, prefix jeap.rest.tracing)
loads tracer.properties, binds the properties and @ComponentScans the module to wire the tracer and
its servlet filters:
RestRequestTracer— buildsRestRequestTrace(on request) andRestResponseTrace(on response) events and dispatches them to allRestRequestListener/RestResponseListenerbeans. It short- circuits when no active listener is present, applies header masking/blacklisting and attribute filtering, and extracts the caller from theJEAP-APPLICATION-NAMErequest header. Listener exceptions are caught and logged so a listener never breaks the request.ServletRequestTracer— a high-precedence (HIGHEST_PRECEDENCE + 10)OncePerRequestFilterthat traces the incoming request and, in afinallyblock, the response (status, headers, attributes, elapsed time). Async dispatches are skipped.ServletRequestSecurityTracer— a lowest-precedence filter that traces the request after the security context is established (so authentication is known), emittingRestResponseSecurityTraceto an optionalRestSecurityResponseListener. It skipsuri-filter-patternmatches, 401/403 responses, requests marked as frontend routes (see below) and requests served by the spring-webmvc static resource handler (ResourceHttpRequestHandler— the SPA entry point, its assets and paths matching no handler), so that only requests actually reaching a backend endpoint are traced.FrontendRouteRequestMarker— marks a request as a single-page-application route, i.e. a request answered with the SPA entry point (index.html) instead of by a backend endpoint. Marked requests are excluded from the security tracing above, so SPA deep links do not show up as endpoints called without a JWT. The application starter'sFrontendRouteRedirectExceptionHandlermarks such requests automatically; applications with their own frontend route handler can callFrontendRouteRequestMarker.markAsFrontendRoute(request)(accepting aServletRequestor aWebRequest) themselves.ServletStoreUserFilter— present only when the jEAP securityJeapAuthenticationTokenis on the classpath; stores the token subject as a request attribute soRestRequestTracercan reportuser.AddSenderSystemHeaderToRestClient— aRestClientCustomizer(whenRestClient.Builderis on the classpath) that adds theJEAP-APPLICATION-NAMEheader (value =application-name) to every outgoingRestClientcall, which is how the receiving service learns thecaller.
Consuming traces
Implement and register RestRequestListener and/or RestResponseListener beans. Both expose an
isRequest/ResponseListenerActive() gate so the tracer can avoid building events when no listener is
interested (e.g. when the corresponding log level is disabled). The logging starter ships listeners
that emit the structured trace log; provide your own to feed traces elsewhere.
Header masking & filtering
For each request/response header the tracer applies, in order:
- blacklist (
header-blacklist) — header dropped from the trace entirely (prefix match, case-insensitive); - mask (
header-masked) — header emitted with each value replaced by***.
Request attributes are included only if their name matches a prefix in attributes-whitelist.
Properties
Prefix: jeap.rest.tracing (defaults from tracer.properties).
| Property | Type | Default | Description |
|---|---|---|---|
header-masked | List<String> | Authorization, Cookie, Set-Cookie, Set-Cookie2, x-jwt-assertion | Headers whose values are masked as *** |
header-blacklist | List<String> | (empty) | Headers excluded from traces entirely |
attributes-whitelist | List<String> | org.springframework.web.servlet.HandlerMapping | Request-attribute name prefixes to include |
application-name | String | ${spring.application.name} | Name sent as JEAP-APPLICATION-NAME on outgoing calls |
uri-filter-pattern | Pattern | .*/actuator/.* | URIs excluded from tracing; read both by ServletRequestSecurityTracer and by the logging starter's RestRequestLogger |
full-response-details-in-message | boolean | false | Include full response details in the trace message |
Whether trace logs are produced is governed by the log level of the tracer logger (the logging
starter logs after responding at DEBUG and additionally on receipt at TRACE):
logging:
level:
ch.admin.bit.jeap.log.RestRequestTracer: DEBUG # or TRACE
Pitfalls
- This module emits trace events only — without the logging starter (or a custom listener) nothing is logged.
calleris populated only when the upstream service also runs this tracing (it sets theJEAP-APPLICATION-NAMEheader on itsRestClientcalls).useris populated only when the jEAP security starter is present (theJeapAuthenticationTokenclass drivesServletStoreUserFilter).- Always keep sensitive headers in
header-masked/header-blacklist; the defaults cover auth and cookies but not custom secret headers.