Swiftpack.co - Package - elegantchaos/Logger

Test results Latest release swift 5.0 shield swift 5.1 shield swift 5.2 shield swift dev shield Platforms: macOS, iOS, tvOS, watchOS, Linux


Configurable logging for Swift.

Declare multiple log channels. Send log messages and objects to them. Enable individual channels with minimal overhead for the disabled ones.

Basic Usage

Just import the module and make one or more channels.

import Logger

let logger = Channel("com.acme.example.main")
let detailLogger = Channel("com.acme.example.detail")

To log output, just write it to a channel. Different kinds or levels of info can go to different channels as required:

logger.log("Hello world!")
detailLogger.log("We just logged hello world in the main channel")

To log for debug builds only:

logger.debug("This will never show up in a release build")


The list of enabled channels is persistent between runs of your program, and all channels start disabled by default.

You can enable specific channels from the command line when you run:

.build/debug/Example -logs "+myChannel,+anotherChannel"

You can also disable channels:

.build/debug/Example -logs "-myChannel,-anotherChannel"

Or completely reset the list of enabled channels:

.build/debug/Example -logs "=someChannel,someOtherChannel"


This is a swift version of a pattern I've implemented a number of times before. I often use it as a kind of test project to learn a language with, but I also use the library functionality in pretty much everything that I do.

The main idea is that when debugging complex problems, it's often useful to be able to write extensive logging code.

It's healthy to be able to leave this code in place, but enable it only when needed. It's useful to be able to do this at runtime, sometimes even in release versions, without disabled logging code having a negative performance impact.

For this to scale to a large application with many subsystems, you need to be able to separate log output into functional areas, so that you can look only at the bit you're interested in.

Additional features and/or motivations:

  • enabling/disabling channels persistently or at runtime
  • logging to console, disk, the network, or anywhere else
  • auto-generatating an interface for runtime configuration
  • being able to keep some logging in a final release, but dissolve other debug-only stuff away

This Version

Motto for this version: less is more.

The implementation of ECLogging started getting a bit gnarly.

This aims to be a stripped down version with just the essentials.

Specific aims

  • swifty
  • asynchronous
  • simple(r) way to enable/disable channels from the command line
  • support the new os_log() model


Stars: 0



1.5.5 - 2020-05-20 11:20:48

Don't build AppKit stuff under Catalyst.

1.5.4 - 2020-04-10 17:49:38

Added LoggerApplication implementation for AppKit.

1.5.3 - 2020-03-18 10:33:33

Added ChainableResponder, and made LoggerApplication and LoggerMenu use it.

This makes it easier to have other dependencies which also install things into the responder chain.

1.5.2 - 2020-03-05 18:38:55

For LoggerApplication instances, enable Debug/Logger menus in Debug builds by default. You can enable it in a release build using the ShowDebugMenu preference.

1.5.1 - 2020-02-26 12:09:53

Logs the willTerminate delegate method.

1.5 - 2020-02-21 11:59:27

Now builds for tvOS and watchOS as well as iOS/macOS/linux.

1.4.2 - 2020-02-19 12:04:23

Minor tweaks to the application shell. Fixed a unit testing race condition.

1.4.1 - 2020-02-05 11:37:34

Added standard AppDelegate and SceneDelegate classes to LoggerKit. These are entirely optional, but can form the foundation of a UIKit app that uses Logger.

1.4.0 - 2020-01-29 13:30:12

Updated tests to Swift 5.1 on Linux. Added UIKitExample. Ensure that defaultManager returns the same instance even if Logger has been linked multiple times. Added channels updated notification. Posted when new channels are registered. Added a UIKit LoggerMenu.

1.3.7 - 2019-06-19 23:26:18

Suppress startup output unless environment variable is set. It can mess up the output of command line apps.

1.3.6 - 2019-06-17 15:01:51

Xcode 11 and UIKitForMac compatibility tweaks.

1.3.5 - 2019-06-06 16:01:55

Reverted to a simpler form of endless loop for unreachable.

1.3.4 - 2019-04-04 12:46:27

Fixed some timeout/deadlock issues with XCTAssertFatalError.

1.3.3 - 2019-04-04 10:08:10

Allow timeout to be specified for fatal error assertion.

1.3.2 - 2019-03-08 15:04:00

Updated hash implementation to avoid deprecation warnings. Save settings using fullName. Mark result of XCTAssertFatalError as discardable.

1.3.1 - 2019-01-31 14:52:42

Changed the initialisation of channels to happen when they're first accessed, to avoid race conditions.

The race conditions were fairly harmless, but thread sanitizer was complaining about them, which was a pain in the arse.

1.3.0 - 2019-01-30 16:16:14

Asynchronous logging. A slightly refined handler API. Renamed Logger as Channel (with an alias back to Logger for backward-compatibility).

1.2.4 - 2019-01-30 13:06:52

Added a settings view to LoggerKit on iOS.

1.2.3 - 2019-01-25 13:22:09

Added enable/disable all. Added tick for enabled channels.

1.2.2 - 2018-12-19 16:25:38

Allow the test support framework to build, even on platforms that don't have XCTest.

This is a workaround for a problem with Xcode project generation, which means that the LoggingTestSupport library may be built when targetting a real iOS device - even though XCTest is not available for real devices.

1.2.1 - 2018-12-18 15:41:31

Fixed bug where duplicate log channel settings built up over time.

1.2.0 - 2018-12-13 19:04:36

Changed the way command line settings are interpreted. Added the beginnings of some UI support in LoggerKit.

1.1.1 - 2018-12-11 15:43:57

Added more fatalError test helpers.

1.1.0 - 2018-12-11 13:33:34

Added fatal error logging.

You can log a fatal error to any log channel.

This will log the output to the channel, and then call the fatal error handler on the log manager.

By default, this handler just calls on to fatalError, but you can override it with something else.

In addition, there is unit testing support which allows you to assert that something causes a fatal error (without the test actually fatal exiting too early to report a result).

1.0.11 - 2018-08-24 15:02:22

Fixed debug build from Xcode.

1.0.9 - 2018-08-24 15:01:42

removed tvos and watchos from example

1.0.10 - 2018-08-24 11:51:24

Tweaked the platforms that the examples are built for.

1.0.8 - 2018-04-05 15:18:06

Added xcode project file for use in hybrid spm/xcode situations.

1.0.7 - 2018-03-12 17:48:34

Added ability to inject UserDefaults for testing.

1.0.6 - 2018-03-07 17:01:58

Added function to filter arguments that have been dealt with.