Does Swift Compiler Remove `OSLog` Debug Logs in Release Builds, or Is `#if DEBUG` Necessary to Avoid Overhead?

Does Swift Compiler Remove `OSLog` Debug Logs in Release Builds, or Is `#if DEBUG` Necessary to Avoid Overhead?
ios
Ethan Jackson

I'm working on an iOS app using Swift and leveraging OSLog for logging debug information during development. I’ve been using OSLog like this:

import OSLog let logger = Logger(subsystem: "com.example.app", category: "General") func someFunction() { logger.debug("Debugging someFunction execution") // Function logic }

1. Is #if DEBUG necessary for debug logs with OSLog?

I’ve seen some codebases wrap debug log statements in #if DEBUG preprocessor directives to ensure they’re only included in debug builds, like this:

#if DEBUG logger.debug("Debugging someFunction execution") #endif

Is this necessary when using OSLog? Does the Swift compiler (or OSLog itself) automatically strip out debug-level log calls in release builds, or do I need to explicitly use #if DEBUG to prevent them from executing?

2. Is there any function call overhead or other performance impact for debug logs in release mode?

If debug logs (e.g., logger.debug) are not stripped out by the compiler in release builds, is there a measurable overhead (e.g., function call overhead, memory usage, or logging system initialization)? Or does the Swift compiler’s optimization process (or OSLog’s implementation) ensure that debug logs have no impact in release builds?

3. What’s a good practice to avoid writing #if DEBUG everywhere?

If #if DEBUG is needed, is there a way to avoid wrapping every log statement with preprocessor directives? For example, can I conditionally define a no-op logger or empty content for release mode to simplify the code? I’m looking for a clean, maintainable approach to handle debug logging globally without repetitive #if DEBUG checks.


I’m targeting iOS 14+ and using Swift 5.7+. I’d appreciate any insights into how the Swift compiler handles OSLog calls in release builds and whether wrapping debug logs in #if DEBUG is a best practice or redundant.

Answer

i have one logger file which have function as you want and that function contains DEBUG condition you can use i easily. check with given code below:

// // RBLogger.swift // // Created by JatinRB. // import UIKit import Foundation class RBLogger { static var logFile: URL? { guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil } let formatter = DateFormatter() formatter.dateFormat = "dd-MM-yyyy" let dateString = formatter.string(from: Date()) let fileName = "\(dateString).log" return documentsDirectory.appendingPathComponent(fileName) } static func log(_ message: String) { #if DEBUG guard let logFile = logFile else { return } print("FILE URL:",logFile) let formatter = DateFormatter() formatter.dateFormat = "HH:mm:ss" let timestamp = formatter.string(from: Date()) guard let data = (timestamp + ": " + message + "\n").data(using: String.Encoding.utf8) else { return } if FileManager.default.fileExists(atPath: logFile.path) { if let fileHandle = try? FileHandle(forWritingTo: logFile) { fileHandle.seekToEndOfFile() fileHandle.write(data) fileHandle.closeFile() } } else { try? data.write(to: logFile, options: .atomicWrite) } #else #endif } }

Usage:

RBLogger.log("\(self) ==> \(#line) ==> \(#function)")

What you want to print in debug you can print it using this function and it also avoid debug everywhere.

Location(Where it's store):

it will store logfile in your running device Documents folder you can access it using Supports Document Browser to YES in info.plist

Result

enter image description here

Related Articles