feat(minimald,minvmd,minimal): OTEL-compatible log format and trace propagation - #835
Conversation
📝 WalkthroughWalkthroughAdds W3C-style trace context creation, validation, and SSH propagation from the CLI to daemon RPC handlers. Introduces the shared ChangesTracing and daemon observability
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant MinimalCLI
participant SSHChannel
participant minimald
participant RPCHandler
MinimalCLI->>SSHChannel: Send TRACEPARENT environment request
SSHChannel->>minimald: Deliver RPC channel request
minimald->>minimald: Parse or mint trace context
minimald->>RPCHandler: Spawn instrumented RPC future
RPCHandler->>minimald: Emit structured JSON log events
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
aaa29fc to
468b40d
Compare
468b40d to
99707ea
Compare
…ce propagation File logs become JSON-lines with span context and OTLP-shaped ids, so correlation is a grep and a future OTLP export is a field-copy — with zero OTEL runtime dependencies. minimald-rpc grows the wire-contract trace module: TraceContext mints 16/8-byte non-zero ids, formats/parses the W3C version-00 traceparent, and TRACEPARENT_ENV names the channel env variable both sides reference. The CLI mints one context per invocation, carries it on a root span at command dispatch, and sends it on every channel open (oneshot RPCs, exec, workspace upload) as a reply-less env request — the same mechanism MINIMAL_SESSION_ID already rides, so no wire change. The daemon parses it in the RPC dispatch, adopting the trace id with a fresh span id and the client's span as parent; absent or malformed values mint fresh, never error. Both daemons' file appenders switch from human-format fmt layers to json-subscriber layers: flat records with span fields flattened to the top level and static service.name/service.version resource fields named by opentelemetry-semantic-conventions. Console output stays human-format. Refs: #801 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
99707ea to
001f197
Compare
…rate The JSON-lines file-log layer (R4.1/R4.2) was defined twice — in minimald's DaemonLogger and minvmd's init_tracing — with byte-identical bodies bar a hardcoded vs. parameterized service name. Two copies of a pinned wire contract drift silently, and the shape test guarded only the minvmd copy. Hoist it into a new leaf crate `mlog` both daemons depend on: one json_file_layer(writer, service_name), one json_log_shape contract test. The shared version::LONG_VERSION is read internally (identical for every binary), so only the service name is a parameter. json-subscriber and opentelemetry-semantic-conventions move off both daemons and become transitive via mlog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/minimald-rpc/src/trace.rs`:
- Around line 22-25: Update TraceContext and the
parse_traceparent/child/traceparent flow to preserve the parent traceparent
flags through child contexts and emitted headers, while enforcing W3C-compliant
lowercase hexadecimal input. Do not normalize accepted flags to 01; either
retain valid flags in TraceContext or reject values other than 01, with parsing
rejecting uppercase hex.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 67bded5a-3fac-4925-a851-4cb54d6779a9
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (13)
Cargo.tomlcrates/minimal/src/client.rscrates/minimal/src/lib.rscrates/minimald-rpc/Cargo.tomlcrates/minimald-rpc/src/lib.rscrates/minimald-rpc/src/trace.rscrates/minimald/Cargo.tomlcrates/minimald/src/logging.rscrates/minimald/src/rpc.rscrates/minvmd/Cargo.tomlcrates/minvmd/src/main.rscrates/mlog/Cargo.tomlcrates/mlog/src/lib.rs
parse_traceparent accepted arbitrary 2-hex flags but TraceContext stored none, so traceparent() always emitted `01` — a version-00 `00` (not sampled) parent round-tripped to sampled. It also accepted uppercase hex, looser than the W3C version-00 contract the module claims to follow. Carry a `flags` byte on TraceContext: mint() sets it sampled, child() inherits it, parse stores it, and traceparent() emits it — so a parsed context re-emits its parent's sampling decision unchanged. Reject uppercase in the trace/span/flags fields. Tests cover flag preservation through child()/re-emission and uppercase rejection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Unit 4 of the diagnostics series (spec: #802, epic: #801). Builds on Unit 3 (#833, merged): the JSON layer replaces the file
fmtlayers Unit 3 introduced, installed through a sharedmloglayer. 467 insertions.What
Make correlation a grep and a future OTLP export a field-copy. The only OTEL-orbit crates involved execute nothing at collection time:
opentelemetry-semantic-conventions(string constants) andjson-subscriber(a serializer on the log-write path of a healthy process).Refs: #801
🤖 Generated with Claude Code
Summary by CodeRabbit
traceparentvalues.