OSLogKit is a layer 2 framework developed on top of the native OSLog system, aiming to simplify the integration of OSLog into your project. Apple has done an excellent job in ensuring that OSLogging is straightforward and easy to use. However, when it comes to implementing OSLog in your codebase, can be challenging.

To address this, OSLogKit has been developed, further simplifying the process of adopting OSLog. One notable advantage of OSLogKit is that it offers additional functionalities not available in the native API.

OSLogKit has a variety of Modifiers which makes OSLogKit adoption very easy. Don’t worry if your code base is in UIKit, you can still adopt it quickly.

Demo App

? Usage

⚙️ Initialisation

In order to use Logger you need to initialize the instance of Logger. OSLogKit supports a variety of Initialisation

? Basic Initialisation

  • The default behavior of the empty initialization is to store the logs in the subsystem that has the same name as the app’s Bundle ID.
  • It is always suggested to use the default initializer, making it easy to manage Subsystems.
let logger = Logger()

? Advance Initialisation

  • This initialization provides the leverage to select your own Subsystem and Category
  • When Subsytem is left empty then the Bundle ID of the app is taken into consideration
let logger = Logger(subSystem: "com.gokulnair.Test-OSKit", category: "ContentView")

? Operations

Following are the methods which OSLogKit supports

? Single Capture/Logging

  • Captures a single log with specified OSLogLevel and message
  • By default the capture level is .default
 func capture(level: OSLogType? = nil, message: String)

? Bulk Capturing/Logging

  • Captures logs in bulk with the specified OSLogLevels and messages
func captureInBulk(levels: [OSLogType] = [], messages: [String])

? Log Exporting

  • This method exports the log entries for a specific SubSystem within the specified time span
  • Use the same subsystem using which the logs are made
  • timeSpan denotes the span for which logs needs to be exported(Default 1 day)
  • completion Block returns an array of logs captured if the process succeeds and on failure, OSLogKit provides the error.
  • Exported Log format – [[Date] [Category] message]
func exportLogs(forSubsystem subsystem: String = "", timeSpan span: OSLogSpan = .day(1), completion: @escaping((Result<[String], OSLogError>) -> ()))


  • OSLogSpan is the duration for which any log is exported Following are the OSLogSpans
Name Cases Description
minutes .minute(x) Considers x minutes in past
hours .hour(x) Considers x hours in past
days .day(x) Considers x days in past


  • The default error type returned in OSLogKit for any form of failure is OSLogError
  • Use errorDescription in the failure case in order to get the error description
  • Demo App
Name Case Description
Export Failure .exportFailure(let customString) Custom export failure error
Invalid Subsystem .invalidSubsystem Occurs when an Invalid Subsystem is used

SwiftUI Modifiers

? CaptureLogOnAppear

  • logger log instance for which logs need to be captured
  • message string which needs to be logged
  • level specific level on which log needs to be captured
  • performSince this modifier is made on top of OnAppear in order to perform additional actions in OnApper you can use this param
func captureLogOnAppear(_ logger: OSLogKit, _ message: String, _ level: OSLogType = .default, _ perform: (() -> Void)? = nil)

? CaptureBulkLogOnAppear

  • logger log instance for which logs need to be captured
  • message strings that need to be logged
  • level specific levels on which logs need to be captured
  • performSince this modifier is made on top of OnAppear in order to perform additional actions in OnApper you can use this param
func captureBulkLogOnAppear(_ logger: OSLogKit, _ messages: [String], _ levels: [OSLogType], _ perform: (() -> Void)? = nil)

Other modifiers are

Case Description
.captureLogOnDisappear Captures log on disappear
.captureBulkLogOnDisappear Captures bulk log on disappear
.captureLogOnLongPress Captures log on long press
.captureBulkLogOnLongPress Captures bulk log on long press
.captureLogOnTap Captures log on tap
.captureBulkLogOnTap Captures bulk log on tap
.captureLogOnSubmit Captures log on submit
.captureBulkLogOnSubmit Captures bulk log on submit
  • Parameters for the above modifiers are same as CaptureLogOnAppear & captureBulkLogOnAppear

⌨️ In Code Usage


 VStack {
 // Some view
 }.captureLogOnTap(logger, "OSLogKit test log") {
  // additional on tap action (Optional)


logger.capture(message: "OSLogKit test log")
  • The following are the most basic usage, various other parameters are available which can be used as per need

⚠️ Caution

  • OSLogKit only supports messages of String type, thus in order to log messages with various privacy levels you still need to use the classic logger. This is because Apple doesn’t provide the option to create an instance of OSLogMessage.
  • Thus create an instance of OSLogKit and directly access the classic logger.


OSLogKit is available through Swift Package Manager. To add OSLogKit through SPM

  • Open project in Xcode
  • Select File > Add Packages

✨ Upcoming Features

  • I am currently working on this version, aiming to delve deeper and offer a bunch of additional features. Keep an eye on my Twitter handle for further updates.

⚖️ License

  • OSLogKit is available under MIT License.

? How to contribute?

  • Use the framework through SPM
  • If you face any issue or you feel you can contribute in any way then fork this repository, make your changes, and make a Pull Request

Made with ❤️ in ?? By Gokul Nair


View Github