Skip to content

Legatium — one structured adapter_* line per outbound HTTP exchange

Maven Central CI Coverage License Java Kotlin Last commit Issues Docs OpenSSF Scorecard

Legatium logs one structured adapter_* line per outbound HTTP exchange — named after the Roman legatus, the envoy a service sends to a foreign party, and the record of what came of it. Two auto-configured Spring Boot twins with identical fields and configuration: a RestClient/RestTemplate interceptor and a WebClient filter. No starter, no forced transitives.

About the name

Legatium derives from legatus, the Roman envoy. A client call is exactly that: the service sends someone to a foreign party and records what came of it. Limesium guards the border from within; Legatium accompanies the envoy outward. The pair of names explains itself in a single sentence, sounds like an element, and is entirely unclaimed on GitHub.

The form follows the naming of chemical elements, like its sibling Limesium — the project that logs the inbound crossings at the service's own frontier. Together they cover both directions of a service's HTTP traffic with the same design: one structured line per exchange, fail-open, identical across two paradigm twins. Legatium's fields carry the adapter_ prefix and Limesium's the endpoint_ prefix, so a log document may hold both — a client line emitted while a request is being served inherits the server line's identity from the MDC — and no field ever means two things. Both are published under the eu.inqudium group, the fictional periodic table of Inqudium.

Two paradigm twins with identical fields and identical configuration:

Module Client Root package
legatium-restclient-logging RestClient and RestTemplate (blocking, ClientHttpRequestInterceptor) eu.inqudium.legatium.restclient.logging
legatium-webclient-logging WebClient (reactive, ExchangeFilterFunction) eu.inqudium.legatium.webclient.logging

Both are auto-configured Spring Boot libraries — no starter, no forced logging transitives; the host application brings the client and its engine (the JDK HttpClient, Apache, Reactor Netty, ...) and the Logback binding. Neither needs a web application: a batch job or a message consumer that calls out is a client too.

What one line says

Adapter http exchange POST https://api.example.com/things/42 -> 200 [adapter_request_id=4bf92f3577b34da6a3ce929d0e0e4736 traceId=4bf92f3577b34da6a3ce929d0e0e4736 spanId=00f067aa0ba902b7]

plus the structured adapter_* key-values — outcome, duration until the response was fully read, method, status, peer host, URI template, path, query, optional headers and bodies — and the identity in the MDC. The trace ids come from the traceparent header the host's tracing propagation put on the request; on a traceless call the module sends an X-Correlation-Id instead, so the peer can quote it. Outcomes: success, failure, timeout, and on the reactive stack cancelled.

Documentation

Documentation site: inqudium.github.io/legatium — guides, Elasticsearch mapping, generated test evidence, coverage reports, and the Dokka API references.

  • Common guide — everything that is one contract for both twins, written once: prerequisites, dependency, overriding beans, the exchange line and the logging backend, index mapping, configuration, fields, MDC keys, meters, trace correlation, scope and fail-open guarantees, the shared code.
  • RestClient guide — the long-form guide of the reference implementation: architecture, integration, configuration, metrics.
  • WebClient guide — the twin's guide, including the deliberate stack differences.
  • Configuration reference — every adapter-logging.* key with its default, contract-tested against both twins.
  • Elasticsearch mapping — the ready-made component template for the adapter_* fields.
  • Decision records — why the trace id is the request id, why the shared code is inlined, why the default id counts instead of rolling dice.
  • Limesium — the sibling project for the inbound side: one structured endpoint_* line per request the service receives, on the logger endpoint-http-exchange, built to the same design. Run both and a log document holds the server line and the client lines of the calls it made, joined by the shared request id - and because both mask header values with the same stable fingerprint (the same masking-key on both sides keeps it so), a masked token reads identically on the inbound and the outbound line.

Quick start

Each Legatium release is built and tested against one Spring Boot line, one Kotlin line and one Java target; the table is the history of those lines, newest first. The Java column is the bytecode target the artifacts run on - the build itself needs JDK 24+.

Legatium Spring Boot Kotlin Java
1.0.0 4.1.x 2.4.x 21

Pick the module for the client the host calls out with and follow the Usage section of its README — prerequisites, the dependency with the current version, how the interceptor or filter is wired automatically, when and how to wire it by hand, and what one logged exchange looks like as text and as JSON:

An application may carry both jars — a servlet host using RestClient for most calls and WebClient for a streaming one gets both logged, in one format.

Build

mvn verify

Maven multi-module build (group eu.inqudium), Java 21, Kotlin, Spring Boot parent. The twins compile against the shared legatium-common module through the reactor, so build from the root (or with -am).

Contributing

Contributions are welcome — please read CONTRIBUTING.md first. The Code of Conduct applies to all project spaces, and security issues should be reported privately as described in SECURITY.md.

License

Licensed under the Apache License, Version 2.0.

About

Legatium logs one structured adapter_* line per outbound HTTP exchange — the envoy's report of what came of a call to a foreign party. Two auto-configured Spring Boot twins with identical fields, configuration and meters: a RestClient/RestTemplate interceptor and a WebClient filter. Fail-open, trace-aware, no starter. The outbound twin of Limesium.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages