os_log: co to je, možnosti a fungování unified logging v Apple

Autor: IT Sectr Publikováno: 2026-05-28 Doba čtení: 9 min

os_log — je unified logging API od Apple pro iOS a macOS, které nahradilo NSLog a os_trace. Na rozdíl od starých mechanismů, os_log pracuje na úrovni jádra: zprávy jsou bufferovány v kruhovém bufferu a zapisovány na disk pouze po dosažení prahu aktivity. Podle údajů Apple WWDC 2016, os_log snižuje zatížení disku 10krát ve srovnání s NSLog a poskytuje kontrolu nad úrovní podrobností prostřednictvím kategorií a typů. Je to základní diagnostický nástroj pro iOS vývojáře: prostřednictvím Console.app lze filtrovat zprávy podle procesu, kategorie a úrovně kritičnosti v reálném čase.

Hlavní body

  • os_log — systémové API pro logování od Apple, které bufferuje zprávy v jádře a snižuje zatížení disku až o 90% ve srovnání s NSLog
  • Úrovně — Default, Info, Debug, Error, Fault — každá je filtrována nezávisle a může být zapnuta nebo vypnuta pomocí profilu sběru logů
  • Kategorie — textové štítky v rámci jednoho subsystem, které umožňují seskupovat logy podle modulů aplikace bez vytváření samostatných souborů
  • Soukromí — os_log automaticky maskuje data v uvozovkách označená jako private a šifruje je v produkčních logách
  • log collect — nástroj příkazového řádku pro export sebraných logů ze zařízení pro pozdější analýzu v Console.app

Co je os_log

os_log — je unified logging API představené Apple v iOS 10 a macOS Sierra. Sjednotilo roztříštěné mechanismy logování NSLog, os_trace a syslog do jednoho systému s bufferováním na úrovni jádra XNU.

Na rozdíl od NSLog, které každou zprávu synchronně zapisuje na disk a blokuje vlákno, os_log používá asynchronní kruhový buffer v paměti. Zprávy se zapisují na disk pouze když aktivita překročí určitý práh nebo na příkaz log collect. To radikálně snižuje dopad logování na výkon aplikace.

os_log podporuje šest úrovní kritičnosti, rozlišení podle subsystem a category a vestavěný mechanismus soukromí: data označená jako private jsou automaticky maskována v produkčních logách a přístupná pouze vývojáři po připojení Xcode.

Historie vzniku unified logging

Před iOS 10 vývojáři používali NSLog pro ladění a syslog pro systémové zprávy. NSLog zapisoval do stderr a konzole, ale byl extrémně neefektivní: každá zpráva se synchronně zapisovala na disk, což při častém logování způsobovalo zpoždění v UI. os_log tento problém vyřešil přesunutím bufferování na úroveň BSD části jádra XNU a asynchronním zápisem na disk.

Kde se os_log používá

os_log se používá ve všech aplikacích Apple a Apple jej doporučuje jako jediné API pro logování pro iOS, macOS, tvOS a watchOS. Systém a aplikace třetích stran přes něj zapisují zprávy do jediné databáze — uložené v paměti a periodicky vypisované na disk. Tyto logy lze analyzovat přes Console.app na Macu nebo přes příkaz log v terminálu.

Jak funguje os_log: architektura a bufferování

Architektura os_log se skládá ze tří vrstev: klientské API v uživatelském prostoru (libsystem_trace.dylib), kruhového bufferu v jádře XNU a démona logd, který asynchronně vypisuje buffer na disk.

Když aplikace zavolá os_log, zpráva se zkopíruje do kruhového bufferu jádra o velikosti několika megabajtů. Buffer funguje na principu FIFO: pokud je plný, staré zprávy jsou přepsány novými. Démon logd periodicky kontroluje buffer a ukládá zprávy do souborů .tracev3 v chráněné oblasti souborového systému.

Podle údajů Apple Engineering, typické zpoždění od volání os_log do objevení se zprávy v Console.app je 1–5 sekund na zařízení a až 60 sekund při dávkovém zápisu na disk. Toto je vědomý kompromis: výkon aplikace netrpí kvůli logování, ale vývojář vidí zprávy s malým zpožděním.

swift
// Deklarace os_log pomocí OSLog
import OSLog

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

Kruhový buffer a jeho nastavení

