2.9 KiB
Architecture
Log Tools is a static React/Vite application inside the shared Toolbox shell. src/log/model.ts contains the streaming and bounded trust boundary. scanLogBlob() obtains a ReadableStream from the supplied Blob/File, reads byte chunks, decodes UTF-8 incrementally with TextDecoder.decode(..., {stream:true}), and feeds a line framer that retains at most 256 KiB for one physical line. A bounded multiline assembler groups configured stack-trace continuations and records their first and last physical lines. It never calls File.text(), arrayBuffer(), or constructs a complete-file string.
Automatic detection buffers only the first 30 nonblank bounded lines, chooses among JSON Lines, nginx common/combined, RFC 5424/common RFC 3164 syslog, logfmt, and plain text, then replays that small buffer through the selected parser. Explicit selection skips detection. Parsing continues up to five million lines or eight GiB. At most the first 10,000 nonblank records and 32 MiB of retained characters are kept; individual retained raw/message strings, fields, level/source maps, hourly timestamp buckets, field names, counters, and progress are independently capped. Reads yield between progress intervals so cancellation and UI updates can run.
Filtering operates interactively on the retained preview. Correlation counts describe the scanned portion. Redaction recipes transform raw text, normalized messages, sources, and extracted values using fixed, linear-oriented patterns and an optional exact literal. Expanded redaction output is capped per value and truncation is reported. Salted pseudonyms use a stable non-cryptographic hash: useful for local equality correlation, not encryption or resistance to guessing. Quick exports use the preview; exportLogBlob() performs a second cancellable streaming pass and reapplies parsing, filters, and redaction to all records. It writes through a supplied WritableStream, or returns a Blob under a 256 MiB cap. CSV prefixes spreadsheet-formula-leading cells.
Multi-file analysis streams each selected file through the same scanner, retains at most 3,000 records per file, and merges only those retained records. analyzeLogSources() caps file count, record count, retained characters, merged events, and correlation groups. It recognizes valid non-zero W3C-sized trace/span IDs plus bounded common request identifiers, reports unresolved parent references as retained-evidence gaps, and never adjusts timestamps. exportOtlpJson() produces a focused bounded OTLP/JSON request from retained records; it does not claim to reconstruct complete traces or export the unretained source.
React renders log values through text nodes only. ANSI escape sequences are removed and other control bytes are replaced; HTML-like content is never interpreted. Relative assets and a same-origin scoped service worker keep the build relocatable below nested portal routes. There is no telemetry, database, server API, worker, or remote dependency at runtime.