os_log : qu'est-ce que c'est, capacités et fonctionnement de la journalisation unifiée chez Apple

Auteur : IT Sectr Publié le : 2026-05-28 Temps de lecture : 9 min

os_log est l'API de journalisation unifiée d'Apple pour iOS et macOS qui a remplacé NSLog et os_trace. Contrairement aux anciens mécanismes, os_log fonctionne au niveau du noyau : les messages sont mis en mémoire tampon dans un buffer circulaire et écrits sur le disque uniquement lorsqu'un seuil d'activité est atteint. Selon l'Apple WWDC 2016, os_log réduit la charge du disque de 10 fois par rapport à NSLog et offre un contrôle sur le niveau de détail via des catégories et des types. C'est l'outil de diagnostic principal pour le développeur iOS : via Console.app, vous pouvez filtrer les messages par processus, catégorie et niveau de criticité en temps réel.

Points clés

  • os_log est l'API de journalisation système d'Apple qui met en mémoire tampon les messages dans le noyau et réduit la charge du disque jusqu'à 90% par rapport à NSLog
  • Niveaux — Default, Info, Debug, Error, Fault — chacun est filtré indépendamment et peut être activé ou désactivé via un profil de collecte de journaux
  • Catégories — des étiquettes textuelles au sein d'un même subsystem qui permettent de regrouper les journaux par modules d'application sans créer de fichiers séparés
  • Confidentialité — os_log masque automatiquement les données entre guillemets marquées comme private et les chiffre dans les journaux de production
  • log collect — un utilitaire en ligne de commande pour exporter les journaux collectés d'un appareil pour une analyse ultérieure dans Console.app

Qu'est-ce que os_log

os_log est une API de journalisation unifiée présentée par Apple dans iOS 10 et macOS Sierra. Elle a unifié les mécanismes de journalisation disparates NSLog, os_trace et syslog en un seul système avec mise en mémoire tampon au niveau du noyau XNU.

Contrairement à NSLog, qui écrit chaque message de manière synchrone sur le disque et bloque le thread, os_log utilise un buffer circulaire asynchrone en mémoire. Les messages sont vidés sur le disque uniquement lorsque l'activité dépasse un seuil défini ou sur commande log collect. Cela réduit radicalement l'impact de la journalisation sur les performances de l'application.

os_log prend en charge six niveaux de criticité, une différenciation par subsystem et category, ainsi qu'un mécanisme de confidentialité intégré : les données marquées comme private sont automatiquement masquées dans les journaux de production et ne sont disponibles que pour le développeur lorsqu'il est connecté via Xcode.

Histoire de la journalisation unifiée

Avant iOS 10, les développeurs utilisaient NSLog pour le débogage et syslog pour les messages système. NSLog écrivait sur stderr et la console, mais était extrêmement inefficace : chaque message était écrit de manière synchrone sur le disque, provoquant des retards dans l'interface utilisateur lors de journalisations fréquentes. os_log a résolu ce problème en déplaçant la mise en mémoire tampon vers la partie BSD du noyau XNU et en rendant les écritures sur disque asynchrones.

Où os_log est utilisé

os_log est utilisé dans toutes les applications Apple et est recommandé par Apple comme la seule API de journalisation pour iOS, macOS, tvOS et watchOS. Le système et les applications tierces écrivent via lui des messages dans une base de données unifiée — elle est stockée en mémoire et vidée périodiquement sur le disque. Ces journaux peuvent être analysés via Console.app sur Mac ou via la commande log dans le terminal.

Comment fonctionne os_log : architecture et mise en mémoire tampon

L'architecture d'os_log se compose de trois couches : une API côté client dans l'espace utilisateur (libsystem_trace.dylib), un buffer circulaire dans le noyau XNU et le démon logd qui vide le buffer de manière asynchrone sur le disque.

Lorsqu'une application appelle os_log, le message est copié dans un buffer circulaire du noyau de plusieurs mégaoctets. Le buffer fonctionne sur le principe FIFO : s'il est plein, les anciens messages sont écrasés par les plus récents. Le démon logd vérifie périodiquement le buffer et enregistre les messages dans des fichiers .tracev3 dans une zone protégée du système de fichiers.

Selon Apple Engineering, le délai typique entre l'appel d'os_log et l'apparition du message dans Console.app est de 1 à 5 secondes sur un appareil et jusqu'à 60 secondes lors du vidage sur le disque en mode batch. Il s'agit d'un compromis délibéré : les performances de l'application ne sont pas affectées par la journalisation, mais le développeur voit les messages avec un léger retard.

swift
// Déclaration d'os_log via OSLog
import OSLog

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

