Files
james.maesandJames Maes 9f39fb095e feat(nunciod): per-RPC tracing span with request-id correlation and auth logging (#371)
Add a tower Layer on the tonic server that wraps every RPC in a root span
carrying a generated request_id, the gRPC method, and the peer address. The
inner service (routing, the bearer-auth interceptor, and the handler) runs
inside that span, so all events emitted while handling a request inherit the
request_id. The span opens with a DEBUG event and closes, once the response
body drains, with an INFO event carrying the terminal gRPC status and elapsed
time.

Propagate the correlation span into the SyncDispatcher's detached sync tasks so
a sync triggered by Mail.Sync logs under the triggering request_id.

Log bearer-auth accept (DEBUG) and reject (WARN, with a fixed reason) in the
interceptor, carrying only the peer -- never the token, the authorization
header, or anything derived from them. The constant-time compare is unchanged.

Refs #358

Co-authored-by: James Maes <jmaes@dmdbrands.com>
2026-07-31 18:39:01 -05:00

97 lines
2.3 KiB
TOML

[workspace]
resolver = "2"
members = [
"crates/nuncio-core",
"crates/nuncio-mail",
"crates/nuncio-cal",
"crates/nuncio-store",
"crates/nuncio-cli",
"crates/nunciod",
"crates/nuncio-filter",
"crates/nuncio-contacts",
"crates/nuncio-proto",
]
[workspace.package]
version = "0.1.0"
edition = "2021"
authors = ["James Maes <james@kof22.com>"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/KofTwentyTwo/nuncio"
homepage = "https://nuncio.mx"
[workspace.lints.rust]
warnings = "deny"
unsafe_code = "deny"
unused_must_use = "deny"
[workspace.lints.clippy]
unwrap_used = "deny"
expect_used = "deny"
panic = "deny"
todo = "deny"
unimplemented = "deny"
unreachable = "deny"
[workspace.dependencies]
tokio = { version = "1.38", features = ["full"] }
async-trait = "0.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
tracing-appender = "0.2"
sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite"] }
ratatui = "0.28"
crossterm = { version = "0.28", features = ["event-stream"] }
clap = { version = "4.5", features = ["derive", "env"] }
zeroize = { version = "1.8", features = ["derive"] }
tempfile = "3.10"
keyring = "2.3"
age = "0.10"
aes-gcm = "0.10"
mail-parser = "0.9"
bytes = "1.6"
lettre = { version = "0.11", default-features = false, features = ["tokio1-rustls-tls", "builder", "smtp-transport"] }
async-imap = { version = "0.11", default-features = false, features = ["runtime-tokio"] }
tokio-rustls = "0.26"
rustls = { version = "0.23", features = ["ring"] }
webpki-roots = "1.0"
rustls-pki-types = "1.7"
tokio-stream = "0.1"
futures = "0.3"
wiremock = "0.6"
icalendar = "0.17"
chrono-tz = "0.10"
rrule = "0.10"
chrono = "0.4"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
quick-xml = "0.41"
html2text = "0.12"
rpassword = "7.3"
sqlparser = "0.54"
arc-swap = "1.7"
regex = "1.10"
hmac = "0.12"
sha2 = "0.10"
hex = "0.4"
flate2 = "1.0"
tar = "0.4"
zip = { version = "8.6", default-features = false, features = ["deflate"] }
tonic = "0.14"
tower = "0.5"
http = "1"
http-body = "1"
http-body-util = "0.1"
tonic-prost = "0.14"
prost = "0.14"
prost-types = "0.14"
tonic-prost-build = "0.14"
protoc-bin-vendored = "3.2"
subtle = "2.6"
fs4 = "0.13"