InternalsPackages
observability
observability
Centralized tracing setup for Unbound services.
This crate configures structured JSON logging and ensures every service emits consistent, queryable events without needing to manage sinks directly.
Design Goals
- Services are log producers, not log consumers.
- One config entrypoint for all services.
- Dev mode writes to a shared JSONL file for multi-process streaming.
Remote Export
The dev subscriber can optionally fan out logs to remote sinks:
- PostHog (events for dashboards)
- Sentry (error and warning envelopes)
Remote export is configured through LogConfig and gated by the runtime
ObservabilityMode policy.
Export Policy Modes
DevVerbose- includes payloads after basic secret redaction.ProdMetadataOnly- exports metadata only (no raw payloads).
Dev Mode Output
By default logs are written to:
~/.unbound/logs/dev.jsonlYou can tail it with:
tail -f ~/.unbound/logs/dev.jsonl | jqUsage
fn main() {
observability::init("daemon");
tracing::info!("ready");
}Advanced configuration:
observability::init_with_config(observability::LogConfig {
service_name: "daemon".into(),
default_level: "debug".into(),
also_stderr: true,
mode: observability::ObservabilityMode::DevVerbose,
..Default::default()
});Key Types
LogConfig- service name, level, mode, sinks, samplingObservabilityMode- runtime export policyPosthogConfig- PostHog API key + batching settingsSentryConfig- Sentry DSNSamplingConfig- per-level sampling ratesinit- zero-config setupinit_with_config- fully configurable setup
Module Layout
src/
├── lib.rs # public API
├── dev.rs # JSONL file sink
└── json_layer.rs# tracing layer for structured outputDevelopment
cargo test -p observability