Package com.tnsai.observability.events
Class Breadcrumbs
java.lang.Object
com.tnsai.observability.events.Breadcrumbs
Per-thread ring buffer of recent operations leading up to a point in
time — typically an exception throw.
ErrorReport embeds a snapshot
of breadcrumbs so an operator inspecting an error sees the last N
framework operations (Agent.chat entered, Tool web_search invoked,
LLM gpt-4o called, …) without having to grep neighbouring log lines
by timestamp + thread. Patterned after Sentry / Bugsnag / Rollbar
breadcrumb concepts.
Lifecycle
Framework entry points add breadcrumbs as they enter:
Breadcrumbs.add("Agent.chat", Map.of("agent", agentId));
try (var ignored = AgentContext.enter(ctx)) {
...
}
On exception, ErrorReport.from(t) (a follow-up integration)
snapshots the current list and embeds it. Tests / consumers can also
read with snapshot().
Bounded ring buffer
Default capacity 20. When full, the oldest breadcrumb is evicted. Override per-thread withresizeForCurrentThread(int) (must be
called before any add). Cap kept low because the buffer is
thread-local and snapshotted on every error — overhead must stay
negligible.
Thread-local
Each thread owns its own buffer; no cross-thread sharing. Async propagation is the caller's concern (useAgentContext.wrap(java.lang.Runnable)
which currently does NOT propagate breadcrumbs — that's a known
limitation, see follow-up for AgentAwareExecutor).- Since:
- 0.5.0 (issue #90)
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordSingle recorded operation with timestamp and attributes. -
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionstatic voidConvenience for breadcrumbs without attributes.static voidAppend a breadcrumb to the current thread's buffer.static voidclear()Drop everything in the current thread's buffer.static intstatic voidresizeForCurrentThread(int capacity) Reset the current thread's buffer to a fresh ring ofcapacityentries.static List<Breadcrumbs.Breadcrumb> snapshot()Snapshot the current thread's breadcrumb list (oldest-first).
-
Field Details
-
DEFAULT_CAPACITY
public static final int DEFAULT_CAPACITYDefault ring buffer capacity.- See Also:
-
-
Method Details
-
add
Append a breadcrumb to the current thread's buffer. When the buffer is at capacity the oldest entry is evicted.- Parameters:
operation- human-readable label, e.g."Agent.chat entered"attrs- supplemental fields; null treated as empty
-
add
Convenience for breadcrumbs without attributes. -
snapshot
Snapshot the current thread's breadcrumb list (oldest-first). Returns an immutable copy — later mutations to the buffer do not affect the snapshot. -
clear
public static void clear()Drop everything in the current thread's buffer. Called by framework entry points on session boundaries to avoid breadcrumb bleed across unrelated requests reusing the same worker thread. -
resizeForCurrentThread
public static void resizeForCurrentThread(int capacity) Reset the current thread's buffer to a fresh ring ofcapacityentries. Existing breadcrumbs are discarded. Must be called before the firstaddon a thread to take effect for the whole lifetime of that thread (or untilclear()+ resize again). -
currentCapacity
public static int currentCapacity()- Returns:
- current buffer capacity for this thread (default
DEFAULT_CAPACITY).
-