Логи macOS: unified logging и диагностика

Рейтинг: 45.3% · 9 голосов
Подробный курс по macOS для разработчиков и админов: архитектура и Apple Silicon, терминал и zsh, Homebrew и пакеты, launchd и автоматизация, APFS и Time Machine, безопасность (SIP, Gatekeeper, TCC, FileVault), сеть, логи и диагностика, MDM и DDM, контейнеры и виртуализация, восстановление. По официальной документации Apple, актуально на 2026 (macOS 26 Tahoe).
Ответить
Аватара пользователя
Artem_MacAdmin
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Логи macOS: unified logging и диагностика

Сообщение Artem_MacAdmin »

Оглавление курса (47)
  1. Что такое macOS: Unix под капотом и место в 2026
  2. Архитектура macOS: XNU, тома и Signed System Volume
  3. Apple Silicon: ARM, Rosetta 2 и отличия от Intel
  4. Установка, обновление и восстановление macOS
  5. Finder, рабочий стол и продуктивность
  6. Системные настройки и их управление из CLI (defaults)
  7. Пользователи и группы: учётные записи и управление
  8. Терминал и zsh: командная строка macOS
  9. CLI на macOS: BSD-команды и отличия от Linux
  10. Настройка zsh: .zshrc, prompt, плагины
  11. Файловая система и права: POSIX, ACL, атрибуты, флаги
  12. Homebrew: пакетный менеджер для macOS
  13. Homebrew глубже: tap, Brewfile, services, обслуживание
  14. Другие пакеты: MacPorts, mas, Nix и App Store
  15. Установка приложений: .app, .dmg, .pkg и Gatekeeper
  16. Управление приложениями и их данные
  17. launchd и launchctl: система запуска macOS
  18. Свои службы и периодические задачи на launchd
  19. Автоматизация: Shortcuts, AppleScript и osascript
  20. Конфигурация как код: defaults, plist и профили
  21. APFS: снапшоты, клоны, контейнеры и шифрование
  22. Управление дисками: diskutil, образы и форматирование
  23. Time Machine и резервное копирование
  24. Внешние диски, форматы и сетевые тома
  25. Модель безопасности macOS: SIP и целостность системы
  26. Gatekeeper, нотаризация и защита от вредоносов
  27. Приватность и TCC: разрешения на доступ
  28. FileVault: полнодисковое шифрование
  29. Связка ключей и управление секретами
  30. Сетевой экран и защита сети
  31. Сеть в macOS: настройка и инструменты
  32. Диагностика сети на Mac
  33. Общий доступ: SSH, экран, файлы, удалённое управление
  34. Процессы и ресурсы: мониторинг производительности
  35. Логи macOS: unified logging и диагностика (вы здесь)
  36. Производительность и энергия: powermetrics, диагностика
  37. Энергия, сон и обслуживание системы
  38. Профили конфигурации и основы MDM
  39. Управление парком Mac: MDM, DDM и zero-touch (2026)
  40. Среда разработчика на Mac: Xcode CLT, git, версии
  41. Контейнеры на Mac: Docker Desktop, OrbStack, Apple container
  42. Виртуализация: Virtualization.framework, UTM, Linux и Windows
  43. Режимы загрузки и восстановление (Apple Silicon)
  44. Сброс, NVRAM, Safe Mode и сброс настроек
  45. Траблшутинг macOS: дерево решений по симптомам
  46. Место на диске и обслуживание системы
  47. Сквозной проект: настройка Mac как у профи + куда расти
Открой на Linux-машине /var/log/syslog - и ты сразу видишь, что происходит: текстовый файл, tail -f, grep, готово. Приходишь с этой привычкой на Mac, лезешь в /var/log - а там пусто. Несколько огрызков, install.log, может, пара текстовых файлов от сторонних демонов, и все. Где система пишет, что приложение упало, что Wi-Fi отвалился, что sshd отбил три неудачных логина? Ответ: нигде в текстовом виде. С macOS Sierra (10.12, 2016 год) Apple выкинула привычный syslog/ASL и перешла на unified logging - единый структурированный лог. И это не косметика, а другая модель целиком. Кто этого не знает, тот на Mac слеп: не находит логи mac там, где ищет, и думает, что система "ничего не пишет". Пишет, и очень много. Просто читать надо иначе - через утилиту log, а не через cat.

