wiretrace

command
v0.164.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Binary wiretrace decodes and analyzes wire traces written by the traced tdesktop build (gotd/tdesktop fork, branch "trace") and by the github.com/gotd/td/wiretrace package, so gotd can copy the official client practices: which methods, in which order, how they are wrapped and when they are sent.

wiretrace decode   [--schema S] [--max-bytes N] [--dir in|out] [--method M] [--no-body] RUN
wiretrace timeline [--schema S] [--no-storage] [--kinds K,...] [--ui[=collapse]] RUN
wiretrace stats    [--schema S] [--json] [--top N] [--by method|ui] RUN
wiretrace diff     [--schema S] [--schema-b S] [--timing] [--fields=false] [--align phase|ui|marker] A B

RUN is a run directory with events-NNNN.jsonl and blobs-NNNN.bin, e.g. <tdesktop working dir>/trace/20260101T000000Z-1234 (UTC start time, pid).

The schema is the api.tl and mtproto.tl of the traced build (tdesktop Telegram/SourceFiles/mtproto/scheme): --schema takes that directory or a comma-separated list of .tl files; without it, $WIRETRACE_SCHEMA and the run directory and its parents (and their "schema" subdirectories) are searched. decode and diff need it; timeline and stats only use it for names and fall back to the gotd tg/mt names.

decode prints one JSON line per logical message: containers are split ("container" is the parent msg_id), wrappers are listed in "wrap" (["invokeWithLayer:233","initConnection"]), "method" is the innermost query, "req" and "caller" come from req.msg/req.caller, rpc_result gets "req_msg_id", the request "method", "result", "latency_ms" (wire) and "error", and "body" is the schema-decoded TL:

wiretrace decode --schema ~/src/tdesktop/Telegram/SourceFiles/mtproto/scheme RUN |
	jq -c 'select(.dir=="out") | [.t, .method, .wrap]'

timeline interleaves messages, requests, connection, key, session and storage events, with causes ("⇐ req#57 messages.getDialogs") and effects ("→ caused st.write map, req.new messages.getPeerDialogs"):

wiretrace timeline --no-storage RUN | less

stats prints per-method counts and latency percentiles, rpc errors (with numbers masked), flood waits, reconnect reasons, per-DC sessions, messages and bytes, wire-level message kinds, callers and redactions.

diff splits both runs into phases (connect, bind, init, auth, bootstrap, steady), maps each outgoing message to a shape token such as container[ping_delay_disconnect(75), invokeWithLayer(initConnection(help.getConfig))], aligns the tokens with LCS and reports messages only in A (-) or B (+), reordered methods, field differences of aligned messages (volatile fields such as msg_id, random_id, hashes and dates masked) and, with --timing, offsets, phase durations, ping cadence and reconnect backoff:

wiretrace diff --schema S --timing tdesktop-run gotd-run

With UI events (ui.*, app.*; see package uiattr), timeline --ui groups requests under the UI action they are attributed to (sync, chain, deferred, after; update-driven and background requests separately), --ui=collapse prints one line per action; stats --by ui adds per action, per view and attribution share tables; diff --align ui aligns actions and markers by token (click(Dialogs::InnerWidget)>chat(user)) and diffs the requests of aligned pairs, diff --align marker aligns ui.marker labels (e.g. two tdesktop runs driven by the same script) and diffs the requests between them. --ui-window (default 3s) bounds weak "after" stamps and --ui-infer attributes unstamped main-thread requests by time.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL