diff --git a/.spi.yml b/.spi.yml new file mode 100644 index 0000000..9947ea6 --- /dev/null +++ b/.spi.yml @@ -0,0 +1,4 @@ +version: 1 +builder: + configs: + - documentation_targets: [LoggingOSLog] \ No newline at end of file diff --git a/Package.resolved b/Package.resolved index b05e4dd..56b8a9f 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "041d5a9b2664fe8fba9d0ff5826e7f1955cca0b22d288fe2f2383df27258b52a", + "originHash" : "f8d66a42058d929bf19765cdba6aab75dff1936c233f6720005ce9dbcc464772", "pins" : [ { "identity" : "swift-log", diff --git a/Sources/Logging OSLog/Docs.docc/index.md b/Sources/Logging OSLog/Docs.docc/index.md new file mode 100644 index 0000000..d139703 --- /dev/null +++ b/Sources/Logging OSLog/Docs.docc/index.md @@ -0,0 +1,88 @@ +# ``LoggingOSLog`` + +An unified logging backend implementation for SwiftLog. + +## Overview + +LoggingOSLog is a logging backend implementation for [SwiftLog][swift-log], that +routes log messages to [OSLog][oslog], the +[unified logging system][unified-logging] on Apple platforms. On macOS you can +view the log messages using the Console app or the `log` cli tool. + +While SwiftLog is available on all Swift platforms though, the +unified logging system of OSLog is only available on Apple platforms. +Use this library to combine both worlds. Use SwiftLog in your codebase and use +this library as the backend implementation when compiling for an Apple platform, +i.e. using `#if canImport(Darwin)`. + +[unified-logging]: https://developer.apple.com/documentation/os/logging +[oslog]: https://developer.apple.com/documentation/oslog +[backend]: https://swiftpackageindex.com/apple/swift-log/1.10.1/documentation/logging +[swift-log]: https://github.com/apple/swift-log + +## Getting started + +Use this package if you're writing a cross-platform (for example, Linux and +macOS) application or library and still want to take full advantage of the +unified logging system on Apple platforms. + +### Adding the Dependency + +Add the dependency to your Package.swift: + +```swift +.package(url: "https://github.com/astzweig/swift-log-oslog", from: "1.0.0") +``` + +And to your target: + +```swift +.target( + name: "YourTarget", + dependencies: [ + .product(name: "LoggingOSLog", package: "swift-log-oslog") + ] +) +``` + +### Basic Usage + +```swift +// Import the logging API and this backend implementation +import Logging +#if canImport(Darwin) +import LoggingOSLog +#endif + +// Later, in your application initialization code +func init() { + // ... + #if canImport(Darwin) + LoggingSystem.bootstrap(LoggingOSLog.init) + #endif + + // Start creating loggers + let loggers: [String: Logger] = [ + "main": Logger(label: "com.example.yourapp.Main"), + "mail": Logger(label: "com.example.yourapp.Mail System"), + ] +} +``` + +## Relation to the unified logging system + +The [unified logging system][unified-logging] uses two parameters to allow for +better filtering of log messages: [subsystem][subsystem] and +[category][category]. [SwiftLog][swift-log] has only a label parameter, so this +library maps a reverse domain style label to the subsystem and category +parameters of the unified logging system. See +``/LoggingOSLog/LoggingOSLog/init(label:)`` for more information. + +[subsystem]: https://developer.apple.com/documentation/os/generating-log-messages-from-your-code#:~:text=The%20subsystem%20string,for%20each%20subsystem%20string. +[category]: https://developer.apple.com/documentation/os/generating-log-messages-from-your-code#:~:text=The%20category%20string,for%20these%20strings. + +## Topics + +### API + +- ``LoggingOSLog`` diff --git a/Sources/Logging OSLog/Logging OSLog.swift b/Sources/Logging OSLog/Logging OSLog.swift index 30acca7..f65332b 100644 --- a/Sources/Logging OSLog/Logging OSLog.swift +++ b/Sources/Logging OSLog/Logging OSLog.swift @@ -8,6 +8,22 @@ public struct LoggingOSLog: LogHandler { public var metadataProvider: Logging.Logger.MetadataProvider? private let oslogger: os.Logger + /** + Initializer that may be passed directly to + [LoggingSystem.bootstrap](https://swiftpackageindex.com/apple/swift-log/1.10.1/documentation/logging/loggingsystem/bootstrap(_:)). + + - Parameter label: Example: com.example.sometool.MailProcessing + A reverse domain style identifier. The part up until the + last dot is used as the subsystem and the part after the + last dot is used as the category of the unified logging + message. + After the last dot spaces may be used to separate words. + If you want to use the application bundle identifier as the + subsystem, use a value without any dot and the whole value + will be mapped as the category of the unified logging system and + the subsystem is either the bundle identifier - if any - or + the string "SwiftLogToOsLog". + */ public init(label: String) { let lastDotPosition = label.lastIndex(of: ".") ?? label.startIndex let frontPart = label.prefix(upTo: lastDotPosition) @@ -20,6 +36,16 @@ public struct LoggingOSLog: LogHandler { self.init(subsystem: String(frontPart), category: String(backPart)) } + /** + This Initializer may not be passed directly to + [LoggingSystem.bootstrap](https://swiftpackageindex.com/apple/swift-log/1.10.1/documentation/logging/loggingsystem/bootstrap(_:)). + It must be wrapped beforehand, but allows for direct assignment of subsystem and + category parameters of [OSLog](https://developer.apple.com/documentation/oslog). + + - Parameters: + - subsystem: See the [Apple documentation](https://developer.apple.com/documentation/os/generating-log-messages-from-your-code#:~:text=The%20subsystem%20string,for%20each%20subsystem%20string.) for this parameter. + - category: See the [Apple documentation](https://developer.apple.com/documentation/os/generating-log-messages-from-your-code#:~:text=The%20category%20string,for%20these%20strings.) for this parameter. + */ public init( subsystem: String = Bundle.main.bundleIdentifier ?? "SwiftLogToOsLog", category: String, @@ -29,11 +55,20 @@ public struct LoggingOSLog: LogHandler { self.logLevel = logLevel } + /** + This Initializer may not be passed directly to + [LoggingSystem.bootstrap](https://swiftpackageindex.com/apple/swift-log/1.10.1/documentation/logging/loggingsystem/bootstrap(_:)). + Use it, when you've already a fully configured [os.Logger](https://developer.apple.com/documentation/os/logging) + instance. + */ public init(oslog: os.Logger, logLevel: Logging.Logger.Level = .debug) { self.oslogger = oslog self.logLevel = logLevel } + /** + This function is called by [SwiftLog](https://github.com/apple/swift-log). + */ public func log( level: Logging.Logger.Level, message: Logging.Logger.Message, @@ -50,6 +85,9 @@ public struct LoggingOSLog: LogHandler { self.oslogger.log(level: OSLogType.from(loggerLevel: level), "\(message)") } + /** + Use subscripts on struct instances, to add metadata for all future log messages. + */ public subscript(metadataKey metadataKey: String) -> Logging.Logger.Metadata.Value? { get { return self.metadata[metadataKey] @@ -72,4 +110,4 @@ public struct LoggingOSLog: LogHandler { guard !metadata.isEmpty else { return nil } return metadata.map { "\($0) = \($1)" }.joined(separator: separator) } -} \ No newline at end of file +}