What are macOS Unified Logs?
Since macOS 10.12 Sierra, the kernel, Apple's daemons and any app using os_log write to one logging system. logd stores entries in compressed binary .tracev3 files under /private/var/db/diagnostics; the text of each message is rebuilt from a format string kept in /private/var/db/uuidtext (per binary) or in the shared-cache dsc files, plus the values recorded with the entry.
For an investigator it is the richest time-ordered record on a Mac: logins and sudo, privacy (TCC) decisions, Gatekeeper and XProtect, launchd and login items, SSH and Screen Sharing, disk mounts — each entry with its process, PID, subsystem, category and a microsecond timestamp.
What this tool reads
- A .logarchive (from log collect or sysdiagnose), as a folder or a ZIP, or the raw diagnostics + uuidtext folders copied from a Mac or a disk image, including UAC (.tar.gz) and Velociraptor (ZIP) collections.
- tracev3 chunks: header, catalog, LZ4-compressed chunksets, firehose (log, activity, trace, signpost, loss), oversize strings, statedump and simpledump; boot-relative Mach times converted to UTC through the timesync records (Intel and Apple silicon timebases).
- Format strings resolved through uuidtext and dsc files and rendered like log show (printf conversions, %{public}/%{private}, errno, UUID and mask.hash decoders).
- Exports from log show: --style ndjson and json (every field), and the default, compact and syslog text styles, multi-line messages included.
- Filters by free text or regular expression, type, process, subsystem, category and PID (with exclusions), a time range to the second with a density strip, curated DFIR triage rules, and exports to CSV, NDJSON (log show field names), JSON and Timesketch.
Why it matters in an investigation
- Authentication and privilege: sudo commands and failures, su, authorization rights, SSH and Screen Sharing sessions, new local accounts.
- Defense evasion and persistence: TCC grants such as Full Disk Access to Terminal, Gatekeeper overrides, quarantine removal, new launch agents, daemons, login items and extensions.
- Exfiltration context: USB volumes mounted by DiskArbitration, network and file activity around the same minutes.
- Timeline anchor: microsecond timestamps and boot UUIDs line up every other macOS artifact.
Limits to keep in mind
- Messages are only as complete as the string files: without uuidtext and dsc, text cannot be rendered (entries are marked unresolved). Without timesync, times are approximate.
- <private> values were redacted when logged and cannot be recovered. Most Info and Debug messages are never written to disk.
- The store rotates by size, often keeping only days. An absence of entries is not proof that nothing happened.
- Rendering follows the open-source macos-unifiedlogs parser, validated here against log show (about 99% of log, activity and state messages identical); signpost text and some object decoders differ. Check key entries with log show before relying on them in a report.
- Everything is held in your browser's memory: very large stores (several million entries) may need the import options to load a time window.
How to collect them
- On the Mac: sudo log collect --output host.logarchive (the whole store), then drop the bundle or its ZIP.
- From an image or another tool: copy /private/var/db/diagnostics and /private/var/db/uuidtext with their layout (UAC macos_unified_logs, mac_apt UNIFIEDLOGEXPORT, Velociraptor Generic.Collectors.File).
- If you only have Apple's tool: log show --archive host.logarchive --info --debug --timezone UTC --style ndjson > host.ndjson.
Frequently asked questions
Are my logs uploaded anywhere?
No. The files are read by WebAssembly code running in a Web Worker in your browser. Nothing is sent to a server; closing the tab forgets everything.
Do I need a Mac to use it?
No. The tracev3 decoder runs in any modern browser on Windows, Linux or macOS. You only need the files: a .logarchive, or the diagnostics and uuidtext folders from a Mac or a disk image.
Why are some messages incomplete or marked unresolved?
The text of an entry comes from format strings stored in uuidtext and dsc files. If those files are missing from your collection, or the entry points to a string the files do not contain, the message cannot be fully rendered. Collect the uuidtext folder, or a .logarchive, which includes it.
Is the output identical to log show?
Very close, but not guaranteed. The decoder is based on Mandiant's open-source macos-unifiedlogs parser with fixes for log show fidelity (number formatting, UUIDs, errno and masked hashes). On a real archive about 99% of log messages matched log show exactly; signposts and a few object types are rendered differently. For evidence, confirm important entries with log show.
What time zone are the times in?
Entries are converted to UTC from the boot-relative Mach time using the timesync records. The UTC / Local switch changes only the display; exports always carry UTC.
How large a log store can it handle?
Several million entries, limited by the memory of your browser tab. For bigger stores use the import options to keep only a time window or to skip signposts, Info or Debug entries while reading.
Can it read the output of log show?
Yes: --style ndjson and json keep every field; the default, compact and syslog text styles work too, with less detail. Use --timezone UTC so times are unambiguous (the compact style has no UTC offset).
Are the triage findings proof of compromise?
No. They are presets that point to entries worth reading (sudo, TCC grants, Gatekeeper overrides, new launch items, USB mounts…). Many are routine on a normal Mac; judge them in context.