В этом уроке разберем, как устроено unified logging изнутри, как доставать нужное через log show и log stream с предикатами, что делать с приватными данными в логах, где лежат crash report mac (отчеты о сбоях) и зачем нужен sysdiagnose. Цель - чтобы после урока ты диагностировал проблему на чужом Mac за минуты, а не часами тыкал console mac наугад.

Почему текстовых /var/log больше нет: механика unified logging

Старый syslog был прост и туп: процесс форматировал строку, отдавал ее демону, тот дописывал в текстовый файл. Дешево по коду, дорого по ресурсам - на каждое сообщение строка форматируется (даже если ее никто не прочитает), пишется на диск, занимает место. На ноутбуке с SSD и батареей это расточительно.

Unified logging построен наоборот. Ключевая идея - отложенная сериализация. Когда код вызывает os_log, сообщение не превращается сразу в строку. Сохраняется компактная бинарная запись: указатель на формат-строку (которая лежит в самом бинарнике), сырые аргументы, метаданные (subsystem, category, тип, время, PID, activity ID). Форматирование в человекочитаемый текст происходит только в момент, когда ты реально запрашиваешь лог через log show. Это резко дешевле: писать почти нечего, а если запись никто не прочитает - работы по форматированию ноль.

Где это живет. Сначала записи попадают в кольцевые буферы в памяти (in-memory ring buffer) - самое свежее, быстрое, эфемерное. Записи уровня default и важнее переливаются на диск в /var/db/diagnostics (файлы .tracev3 - бинарный формат), плюс служебные данные в /var/db/uuidtext (там карта UUID бинарников и format-строк, без нее .tracev3 не расшифровать). Демон, который всем этим дирижирует, - logd. Никакого rsyslog, никакого systemd-journald - своя система.

Теперь критичный момент про уровни. В unified logging их несколько, и от уровня зависит, переживет ли запись перезагрузку:
  • default - обычное сообщение, пишется на диск, хранится долго (дни-недели, зависит от объема).
  • info - дополнительная информация. В память пишется, но на диск по умолчанию НЕ персистится надолго - живет, пока ее не вытеснили.
  • debug - отладка. Самый эфемерный уровень, по умолчанию вообще не собирается, пока ты явно его не включишь.
  • error и fault - ошибки уровня процесса и системные сбои, persistent.
Практический вывод: если ловишь баг, который случается раз в час, и хочешь видеть info/debug - их надо ЯВНО запросить флагами, иначе log show их просто не покажет, даже если они были. Это первая массовая грабля новичков: "я же видел в stream, а в show пусто" - потому что в show без --info --debug эти уровни отфильтрованы.

Изображение

log show: достаем историю с предикатами

log show - это машина времени по логу. Читает .tracev3 с диска (или из указанного архива) и разворачивает в текст. Главные рычаги - временное окно и предикат-фильтр.

Временное окно. Либо --last с относительным интервалом, либо --start/--end с абсолютной меткой:

Код: Выделить всё

log show --last 30m
log show --start "2026-06-15 09:00:00" --end "2026-06-15 09:05:00"
Без окна команда вывалит весь лог с момента загрузки - это десятки тысяч строк, читать невозможно. Всегда сужай интервал.

Уровни. По умолчанию show отдает только default и выше. Чтобы увидеть info и debug:

Код: Выделить всё

log show --last 10m --info --debug
Предикат - сердце фильтрации. Синтаксис - это NSPredicate (тот же язык, что в Core Data и Cocoa), а не grep-регекспы. Ключевые поля: process, subsystem, category, eventMessage, messageType. Операторы: ==, !=, CONTAINS, BEGINSWITH, ENDSWITH, matches (это уже ICU-регексп), &&/AND, ||/OR.

Реальный сценарий: разбираемся, почему Mac не уходит в сон. Смотрим подсистему управления питанием:

Код: Выделить всё

log show --last 1h --predicate 'subsystem == "com.apple.powerd"' --info
Другой сценарий - кто-то ломится по SSH, хотим увидеть события sshd за сутки:

Код: Выделить всё

log show --last 1d --predicate 'process == "sshd"'
Фрагмент типичного вывода log show:

Код: Выделить всё

