Files
Pulse/Sources/PulseLogHandler/PersistentLogHandler.swift
2022-08-07 20:52:47 -04:00

99 lines
2.9 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// The MIT License (MIT)
//
// Copyright (c) 20202022 Alexander Grebenyuk (github.com/kean).
import Foundation
import Pulse
import Logging
public typealias NetworkLogger = Pulse.NetworkLogger
public typealias LoggerStore = Pulse.LoggerStore
public typealias URLSessionProxyDelegate = Pulse.URLSessionProxyDelegate
/// Allows ``LoggerStore`` to be used with with [SwiftLog](https://github.com/apple/swift-log).
///
/// ```swift
/// import PulseLogHandler
/// import Logging
///
/// LoggingSystem.bootstrap(PersistentLogHandler.init)
/// ```
///
/// If used this way, you never need to interact with the store directly. To log
/// messages, you'll interact only with the SwiftLog APIs.
///
/// ```swift
/// let logger = Logger(label: "com.yourcompany.yourapp")
/// logger.info("This message will be stored persistently")
/// ```
public struct PersistentLogHandler {
public var metadata = Logger.Metadata()
public var logLevel = Logger.Level.info
private let store: LoggerStore
private let label: String
public init(label: String) {
self.init(label: label, store: .shared)
}
public init(label: String, store: LoggerStore) {
self.label = label
self.store = store
}
}
extension PersistentLogHandler: LogHandler {
public subscript(metadataKey key: String) -> Logger.Metadata.Value? {
get {
metadata[key]
} set(newValue) {
metadata[key] = newValue
}
}
public func log(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata?, file: String, function: String, line: UInt) {
var mergedMetadata = self.metadata
for (key, value) in metadata ?? [:] {
mergedMetadata[key] = value // Override keys if necessary
}
store.storeMessage(label: label, level: .init(level), message: message.description, metadata: .init(mergedMetadata), file: file, function: function, line: line)
}
}
// MARK: - Private (Logger.Level <-> LoggerStore.Level)
private extension LoggerStore.Level {
init(_ level: Logger.Level) {
switch level {
case .trace: self = .trace
case .debug: self = .debug
case .info: self = .info
case .notice: self = .notice
case .warning: self = .warning
case .error: self = .error
case .critical: self = .critical
}
}
}
// MARK: - Private (Logger.Metadata <-> LoggerStore.Metadata)
private extension LoggerStore.Metadata {
init(_ metadata: Logger.Metadata) {
self = metadata.compactMapValues(LoggerStore.MetadataValue.init)
}
}
private extension LoggerStore.MetadataValue {
init?(_ value: Logger.MetadataValue) {
switch value {
case .string(let value): self = .string(value)
case .stringConvertible(let value): self = .stringConvertible(value)
case .dictionary: return nil // Unsupported
case .array: return nil // Unsupported
}
}
}