Observability¶
arcana.observability provides a structured audit log, OpenTelemetry tracing,
and in-process metrics. Everything writes to ~/.arcana/logs/ by default.
from arcana.observability import configure_observability, get_audit_log
configure_observability() # call once at startup
log = get_audit_log()
for event in log.tail(n=20):
print(event)
Install the OTel extras for span export to Jaeger, Grafana, etc.:
Configuration¶
arcana.observability.configure_observability
¶
Set up the global audit log and OTel tracing.
Safe to call multiple times — re-calling replaces the audit log path and reconfigures the OTel tracer provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_dir
|
Path | None
|
Root for all observability data. Defaults to |
None
|
Source code in packages/arcana-core/arcana/observability/__init__.py
arcana.observability.get_audit_log
¶
Return the global AuditLog, or None if configure_observability() has not been called.
arcana.observability.tracer.configure_tracing
¶
Configure OTel with a FileSpanExporter writing to session_dir.
No-op if opentelemetry-sdk is not installed. Install via: pip install arcana-core[observability]
Source code in packages/arcana-core/arcana/observability/tracer.py
arcana.observability.tracer.get_tracer
¶
Return an OTel Tracer, or a no-op tracer if opentelemetry-api is not installed.
Source code in packages/arcana-core/arcana/observability/tracer.py
Audit log¶
arcana.observability.audit.AuditLog
¶
Append-only JSONL log. Each event is one line.
Errors during write are silently swallowed — observability must never break the main agent call path.
Source code in packages/arcana-core/arcana/observability/audit.py
append
¶
Serialize event to JSONL and append. Non-fatal on I/O error.
Source code in packages/arcana-core/arcana/observability/audit.py
tail
¶
Return the last n events, optionally filtered by type.
Source code in packages/arcana-core/arcana/observability/audit.py
Events¶
arcana.observability.events.AuditEvent
module-attribute
¶
AuditEvent = (
SessionEvent
| ModelCallEvent
| RoutingEvent
| MemoryReadEvent
| MemoryWriteEvent
| MemoryPruneEvent
| MemoryDegradedEvent
)
arcana.observability.events.SessionEvent
dataclass
¶
SessionEvent(
session_id,
agent_id,
agent_name,
card,
modifier_cards,
model,
input_tokens,
output_tokens,
duration_ms,
status,
timestamp=_now_iso(),
cost=None,
)
Emitted by Agent after each run() or stream() completes.
arcana.observability.events.ModelCallEvent
dataclass
¶
ModelCallEvent(
session_id,
model,
latency_ms,
input_tokens,
output_tokens,
attempt,
success,
timestamp=_now_iso(),
error=None,
)
Emitted by ModelGateway after each adapter call (including retries).
arcana.observability.events.RoutingEvent
dataclass
¶
RoutingEvent(
session_id,
prompt_preview,
outcome,
matched_rule_trigger,
target_agent_name,
target_card,
rules_evaluated,
confidence,
duration_ms,
timestamp=_now_iso(),
namespace_id="local",
workspace_id="default",
)
Emitted by the World Engine before routing each prompt.
arcana.observability.events.MemoryReadEvent
dataclass
¶
MemoryReadEvent(
session_id,
agent_id,
query_text,
results_count,
latency_ms,
timestamp=_now_iso(),
)
Emitted on each memory retrieval.
arcana.observability.events.MemoryWriteEvent
dataclass
¶
Emitted on each memory write.
arcana.observability.events.MemoryPruneEvent
dataclass
¶
Emitted after a memory prune pass over one store.
arcana.observability.events.MemoryDegradedEvent
dataclass
¶
MemoryDegradedEvent(
agent_id,
session_id,
tier,
operation,
reason,
message="",
timestamp=_now_iso(),
)
Emitted when a memory tier is skipped or drops out of an operation.
A degraded read returns partial context; a degraded shared/global write is dropped. Either way the session proceeds — this event is how the thinning is surfaced instead of being silent.
Emitters¶
emit_degraded records a memory tier degradation to both the audit log and
metrics. It is the default sink the resilience layer uses when a tier is skipped
or drops out of an operation; the emission is best-effort and never raises, so
observability can never break the memory path.
arcana.observability.emit_degraded
¶
Record a memory degradation to the audit log and metrics (best effort).
Observability must never break the memory path, so every failure here is swallowed. Mirrors the best-effort emission the adapters already use.
Source code in packages/arcana-core/arcana/observability/__init__.py
Metrics¶
Alongside the session and model-call instruments, the memory federation
publishes its resilience signals here: arcana.memory.tier.degraded (a counter
labelled by tier / operation / reason), arcana.memory.tier.latency_ms,
arcana.memory.circuit.state (0=closed, 1=half_open, 2=open per tier),
and the background-queue gauges arcana.memory.queue.depth and
arcana.memory.queue.drain_seconds.
arcana.observability.metrics.ArcanaMetrics
¶
All OTel metric instruments used by arcana. One instance per process.
Source code in packages/arcana-core/arcana/observability/metrics.py
arcana.observability.metrics.get_metrics
¶
Return the process-wide ArcanaMetrics instance, creating it on first call.