Timestamp                       Thread     Type        Activity             PID    TTL
2026-06-15 09:42:11.083214+0300 0x1f3a     Default     0x0                  481    0    sshd: (libpam) Authentication failure
2026-06-15 09:42:11.084902+0300 0x1f3a     Error       0x0                  481    0    sshd: error: PAM: authentication error for admin from 203.0.113.7
Разбор по колонкам. Timestamp - время с микросекундами и таймзоной. Thread - идентификатор потока (хекс). Type - тот самый уровень (Default, Error, Fault, Info, Debug) - на него смотришь в первую очередь, Error и Fault это твои красные флажки. Activity - ID активности, по нему можно сшить цепочку связанных событий через несколько процессов. PID - процесс. TTL (time to live) - сколько записи жить. Дальше сам eventMessage. Видим: PAM-ошибка аутентификации, кто-то с 203.0.113.7 подбирал пароль admin. За пару команд - картина инцидента.

Полезный флаг вывода - --style. compact дает однострочный плотный формат, json - машиночитаемый для скриптов и jq, syslog - привычный для тех, кто пришел с Linux:

Код: Выделить всё

log show --last 5m --predicate 'process == "sshd"' --style syslog
log stream: живой поток в реальном времени

Если log show - это про прошлое, то log stream - про здесь и сейчас. Это аналог tail -f, но по unified logging. Подключаешься к logd и видишь события по мере их появления. Незаменимо, когда воспроизводишь баг руками: запустил stream, ткнул в приложение, смотришь, что полетело.

Предикаты те же, что в show. Ловим живьем все, что пишет конкретное приложение:

Код: Выделить всё

log stream --predicate 'process == "Safari"' --level debug
Важное отличие в управлении уровнем. В stream используется флаг --level (default | info | debug), а не отдельные --info/--debug как в show. --level debug включает самый подробный режим. Без него ты в потоке тоже не увидишь debug.

Грабля стрима: по умолчанию он показывает default-уровень и НЕ показывает activity-tracing-сообщения и backtraces, плюс глушит часть приватных полей. Если охотишься за деталями - ставь --level debug и при необходимости --type. И помни: stream это живой поток, прошлое он не покажет в принципе - для прошлого только show.

Связка на каждый день - живой мониторинг сетевого демона при отладке VPN или Wi-Fi:

Код: Выделить всё

log stream --predicate 'subsystem == "com.apple.network" OR process CONTAINS "wifi"' --info
Приватность: загадочное слово private в логах

Рано или поздно ты упрешься в это и потеряешь полчаса, если не знать заранее. Запускаешь log show, ждешь увидеть имя файла, IP, имя пользователя - а вместо значения стоит <private>:

Код: Выделить всё

2026-06-15 10:03:55.124+0300 Default  mDNSResponder  Query for <private> (PTR)
Это не баг. Это политика приватности unified logging. Разработчик в os_log помечает аргументы как public или private. Все, что не помечено явно как public, динамические строковые аргументы по умолчанию считаются private и редактируются. Цель благая - чтобы DNS-запросы, пути с именами людей, токены не утекали в логи, которые потом уезжают в support и diagnostic-архивах.

Критично понять: редакция происходит при записи, а не при чтении. Когда в .tracev3 уже легло <private> - реального значения там нет, оно не сохранялось вообще. Никаким sudo и никаким флагом log show ты его задним числом не достанешь. Если хочешь видеть приватные данные - надо ВКЛЮЧИТЬ их раскрытие ДО того, как событие произошло.

Делается это конфигурационным профилем (.mobileconfig) с payload SystemLogging и свойством Enable-Private-Data для нужного subsystem, либо - для локальной отладки - кладешь plist в /Library/Preferences/Logging/Subsystems/ с именем подсистемы. Например, чтобы раскрыть приватные данные mDNSResponder:

Код: Выделить всё

sudo defaults write /Library/Preferences/Logging/Subsystems/com.apple.mDNSResponder Enable-Private-Data -bool YES
После этого новые (только новые) записи этой подсистемы пишутся без редакции. Обязательно выключи обратно, когда закончил - иначе на машине годами копятся незамаскированные DNS-запросы, пароли в URL и прочая чувствительная фактура, и это уже дыра:

Код: Выделить всё

sudo rm /Library/Preferences/Logging/Subsystems/com.apple.mDNSResponder.plist
Делай это только на тестовых машинах и временно. На проде и тем более на пользовательских Mac раскрытие private - прямое нарушение приватности.

Console.app, отчеты о сбоях и архивы для пересылки

Графика для тех, кому терминал не нужен или нужен второй ракурс - Console (console mac, Программы -> Утилиты -> Консоль). Слева список устройств (включая подключенные iPhone/iPad), сверху живой поток с поиском, и - самое ценное - раздел отчетов. Чтобы Console показывала info и debug, в меню Действие надо явно включить "Включить сообщения информации" и "Включить отладочные сообщения" - по умолчанию, как и в CLI, они скрыты.

Crash report mac - отчеты о сбоях. Когда приложение падает, система пишет детальный отчет: стек вызовов всех потоков, состояние регистров, загруженные образы, причина (signal, exception). Лежат эти отчеты в двух местах:
  • ~/Library/Logs/DiagnosticReports - сбои пользовательских процессов (от твоего имени).
  • /Library/Logs/DiagnosticReports - системные и корневые процессы.
Современный формат - .ips (это JSON: первая строка - метаданные-заголовок, дальше тело отчета). Старый формат назывался .crash (plain text), сейчас ты в основном встретишь .ips, особенно на свежих macOS. Помимо полных сбоев туда же кладутся spin-отчеты (приложение зависло, "вертушка") и jetsam/wakeups-отчеты. Глянуть последние сбои из терминала:

Код: Выделить всё

ls -lt ~/Library/Logs/DiagnosticReports | head
log show --last 1d --predicate 'eventMessage CONTAINS "crash" OR messageType == 17'
В заголовке .ips-отчета ищи поля "Exception Type" (например EXC_BAD_ACCESS - обращение к чужой памяти, классика segfault) и "Termination Reason" - это первое, что говорит, ОТ ЧЕГО упало.

log collect - архив логов для пересылки. Нужно отдать коллеге или в support срез лога? Не копируй /var/db/diagnostics руками (без uuidtext он бесполезен). Есть штатная команда:

Код: Выделить всё

sudo log collect --last 2h --output ~/Desktop/incident.logarchive
Получаешь самодостаточный .logarchive-бандл. Его потом открывают той же командой на любой машине: log show --archive incident.logarchive --predicate '...'. Перенос лога с одного Mac на другой - именно так, а не копированием сырых файлов.

sysdiagnose: тяжелая артиллерия диагностики

Когда проблема плавающая, охватывает всю систему и одним предикатом ее не локализуешь, нужен sysdiagnose. Это не лог, а полный снимок состояния системы одной командой: весь unified log за период, лог ядра, spindump, несколько секунд fs_usage и top, список загруженных kext, отчет System Profiler, ВСЕ crash/spin-отчеты, состояние сети, использование диска, IOKit-реестр, лог управления питанием и так далее. Именно sysdiagnose просит инженер Apple, когда заводишь Feedback по серьезному багу.

Код: Выделить всё

sudo sysdiagnose
Команда крутится несколько минут (она тяжелая - грузит систему, не запускай на проде в час пик) и складывает gzip-архив в /var/tmp/. Есть и горячая комбинация - Control-Option-Command-Shift-точка - она инициирует сбор в фоне и подает короткий гудок/вспышку; удобно, когда баг происходит прямо сейчас и нет терминала под рукой. Архив большой (сотни мегабайт), внутри - дерево папок, разбирать которое можно тем же log show по вложенному system_logs.logarchive.

Что все-таки осталось в /var/log

Чтобы не было иллюзии, что текстовых логов нет совсем. Часть подсистем и сторонних демонов по историческим причинам пишет по-старому. Самый известный житель - /var/log/install.log: подробный текстовый лог установки системы и обновлений, читается обычным tail/grep и очень помогает при разборе провалившегося апдейта macOS. Там же могут лежать wifi.log (если включено сетевое логирование), логи отдельных пакетов из Homebrew или сторонних установщиков. Но это исключения. Системные события - в unified logging, и точка. Привычку "сразу в /var/log" на Mac надо переучить в "сразу в log show / log stream".

