Apple's SwiftLog + OSLog style StringInterpolation
Logging
A version of Apple’s SwiftLog that adds some improved formatting for app development and includes OSLog-ish string interpolation.
Feature List
-
Privacy (public, private and masked) -
Log levels -
FormattedLogHandler -
Literal string -
Numerical formats -
Boolean formats - Exponential formats
- Hexadecimal formats
- Column formatting
I’ve also added many tests to ensure the string interpolation and privacy features are working as expected. However, I have not included any of SwiftLog’s tests since the library is simply a direct copy (see below).
Examples
// Somewhere in your code, define your log handler(s)
LoggingSystem.bootstrap { label in
FormattedLogHandler(label: label)
}
// Then in a framework or subsystem, define a logger
let logger = Logger(label: "com.benkau.logging")
logger.debug("Hello, world!")
Similar to OSLog, all interpolated values default to a private
scope (in a non-DEBUG
) environment, with their values redacted.
logger.debug("Logged in as \(user, privacy: .private)")
// Logged in as <redacted>
logger.debug("Fetching data from \(url, privacy: .private(.hash))")
// Fetching data from 210237823
There are conveniences for logging numerical values:
logger.debug("Pi is \(3.14159265359, format: .fixed(precision: 2))")
// Pi is 3.14
logger.debug("Current score: \(score, format: .decimal(minDigits: 2)")
// Current score: 03
Formatting
The library includes a custom FormattedLogHandler
that you’re free to use or create your own. The provided handler uses SFSymbols to improve readability and clarity in the console, as well as providing a simple closure based formatter so you can make it your own.
FormattedLogHandler { options in
// simply return your formatted log
FormattedLogHandler(label: label) { data in
"\(data.timestamp()) [\(data.label)] \(data.level.symbol) \(data.message)"
}
}
Obviously you can always use your own
LogHandler
as you can directly with SwiftLog.
SwiftLog
The actual logging framework is a direct copy of Apple’s own SwiftLog. The reason I didn’t include it as a dependency is because there was no way for me to extend it to include string interpolation that I could see. If anyone has ideas on how to make this work, I would love to hear about them. Please open an Issue so we can discuss it as this would allow me to properly attribute and pin to a dependency version etc…
Installation
The code is packaged as a framework. You can install manually (by copying the files in the Sources
directory) or using Swift Package Manager (preferred)
To install using Swift Package Manager, add this to the dependencies
section of your Package.swift
file:
.package(url: "https://github.com/shaps80/Logging.git", .upToNextMinor(from: "1.0.0"))