-
Notifications
You must be signed in to change notification settings - Fork 0
how to contribute debugging
Capto is privacy-first, so almost all debugging is local: structured logs, contextual crash reports written to disk, a loopback metrics endpoint, and an ETW sampling path. There is no cloud telemetry to query. This page collects the techniques and the common failure modes, from a silent CLI exit to a recording that drops frames.
This page is the first stop when something does not work: how to read logs, how to turn a crash report back into a code path, how to recover when the control plane is unreachable, and how to approach recorder failures. For the deeper observability details (metrics, breadcrumbs, crash schema) see How to monitor.
Logging uses tracing with a capto_* target convention. Two environment variables control output:
-
CAPTO_LOGgoverns the desktop process. Its default filter iscapto=debug,capto_core=debug,capto_encode=debug,warn(seeinit_tracinginapps/desktop/src-tauri/src/lib.rs). Raise a crate's level to get more detail, for examplecapto_core=debug,capto=warn. -
RUST_LOGgoverns the CLI. It iswarnby default.
The CLI writes the JSON envelope to stdout and human-readable log lines to stderr, so when a capto command misbehaves, capture stderr rather than stdout. The full env-var list is in .env.example.
Logs and error strings pass through crates/capto-ipc/src/redact.rs, which masks known secret patterns by construction. It rewrites Bearer <token> to Bearer *** and replaces the value of secret-looking query parameters (token, api_key, password, and the others listed in the file's SECRET_QUERY_KEYS). Two rules follow from this:
- Never log the bearer token yourself. It is read from
%APPDATA%\Capto\cli-server.json, and the whole point ofredactis that it never appears in tracing output. - Treat redaction as best-effort masking of known patterns, not full PII redaction. If you add a new endpoint or log line, route text through
capto_ipc::redact.
When the desktop process panics, the panic hook at apps/desktop/src-tauri/src/crashlog.rs writes a contextual report to <config>/Capto/crashes/crash-<epoch-ms>.json. The most useful fields for debugging are:
-
panicLocation, the exactfile:line:colof the panic, which is the fastest anchor to the code. -
subject, the panic message, andbacktrace, the captured stack (RUST_BACKTRACE=1enriches symbols). -
breadcrumbs, a capped, in-memory trail of the events that preceded the panic (control-plane requests, session transitions, lifecycle and hotkey markers), held incrates/capto-core/src/breadcrumbs.rs. -
lastRequestId, the most recent control-planex-request-id, for correlating the report with log output.
Read a crash from the end: the most recent breadcrumbs are the likely trigger. To reproduce, replay the breadcrumb sequence on a dev build and add a regression test once the trigger is isolated. The full walkthrough and report schema are in docs/crash-tracing.md. Reports are local only; delete <config>/Capto/crashes to remove them.
Most CLI friction comes from the control plane, which is a loopback HTTP server owned by the desktop process.
-
Exit code 2 (
desktopUnavailable). The desktop is not running. Start it first: runcapto open, or launch Capto from the Start menu, or setCAPTO_APP_PATHto a builtcapto-app.exeso the CLI auto-launches the dev desktop. Merge requests that return 404 with a fresh token usually mean the lockfile is stale (see gotchas). -
Lockfile. The desktop writes
%APPDATA%\Capto\cli-server.jsonwith the port and bearer token. If you hand-edit or copy it, the CLI's token may no longer match and every authenticated call returns 401. Delete the stale lockfile and restart the desktop. -
One-session rule. Only one desktop instance writes the lockfile. A second
capto-appinstance does not take over the control plane and can confuse which process owns the server; run a single instance when debugging.
Recording and encoding go through a single sidecar path (capto-encode and the frame pump in crates/capto-core/src/session.rs). A few signals help when output is missing or frozen:
- FFmpeg's stderr tail is captured into error messages, so a failed encode includes the relevant sidecar output.
- Slow-write instrumentation. The frame pump logs debug-level timing lines. A
slow ffmpeg write - capture outrunning encoderline means a single rawvideo write blocked 250 ms or more, the classic cause of dropped or frozen output. SetCAPTO_LOG="capto_core=debug,capto=warn"on the desktop process, drive a recording, then inspect the desktop's stderr. This and the ETW path are documented indocs/profiling.md. -
/v1/metricsexposes local usage counters, including per-status request counts andhttp_request_duration_ms, behind authentication and thecontrol-plane-metricsfeature flag.
-
Missing FFmpeg sidecar. The encode path needs
apps/desktop/src-tauri/binaries/ffmpeg-<triple>.exe(bundled via TauriexternalBin). Ifcapto doctorreports FFmpeg missing, re-run.\scripts\download-ffmpeg.ps1(orcopy-ffmpeg.ps1for a local build) before building. The sidecar comes only from the pinnedelwina/capto-ffmpegrelease, never from PATH. -
Stale
cli-server.json. Leftover from a previous run can point at a dead port and return mismatched-token 401s; clear it and restart the desktop. - Second desktop instance. Keep the single-instance rule in mind; it owns the control plane and the lockfile.