Observability
Logging
Riverbase logs through tracing. RiverbaseApp::init installs the
subscriber from config; workers and CLIs call it themselves:
riverbase_core::applog::init_logging("info", riverbase_core::LogFormat::Json);
| Setting | Env | Values |
|---|---|---|
log_level | RIVERBASE_LOG_LEVEL | A tracing filter such as info or riverbase_core=debug,info. RUST_LOG overrides it. |
log_format | RIVERBASE_LOG_FORMAT | compact for local runs, pretty for multi-line, json for log shippers |
log_http_requests | RIVERBASE_LOG_HTTP_REQUESTS | One line per request: method, URI, status, latency |
Use json in production. Every line then carries structured fields that log pipelines can index.
Correlation
Each request gets a correlation id that travels in EngineContext. It is written to every audit row
the request produces and echoed in the response headers. Forward it on outbound calls, and the trail
connects across services.
The audit log as an operational record
The audit schema answers most "what happened?" questions without extra instrumentation:
| Question | Look at |
|---|---|
| Did the command run, and how did it end? | The command log status (Created stuck means the process died mid-command) |
| What did it change? | Events (event_log) keyed by action |
| What did the user see? | The response log |
| Was a message published? | Message log and outbox rows |
| Who read what? | The query log, when audit_log.query = true |
Bound its growth with purge_audit_logs and an AuditRetentionConfig on a schedule.
Errors
Every failure is a RiverbaseError with a stable errcode. Alert on codes, not on message text:
DAT-*storage failures, especiallyDAT-090conflicts under load;AUT-*andCAS-*spikes, which point at an IdP or policy rollout;CMD-027, a store that broke transactional guarantees.
In main, prefer riverbase_http::report_fatal(err) over returning the error. It logs through
tracing, then exits with status 1.
OpenTelemetry
The otel feature on riverbase_core enables OpenTelemetry hooks. The framework does not install
exporters: configure the OTLP exporter and tracer provider in your binary, and Riverbase's spans flow
into it. This keeps the choice of vendor and sampling with the service owner.