Типичные грабли
  • Ищешь логи в /var/log и делаешь вывод, что система молчит. Она не молчит - смотри через log, а не через файлы.
  • log show без временного окна. Вывалит весь лог от загрузки, утонешь. Всегда --last или --start/--end.
  • Не видишь info/debug. В show нужны --info --debug, в stream нужен --level debug. По умолчанию они отфильтрованы.
  • Путаешь флаги уровней. show использует --info/--debug, stream использует --level. Не взаимозаменяемы.
  • Ждешь, что <private> раскроется задним числом. Нет. Редакция при записи. Раскрывать надо профилем/plist ДО события и потом вернуть обратно.
  • Копируешь сырые .tracev3 для пересылки. Без uuidtext они не читаются. Используй log collect и .logarchive.
  • Предикат как grep. Это NSPredicate, а не регексп. CONTAINS, не =~. Регексп только через matches и ICU-синтаксис.
  • Запускаешь sysdiagnose на нагруженном проде в пик. Команда тяжелая, бьет по производительности на минуты.
Мини-лаба (повтори руками)
  • 1. Открой Терминал. Выполни log show --last 5m --predicate 'process == "loginwindow"'. Найди в выводе колонки Type и PID, определи, есть ли там Error.
  • 2. Запусти живой поток своего браузера: log stream --predicate 'process CONTAINS "Safari"' --level info. В другом окне открой вкладку и посмотри, что полетело. Останови по Control-C.
  • 3. Найди приватные данные: log show --last 10m --predicate 'process == "mDNSResponder"' и убедись, что часть значений - <private>.
  • 4. Сними архив за полчаса: sudo log collect --last 30m --output ~/Desktop/lab.logarchive. Открой его обратно: log show --archive ~/Desktop/lab.logarchive --last 5m.
  • 5. Загляни в отчеты о сбоях: ls -lt ~/Library/Logs/DiagnosticReports. Если есть .ips, открой его и найди строку Exception Type.
  • 6. Бонус: открой Console (console mac), включи в меню Действие отображение info и debug, поищи "wifi" в живом потоке.
Контрольные вопросы
  • 1. Почему unified logging дешевле старого syslog по ресурсам - в чем суть отложенной сериализации?
  • 2. Команда log show --last 1h ничего не показывает на уровне debug, хотя ты уверен, что debug-события были. Что добавить и почему?
  • 3. В выводе стоит <private>. Можно ли достать реальное значение из уже записанного лога? Что нужно было сделать заранее и где это переключается?
  • 4. Чем отличаются log collect и sysdiagnose, и в какой ситуации ты выберешь каждый?
Итог

Логи на Mac - это не файлы, это запросы. Сердце системы - unified logging: бинарные структурированные записи в памяти и в /var/db/diagnostics, которыми рулит logd, а форматируются они только при чтении. Твои основные инструменты: log show для истории с предикатами и временным окном, log stream для живого потока, log collect для самодостаточного .logarchive на пересылку, Console для графики и отчетов о сбоях, и sysdiagnose для полного снимка системы. Помни про уровни (default/info/debug) и явное включение info/debug, про редакцию <private> при записи, и про то, что crash report mac лежат в DiagnosticReports в формате .ips. Освой предикаты NSPredicate - и любой Mac станет для тебя прозрачным.
👍4 ❤️2 🔥 😄 🤔1
Аватара пользователя
vuekun
Сообщения: 1
Зарегистрирован: 24 май 2026, 22:58

Re: Логи macOS: unified logging и диагностика

Сообщение vuekun »

Блин, полгода на маке искал логи в /var/log и думал что система их не пишет. Этот <private> меня вообще в ступор вводил, теперь понятно почему sudo не помогал. Спасибо за разбор предикатов.
👍2 ❤️1 🔥 😄 🤔1
Аватара пользователя
nikita1337
Сообщения: 1
Зарегистрирован: 23 май 2026, 14:49

Re: Логи macOS: unified logging и диагностика

Сообщение nikita1337 »

Вопрос: а log collect --last 2h реально вытащит весь debug за два часа или там тоже надо что-то доввести? И .logarchive потом на другом маке точно откроется без плясок с uuidtext?
👍3 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Процессы и ресурсы: мониторинг производительности
Следующая глава →
Производительность и энергия: powermetrics, диагностика

Все главы курса «macOS для профи: администрирование, терминал и Homebrew»

Поделиться темой: ✈ Telegram VK
  • Похожие темы
Похожие запросы: Логи и диагностика macOSТраблшутинг и обслуживание MacЧто такое macOS и Unix под капотом

Вернуться в «macOS для профи: администрирование, терминал и Homebrew»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость