Skip to content

Limesium — one structured endpoint_* line per HTTP exchange

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

Limesium logs one structured endpoint_* line per HTTP exchange at the service's own boundary — named after the Roman Limes, the watched frontier where every crossing was recorded. Two auto-configured Spring Boot twins with identical fields and configuration: a servlet filter and a WebFlux/coroutines web filter. No starter, no forced transitives.

The name

Limesium is named after the Limes, the fortified frontier of the Roman Empire — not a wall meant to seal the border shut, but a controlled line of crossing points and watchtowers. Traffic was allowed through; what the Limes added was observation: every crossing passed a manned post where it could be seen and accounted for.

That is precisely this project's job, transposed to HTTP. The service's own request boundary is its Limes: exchanges pass through unhindered, and the filter is the watchtower that records each one — exactly one structured line per crossing, whether it came through a servlet or a reactive stack. The name deliberately does not refer to the "edge" in the infrastructure sense (CDN, gateway, mesh): the Limes here is the service's own perimeter, inside the application, behind whatever sits in front of it.

The form follows the naming of chemical elements. Real elements are often named after places — rhenium after the Rhine, germanium, polonium — and Limes + the element suffix -ium yields a plausible entry in that series. This places Limesium in the same fictional periodic table as Inqudium (the eu.inqudium group it is published under): an element-style name for one well-defined capability, here the element of the observed boundary.

The frontier has two directions, and Limesium watches one of them. Its sibling Legatium — named after the legatus, the envoy a service sends to a foreign party — logs the outbound crossings: the RestClient, RestTemplate and WebClient calls the service makes to others, with the same design (one structured line per exchange, fail-open, identical across two paradigm twins). Limesium's fields carry the endpoint_ prefix and Legatium's the adapter_ 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.

Two paradigm twins with identical fields and identical configuration:

Module Stack Root package
limesium-servlet-logging Spring MVC / servlet filter eu.inqudium.limesium.servlet.logging
limesium-reactive-logging Spring WebFlux (Reactor and coroutines) eu.inqudium.limesium.reactive.logging

Both are auto-configured Spring Boot libraries — no starter, no forced logging transitives; the host application brings the runtime (Tomcat 11+/Jetty 12.1+ resp. Netty) and the Logback binding. Undertow/WildFly is unsupported on this stack (no Jakarta Servlet 6.1 implementation; no linkage blocker was found on the servlet-MVC path, but Spring gives no downward guarantee — see the servlet module's README).

Documentation

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

  • Common guide — everything both modules share: the exchange line, the shared architecture, dependency and encoder setup, the configuration namespace, the field family, the meters, the trace contract, and the table of deliberate stack differences.
  • Servlet guide — what the servlet stack decides in the reference implementation: the filter and its two registrations, request destruction as the emission point, async exchanges, the chain-wide MDC, the servlet-only edge cases.
  • Container guide — Tomcat, Jetty and Undertow documented individually: destruction models, error paths, pinned per-engine deviations.
  • Reactive guide — what the reactive stack decides: the two filter variants, the commit-deferred emission, the Reactor context and handler-side MDC, the reactive-only edge cases.
  • Configuration reference — every endpoint-logging.* key with its default, contract-tested against both twins.
  • Elasticsearch mapping — the ready-made component template for the endpoint_* 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.
  • Legatium — the sibling project for the outbound side: one structured adapter_* line per call the service makes, on the logger adapter-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 Limesium 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+.

Limesium Spring Boot Kotlin Java
3.0.0 4.1.x 2.4.x 21
2.0.0 4.1.x 2.4.x 21
1.1.0 4.1.x 2.4.x 21
1.0.0 4.1.x 2.4.x 21

Pick the module for the host's stack and follow the Usage section of its README — prerequisites, the dependency with the current version, how the 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; each activates for its own web application type only.

Build

mvn verify

Maven multi-module build (group eu.inqudium), Java 21, Kotlin, Spring Boot parent.

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

Limesium logs one structured endpoint_* line per HTTP exchange at the service's own boundary — named after the Roman Limes, the watched frontier where every crossing was recorded. Two auto-configured Spring Boot twins with identical fields and configuration: a servlet filter and a WebFlux/coroutines web filter. No starter, no forced transitives.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages