os_log: o que é, recursos e funcionamento do registro unificado na Apple

Autor: IT Sectr Publicado: 2026-05-28 Tempo de leitura: 9 min

os_log é a API de registro unificado da Apple para iOS e macOS que substituiu o NSLog e o os_trace. Ao contrário dos mecanismos antigos, o os_log funciona no nível do kernel: as mensagens são armazenadas em um buffer circular e gravadas no disco somente quando um limite de atividade é atingido. De acordo com a Apple WWDC 2016, o os_log reduz a carga do disco em 10 vezes em comparação com o NSLog e oferece controle sobre o nível de detalhes por meio de categorias e tipos. É a principal ferramenta de diagnóstico para o desenvolvedor iOS: através do Console.app é possível filtrar mensagens por processo, categoria e nível de criticidade em tempo real.

Principais pontos

  • os_log é a API de registro do sistema da Apple que armazena mensagens em buffer no kernel e reduz a carga do disco em até 90% em comparação com o NSLog
  • Níveis — Default, Info, Debug, Error, Fault — cada um é filtrado independentemente e pode ser ativado ou desativado por meio de um perfil de coleta de registros
  • Categorias — rótulos de texto dentro de um mesmo subsystem que permitem agrupar registros por módulos do aplicativo sem criar arquivos separados
  • Privacidade — o os_log mascara automaticamente os dados entre aspas marcados como private e os criptografa nos logs de produção
  • log collect — um utilitário de linha de comando para exportar logs coletados de um dispositivo para análise posterior no Console.app

O que é os_log

os_log é uma API de registro unificado apresentada pela Apple no iOS 10 e macOS Sierra. Ela unificou os mecanismos de registro distintos NSLog, os_trace e syslog em um único sistema com buffer no nível do kernel XNU.

Ao contrário do NSLog, que grava cada mensagem de forma síncrona no disco e bloqueia a thread, o os_log usa um buffer circular assíncrono na memória. As mensagens são liberadas para o disco somente quando a atividade excede um limite definido ou mediante o comando log collect. Isso reduz radicalmente o impacto do registro no desempenho do aplicativo.

O os_log suporta seis níveis de criticidade, diferenciação por subsystem e category, e um mecanismo de privacidade integrado: dados marcados como private são automaticamente mascarados nos logs de produção e ficam disponíveis apenas para o desenvolvedor quando conectado via Xcode.

História do registro unificado

Antes do iOS 10, os desenvolvedores usavam NSLog para depuração e syslog para mensagens do sistema. O NSLog gravava no stderr e no console, mas era extremamente ineficiente: cada mensagem era gravada de forma síncrona no disco, causando atrasos na interface do usuário com registro frequente. O os_log resolveu esse problema movendo o buffer para a parte BSD do kernel XNU e tornando as gravações em disco assíncronas.

Onde o os_log é usado

os_log é usado em todos os aplicativos da Apple e é recomendado pela Apple como a única API de registro para iOS, macOS, tvOS e watchOS. O sistema e aplicativos de terceiros usam-no para gravar mensagens em um banco de dados unificado — ele é armazenado na memória e liberado periodicamente para o disco. Esses logs podem ser analisados através do Console.app no Mac ou através do comando log no terminal.

Como funciona o os_log: arquitetura e buffer

A arquitetura do os_log consiste em três camadas: uma API do lado do cliente no espaço do usuário (libsystem_trace.dylib), um buffer circular no kernel XNU e o daemon logd que libera o buffer de forma assíncrona para o disco.

Quando um aplicativo chama o os_log, a mensagem é copiada para um buffer circular do kernel de vários megabytes. O buffer opera no princípio FIFO: se estiver cheio, as mensagens antigas são sobrescritas pelas mais novas. O daemon logd verifica periodicamente o buffer e salva as mensagens em arquivos .tracev3 em uma área protegida do sistema de arquivos.

De acordo com a Apple Engineering, o atraso típico desde a chamada do os_log até o aparecimento da mensagem no Console.app é de 1 a 5 segundos em um dispositivo e de até 60 segundos ao liberar para o disco em modo lote. Esta é uma compensação deliberada: o desempenho do aplicativo não é afetado pelo registro, mas o desenvolvedor vê as mensagens com um pequeno atraso.

swift
// Declaração do os_log através do OSLog
import OSLog

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

Buffer circular e sua configuração

O buffer circular do os_log tem um tamanho fixo e não pode ser alterado do espaço do usuário. O tamanho do buffer varia de 256 KB no Apple Watch a 4 MB no Mac. Quando um aplicativo gera mais mensagens do que o buffer pode comportar, as mensagens antigas são perdidas — este é um comportamento esperado para registro de alto volume.

Para coleta de longo prazo de todas as mensagens, é usado o comando log collect. Ele inicia um daemon de coleta no dispositivo e exporta um .logarchive para o computador do desenvolvedor. Neste modo, o buffer não é sobrescrito — as mensagens são gravadas diretamente no arquivo.

Níveis do os_log: Default, Info, Debug, Error, Fault

os_log suporta cinco níveis de criticidade, cada um responsável por um tipo diferente de mensagem e processado de forma diferente pelo sistema. Default é o nível base para mensagens que sempre entram no buffer. Info e Debug são desabilitados em compilações de produção sem um perfil de coleta. Error e Fault estão sempre ativos e são marcados com um sinalizador especial no banco de dados.

NívelSignificadoEntrada no buffer por padrão
DefaultMensagens normais importantes para diagnósticoSim
InfoMensagens informativas para análise detalhadaNão (apenas com perfil)
DebugMensagens de depuração para desenvolvimentoNão (apenas com perfil)
ErrorErros que requerem atençãoSim
FaultFalhas críticas que levam a travamentosSim

Escolher o nível de criticidade correto é importante para o desempenho: Info e Debug não são gravados no disco no modo normal, portanto podem ser usados abundantemente sem risco de retardar o aplicativo. Error e Fault são sempre salvos, mas sua quantidade deve ser mínima — cada uma dessas mensagens aumenta o tempo de gravação devido aos metadados adicionais.

Categorias e subsystem no os_log

Subsystem é um identificador de aplicativo ou módulo no formato reverse-DNS (com.example.app). Category é um rótulo de texto dentro de um subsystem que agrupa os logs por áreas funcionais: network, ui, database, auth. Essa hierarquia permite filtrar logs sem ler cada mensagem e coletar estatísticas para cada módulo separadamente.

A Apple recomenda definir um OSLog por módulo e usá-lo em todos os arquivos desse módulo. Para diferentes camadas do aplicativo — networking, UI, persistência — devem ser criadas categorias separadas. Então no Console.app você pode habilitar logs apenas para network e desabilitar para outros sem recompilar o aplicativo.

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

Privacidade de dados no os_log

os_log fornece um mecanismo de controle de privacidade integrado: cada valor em uma string de formato pode ser marcado como public, private ou auto (comportamento padrão). Por padrão, o os_log considera todas as strings dinâmicas e objetos como potencialmente confidenciais e os substitui pela máscara <private> nos logs de produção.

Isso é fundamental para a conformidade com GDPR e HIPAA: se um aplicativo registrar o e-mail ou número de cartão de um usuário através do os_log no modo automático, os dados reais nunca chegam ao disco. O desenvolvedor vê a mensagem completa apenas quando conectado via Xcode ou ao usar um perfil de coleta de um dispositivo conectado ao mesmo Mac.

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

// Em logs de produção: "User login: "
// Na depuração com Xcode: "User login: user@example.com"
logger.log("Payment token: \(token)")

Regras de privacidade padrão

Números (Int, Double, Float) são considerados públicos por padrão — podem ser registrados com segurança sem marcação. Strings (String, NSString, StaticString) e objetos (NSObject, CFType) são privados por padrão — são mascarados em produção. Strings estáticas (literais de string entre aspas dentro da string de formato) são sempre visíveis — fazem parte da própria mensagem, não são dados.

Esse comportamento difere do NSLog, onde todos os dados eram registrados em texto simples. A migração para o os_log reduz significativamente o risco de vazamento de dados confidenciais do usuário através dos logs.

os_log vs NSLog: comparação de desempenho

os_log é 90–95% mais rápido que o NSLog em registro de alta frequência. Em um teste com 10.000 chamadas em loop, o NSLog cria um atraso de aproximadamente 2,8 segundos, enquanto o os_log executa as mesmas chamadas em 0,3 segundos. A diferença é explicada pelas gravações síncronas em disco no NSLog versus o buffer assíncrono no os_log.

