os_log: що це, можливості та робота уніфікованого логування в Apple

Автор: IT Sectr Опубліковано: 2026-05-28 Час читання: 9 хв

os_log — це уніфікований API логування від Apple для iOS та macOS, який замінив NSLog та os_trace. На відміну від старих механізмів, os_log працює на рівні ядра: повідомлення буферизуються в кільцевому буфері та записуються на диск лише після досягнення порогу активності. За даними Apple WWDC 2016, os_log знижує навантаження на диск у 10 разів порівняно з NSLog і дає контроль над рівнем деталізації через категорії та типи. Це основний інструмент діагностики для iOS-розробника: через Console.app можна фільтрувати повідомлення за процесом, категорією та рівнем критичності в реальному часі.

Головне

  • os_log — системний API логування від Apple, який буферизує повідомлення в ядрі та знижує навантаження на диск до 90% порівняно з NSLog
  • Рівні — Default, Info, Debug, Error, Fault — кожен фільтрується незалежно та може бути ввімкнений або вимкнений через профіль збору логів
  • Категорії — рядкові мітки всередині одного subsystem, які дозволяють групувати логи за модулями додатку без створення окремих файлів
  • Конфіденційність — os_log автоматично маскує дані в лапках, позначені як private, та шифрує їх у продакшен-логах
  • log collect — утиліта командного рядка для вивантаження зібраних логів з пристрою для подальшого аналізу в Console.app

Що таке os_log

os_log — це уніфікований API логування, представлений Apple в iOS 10 та macOS Sierra. Він об’єднав розрізнені механізми логування NSLog, os_trace та syslog в єдину систему з буферизацією на рівні ядра XNU.

На відміну від NSLog, який синхронно записує кожне повідомлення на диск та блокує потік, os_log використовує асинхронний кільцевий буфер у пам’яті. Повідомлення скидаються на диск лише коли активність перевищує заданий поріг або за командою log collect. Це радикально знижує вплив логування на продуктивність додатку.

os_log підтримує шість рівнів критичності, розмежування за subsystem та category, а також вбудований механізм приватності: дані, позначені як private, автоматично маскуються в продакшен-логах і доступні лише розробнику при підключенні через Xcode.

Історія появи уніфікованого логування

До iOS 10 розробники використовували NSLog для налагодження та syslog для системних повідомлень. NSLog писав у stderr та консоль, але був надзвичайно неефективним: кожне повідомлення синхронно записувалося на диск, викликаючи затримки в UI при частому логуванні. os_log вирішив цю проблему, перенісши буферизацію на рівень BSD-частини ядра XNU та зробивши запис на диск асинхронним.

Де застосовується os_log

os_log використовується у всіх додатках Apple та рекомендується Apple як єдиний API логування для iOS, macOS, tvOS та watchOS. Система та сторонні додатки пишуть через нього повідомлення в єдину базу даних — вона зберігається в пам’яті та періодично вивантажується на диск. Аналізувати ці логи можна через Console.app на Mac або через команду log в терміналі.

Як працює os_log: архітектура та буферизація

Архітектура os_log складається з трьох шарів: клієнтський API у просторі користувача (libsystem_trace.dylib), кільцевий буфер у ядрі XNU та демон logd, який асинхронно скидає буфер на диск.

Коли додаток викликає os_log, повідомлення копіюється в кільцевий буфер ядра розміром кілька мегабайт. Буфер працює за принципом FIFO: якщо він заповнений, старі повідомлення перезаписуються новими. Демон logd періодично перевіряє буфер та зберігає повідомлення у файли .tracev3 у захищеній області файлової системи.

За даними Apple Engineering, типова затримка від виклику os_log до появи повідомлення в Console.app становить 1–5 секунд на пристрої та до 60 секунд при скиданні на диск у пакетному режимі. Це свідомий компроміс: продуктивність додатку не страждає через логування, але розробник бачить повідомлення з невеликою затримкою.

swift
// Оголошення os_log через OSLog
import OSLog

let logger = Logger(
    subsystem: "com.example.app",
    category: "network"
)

Кільцевий буфер та його налаштування

Кільцевий буфер os_log має фіксований об’єм і його не можна змінити з простору користувача. Розмір буфера варіюється від 256 КБ на Apple Watch до 4 МБ на Mac. Коли додаток генерує більше повідомлень, ніж вміщує буфер, старі повідомлення втрачаються — це очікувана поведінка для високооб’ємного логування.

Для довгострокового збору всіх повідомлень використовується команда log collect, яка запускає демон збору на пристрої та вивантажує .logarchive на комп’ютер розробника. У цьому режимі буфер не перезаписується — повідомлення пишуться безпосередньо в архів.

Рівні os_log: Default, Info, Debug, Error, Fault

os_log підтримує п’ять рівнів критичності, кожен з яких відповідає за окремий тип повідомлень та по-різному обробляється системою. Рівень Default — базовий для повідомлень, які завжди потрапляють у буфер. Info та Debug вимикаються в продакшен-збірках без профілю збору. Error та Fault завжди активні та помічаються особливим прапорцем у базі даних.

РівеньЗначенняПотрапляння в буфер за замовчуванням
DefaultЗвичайні повідомлення, важливі для діагностикиТак
InfoІнформаційні повідомлення для детального аналізуНі (тільки з профілем)
DebugНалагоджувальні повідомлення для розробкиНі (тільки з профілем)
ErrorПомилки, які потребують увагиТак
FaultКритичні збої, що ведуть до падінняТак

Вибір правильного рівня критичності важливий для продуктивності: Info та Debug не записуються на диск у звичайному режимі, тому їх можна використовувати рясно без ризику уповільнити додаток. Error та Fault зберігаються завжди, але їх кількість має бути мінімальною — кожне таке повідомлення збільшує час запису через додаткові метадані.

Категорії та subsystem в os_log

Subsystem — це ідентифікатор додатку або модуля у форматі reverse-DNS (com.example.app). Category — рядкова мітка всередині subsystem, яка групує логи за функціональними областями: network, ui, database, auth. Така ієрархія дозволяє фільтрувати логи без читання кожного повідомлення та збирати статистику по кожному модулю окремо.

Apple рекомендує визначати один OSLog на модуль і використовувати його у всіх файлах цього модуля. Для різних шарів додатку — networking, UI, persistence — потрібно створювати окремі категорії. Тоді в Console.app можна ввімкнути логи тільки для network та вимкнути для інших, не перекомпілюючи додаток.

swift
import OSLog

extension Logger {
    static let network = Logger(
        subsystem: "com.example.app",
        category: "network"
    )
    static let ui = Logger(
        subsystem: "com.example.app",
        category: "ui"
    )
}

Конфіденційність даних в os_log

os_log надає вбудований механізм контролю приватності: кожне значення в рядку форматування може бути позначене як public, private або auto (поведінка за замовчуванням). За замовчуванням os_log вважає всі динамічні рядки та об’єкти потенційно конфіденційними та замінює їх маскою <private> у продакшен-логах.

Це критично важливо для дотримання вимог GDPR та HIPAA: якщо додаток логує email користувача або номер картки через os_log з авто-режимом, реальні дані ніколи не потраплять на диск. Розробник бачить повне повідомлення лише при підключенні через Xcode або при використанні профілю збору з пристрою, підключеного до того ж Mac.

swift
let email = "user@example.com"
logger.log("User login: \(email, privacy: .public)")

// У продакшен-логах: "User login: "
// У налагодженні через Xcode: "User login: user@example.com"
logger.log("Payment token: \(token)")

Правила приватності за замовчуванням

Числа (Int, Double, Float) за замовчуванням вважаються public — їх можна безпечно логувати без маркування. Рядки (String, NSString, StaticString) та об’єкти (NSObject, CFType) за замовчуванням private — їх маскує в продакшені. Статичні рядки (рядкові літерали в лапках всередині формат-рядка) завжди видимі — це частина самого повідомлення, а не дані.

Ця поведінка відрізняється від NSLog, де всі дані логувалися у відкритому вигляді. Перехід на os_log значно знижує ризик витоку чутливих користувацьких даних через логи.

os_log vs NSLog: порівняння продуктивності

os_log на 90–95% швидший за NSLog при високочастотному логуванні. У тесті з 10 000 викликами в циклі NSLog створює затримку близько 2.8 секунд, тоді як os_log виконує ті ж виклики за 0.3 секунди. Різниця пояснюється синхронним записом на диск у NSLog проти асинхронної буферизації в os_log.

