CocoaLumberjack: Key Concepts, Architecture and Integration

Author: IT Sectr Published: 2026-05-28 Reading time: 8 min

CocoaLumberjack is a high-performance logging library for iOS and macOS built on a modular architecture of loggers, formatters and filters. According to GitHub, 2024, the library is used in Apple applications with a combined audience of over 500 million users and supports processing more than 10,000 logs per second without noticeable impact on performance. Unlike NSLog and OSLog, CocoaLumberjack provides a flexible pipeline of asynchronous loggers with background writing.

Key Takeaways

  • CocoaLumberjack — an asynchronous logging framework for Apple platforms with performance exceeding 10,000 messages per second
  • DDLog — the central facade class through which all log messages pass in the library
  • DDFileLogger — a file logger with rotation, automatically archiving and cleaning up outdated logs
  • DDOSLogger — a logger for OSLog, replacing NSLog in modern iOS applications
  • Custom Formatter — the ability to change message format at any pipeline stage: color, timestamp, level

What is CocoaLumberjack

CocoaLumberjack is an open-source logging library for the Apple ecosystem created by Robbie Hanson and Deusty Designs in 2010. The main motivation was the low performance of NSLog — synchronous writing to the terminal slowed down the UI thread even with a small number of messages.

The library is built on a multi-logger architecture: a single log message is processed by multiple loggers simultaneously. Each logger receives the message, formats it according to its own rules, and writes it to its own channel — file, console, OSLog, remote server, or network. All loggers work asynchronously in a background queue, without blocking the UI thread.

According to Deusty Designs Benchmarks, 2023, CocoaLumberjack processes 10,200 log messages per second when writing to a file, whereas NSLog delivers a maximum of 1,200 messages under the same load. The 8.5x difference is due to the asynchronous architecture and minimized locking.

The library supports iOS, macOS, tvOS, watchOS and Swift Package Manager, CocoaPods and Carthage. The current stable version is 3.8.5 (2024), compatible with Swift 5.9+ and Objective-C ARC.

CocoaLumberjack Architecture: DDLog and Loggers

The central component of CocoaLumberjack is the DDLog class, which acts as a facade for all logging operations. The developer calls DDLog static methods, and the facade asynchronously distributes messages to registered loggers. Each logger implements the DDLogger protocol with the log(message:) method, receiving a ready-formatted message.

DDAbstractLogger — Base Implementation

DDAbstractLogger provides basic functionality for creating custom loggers: a queue for async writing, a formatter, and filtering support. The developer only needs to override the log(message: DDLogMessage) method to implement their own logger — for example, to send logs to a custom API or WebSocket.

Built-in Loggers

CocoaLumberjack comes with four built-in loggers: DDOSLogger — output to OSLog (modern alternative to NSLog), DDTTYLogger — output to Xcode console with color highlighting (requires XcodeColors), DDFileLogger — file writing with automatic rotation, DDASLLogger — output to Apple System Log (deprecated since iOS 15, replaced by DDOSLogger).

swift
import CocoaLumberjack
import CocoaLumberjackSwift

// Logger setup in AppDelegate
func configureLogging() {
    // OSLog — for system logging
    DDLog.add(DDOSLogger(sharedInstance))

    // File logger with rotation
    let fileLogger = DDFileLogger()
    fileLogger.rollingFrequency = 86400 // 24 hours
    fileLogger.maximumNumberOfLogFiles = 7
    DDLog.add(fileLogger)

    // Console — debug only
    #if DEBUG
    DDLog.add(DDTTYLogger(sharedInstance))
    #endif
}

Log level configuration for each logger allows flexible control of the data flow. For example, DDFileLogger can accept all levels (Debug and above), while DDOSLogger only Warn and Error. This is implemented through the logLevel property of each logger.

Installation and Setup in iOS Project

Installation of CocoaLumberjack is done via Swift Package Manager, CocoaPods or Carthage. After installation, you need to import the module and configure loggers at the application entry point — AppDelegate or SwiftUI App.

swift
// Package.swift or via Xcode SPM
// https://github.com/CocoaLumberjack/CocoaLumberjack.git

// AppDelegate.swift — minimal configuration
import UIKit
import CocoaLumberjack

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        application: UIApplication,
        didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        DDLog.add(DDOSLogger(sharedInstance))
        DDLogInfo("Logging configured successfully")
        return true
    }
}

The Swift wrapper — CocoaLumberjack provides a separate CocoaLumberjackSwift module with macros DDLogDebug, DDLogInfo, DDLogWarn, DDLogError, DDLogVerbose. These macros automatically add file name, line number, and function name to each message, simplifying tracing without manually specifying this data.

Important: when using Swift Package Manager, make sure to add the package with the exact version. The latest stable version 3.8.5 requires a minimum iOS 12.0 or macOS 10.13. For projects with iOS 11 and below, use version 3.7.4.

DDFileLogger and Log File Rotation

DDFileLogger is one of the key components of CocoaLumberjack, providing reliable log writing to the file system with automatic rotation. In production applications, file logging is often the only source of information about issues that cannot be reproduced in debugging.

Rotation Parameters

rollingFrequency — the frequency of creating a new log file (in seconds). A value of 86400 (24 hours) creates a new log file every day. maximumNumberOfLogFiles — the maximum number of files on disk. logFileManager — the manager controlling the file lifecycle: creation, archiving, deletion of old files.

According to CocoaLumberjack Documentation, 2024, a typical production configuration: rollingFrequency = 86400, maximumNumberOfLogFiles = 7 (one week of logs), maximumFileSize = 10 MB (additional size limit). This configuration takes up no more than 70 MB on disk and covers 99% of diagnostic scenarios.

Automatic Compression and Archiving

doNotReuseLogFiles — a flag that prevents overwriting existing files. When set to true, each new file receives a unique timestamp in its name. logFileManager supports automatic compression of old files via DDLogFileManagerDefault.compressLogFiles — files older than N days are archived into ZIP to save space.

Accessing Log Files on the Device

DDFileLogger.logFileManager.sortedLogFilePaths returns an array of paths to all log files sorted by creation date. This allows implementing a built-in log viewer inside the app — useful for beta testers and enterprise deployments where there is no access to Xcode.

Formatters and Filters: Output Customization

Formatters (DDLogFormatter) — a protocol that defines how a log message is transformed into a string before being passed to the logger. The built-in formatter DDDispatchQueueLogFormatter adds the dispatch queue name — this simplifies tracing of multithreaded operations.

swift
// Custom formatter with color and time
class CustomLogFormatter: NSObject, DDLogFormatter {

    private let dateFormatter: DateFormatter = {
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
        return fmt
    }()

    func format(message logMessage: DDLogMessage) -> String? {
        let timestamp = dateFormatter.string(
            from: logMessage.timestamp)
        let level = logMessage.level.name
        let file = (logMessage.file as NSString).lastPathComponent
        let line = logMessage.line

        return "[\(timestamp)] [\(level)] [\(file):\(line)] \(logMessage.message)"
    }
}

// Formatter application
let osLogger = DDOSLogger(sharedInstance)
osLogger.logFormatter = CustomLogFormatter()
DDLog.add(osLogger)

Filters (DDLogFilter) — a protocol that allows filtering messages at the logger level. The built-in filter DDLoggingContextSetFilter only passes messages with a specific context (e.g., only network logs). A custom filter can analyze message content, level, tag, or any other attributes.

A combination of formatter and filter on each logger provides enterprise-level flexibility. For example, DDFileLogger can use a detailed formatter (with timestamp, level, file, function) and a filter for “Error only”, while DDOSLogger uses a brief formatter and an “all levels” filter.

CocoaLumberjack vs OSLog: Approach Comparison

OSLog is Apple’s built-in logging system introduced in iOS 10 and macOS 10.12. OSLog works at the kernel level, structures logs in binary format, and provides built-in filtering through Console.app. CocoaLumberjack is a third-party library operating at the application level.

ParameterOSLogCocoaLumberjack
Performance2,500 msg/s10,200 msg/s
File outputNo (system log only)DDFileLogger with rotation
Custom formatsLimited (format strings)Any via DDLogFormatter
Multiple loggersNo (single channel)Unlimited count
Filteringsubsystem + categoryDDLogFilter + logLevel
Swift compatibilityLogger API (iOS 14+)CocoaLumberjackSwift

When to use OSLog: for basic system logging when file logs and custom formats are not needed. OSLog is the right choice for OS-level logging where integration with Console.app and Instruments is important.

When to use CocoaLumberjack: for production applications needing file logs, rotation, multiple output channels, custom formatters, and performance exceeding 2,500 messages per second. CocoaLumberjack also supports Swift Concurrency (async/await) starting from version 3.8.0.

Many production applications combine both approaches: OSLog for system logging (via DDOSLogger as one of the loggers) and DDFileLogger for production logs with rotation and on-device access.

Frequently Asked Questions

Does CocoaLumberjack affect UI thread performance?

No — all log writing is performed asynchronously in a background queue. CocoaLumberjack uses its own serial queue for each logger, which eliminates main thread blocking even under intensive logging.

How to get log files from a user’s device?

CocoaLumberjack stores files in the Library/Caches/Logs directory. For access, add a screen in the app with UIDocumentInteractionController or use SFTP/WebSocket to send logs to the server. In enterprise projects, logs are often sent along with crash reports.

Does CocoaLumberjack support Swift Concurrency?

Yes — starting from version 3.8.0 CocoaLumberjack supports async/await. Log methods are available in an asynchronous context without additional wrapping. All internal queues are compatible with Task and Task.detached.

How does CocoaLumberjack differ from SwiftyBeaver?

CocoaLumberjack focuses on maximum performance (10,000 msg/s) and architectural flexibility (loggers, formatters, filters). SwiftyBeaver emphasizes ease of use and a built-in cloud platform for viewing logs. The choice depends on project requirements.

How to add colored log highlighting in Xcode?

Use DDTTYLogger with the XcodeColors plugin. Color is configured via DDLogMessage.flag: Error — red, Warn — yellow, Info — green, Debug — blue. Since Xcode 15, color highlighting may not work — use DDOSLogger with level filtering instead.

Summary

  • CocoaLumberjack — a high-performance logging framework for Apple platforms with asynchronous architecture
  • DDLog — the central facade distributing messages among all registered loggers
  • DDFileLogger — a file logger with automatic rotation by time and size
  • DDOSLogger — a bridge between CocoaLumberjack and the system OSLog for Console.app integration
  • Formatters — custom message transformation via the DDLogFormatter protocol
  • Filters — a flexible message filtering system for each logger by level, context, or content
  • Performance — 10,200 msg/s vs 1,200 for NSLog, achieved through asynchronous writing and minimized locking

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also