How to Collect macOS Unified Logs for Forensics
Collect macOS Unified Logs with log collect, a raw copy of diagnostics and uuidtext, UAC, Velociraptor or mac_apt, and avoid the gaps that break parsing.
TL;DR. Collect the whole store, not just the .tracev3 files: message text lives in uuidtext and dsc, and times need timesync. On a live Mac, sudo log collect does all of it in one .logarchive. From an image or with a triage tool, copy /private/var/db/diagnostics and /private/var/db/uuidtext with their layout. Every method below produces something the Unified Log Parser opens directly.
What you need to end up with
| Needed | Why |
|---|---|
diagnostics/Persist, Special, Signpost, HighVolume | the entries (.tracev3) |
diagnostics/timesync | converts boot-relative times to UTC |
uuidtext/00…FF | format strings of each binary |
uuidtext/dsc | strings of the dyld shared cache (most Apple frameworks) |
The per-artifact Unified Logs cheat sheet on Mac Forensics summarises the paths and retention; this article focuses on getting a complete copy.
Option 1: log collect (live Mac, recommended)
sudo log collect --output ~/Desktop/$(hostname -s).logarchive
ditto -c -k --keepParent ~/Desktop/$(hostname -s).logarchive ~/Desktop/$(hostname -s).logarchive.zip
log collect copies the store, the string files and timesync into one bundle, plus the in-memory buffer (logdata.LiveData.tracev3). --last 3d, --start and --size limit the collection when the full store is too large; --predicate also exists but, per Apple's own help text, costs performance and memory. Write to external media when you can, and record the command and the time in UTC.
A .logarchive is a macOS package, which is a folder. Hash the files inside, or zip it with ditto and hash the ZIP. Some file pickers refuse to select a package; dragging it onto the parser page works, and so does the ZIP.
Option 2: copy the raw folders
OUT=/Volumes/EVIDENCE/$(hostname -s)_ul
sudo mkdir -p "$OUT"
sudo ditto /private/var/db/diagnostics "$OUT/diagnostics"
sudo ditto /private/var/db/uuidtext "$OUT/uuidtext"
This keeps files log collect may leave out (older Special files outside the time window) and involves no Apple tool, which some teams prefer. The store is being written while you copy, so the newest file may be incomplete; the parser reports damaged files instead of failing.
Option 3: triage tools
UAC. The macos_unified_logs artifact copies the tracev3 files, the uuidtext folder and timesync, and the ir_triage profile includes it:
sudo ./uac -a ./artifacts/files/logs/macos_unified_logs.yaml /Volumes/EVIDENCE
UAC writes a .tar.gz by default (-f zip for a ZIP). Drop it as-is: the parser streams the archive and keeps only the Unified Log files.
Velociraptor. There is no built-in macOS Unified Logs artifact; use Generic.Collectors.File with Root / and the globs private/var/db/diagnostics/** and private/var/db/uuidtext/**, in a hunt or an offline collector, then drop the collection ZIP.
Aftermath. Jamf's Aftermath does not copy the store; it saves the results of a set of log show predicates. Keep them, and take a .logarchive as well.
mac_apt. From an image, the UNIFIEDLOGEXPORT plugin exports tracev3, uuidtext and dsc files into Export/UNIFIEDLOGEXPORT.
Option 4: from a disk image
Mount the Data volume read-only. On a Mac, log collect can rebuild an archive from an offline store as long as uuidtext sits next to diagnostics:
sudo log collect --directory /Volumes/Image/private/var/db/diagnostics --output ~/case.logarchive
On Linux, copy both folders with their layout, for example cd /mnt/mac/private/var/db && zip -r ~/case_ul.zip diagnostics uuidtext.
Pitfalls
- Missing
uuidtext: the most common mistake. The parser shows the entries but marks their messages unresolved. - Collecting late: the store rotates by size, and
sudo log erasedeletes it. Collect before anything else that writes a lot of logs. - Only
log showtext: an export is fine for a quick look, but it depends on the options used (--info,--debug,--signpost,--timezone). See exporting and building timelines. - Paths flattened: tools that copy files without their folders lose the UUID encoded in the path of each
uuidtextfile.
Once collected, follow the browser walkthrough or jump straight to the triage queries.