Kruhový buffer os_log má pevný objem a nelze jej změnit z uživatelského prostoru. Velikost bufferu se pohybuje od 256 KB na Apple Watch do 4 MB na Macu. Když aplikace generuje více zpráv, než buffer pojme, staré zprávy se ztrácejí — to je očekávané chování pro logování s vysokým objemem.

Pro dlouhodobý sběr všech zpráv se používá příkaz log collect, který spustí sběrného démona na zařízení a exportuje .logarchive do počítače vývojáře. V tomto režimu se buffer nepřepisuje — zprávy se zapisují přímo do archivu.

Úrovně os_log: Default, Info, Debug, Error, Fault

os_log podporuje pět úrovní kritičnosti, z nichž každá odpovídá za samostatný typ zpráv a je systémem zpracovávána odlišně. Úroveň Default — základní pro zprávy, které vždy padnou do bufferu. Info a Debug jsou vypnuty v produkčních sestaveních bez profilu sběru. Error a Fault jsou vždy aktivní a označeny speciálním příznakem v databázi.

ÚroveňVýznamVýchozí vstup do bufferu
DefaultBěžné zprávy důležité pro diagnostikuAno
InfoInformační zprávy pro podrobnou analýzuNe (pouze s profilem)
DebugLadicí zprávy pro vývojNe (pouze s profilem)
ErrorChyby vyžadující pozornostAno
FaultKritické selhání vedoucí k páduAno

Výběr správné úrovně kritičnosti je důležitý pro výkon: Info a Debug se nezapisují na disk v normálním režimu, takže je lze používat hojně bez rizika zpomalení aplikace. Error a Fault se vždy ukládají, ale jejich počet by měl být minimální — každá taková zpráva zvyšuje dobu zápisu kvůli dalším metadatům.

Kategorie a subsystem v os_log

Subsystem — je identifikátor aplikace nebo modulu ve formátu reverse-DNS (com.example.app). Category — textový štítek v rámci subsystem, který seskupuje logy podle funkčních oblastí: network, ui, database, auth. Taková hierarchie umožňuje filtrovat logy bez čtení každé zprávy a sbírat statistiky pro každý modul zvlášť.

Apple doporučuje definovat jeden OSLog na modul a používat jej ve všech souborech tohoto modulu. Pro různé vrstvy aplikace — networking, UI, persistence — je třeba vytvořit samostatné kategorie. Pak lze v Console.app zapnout logy pouze pro network a vypnout pro ostatní, bez překompilování aplikace.

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"
    )
}

Soukromí dat v os_log

os_log poskytuje vestavěný mechanismus kontroly soukromí: každá hodnota v řetězci formátu může být označena jako public, private nebo auto (výchozí chování). Ve výchozím nastavení os_log považuje všechny dynamické řetězce a objekty za potenciálně důvěrné a nahrazuje je maskou <private> v produkčních logách.

To je kriticky důležité pro dodržování požadavků GDPR a HIPAA: pokud aplikace loguje e-mail uživatele nebo číslo karty přes os_log v automatickém režimu, skutečná data se nikdy nedostanou na disk. Vývojář vidí úplnou zprávu pouze při připojení přes Xcode nebo při použití profilu sběru ze zařízení připojeného ke stejnému Macu.

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

// V produkčních logách: "User login: <private>"
// Při ladění přes Xcode: "User login: user@example.com"
logger.log("Payment token: \(token)")

Výchozí pravidla soukromí

Čísla (Int, Double, Float) jsou ve výchozím nastavení považována za public — lze je bezpečně logovat bez označení. Řetězce (String, NSString, StaticString) a objekty (NSObject, CFType) jsou ve výchozím nastavení private — maskují se v produkci. Statické řetězce (řetězcové literály v uvozovkách uvnitř formátovacího řetězce) jsou vždy viditelné — to je součást samotné zprávy, nikoli data.

Toto chování se liší od NSLog, kde byla všechna data logována v otevřené podobě. Přechod na os_log výrazně snižuje riziko úniku citlivých uživatelských dat prostřednictvím logů.

os_log vs NSLog: srovnání výkonu

os_log je o 90–95% rychlejší než NSLog při vysokofrekvenčním logování. V testu s 10 000 voláními ve smyčce NSLog vytváří zpoždění asi 2,8 sekundy, zatímco os_log provádí stejná volání za 0,3 sekundy. Rozdíl je vysvětlen synchronním zápisem na disk u NSLog oproti asynchronnímu bufferování u os_log.

