You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+23-1Lines changed: 23 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -50,12 +50,34 @@ Pass `--codetracer-json-errors` (or set the policy via `configure_policy(json_er
50
50
51
51
### IO capture configuration
52
52
53
-
Line-aware stdout/stderr capture proxies are now enabled by default. Control them through the policy layer:
53
+
Line-aware capture (see [ADR 0008](design-docs/adr/0008-line-aware-io-capture.md)) installs `LineAwareStdout`, `LineAwareStderr`, and `LineAwareStdin` proxies so every chunk carries `{path_id, line, frame_id}` metadata. The proxies forward writes immediately to keep TTY behaviour unchanged and the batching sink emits newline/flush/step-delimited chunks. When the FD mirror fallback observes bytes that bypassed the proxies, the resulting `IoChunk` carries the `mirror` flag so downstream tooling can highlight native writers separately. Recorder logs and telemetry use `ScopedMuteIoCapture` to avoid recursive capture.
54
+
55
+
Control the feature through the policy layer:
54
56
55
57
- CLI: `python -m codetracer_python_recorder --io-capture=off script.py` disables capture, while `--io-capture=proxies+fd` also mirrors raw file-descriptor writes.
56
58
- Python: `configure_policy(io_capture_line_proxies=False)` toggles proxies, and `configure_policy(io_capture_fd_fallback=True)` enables the FD fallback.
57
59
- Environment: set `CODETRACER_CAPTURE_IO=off`, `proxies`, or `proxies+fd` (`,` is also accepted) to match the CLI and Python helpers.
58
60
61
+
Manual smoke check: `python -m codetracer_python_recorder examples/stdout_script.py` should report the proxied output while leaving the console live.
62
+
63
+
#### Troubleshooting replaced stdout/stderr
64
+
65
+
Third-party tooling occasionally replaces `sys.stdout` / `sys.stderr` after the proxies install. When that happens, IO metadata stops updating and the recorder falls back to passthrough behaviour. You can verify the binding at runtime:
66
+
67
+
```python
68
+
import sys
69
+
from codetracer_python_recorder.runtime import LineAwareStdout, LineAwareStderr
Copy file name to clipboardExpand all lines: design-docs/io-capture-line-proxy-implementation-plan.status.md
+5-2Lines changed: 5 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,9 +17,12 @@
17
17
- ✅ **Stage 2 – Implement IoEventSink and batching:** Added the `IoChunk` model plus a `IoEventSink` batching layer that groups stdout/stderr writes per thread, flushes on newline, explicit `flush()`, step boundaries, and 5 ms gaps, and emits stdin reads immediately. Updated the proxies to surface flush events and introduced focused unit tests that cover batching, timer splits, step flushes, and stdin capture. `just test` runs the sink tests alongside the existing proxy coverage.
18
18
- ✅ **Stage 3 – Wire proxies into lifecycle:**`RuntimeTracer::install_io_capture` now instantiates the sink, installs the proxies behind the policy flag, and drains/flushed buffered chunks at step and finish boundaries. `IoChunk` records path IDs, frame IDs, and thread IDs sourced from the `LineSnapshotStore`, with a Python stack fallback filling metadata when monitoring snapshots are not yet available. Metadata emitted by `RecordEvent` now includes `path_id`, `line`, and `frame_id` for stdout/stderr chunks, and the Stage 3 integration test passes end-to-end.
19
19
- 🔄 **Stage 4 – Optional FD mirror:** Implemented the shared ledger (`runtime::io_capture::fd_mirror`), plumbed optional `MirrorLedgers`/`FdMirrorController` through `IoEventSink` and `RuntimeTracer::install_io_capture`, and added runtime tests that assert `os.write` payloads are captured only when `io_capture_fd_fallback` is enabled. Next actions: tighten metadata/telemetry (expose mirror stats, warn when descriptor duplication fails) and stress-test concurrent native writers.
20
-
- ⏳ **Stage 5 – Hardening and docs:** Not started.
20
+
- 🔄 **Stage 5 – Hardening and docs:** Kickoff 2025-10-15. Focus areas: add teardown timeouts for the FD mirror threads, expand README coverage (include ADR 0008 link plus troubleshooting steps for replaced `sys.stdout`), and capture manual/CI verification notes.
21
+
- ✅ Added FD mirror shutdown timeout with a polling helper to detach stuck reader threads plus unit coverage.
22
+
- ✅ Documented README guidance (ADR link, mirror flag notes, troubleshooting for replaced `sys.stdout`) and recorded the manual smoke command.
23
+
- ✅ Verification: `just dev test` (Linux) passes with new mirror timeout tests; Windows CI regression run still queued.
21
24
22
25
## Next Steps
23
26
1. Stage 4: finish FD mirror wiring — add mirror-only tests (`os.write` / mixed stdout/stderr), surface user-facing warnings on setup failure, and document the new `mirror` flag in chunk metadata.
2. Stage 5 follow-up: monitor the queued Windows CI regression run and flip ADR 0008 to Accepted once cross-platform verification lands.
25
28
3. Evaluate performance impact of the Python stack fallback and gate it behind monitoring snapshots once `sys.monitoring` integration fully drives the snapshot store.
0 commit comments