Mastering log show and log stream on macOS
Complete reference for macOS log commands — filtering with predicates, output styles, time ranges, and real-world troubleshooting workflows
log show vs. log stream
The log command-line tool has two primary modes, and choosing the right one matters:
log show queries the persistent log store on disk. It searches historical data that has already been written. Use it when investigating something that already happened.
log stream taps into the live message stream from logd. It displays messages in real time as they are generated. Use it when you need to observe what is happening right now, typically while reproducing a problem.
| Capability | log show | log stream |
|---|---|---|
| Data source | On-disk log store | Live in-memory stream |
| Time range | Any historical period | Present moment only |
| Debug/Info messages | Only if they were persisted | Available if --level is set |
| Output volume | Bounded by time range | Continuous until stopped |
| Remote devices | Via .logarchive files | Via log stream on device |
Key difference:
log showcan only display messages that were persisted to disk. Default and Error/Fault messages are always there, but Info and Debug messages may have been dropped.log streamsees everything at the requested level because it reads directly from the in-memory buffer.
Time Range Options for log show
Relative Time with –last
The simplest way to scope a query:
log show --last 5m # Last 5 minutes
log show --last 2h # Last 2 hours
log show --last 1d # Last 1 day
log show --last 3d # Last 3 days
Absolute Time with –start and –end
For precise investigation windows:
# Specific time range
log show --start "2026-02-14 09:15:00" --end "2026-02-14 09:45:00"
# From a start time to now
log show --start "2026-02-14 08:00:00"
# Combine with predicates
log show --start "2026-02-14 14:00:00" --end "2026-02-14 14:30:00" \
--predicate 'subsystem == "com.apple.mdmclient"'
Reading Log Archives
When working with collected archives from another machine:
# Query a .logarchive bundle
log show --archive ~/Desktop/incident.logarchive --last 1h
# Same predicate syntax works on archives
log show --archive ~/Desktop/incident.logarchive \
--predicate 'process == "kernel"' --last 4h
Output Styles
Control how log entries are formatted with --style:
syslog (default)
Traditional syslog-like format. Verbose but familiar:
log show --last 5m --style syslog
compact
Condensed single-line output. Best for scanning large volumes of data:
log show --last 1h --style compact --predicate 'subsystem == "com.apple.mdmclient"'
json
Structured JSON output. Essential for scripting and piping to jq:
log show --last 30m --style json --predicate 'process == "jamf"'
ndjson
Newline-delimited JSON (one JSON object per line). Ideal for streaming analysis:
log show --last 1h --style ndjson \
--predicate 'subsystem == "com.apple.SoftwareUpdate"' | \
jq 'select(.eventMessage | test("error"; "i"))'
Predicate Syntax
Predicates use NSPredicate format to filter log messages. This is the most powerful feature of the log command.
Basic Comparison Operators
# Exact match
--predicate 'process == "softwareupdated"'
# Not equal
--predicate 'process != "kernel"'
# String contains
--predicate 'eventMessage CONTAINS "failed"'
# Case-insensitive contains
--predicate 'eventMessage CONTAINS[c] "error"'
Available Predicate Fields
| Field | Description | Example |
|---|---|---|
process | Process name | process == "jamf" |
processImagePath | Full binary path | processImagePath ENDSWITH "mdmclient" |
subsystem | Subsystem identifier | subsystem == "com.apple.WiFiManager" |
category | Category within subsystem | category == "connection" |
eventMessage | The log message text | eventMessage CONTAINS "timeout" |
messageType | Log level | messageType == error |
senderImagePath | Library/framework path | senderImagePath CONTAINS "Security" |
eventType | Event type | eventType == logEvent |
Combining Predicates with AND / OR / NOT
# AND: both conditions must be true
--predicate 'subsystem == "com.apple.mdmclient" AND messageType == error'
# OR: either condition
--predicate 'process == "jamf" OR process == "JamfManagementService"'
# NOT: exclude matches
--predicate 'subsystem == "com.apple.mdmclient" AND NOT eventMessage CONTAINS "heartbeat"'
# Complex combinations with parentheses
--predicate '(subsystem == "com.apple.mdmclient" OR subsystem == "com.apple.ManagedClient") AND messageType == error'
String Matching
# Starts with
--predicate 'subsystem BEGINSWITH "com.apple.Wi"'
# Ends with
--predicate 'processImagePath ENDSWITH "daemon"'
# Wildcard (LIKE)
--predicate 'eventMessage LIKE "*certificate*expired*"'
# Regular expression (MATCHES)
--predicate 'eventMessage MATCHES ".*error code:? -?[0-9]+"'
Exporting and Piping
Save Output to a File
# Export filtered logs to a text file
log show --last 2h --predicate 'subsystem == "com.apple.mdmclient"' \
--style compact > ~/Desktop/mdm_logs.txt
# Export as JSON for programmatic analysis
log show --last 4h --style ndjson \
--predicate 'process == "softwareupdated"' > ~/Desktop/su_logs.json
Pipe to Unix Tools
# Count occurrences of specific errors
log show --last 1h --style compact \
--predicate 'messageType == error' | wc -l
# Extract unique error messages
log show --last 2h --style ndjson \
--predicate 'messageType == error' | \
jq -r '.eventMessage' | sort -u
# Find the most chatty processes
log show --last 10m --style ndjson | \
jq -r '.process' | sort | uniq -c | sort -rn | head -20
Performance Tips
- Always use predicates. An unfiltered
log show --last 1hcan return millions of entries and take minutes to complete. - Narrow the time range first. Start with
--last 5mand widen only if needed. - Use
--style compactfor scanning. JSON output is slower to render for large result sets. - Prefer
subsystemandprocesspredicates overeventMessage. Structured field matching is significantly faster than string searching through message text. - Use
log streamwith--level inforather than enabling persistent debug logging when you only need to observe a brief reproduction window.
Real-World Command Reference
MDM and Configuration Profiles
# MDM enrollment and command processing
log show --last 2h --predicate 'subsystem == "com.apple.mdmclient"' --style compact
# Profile installation events
log show --last 1h --predicate 'subsystem == "com.apple.ManagedClient" AND eventMessage CONTAINS "profile"' --style compact
# Live MDM debugging (enable debug level)
log stream --predicate 'subsystem == "com.apple.mdmclient"' --level debug
Software Updates
# Full software update timeline
log show --last 6h --predicate 'subsystem == "com.apple.SoftwareUpdate" OR process == "softwareupdated" OR process == "SoftwareUpdateNotificationManager"' --style compact
# Download progress and errors
log show --last 4h --predicate 'subsystem == "com.apple.SoftwareUpdate" AND eventMessage CONTAINS[c] "download"'
Bluetooth Issues
# Bluetooth connection events
log show --last 30m --predicate 'subsystem == "com.apple.bluetooth"' --style compact
# Pairing failures
log show --last 1h --predicate 'subsystem == "com.apple.bluetooth" AND eventMessage CONTAINS[c] "pair"'
Wi-Fi Connectivity
# Wi-Fi association and roaming
log show --last 1h --predicate 'subsystem == "com.apple.WiFiManager"' --style compact
# Authentication failures (802.1X)
log show --last 2h --predicate 'subsystem == "com.apple.WiFiManager" AND eventMessage CONTAINS[c] "auth"'
# Live Wi-Fi monitoring
log stream --predicate 'subsystem == "com.apple.WiFiManager"' --level info
Kernel Panics and Stability
# Kernel-level messages
log show --last 24h --predicate 'process == "kernel" AND (messageType == error OR messageType == fault)' --style compact
# Check for recent panic reports
ls -lt /Library/Logs/DiagnosticReports/*panic* 2>/dev/null
# I/O and storage errors
log show --last 2h --predicate 'process == "kernel" AND eventMessage CONTAINS "I/O"'
Login and Authentication
# Login window activity
log show --last 1h --predicate 'subsystem == "com.apple.loginwindow"' --style compact
# Authorization events (sudo, admin prompts)
log show --last 2h --predicate 'subsystem == "com.apple.Authorization"' --style compact
# PAM authentication
log show --last 1h --predicate 'process == "authorizationhost" OR (eventMessage CONTAINS "PAM")'
Push Notifications (APNS)
# APNS connectivity (critical for MDM push commands)
log show --last 2h --predicate 'subsystem == "com.apple.apsd"' --style compact
# APNS errors only
log show --last 4h --predicate 'subsystem == "com.apple.apsd" AND messageType == error'
Application Crashes
# ReportCrash activity
log show --last 1h --predicate 'process == "ReportCrash"' --style compact
# Specific app crashes
log show --last 2h --predicate 'process == "ReportCrash" AND eventMessage CONTAINS "Safari"'
FileVault and Encryption
# FileVault operations
log show --last 4h --predicate 'subsystem == "com.apple.fdesetup" OR eventMessage CONTAINS[c] "filevault"' --style compact
Quick Reference Card
# Template: log show
log show --last <time> --predicate '<filter>' --style <format>
# Template: log stream
log stream --predicate '<filter>' --level <debug|info|default> --style <format>
# Template: log collect
sudo log collect --last <time> --output <path>.logarchive
# Template: query a log archive
log show --archive <path>.logarchive --predicate '<filter>'
Build your own commands by combining a time range, a predicate, and an output style. Once you internalize this pattern, the unified logging system becomes one of the most powerful diagnostic tools in your Mac admin toolkit.