The runtime exposes three credential- and payload-free windows into a running client: a diagnostics snapshot, a bounded observer stream, and optional metrics and tracing bridges.
Diagnostics#
diagnostics() returns a credential- and payload-free snapshot of live in-flight operations plus saturating counters for admission rejections, dropped observer events, and observer/telemetry failures:
RuntimeDiagnostics diagnostics = repost.diagnostics();
System.out.println("in flight: " + diagnostics.getInFlightOperations());
System.out.println("dropped observer events: " + diagnostics.getDroppedObserverEvents());
System.out.println("observer failures: " + diagnostics.getObserverFailures());Observers#
Register a RepostObserver to receive bounded, credential-free lifecycle events (operation start/end, attempt start/end, retry-delay, cancel):
ClientOptions options = ClientOptions.builder()
.apiKey(System.getenv("REPOST_SEND_API_KEY"))
.observer(event -> {
// Runs on a dedicated dispatch thread, never the transport thread. Keep it
// fast: if the bounded queue overflows, events are dropped and counted
// (RuntimeDiagnostics.getDroppedObserverEvents), never blocked. A throwing
// observer is isolated and never changes the send result.
if (event.getKind() == ObserverEventKind.OPERATION_END) {
recordEnd(event.getOperationId(), event.getDeliveryState());
}
})
.build();
return RepostClient.create(options);The observer is intentionally lossy: its queue is bounded (1,024 events), and when it fills, the runtime drops and counts events rather than slowing a send. Observers run on a dedicated dispatch thread (or a borrowed observerExecutor), never on the transport thread, so a slow or throwing observer can never change or block an application send.
Micrometer and OpenTelemetry#
For metrics and traces, add a bridge module and wire it as an observer or telemetry sink, with no reflection and no auto-magic:
// sh.repost:repost-client-micrometer
ClientOptions.builder()
.observer(MicrometerRepostObserver.create(meterRegistry))
.build();Micrometer records repost.client.operations, repost.client.operation.duration, repost.client.attempts, repost.client.attempt.duration, and repost.client.retry.delay, tagged with outcome, error.code, delivery.state, and http.status.class. OpenTelemetry emits one repost.send span with a repost.send.attempt child per attempt. Both carry only low-cardinality metadata, never payloads or credentials.