This page consolidates Humboldt’s public surface: artifacts to declare, exported Java modules, configuration keys recognized by HumboldtAutoConfigure, and OTel semantic conventions applied by the automatic filters.
Maven artifacts
groupId |
artifactId |
Role |
|---|---|---|
|
|
Public façade and stable SPI ( |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OTLP/HTTP exporter (JSON encoding only — no protobuf) via |
|
|
|
|
|
JAX-RS filters |
|
|
Aggregator, |
|
|
Java Modules re-bundle of |
|
|
Java Modules re-bundle of |
|
|
Java Modules re-bundle of |
|
|
Optional bridge to the OTel SDK autoconfigure SPI: discovers |
|
|
Official MicroProfile Telemetry 2.2 TCK runner — in-reactor, gated by the |
All versions are 0.4.0-SNAPSHOT.
Java modules
| Module | Contents |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Java modules of the public OTel artifacts, rebundled with explicit |
Upstream, the OpenTelemetry jars are automatic modules, which export every package. The rebundled modules differ in three ways, so that the OpenTelemetry SDK and OTLP exporter jars can run next to them on the module path NEW:
-
Packages that are not API but that the OpenTelemetry jars use across jars are exported, each only to the OpenTelemetry 1.66 stable modules whose classes reference it (found with
jdeps; the lists are in the twosrc/main/moditect/module-info.javadescriptors):io.opentelemetry.api.internal,io.opentelemetry.api.implandio.opentelemetry.api.trace.propagation.internalfromio.opentelemetry.api,io.opentelemetry.context.internal.shadedfromio.opentelemetry.context. -
A qualified export reaches only target modules of the same module layer or of a parent layer. When
humboldt-otel-interopdiscovers an OpenTelemetry provider defined in another layer (a child layer of Humboldt’s modules, for instance), the two modules add the exports their descriptors name to the modules of that layer, at run time. An OpenTelemetry component that the application builds itself, outside that discovery, does not get them. Limitation: whenhumboldt-otel-interopitself sits in a child layer ofio.opentelemetry.api/io.opentelemetry.context, it cannot call the layer helper (the package is exported to the interop module by name, which reaches only the same layer or a parent layer). The provider is still kept, but its layer’s exports are not extended and the exporter can later fail with anIllegalAccessError; keep interop in the same layer as the two API modules (as the Vidocq runtime does), or add the--add-exportsby hand. -
io.opentelemetry.contextships Humboldt’s ownio.opentelemetry.common.ServiceLoaderComponentLoader, the defaultComponentLoader: it adds theusesof a service to the module before loading it, so an exporter finds its sender and its compressor.
A module-layer test checks the result with opentelemetry-exporter-otlp 1.66 and the JDK sender: a span, a metric and a log record are exported (to a closed port, the only failure being the connection), with the exporter in the same layer as Humboldt’s modules and in a child layer. The other modules of the lists (the OkHttp sender, the Jaeger remote sampler, …) rest on jdeps only. An artifact that is not in the lists, such as an incubating (-alpha) one, must be given --add-exports <module>/<package>=<consumer> for each package it uses, where <module> is the Humboldt module that holds the package: io.opentelemetry.api for the io.opentelemetry.api.* packages, io.opentelemetry.context for io.opentelemetry.context.internal.shaded and io.opentelemetry.common.impl (opentelemetry-common is shaded into humboldt-otel-context). For 1.66.0-alpha, opentelemetry-sdk-extension-incubator uses io.opentelemetry.context.internal.shaded and opentelemetry-api-incubator uses io.opentelemetry.common.impl. The option applies to the boot layer only.
io.vidocq.humboldt.internal.* packages are never exported. Any direct access fails with a clear Java Modules crash.
Bean archives NEW
humboldt-cdi and humboldt-rest are explicit bean archives: each ships a META-INF/beans.xml with bean-discovery-mode="annotated". A CDI container that does not scan implicit archives, such as Weld SE by default, therefore still discovers the @WithSpan interceptor, the telemetry producers (Tracer, Meter, Span, …), the server request and response filters and the span finalizer. Without it, @WithSpan did nothing there, and no error was reported (BUG-20261009-01).
Other CDI containers NEW
Humboldt does not need Vauban. The jars run unchanged under another CDI container, and two integration-test modules, grouped under humboldt-it-other-containers, prove it on every build (humboldt#23):
| Module | What it runs |
|---|---|
|
Weld SE 6.0 (CDI 4.1), class path, no Vauban: a |
|
A WAR on Open Liberty 26.0.0.10, MicroProfile 7 distribution (CDI 4.0, Jakarta REST 3.1, MicroProfile Rest Client 4.0), with Liberty’s |
Neither module is published. What it takes:
-
Install the SDK once. Under Vidocq the Telemetry extension builds the SDK and sets it as
GlobalOpenTelemetry. Elsewhere nothing does, and the API stays a no-op:@WithSpanruns, but no span is recorded. Install it when the application starts, with the sameOTEL_*keys as under Vidocq. MicroProfile Telemetry keeps the SDK off unlessOTEL_SDK_DISABLEDisfalse:@ApplicationScoped public class TelemetryBootstrap { void install(@Observes @Initialized(ApplicationScoped.class) Object started) { GlobalOpenTelemetry.set(HumboldtAutoConfigure.configure(EnvConfig.system())); // humboldt-runtime } } -
vauban-apiis a runtime dependency ofhumboldt-cdi, under any container. The Vauban build weaves aprotectedconstructor takingio.vidocq.vauban.api.ProxyLinkinto the normal-scopedHumboldtTelemetryProducers; a container that cannot load that type cannot load the class, and Weld drops the producers with an INFO message (WELD-000119), then fails on the first injectedTracerorSpan(BUG-20261010-01).vauban-apiholds API types only (13 KB): no Vauban code runs outside Vauban. -
The Jakarta APIs come from the container — CDI, Annotation and Jakarta REST are
providedinhumboldt-cdiandhumboldt-rest. The Vidocq Telemetry extension brings Jakarta REST itself, so an application with no REST endpoint still starts. -
The span finalizer only records the exception.
HumboldtSpanFinalizer, anExceptionMapper<Throwable>, records an exception escaping a resource on the current SERVER span and answers 500; the response filter ends the span. AWebApplicationExceptionkeeps its own response. It used to injectContainerRequestContext, which Jakarta REST does not make injectable into a provider, and to answer 500 for everything: on RESTEasy every application exception, even a 404, became an internal error (BUG-20261010-02).
|
Deploying on an application server
|
Configuration keys
Humboldt reads standard OpenTelemetry env vars, with fallback to equivalent system properties (SCREAMING_SNAKE_CASE → lower.dot.case). Env vars take priority.
SDK gate
| Key | Default | Effect |
|---|---|---|
|
|
Per MP Telemetry 2.2 the SDK is disabled by default: the OTel API stays usable but nothing is exported. Set explicitly to |
Service identification
| Key | Default | Effect |
|---|---|---|
|
|
|
|
(empty) |
|
Exporter per signal
| Key | Default | Values |
|---|---|---|
|
|
|
|
|
|
|
|
|
OTLP HTTP endpoint
| Key | Default | Effect |
|---|---|---|
|
Common endpoint (suffix |
|
|
(inherited) |
Traces override. |
|
(inherited) |
Metrics override. |
|
(inherited) |
Logs override. |
|
(empty) |
Comma-separated HTTP headers |
|
(not read) |
Not read by Humboldt — the request timeout is the exporter-builder default (10 s). |
|
(not read) |
Not read — the exporter always sends OTLP/HTTP with JSON encoding; there is no protobuf variant to switch to. |
Sampling
| Key | Default | Values |
|---|---|---|
|
|
|
|
|
Ratio for |
Metric reading
| Key | Default | Effect |
|---|---|---|
|
|
Period of |
|
(not read) |
Not read by Humboldt. |
MicroProfile Telemetry keys
The runtime reads no mp.telemetry.* key: enabling/disabling goes through OTEL_SDK_DISABLED (see the SDK gate above), and propagators default to W3C TraceContext + Baggage. The single exception lives in the optional humboldt-otel-interop bridge, whose SPI autoconfiguration accepts mp.telemetry.propagators as an alias of otel.propagators (MP Telemetry §3.3).
Applied semantic conventions
humboldt-rest applies the OpenTelemetry HTTP semantic conventions automatically on the server side. It does not depend on opentelemetry-semconv: the attribute names are written in its code, against conventions 1.27. The REST tests of the official MicroProfile Telemetry 2.2-RC3 TCK check them, with opentelemetry-semconv 1.44.0 in the runner, and pass:
| Attribute | Source |
|---|---|
|
|
|
|
|
|
|
|
|
Added to the |
span status |
Set on the server span only when |
For client-side attributes (HTTP, DB, messaging…), Humboldt does not generate them automatically: set them in application code (either as plain AttributeKey`s, or with the constants from `opentelemetry-semconv — an artifact Humboldt itself does not ship). Full reference: OpenTelemetry Semantic Conventions.
Exception attributes NEW
Span.recordException(Throwable) and the log API’s LogRecordBuilder.setException(Throwable) derive the same attributes, as the OpenTelemetry SDK 1.66 does:
| Attribute | Value |
|---|---|
|
The exception’s canonical class name ( |
|
|
|
The printed stack trace. |
On a span, the additional attributes passed to recordException(Throwable, Attributes) are applied last and override the derived ones. On a log record, an attribute already set on the builder under one of these keys is kept. @WithSpan records the exception a method throws through recordException (see Instrument a method with @WithSpan); the JUL bridge passes the exception of a JUL record to setException (see What a log record carries).
Registered propagators
AutoConfiguredHumboldt.getPropagators() returns by default a composite TextMapPropagator:
-
W3CTraceContextPropagator— headerstraceparent,tracestate. -
W3CBaggagePropagator— headerbaggage.
No B3 by default. With the optional humboldt-otel-interop bridge on the module path, otel.propagators (alias mp.telemetry.propagators) can select tracecontext, baggage, b3, b3multi, jaeger, or any propagator discovered through the OTel ConfigurablePropagatorProvider SPI.
Outputs and formats
| Exporter | Output |
|---|---|
|
OTLP/HTTP POST, JSON encoding — always; |
|
|
|
|
|
No processor registered — signal disabled. |
OTLP/JSON encoding NEW
The otlp exporter follows the OTLP JSON encoding, as the OpenTelemetry Java 1.66 JSON marshalers do:
-
Metrics — sums and gauges carry their long points as
asInt(a JSON string) and their double points asasDouble, so double counters, double up-down counters and double gauges are exported with their data points. A synchronous gauge (InstrumentType.GAUGE) is exported as a gauge, like an observable one. -
Non-finite doubles —
NaN,+∞and-∞are written as the strings"NaN","Infinity"and"-Infinity", in attributes (plain, in arrays, nested in aValue), double points and histogramsum/min/max, since JSON has no literal for them. -
Complex attributes — an attribute set through
setAttribute(String, Value)on a span or a log record is encoded recursively: scalars asstringValue/boolValue/intValue/doubleValue, arrays asarrayValue, maps askvlistValue, bytes as base64bytesValue, and an empty value as anAnyValuewith no field set. -
Log records — structured bodies are encoded as
AnyValue, and the event name as theeventNamefield (see What a log record carries). -
A metric batch that cannot be encoded fails — a data point that does not match its metric (a histogram point in a sum or a gauge, a number point in a histogram) or an instrument type with no OTLP encoding makes the batch fail instead of being dropped silently. The exporter sends nothing, returns a failed
CompletableResultCode, and logs the first such batch atWARNINGwith the metric, its instrument type and the point type.humboldt-sdk-metricnever produces such data; aMetricDatabuilt elsewhere may.
Compatibility
-
Java 25 LTS minimum (compile and runtime).
-
OpenTelemetry API and context 1.66.0,
opentelemetry-instrumentation-annotations2.31.1, repackaged in thehumboldt-otel-*artifacts. OpenTelemetry SDK, autoconfigure SPI and exporter jars you supply next tohumboldt-otel-interopbelong to the same 1.66 line; the semantic conventions used by the TCK harness are 1.44.0 NEW. -
Maven 3.9.16 or later (Model 4.0.0 everywhere; the TCK runner is in-reactor behind the
tckprofile). -
Compatible with CDI 4.1 Lite (Vauban) and JAX-RS 4.0 (Cassini). Also proven on Weld SE 6.0 and on Open Liberty (CDI 4.0, Jakarta REST 3.1): see Other CDI containers NEW.
Next: Internals.