De acordo com o Apple Performance Lab (2016), um aplicativo iOS com 20 chamadas de registro por segundo através do NSLog perde de 5 a 8 quadros de animação por segundo devido ao bloqueio da thread principal. Com o os_log não há perda de quadros porque o buffer ocorre em uma thread separada do kernel.

ParâmetroNSLogos_log
Mecanismo de gravaçãoGravação síncrona em discoBuffer assíncrono no kernel
Tempo para 10.000 chamadas~2,8 s~0,3 s
Impacto no FPSPerda de 5–8 quadros0 quadros
Níveis de criticidadeNenhum5 níveis
PrivacidadeTodos os dados visíveisMascaramento automático
FiltragemNão suportadaPor subsystem / category / level

Exemplos de código com os_log em Swift

os_log tem duas APIs: a clássica em C os_log_create e o wrapper moderno em Swift Logger apresentado no iOS 14. O Logger do Swift usa o sistema ResultBuilder para formatação — os argumentos são interpolados através de literais de string com marcação explícita de privacidade.

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 é um utilitário de linha de comando para exportar logs coletados de um dispositivo. Ele é executado no Terminal após conectar o dispositivo a um Mac via USB.

swift
// Coleta de logs em .logarchive
// No Terminal: log collect --device --output ./app_logs.logarchive
// Visualização de logs de subsystem: log show --subsystem com.example.app

// Registro com valores dinâmicos
logger.log("User \(userId) opened screen \(screenName)")

Ao usar Logger, é importante lembrar que os argumentos são interpolados via String Interpolation, não através de strings de formato como na versão C do os_log. Isso é mais seguro, mas requer marcação explícita de privacidade para cada argumento se o comportamento padrão não for adequado para o desenvolvedor.

Perguntas frequentes

Como o os_log difere do NSLog?

O os_log armazena mensagens em buffer de forma assíncrona no kernel e não bloqueia a thread principal, enquanto o NSLog grava de forma síncrona no disco. O os_log é 10 vezes mais rápido, oferece 5 níveis de criticidade e mascara automaticamente dados privados — o NSLog não tem nenhuma dessas características.

Qual nível do os_log devo usar para depuração?

Para mensagens de depuração temporárias, use .debug — elas são desabilitadas em compilações de produção e não afetam o desempenho dos usuários. Para mensagens importantes que devem ser sempre preservadas, use .default ou .info.

Como habilitar logs Info e Debug no dispositivo de um usuário?

Através de Configure Profile no Xcode: Devices → selecione o dispositivo → Open Console → Actions → Configure Profile. Defina o nível de coleta para o subsystem desejado como Include. Isso cria um perfil que permanece ativo até a primeira reinicialização do dispositivo.

Pode-se usar os_log em aplicativos SwiftUI?

Sim, os_log funciona em todos os aplicativos SwiftUI sem configuração adicional. Crie um Logger estático no seu modelo ou em uma extensão de View e use-o em onChange, task e manipuladores de gestos para rastrear o ciclo de vida das telas.

Por que o os_log mostra <private> em vez dos valores?

Por padrão, o os_log mascara strings e objetos como private. Para ver o valor, especifique explicitamente privacy: .public na interpolação. Sem essa marcação, os valores serão substituídos pela máscara em compilações de produção, mas na depuração com Xcode eles são exibidos normalmente.

Resumo

  • os_log é a API de registro unificado da Apple que opera através de um buffer circular no kernel XNU com gravação assíncrona em disco
  • Desempenho — o os_log é 10 vezes mais rápido que o NSLog, não bloqueia a thread principal e não afeta a taxa de quadros de animação em qualquer volume de registro
  • Níveis — cinco níveis de Debug a Fault: Info e Debug são desabilitados em produção, Error e Fault são sempre salvos
  • Subsystem e Category — uma hierarquia para agrupar logs por módulos do aplicativo, filtragem no Console.app sem ler cada mensagem
  • Privacidade — mascaramento automático de strings e objetos em logs de produção, proteção de dados pessoais sem código adicional
  • Ferramentas — Console.app para visualização em tempo real e log collect para exportar um arquivo do dispositivo
  • Migração — substituir o NSLog pelo os_log reduz o risco de vazamento de dados e melhora o desempenho, especialmente em módulos de rede com carga intensiva e processos em segundo plano

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também