Skip to content

macOS Unified Logs Forensics: tracev3, log show, Predicates

Investigate macOS Unified Logs: tracev3 and uuidtext storage, log show predicates, logarchive collection, private redaction, retention and offline parsing.

Published on 8 min read

The Unified Logging system is the single most information-dense source of system activity on macOS. For an investigator it answers questions such as: who logged in and when, which commands ran with sudo, which apps requested privacy permissions, what software was installed, and whether Gatekeeper blocked or allowed a download. It replaced most of the classic text logs in macOS 10.12 Sierra, and its binary format, rotation behavior and privacy redaction all shape what you can prove. This article covers where the logs live, how to collect them, how to query them with log show, useful predicates for common investigative questions, and how to parse them away from a Mac. For a short definition see the Unified Logs glossary entry.

Where the logs live

Unified Logs are stored in two directory trees on the Data volume:

PathContent
/private/var/db/diagnostics/Persist/.tracev3 files with persisted log messages (the bulk of useful history)
/private/var/db/diagnostics/Special/.tracev3 files for special-purpose, lower-volume messages that may be kept longer
/private/var/db/diagnostics/Signpost/Performance signpost events
/private/var/db/diagnostics/HighVolume/High-volume messages, when present
/private/var/db/diagnostics/timesync/Boot and time correlation records used to convert internal timestamps to wall-clock time
/private/var/db/uuidtext/Format strings and image paths referenced by log entries, in subfolders named by the first byte of a UUID, plus dsc for the dyld shared cache

The .tracev3 files do not contain the full message text. An entry stores a reference to the executable image (by UUID), an offset to the format string, and the argument values. The format strings live in uuidtext. This design saves space, but it has a key consequence: you need both directories (and the timesync data) to reconstruct readable messages. Copying only diagnostics gives you entries you cannot fully render.

In-memory buffers hold messages that are never persisted, typically debug and many info-level messages. Those disappear at reboot or when overwritten, which is one reason to collect logs from a live system before shutting it down.

Collecting logs

log collect

On a live Mac, log collect packages the relevant data into a .logarchive bundle:

sudo log collect --output /Volumes/EVIDENCE/MBP-IR-01/system_logs.logarchive
sudo log collect --output /Volumes/EVIDENCE/MBP-IR-01/last3d.logarchive --last 3d
sudo log collect --output /Volumes/EVIDENCE/MBP-IR-01/window.logarchive --start "2026-09-20 00:00:00"

A .logarchive is a directory bundle containing the tracev3 files, the needed uuidtext data and an Info.plist. Without a time limit it can be large; collecting everything is usually worth the disk space. A sysdiagnose also contains a logarchive, which is useful when a user or MDM workflow can trigger one for you.

From a dead-box or triage collection

If you only have a disk image or a file-level copy, preserve /private/var/db/diagnostics and /private/var/db/uuidtext in full. Several parsers read these directories directly. Triage tools such as Aftermath and UAC can collect them; see macOS forensic acquisition for context.

Hash the collection as you would any other evidence. Because a logarchive is a directory, hash its files or wrap it in an archive first.

Querying with log show

log show reads either the live store or an archive:

log show --archive /cases/MBP-IR-01/system_logs.logarchive --last 1h
log show /cases/MBP-IR-01/system_logs.logarchive \
  --start "2026-09-20 08:00:00" --end "2026-09-20 12:00:00" \
  --style syslog

Useful options:

  • --start and --end bound the time window. They accept YYYY-MM-DD, YYYY-MM-DD HH:MM:SS or YYYY-MM-DD HH:MM:SSZZZZZ; include the UTC offset to avoid ambiguity. --last accepts values like 30m, 2h, 3d.
  • --info and --debug include those levels if they were persisted; by default only default, error and fault messages are shown.
  • --style controls output: default, compact, syslog, json, ndjson. JSON output is best for loading into timeline tools.
  • --predicate filters with an NSPredicate expression.

To get a sense of volume before filtering, log stats summarizes an archive by process, subsystem and time:

log stats --archive /cases/MBP-IR-01/system_logs.logarchive

Predicate fields

Predicates filter on entry properties. The fields most used in investigations:

FieldMeaning
processName of the process that logged the message
processImagePathFull path of that process's executable
sender / senderImagePathLibrary or binary that actually emitted the message
subsystemReverse-DNS subsystem, e.g. com.apple.TCC
categoryCategory within the subsystem
eventMessageThe rendered message text
messageTypedefault, info, debug, error, fault
eventTypee.g. logEvent, activityCreateEvent, signpostEvent

Operators include ==, !=, CONTAINS, BEGINSWITH, ENDSWITH, LIKE, MATCHES, and modifiers such as [c] for case-insensitive comparison. Combine terms with AND, OR and parentheses.

Useful predicates for investigations

Message wording changes between macOS releases. Treat these as starting points, run them broadly first, then refine once you see the exact messages on your target version.

sudo usage

sudo logs the invoking user, terminal, working directory and command:

log show system_logs.logarchive --style syslog \
  --predicate 'process == "sudo" AND eventMessage CONTAINS "COMMAND"'

SSH logins

Remote Login is handled by sshd. Accepted and failed authentications appear as sshd messages:

log show system_logs.logarchive --style syslog \
  --predicate 'process == "sshd" AND (eventMessage CONTAINS "Accepted" OR eventMessage CONTAINS[c] "failed")'

Local logins, unlocks and authorization

Console login and screen unlock activity involves loginwindow, and authorization decisions involve authd. These are verbose; narrow the time window first:

log show system_logs.logarchive --style syslog \
  --start "2026-09-20 07:00:00" --end "2026-09-20 09:00:00" \
  --predicate 'process == "loginwindow" OR process == "authd"'

TCC permission requests

Privacy permission checks are logged under the TCC subsystem. They show which client requested which service and the result, complementing the database view described in TCC database forensics:

log show system_logs.logarchive --style syslog \
  --predicate 'subsystem == "com.apple.TCC"'

On recent releases, look for messages mentioning AUTHREQ to follow a request through to its result, and verify the phrasing on your target version. See also TCC.

Software installation

Package installs run through installd and system_installd. The legacy text log /private/var/log/install.log still exists and is worth collecting alongside:

log show system_logs.logarchive --style syslog \
  --predicate 'process == "installd" OR process == "system_installd"'

Gatekeeper and code signing assessments

Gatekeeper decisions are made by syspolicyd. This is the place to confirm whether a quarantined download was assessed, allowed or blocked (see Quarantine events and Gatekeeper and Gatekeeper):

log show system_logs.logarchive --style syslog \
  --predicate 'process == "syspolicyd"'

Persistence and background items

On Ventura and later, Background Task Management activity can be followed via the backgroundtaskmanagementd process, which helps date when a login item or launch agent was registered (see launchd persistence):

log show system_logs.logarchive --style syslog \
  --predicate 'process == "backgroundtaskmanagementd"'

Private data redaction

Many messages show <private> in place of dynamic values such as usernames, paths or URLs. The logging API marks dynamic string arguments private by default unless the developer declares them public, and the value is dropped at write time. Key points:

  • Redacted values are not stored. No tool can recover them from existing logs.
  • On current macOS versions, enabling private data logging requires installing a configuration profile for the com.apple.system.logging domain (for example through MDM). The older log config approach to enable private data no longer works on recent releases.
  • Enabling it is a forward-looking decision for monitoring, not a forensic recovery technique, and it has privacy implications that should be approved.

Even redacted messages are valuable: the process, subsystem, timestamp and message template often reveal what happened, if not every detail.

Retention and persistence limits

Retention is governed by size quotas, not by days. The Persist store rotates as it fills, so a noisy system (for example one with verbose third-party security software) may keep only a few days, while an idle machine may keep weeks. Messages in Special can outlive the main store. Practical guidance:

  • After collecting, check the first and last timestamps actually present before you conclude that "nothing happened" in a window.
  • Collect early. Every hour a compromised Mac keeps running, older entries may be rotated out.
  • Info and debug messages are often not persisted at all unless logging was configured to keep them.
  • log erase exists and requires root. A suspicious gap, or a very short history on an otherwise quiet machine, may warrant a closer look at whether logs were cleared.

Parsing on other platforms

You do not need a Mac to analyze Unified Logs:

ToolLanguageNotes
macos-UnifiedLogs (Mandiant)RustLibrary with example command-line parsers; reads logarchives or raw diagnostics and uuidtext directories; outputs CSV or JSON
Unified Log ParserRust (WebAssembly, in the browser)Built on macos-UnifiedLogs; opens a logarchive, raw diagnostics and uuidtext directories or a log show export without uploading them; filters, DFIR triage rules, CSV or Timesketch output
mac_apt UNIFIEDLOGEXPORT pluginPythonExports diagnostics and uuidtext from images or mounted volumes for parsing with macos-UnifiedLogs; it does not parse the logs itself
UnifiedLogReader (ydkhatri)PythonEarlier cross-platform parser; may lag behind newer tracev3 changes
log showmacOS nativeReference implementation; use it to validate third-party output

Cross-platform parsers reimplement an undocumented format. Validate critical findings against log show on a Mac running the same or newer macOS version, and note the parser version in your report.

Pitfalls

  • Time zones: log show does not follow the TZ environment variable. Without --timezone, it prints each entry in the time zone recorded when the entry was written. Pass --timezone UTC before comparing with other artifacts that use Mac Absolute Time or UTC.
  • Missing uuidtext: without matching format strings, messages render incompletely. Always collect both directories or a proper logarchive.
  • Version drift: message text, subsystems and processes change between releases. Do not copy a predicate from an old write-up and treat an empty result as proof of absence.
  • Volume: unfiltered output from a full archive can reach millions of lines. Use log stats and narrow windows first, and export JSON for tooling.
  • Absence of evidence: redaction, rotation and non-persisted levels all mean a missing message is weak evidence that an event did not occur.

Frequently asked questions

How far back do macOS Unified Logs go?

There is no fixed period. Retention is driven by storage quotas per log class, so a busy Mac may keep only a few days of ordinary messages while quieter systems keep weeks. Some low-volume, persisted categories survive longer. Check the actual earliest timestamp in each collection rather than assuming.

Can I recover values redacted as private in old log entries?

No. Redaction happens when the message is written, so the private value is never stored. Enabling private data logging through a configuration profile only affects messages logged after it is installed.

Can I analyze Unified Logs on Windows or Linux?

Yes. Collect a .logarchive (or the diagnostics and uuidtext directories) and parse it with cross-platform tools such as Mandiant's macos-UnifiedLogs library or the older UnifiedLogReader. mac_apt's UNIFIEDLOGEXPORT plugin can export the log files from a disk image first. Validate results against log show on a Mac when possible.

Related guides

05 · Execution & Persistence

Investigating launchd Persistence on macOS

Find and analyze macOS persistence: LaunchAgents, LaunchDaemons, launchctl, Background Task Management (sfltool dumpbtm), cron, periodic and profiles.

Read guide