Buffer circulaire et sa configuration

Le buffer circulaire d'os_log a une taille fixe et ne peut pas être modifié depuis l'espace utilisateur. La taille du buffer varie de 256 Ko sur Apple Watch à 4 Mo sur Mac. Lorsqu'une application génère plus de messages que le buffer ne peut en contenir, les anciens messages sont perdus — c'est un comportement attendu pour la journalisation à volume élevé.

Pour la collecte à long terme de tous les messages, la commande log collect est utilisée. Elle lance un démon de collecte sur l'appareil et exporte un .logarchive vers l'ordinateur du développeur. Dans ce mode, le buffer n'est pas écrasé — les messages sont écrits directement dans l'archive.

Niveaux os_log : Default, Info, Debug, Error, Fault

os_log prend en charge cinq niveaux de criticité, chacun responsable d'un type différent de message et traité différemment par le système. Default est le niveau de base pour les messages qui entrent toujours dans le buffer. Info et Debug sont désactivés dans les builds de production sans profil de collecte. Error et Fault sont toujours actifs et sont marqués d'un drapeau spécial dans la base de données.

NiveauSignificationEntrée dans le buffer par défaut
DefaultMessages normaux importants pour le diagnosticOui
InfoMessages informatifs pour une analyse détailléeNon (profil uniquement)
DebugMessages de débogage pour le développementNon (profil uniquement)
ErrorErreurs nécessitant une attentionOui
FaultPannes critiques entraînant un plantageOui

Choisir le bon niveau de criticité est important pour les performances : Info et Debug ne sont pas écrits sur le disque en mode normal, ils peuvent donc être utilisés abondamment sans risque de ralentir l'application. Error et Fault sont toujours sauvegardés, mais leur quantité doit être minimale — chacun de ces messages augmente le temps d'écriture en raison des métadonnées supplémentaires.

Catégories et subsystem dans os_log

Subsystem est un identifiant d'application ou de module au format reverse-DNS (com.example.app). Category est une étiquette textuelle au sein d'un subsystem qui regroupe les journaux par domaines fonctionnels : network, ui, database, auth. Cette hiérarchie permet de filtrer les journaux sans lire chaque message et de collecter des statistiques pour chaque module séparément.

Apple recommande de définir un OSLog par module et de l'utiliser dans tous les fichiers de ce module. Pour les différentes couches de l'application — networking, UI, persistance — des catégories séparées doivent être créées. Ensuite, dans Console.app, vous pouvez activer les journaux uniquement pour network et les désactiver pour les autres sans recompiler l'application.

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

Confidentialité des données dans os_log

os_log fournit un mécanisme de contrôle de confidentialité intégré : chaque valeur dans une chaîne de format peut être marquée comme public, private ou auto (comportement par défaut). Par défaut, os_log considère toutes les chaînes dynamiques et les objets comme potentiellement sensibles et les remplace par le masque <private> dans les journaux de production.

C'est essentiel pour la conformité au RGPD et à HIPAA : si une application journalise l'email ou le numéro de carte d'un utilisateur via os_log en mode automatique, les données réelles n'atteignent jamais le disque. Le développeur voit le message complet uniquement lorsqu'il est connecté via Xcode ou lorsqu'il utilise un profil de collecte d'un appareil connecté au même Mac.

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

// Dans les journaux de production : « User login:  »
// Dans le débogage Xcode : « User login: user@example.com »
logger.log("Payment token: \(token)")

Règles de confidentialité par défaut

Les nombres (Int, Double, Float) sont considérés comme publics par défaut — ils peuvent être journalisés en toute sécurité sans marquage. Les chaînes (String, NSString, StaticString) et les objets (NSObject, CFType) sont privés par défaut — ils sont masqués en production. Les chaînes statiques (littéraux de chaîne entre guillemets dans la chaîne de format) sont toujours visibles — elles font partie du message lui-même, pas des données.

Ce comportement diffère de NSLog, où toutes les données étaient journalisées en texte clair. Le passage à os_log réduit considérablement le risque de fuite de données sensibles des utilisateurs via les journaux.

os_log vs NSLog : comparaison des performances

os_log est 90 à 95% plus rapide que NSLog en journalisation haute fréquence. Dans un test avec 10 000 appels en boucle, NSLog crée un délai d'environ 2,8 secondes, tandis qu'os_log exécute les mêmes appels en 0,3 seconde. La différence s'explique par les écritures synchrones sur disque dans NSLog par rapport à la mise en mémoire tampon asynchrone dans os_log.