Podle údajů Apple Performance Lab (2016) ztrácí iOS aplikace s 20 voláními logování za sekundu přes NSLog 5–8 snímků animace za sekundu kvůli blokování hlavního vlákna. S os_log nedochází ke ztrátě snímků, protože bufferování probíhá v samostatném vlákně jádra.

ParametrNSLogos_log
Mechanismus zápisuSynchromní zápis na diskAsynchronní bufferování v jádře
Čas na 10 000 volání~2,8 s~0,3 s
Dopad na FPSZtráta 5–8 snímků0 snímků
Úrovně kritičnostiŽádné5 úrovní
SoukromíVšechna data otevřenáAutomatické maskování
FiltrováníNepodporovánoPodle subsystem / category / level

Příklady kódu s os_log v Swift

os_log má dvě API: klasické C os_log_create a moderní Swift obal Logger, představený v iOS 14. Swift Logger používá systém ResultBuilder pro formátování — argumenty jsou interpolovány pomocí řetězcových literálů s explicitním označením soukromí.

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 — nástroj příkazového řádku pro export sebraných logů ze zařízení. Spouští se z Terminálu po připojení zařízení k Macu přes USB.

swift
// Sběr logů do .logarchive
// V terminálu: log collect --device --output ./app_logs.logarchive
// Zobrazení logů subsystem: log show --subsystem com.example.app

// Logování s dynamickými hodnotami
logger.log("User \(userId) opened screen \(screenName)")

Při použití Logger je důležité si pamatovat, že argumenty jsou interpolovány pomocí String Interpolation, nikoli pomocí formátovacích řetězců jako v C verzi os_log. To je bezpečnější, ale vyžaduje explicitní uvedení privacy pro každý argument, pokud výchozí chování vývojáři nevyhovuje.

Často kladené otázky

Čím se liší os_log od NSLog?

os_log asynchronně bufferuje zprávy v jádře a neblokuje hlavní vlákno, zatímco NSLog synchronně zapisuje na disk. os_log je 10krát rychlejší, poskytuje 5 úrovní kritičnosti a automaticky maskuje soukromá data — NSLog nemá žádnou z těchto vlastností.

Jakou úroveň os_log použít pro ladění?

Pro dočasné ladicí zprávy používejte .debug — jsou vypnuty v produkčním sestavení a neovlivňují výkon uživatelů. Pro důležité zprávy, které by měly být vždy zachovány, použijte .default nebo .info.

Jak zapnout Info a Debug logy na zařízení uživatele?

Přes Configure Profile v Xcode: Devices → vyberte zařízení → Open Console → Actions → Configure Profile. Nastavte úroveň sběru pro požadovaný subsystem na Include. Tím vytvoříte profil, který je aktivní do prvního restartu zařízení.

Lze používat os_log v aplikacích SwiftUI?

Ano, os_log funguje ve všech SwiftUI aplikacích bez dalšího nastavení. Vytvořte statický Logger v modelu nebo v rozšíření View a používejte jej v onChange, task a handlerech gest pro sledování životního cyklu obrazovek.

Proč os_log zobrazuje <private> místo hodnot?

os_log ve výchozím nastavení maskuje řetězce a objekty jako private. Pro zobrazení hodnoty explicitně uveďte privacy: .public v interpolaci. Bez tohoto označení budou hodnoty v produkčních sestaveních nahrazeny maskou, ale při ladění přes Xcode se zobrazují normálně.

Shrnutí

  • os_log — unified logging API Apple fungující přes kruhový buffer v jádře XNU s asynchronním zápisem na disk
  • Výkon — os_log je 10krát rychlejší než NSLog, neblokuje hlavní vlákno a neovlivňuje snímkovou frekvenci animace při jakémkoli objemu logování
  • Úrovně — pět úrovní od Debug po Fault: Info a Debug se vypínají v produkci, Error a Fault se vždy ukládají
  • Subsystem a Category — hierarchie pro seskupování logů podle modulů aplikace, filtrování v Console.app bez čtení každé zprávy
  • Soukromí — automatické maskování řetězců a objektů v produkčních logách, ochrana osobních údajů bez dalšího kódu
  • Nástroje — Console.app pro zobrazení v reálném čase a log collect pro export archivu ze zařízení
  • Migrace — nahrazení NSLog za os_log snižuje riziko úniku dat a zlepšuje výkon, zejména u zatížených síťových modulů a procesů na pozadí

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také