Expand description
Log entry prefix identification and multi-line JSON accumulation.
Detects log entry boundaries using the [UnityCrossThreadLogger],
[ConnectionManager], and Matchmaking: header patterns,
then accumulates subsequent lines until the entry is structurally complete.
§Header classification (Phase 1 of #153)
Each detected header is classified as either single-line or multi-line:
- Single-line:
[UnityCrossThreadLogger]followed by anything other than a date digit (e.g., alpha labels likeSTATE CHANGED,Client.SceneChange, or==>API request markers),[ConnectionManager]…, andMatchmaking:…. These entries are flushed in the sameLineBuffer::push_linecall that received them — no continuation accumulation. - Multi-line:
[UnityCrossThreadLogger]<digit>(date-prefixed API responses, match events). These entries accumulate continuation lines until the entry’s JSON body is structurally complete (brace-balance flush) or the next header arrives (fallback for non-JSON bodies).
§Brace-balance flush (Phase 3 of #153 / #193)
Multi-line entries whose body contains a { are flushed the moment the
brace depth returns to 0 — they no longer wait for the next header to
arrive. A small state machine counts { and } while tracking string
literals (") and backslash escapes (\\), so braces appearing inside
JSON string values do not count. Corpus analysis (44 sessions, 47,412
multi-line entries) shows every entry that opens a { closes it within
the entry boundary; bodies that never open a { (a few true-only REST
responses and the EntryHeader::TruncationMarker entries whose
follow-on :: ... Count = N lines carry no JSON braces) still flush on
the next header via the original fallback path.
This behavior is enabled by default via the brace_depth_flush cargo
feature. Disabling the feature reverts to the original “flush on next
header” behavior for every multi-line entry — kept as a one-flip rollback
in case a string-literal edge case surfaces in live Arena traffic.
§Frame-counter prefix stripping (#240)
The newer MTGA Mac client (UTC_Log archive variant) prepends a
monotonic Unity frame counter of the form [<digits>] to every line
(e.g. [2841] [UnityCrossThreadLogger]…). LineBuffer::push_line
strips this prefix before any byte-0-anchored detector runs, so the
same log content parses identically whether or not it carries the
prefix. Callers and tests need not pre-strip the counter.
§Data flow
File Tailer ──(lines)──▸ LineBuffer ──(complete entries)──▸ RouterThe LineBuffer receives individual lines from the file tailer,
normalizes each line (strips the optional frame-counter prefix), then
classifies and accumulates. When a new log entry header is detected, it
flushes the previously accumulated lines as a complete LogEntry and
either emits the new entry immediately (single-line class) or begins
accumulating it (multi-line class).
Structs§
- Line
Buffer - Accumulates raw lines and produces complete
LogEntryvalues when an entry is structurally complete. - LogEntry
- A complete log entry extracted from the line buffer.
Enums§
- Entry
Header - The known log entry header prefixes in MTG Arena’s
Player.log.