feat(E8): add OTel context propagation to spawned child processes#256
feat(E8): add OTel context propagation to spawned child processes#256KooshaPari wants to merge 7 commits into
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Legacy Tooling Scan Report
No violations detected. This is a WARN-mode scan. Fix before strict enforcement begins. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 92dfb0f662
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| Ok(TracerProvider::builder() | ||
| .with_batch_exporter(exporter, opentelemetry_sdk::runtime::Tokio) |
There was a problem hiding this comment.
Run OTLP initialization inside a Tokio runtime
When byteport-cli calls init_default() from its synchronous main (crates/byteport-cli/src/main.rs:108), this constructs the gRPC OTLP batch processor with the Tokio runtime even though no Tokio runtime has been entered. In normal CLI invocations that can panic during telemetry startup before any codec, transport, ui, or upload command runs; use a blocking/simple exporter for the CLI or initialize telemetry from an async Tokio runtime.
Useful? React with 👍 / 👎.
| let _otel_guard = byteport_otel::init::init_default(); | ||
| info!("byteport-cli starting"); |
There was a problem hiding this comment.
Send CLI telemetry logs somewhere other than stdout
byteport-cli uses stdout as its command output channel, but main now calls init_default() before parsing commands and the default config enables JSON fmt logging to stdout. With the new info! calls this means commands like codec encode hello no longer emit just 68656c6c6f; they are wrapped with log records, which breaks scripts/tests that consume the CLI output. Disable stdout logging by default for the CLI or write telemetry logs to stderr/a file.
Useful? React with 👍 / 👎.
| // Propagate OTel trace context to the child process so that | ||
| // git operations are linked to the parent trace. | ||
| PropagateContextToCmd(context.Background(), cmd) |
There was a problem hiding this comment.
Pass the active context into propagation
This always injects from context.Background(), which has no active span, so PropagateContextToCmd has no parent trace context to serialize and the spawned git ls-remote process will not be linked to the request/operation trace. In the path that validates a repo, thread the caller's request context into ValidateGitRepo and pass that context here instead of creating a fresh background context.
Useful? React with 👍 / 👎.
Code Review SummaryStatus: 3 Issues Found | Recommendation: Address before merge OverviewThis PR adds OTel context propagation to child processes for end-to-end distributed tracing. The core concept is sound, but there are implementation issues that need fixing.
Issue Details (click to expand)CRITICAL
WARNING
SUGGESTION
Files Reviewed (7 files)
CRITICAL: WARNING: SUGGESTION: EXISTING ISSUES (already commented):
Fix these issues in Kilo Cloud Reviewed by laguna-m.1-20260312:free · Input: 304.8K · Output: 18.2K · Cached: 2.8M |
| let mut carrier = Vec::new(); | ||
|
|
||
| global::get_text_map_propagator(|propagator| { | ||
| propagator.inject(&mut carrier); |
There was a problem hiding this comment.
CRITICAL: Missing context argument in inject() call
The OpenTelemetry 0.28 TextMapPropagator::inject method signature is propagator.inject(cx, carrier). The current code calls propagator.inject(&mut carrier) without a context. The context variable cx is defined on line 40 but never passed to inject. This will cause propagation to fail silently or panic at runtime.
| propagator.inject(&mut carrier); | |
| global::get_text_map_propagator(|propagator| { | |
| propagator.inject(&cx, &mut carrier); | |
| }); |
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| let tracer = provider.tracer("test"); | ||
|
|
||
| // We must register the global propagator. | ||
| opentelemetry::global::set_text_map_propagator( |
There was a problem hiding this comment.
CRITICAL: Same inject() call missing context in test code
Same issue as line 44 - propagator.inject(&mut carrier) is called without context. This test will not properly verify traceparent injection.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.



Summary
Add OTel context propagation to child processes spawned by BytePort CLI and Go backend, enabling end-to-end distributed tracing across process boundaries.
Context
BytePort's OTel instrumentation (E6/E7/E9) added tracing and metrics within the Rust CLI process, but trace context was lost when spawning child processes (e.g.,
git ls-remotefor repo validation). This created gaps in the trace tree, making it impossible to correlate parent-spawn operations.Changes
byteport-otel/src/propagation.rs) — New module with:current_context_envs()— injects W3C trace context into env pairspropagate_to_cmd()/propagate_to_tokio_cmd()— convenience wrappers forstd::process::Commandandtokio::process::CommandEnvSettertrait for extensible env injectioninit.rs) — Register globalTraceContextPropagatorininit_telemetry()backend/byteport/lib/otelpropagation.go) — New helperPropagateContextToCmd()for Goexec.Cmdbackend/byteport/lib/apilink.go) — Wire propagation intoValidateGitRepo()(spawnsgit ls-remote)backend/byteport/main.go) — Register W3Cpropagation.TraceContext{}as global propagatorUse Cases
git ls-remotespawn now carries the parent HTTP request's trace contextTesting
Links