Selon Apple Performance Lab (2016), une application iOS avec 20 appels de journalisation par seconde via NSLog perd 5 à 8 images d'animation par seconde en raison du blocage du thread principal. Avec os_log, il n'y a pas de perte d'images car la mise en mémoire tampon se produit dans un thread séparé du noyau.

ParamètreNSLogos_log
Mécanisme d'écritureÉcriture synchrone sur disqueMise en mémoire tampon asynchrone dans le noyau
Temps pour 10 000 appels~2,8 s~0,3 s
Impact sur les FPSPerte de 5 à 8 images0 image
Niveaux de criticitéAucun5 niveaux
ConfidentialitéToutes les données visiblesMasquage automatique
FiltrageNon pris en chargePar subsystem / category / level

Exemples de code avec os_log en Swift

os_log dispose de deux API : la version classique en C os_log_create et l'enveloppe moderne Swift Logger présentée dans iOS 14. Le Logger Swift utilise le système ResultBuilder pour le formatage — les arguments sont interpolés via des littéraux de chaîne avec un marquage explicite de confidentialité.

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 est un utilitaire en ligne de commande pour exporter les journaux collectés d'un appareil. Il est exécuté depuis le Terminal après avoir connecté l'appareil à un Mac via USB.

swift
// Collecte des journaux dans .logarchive
// Dans le Terminal : log collect --device --output ./app_logs.logarchive
// Affichage des journaux subsystem : log show --subsystem com.example.app

// Journalisation avec des valeurs dynamiques
logger.log("User \(userId) opened screen \(screenName)")

Lors de l'utilisation de Logger, il est important de se rappeler que les arguments sont interpolés via String Interpolation, et non via des chaînes de format comme dans la version C d'os_log. C'est plus sûr, mais cela nécessite un marquage explicite de la confidentialité pour chaque argument si le comportement par défaut ne convient pas au développeur.

Questions fréquentes

En quoi os_log diffère-t-il de NSLog ?

os_log met en mémoire tampon les messages de manière asynchrone dans le noyau et ne bloque pas le thread principal, tandis que NSLog écrit de manière synchrone sur le disque. os_log est 10 fois plus rapide, offre 5 niveaux de criticité et masque automatiquement les données privées — NSLog n'a aucune de ces caractéristiques.

Quel niveau os_log dois-je utiliser pour le débogage ?

Pour les messages de débogage temporaires, utilisez .debug — ils sont désactivés dans les builds de production et n'affectent pas les performances des utilisateurs. Pour les messages importants qui doivent toujours être conservés, utilisez .default ou .info.

Comment activer les journaux Info et Debug sur l'appareil d'un utilisateur ?

Via Configure Profile dans Xcode : Devices → sélectionnez l'appareil → Open Console → Actions → Configure Profile. Définissez le niveau de collecte pour le subsystem souhaité sur Include. Cela crée un profil qui reste actif jusqu'au premier redémarrage de l'appareil.

Peut-on utiliser os_log dans les applications SwiftUI ?

Oui, os_log fonctionne dans toutes les applications SwiftUI sans configuration supplémentaire. Créez un Logger statique dans votre modèle ou dans une extension de View et utilisez-le dans onChange, task et les gestionnaires de gestes pour suivre le cycle de vie des écrans.

Pourquoi os_log affiche-t-il <private> au lieu des valeurs ?

Par défaut, os_log masque les chaînes et les objets comme private. Pour voir la valeur, spécifiez explicitement privacy: .public dans l'interpolation. Sans ce marquage, les valeurs seront remplacées par le masque dans les builds de production, mais dans le débogage Xcode, elles s'affichent normalement.

Résumé

  • os_log est l'API de journalisation unifiée d'Apple qui fonctionne via un buffer circulaire dans le noyau XNU avec une écriture asynchrone sur le disque
  • Performances — os_log est 10 fois plus rapide que NSLog, ne bloque pas le thread principal et n'affecte pas le taux d'images d'animation quel que soit le volume de journalisation
  • Niveaux — cinq niveaux de Debug à Fault : Info et Debug sont désactivés en production, Error et Fault sont toujours sauvegardés
  • Subsystem et Category — une hiérarchie pour regrouper les journaux par modules d'application, filtrage dans Console.app sans lire chaque message
  • Confidentialité — masquage automatique des chaînes et des objets dans les journaux de production, protection des données personnelles sans code supplémentaire
  • Outils — Console.app pour la visualisation en temps réel et log collect pour exporter une archive depuis l'appareil
  • Migration — remplacer NSLog par os_log réduit le risque de fuite de données et améliore les performances, en particulier dans les modules réseau fortement sollicités et les processus d'arrière-plan

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi