Production-grade structured logging (v0.9.0) - #42
Merged
Conversation
Replace the global-max-level subscriber with `tracing-subscriber` +
`EnvFilter`, add `--quiet` and `--log-format compact|json`, and unify
every log call site around a stable span schema that mirrors the
`rusnel ctl` ID model (`client_id` / `tunnel_id` / `conn_id`).
Why
- The old subscriber was a single global level knob with no per-module
control and no way to gate noisy upstream crates separately, so
`--debug` drowned rusnel's own messages in quinn / rustls trace output.
- Field names drifted between sites (`id` vs `client_id`, local TCP
counter `id` vs admin `conn_id`, `Forward` vs `"forward"`), which
made greppable correlation with the admin API unreliable.
- Connection lifecycles only logged "opened"; closing was silent unless
there was an error, so basic "who used the most bytes" questions
required either standing up an aggregator or shelling into the admin
socket.
What changes
- `init_logging` in `src/main.rs`: `EnvFilter` honoring `RUST_LOG`,
synthesized defaults that keep quinn/rustls/h3/hyper at WARN while
rusnel modules respect `-v` / `--debug` / `-q`. Compact format with
ISO-8601 UTC millisecond timestamps, target hidden, ANSI auto-detected
from stderr TTY-ness. `--log-format json` emits one event per line for
log aggregators.
- Stable spans: `client{client_id,peer}` (server) / `session{peer}`
(client) → `tunnel{tunnel_id,dir,spec}` → `conn{conn_id,tunnel_id,
peer,proto}`. Server-side conn span now uses the real `conn_id` from
`ServerState::register_conn`; client-side falls back to a local
counter when admin tracking is off.
- Every conn emits structured `conn opened` / `conn closed` events; the
close line carries `bytes_in`, `bytes_out` (snapshotted from the
`ConnGuard` before drop), and `dur_ms`.
- Subcommand subscribers (`ctl`, `cert`) collapsed into a shared
`init_simple_logger` so they pick up `RUST_LOG` overrides too.
- Cargo.toml: enabled the `env-filter`/`fmt`/`ansi`/`json`/`time`
features on `tracing-subscriber` and added `time` for the timestamp
format description.
- Messages rewritten throughout server/, client/, common/{tcp,udp,
socks,proxy,tunnel,quic}, server/admin, lib: lowercase, terse,
present-tense, key-value structured fields instead of inline format
args.
- README: marked the `RUST_LOG` TODO done and added a Logging section
with the schema, flags, and a real example trace.
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replace the global-max-level subscriber with
tracing-subscriber+EnvFilter, add--quietand--log-format compact|json, and unify every log call site around a stable span schema that mirrors therusnel ctlID model (client_id/tunnel_id/conn_id).Why
--debugdrowned rusnel's own messages in quinn / rustls trace output.idvsclient_id, local TCP counteridvs adminconn_id,Forwardvs"forward"), which made greppable correlation with the admin API unreliable.What changes
init_logginginsrc/main.rs:EnvFilterhonoringRUST_LOG, synthesized defaults that keep quinn/rustls/h3/hyper at WARN while rusnel modules respect-v/--debug/-q. Compact format with ISO-8601 UTC millisecond timestamps, target hidden, ANSI auto-detected from stderr TTY-ness.--log-format jsonemits one event per line for log aggregators.client{client_id,peer}(server) /session{peer}(client) →tunnel{tunnel_id,dir,spec}→conn{conn_id,tunnel_id, peer,proto}. Server-side conn span now uses the realconn_idfromServerState::register_conn; client-side falls back to a local counter when admin tracking is off.conn opened/conn closedevents; the close line carriesbytes_in,bytes_out(snapshotted from theConnGuardbefore drop), anddur_ms.ctl,cert) collapsed into a sharedinit_simple_loggerso they pick upRUST_LOGoverrides too.env-filter/fmt/ansi/json/timefeatures ontracing-subscriberand addedtimefor the timestamp format description.RUST_LOGTODO done and added a Logging section with the schema, flags, and a real example trace.