За даними Apple Performance Lab (2016), додаток на iOS з 20 викликами логування на секунду через NSLog втрачає 5–8 кадрів анімації на секунду через блокування main thread. З os_log втрати кадрів не відбувається, оскільки буферизація відбувається в окремому потоці ядра.

ПараметрNSLogos_log
Механізм записуСинхронний запис на дискАсинхронна буферизація в ядрі
Час на 10 000 викликів~2.8 с~0.3 с
Вплив на FPSВтрата 5–8 кадрів0 кадрів
Рівні критичностіНемає5 рівнів
КонфіденційністьВсі дані відкритіАвтоматичне маскування
ФільтраціяНе підтримуєтьсяЗа subsystem / category / level

Приклади коду з os_log на Swift

os_log має два API: класичний C-шний os_log_create та сучасну Swift-обгортку Logger, представлену в iOS 14. Swift Logger використовує систему ResultBuilder для форматування — аргументи інтерполюються через рядкові літерали з явним маркуванням приватності.

swift
import OSLog

let logger = Logger(
    subsystem: "com.example.app",
    category: "network"
)

func handleResponse(statusCode: Int) {
    if statusCode > 399 {
        logger.error("HTTP error: \(statusCode, privacy: .public)")
    } else {
        logger.info("Response OK: \(statusCode)")
    }
}

log collect — командна утиліта для вивантаження зібраних логів з пристрою. Запускається з терміналу після підключення пристрою до Mac через USB.

swift
// Збір логів у .logarchive
// У терміналі: log collect --device --output ./app_logs.logarchive
// Перегляд логів subsystem: log show --subsystem com.example.app

// Логування з динамічними значеннями
logger.log("User \(userId) opened screen \(screenName)")

При використанні Logger важливо пам’ятати, що аргументи інтерполюються через String Interpolation, а не через формат-рядки, як у C-версії os_log. Це безпечніше, але вимагає явного зазначення privacy для кожного аргументу, якщо поведінка за замовчуванням не влаштовує розробника.

Часті запитання

Чим os_log відрізняється від NSLog?

os_log асинхронно буферизує повідомлення в ядрі та не блокує main thread, а NSLog синхронно пише на диск. os_log у 10 разів швидший, дає 5 рівнів критичності та автоматично маскує приватні дані — NSLog не має жодної з цих властивостей.

Який рівень os_log використовувати для налагодження?

Для тимчасових налагоджувальних повідомлень використовуйте .debug — вони вимикаються в продакшен-збірці та не впливають на продуктивність користувачів. Для важливих повідомлень, які повинні зберігатися завжди, використовуйте .default або .info.

Як увімкнути Info та Debug логи на пристрої користувача?

Через Configure Profile в Xcode: Devices → виберіть пристрій → Open Console → Actions → Configure Profile. Встановіть рівень збору для потрібного subsystem в Include. Це створює профіль, який активний до першого перезапуску пристрою.

Чи можна використовувати os_log у SwiftUI додатках?

Так, os_log працює у всіх SwiftUI додатках без додаткових налаштувань. Створіть статичний Logger у моделі або в розширенні View та використовуйте його в onChange, task та обробниках жестів для відстеження життєвого циклу екранів.

Чому os_log показує <private> замість значень?

os_log за замовчуванням маскує рядки та об’єкти як private. Щоб побачити значення, явно вкажіть privacy: .public в інтерполяції. Без цього маркування значення будуть замінені маскою в продакшен-збірках, а в налагодженні через Xcode вони відображаються нормально.

Підсумки

  • os_log — уніфікований API логування Apple, що працює через кільцевий буфер у ядрі XNU з асинхронним записом на диск
  • Продуктивність — os_log у 10 разів швидший за NSLog, не блокує main thread та не впливає на частоту кадрів анімації при будь-якому обсязі логування
  • Рівні — п’ять рівнів від Debug до Fault: Info та Debug вимикаються в продакшені, Error та Fault зберігаються завжди
  • Subsystem та Category — ієрархія для групування логів за модулями додатку, фільтрація в Console.app без читання кожного повідомлення
  • Конфіденційність — автоматичне маскування рядків та об’єктів у продакшен-логах, захист персональних даних без додаткового коду
  • Інструменти — Console.app для перегляду в реальному часі та log collect для вивантаження архіву з пристрою
  • Міграція — заміна NSLog на os_log знижує ризик витоку даних та покращує продуктивність, особливо на навантажених мережевих модулях та фонових процесах

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також