When troubleshooting an intermittent issue on a Mac—such as a Wi-Fi connection that drops every hour, or a background process that silently crashes upon waking from sleep—traditional log files are often useless. Starting with macOS Sierra, Apple entirely replaced the old text-based syslog system (where logs were simply written to /var/log/system.log) with the Unified Logging System. This new system stores logs in a proprietary, highly compressed binary format. To read, filter, and stream these logs from the Terminal, you must use the incredibly powerful log command.
The Problem with the Console App
While macOS includes a graphical “Console” application to view these logs, it is often too slow and overwhelming for deep troubleshooting. The unified system generates thousands of log entries per second. If you are trying to catch a specific error state, clicking through the GUI is inefficient. The command-line log tool allows you to use complex predicate filtering to pinpoint exactly what you need.
Step 1: Streaming Logs in Real-Time
The most powerful feature of the log command is the stream function, which acts like a modernized version of tail -f.
If you simply type log stream, your terminal will instantly flood with an unreadable torrent of data from every process on the Mac. You must apply a filter.
Suppose you are troubleshooting a Wi-Fi connection issue. You only want to see logs generated by the specific background process responsible for wireless networking (airportd).
log stream --process airportd
Now, watch the terminal while you manually turn Wi-Fi off and back on using the menu bar. You will see exactly what the daemon is doing in real-time, including the specific reasons it rejects a network or fails a password handshake.
Step 2: Using Predicate Filters
The --process flag is useful, but what if you don’t know which specific background daemon is causing the error? You can use NSPredicate syntax to search the actual text of the log messages across the entire system.
To stream any log message that contains the word “kernel” or “panic”:
log stream --predicate 'eventMessage CONTAINS[c] "panic"'
(The [c] makes the search case-insensitive).
Step 3: Querying Past Logs
Streaming is great for real-time issues, but if a user complains that their Mac crashed “sometime yesterday afternoon,” you need to look back in time. For this, you use the show command instead of stream.
To view all logs generated by the system’s power management daemon (powerd) in the last 24 hours, which is useful for diagnosing sleep/wake failures:
log show --predicate 'process == "powerd"' --last 24h
Step 4: Filtering by Subsystem
Apple developers strictly categorize their logs into “subsystems.” This is the most efficient way to filter the database. For example, all Bluetooth-related logs, regardless of which specific process generated them, are tagged with the com.apple.bluetooth subsystem.
If a user’s wireless headphones keep disconnecting, you can pull the logs for the exact timeframe the issue occurred:
log show --subsystem com.apple.bluetooth --start "2024-05-15 14:00:00" --end "2024-05-15 14:15:00"
Step 5: Exporting Logs for Apple Support
If you are escalating an issue to Apple Enterprise Support, they will almost always ask for a “sysdiagnose” or a log archive. You can package the entire compressed binary log database for a specific timeframe to send to an engineer.
sudo log collect --last 1h --output /tmp/mac_logs.logarchive
The resulting .logarchive file can be sent to Apple, or you can open it on another Mac using the graphical Console app to analyze it off-site. By mastering the log command, you bypass the limitations of graphical tools and gain direct access to the most detailed diagnostic data the Mac operating system produces.