#if canImport(os)import Foundationimport Loggingimport os struct OSLogLogHandler: LogHandler { var metadata: Logging.Logger.Metadata = [:] var logLevel: Logging.Logger.Level = .info private let label: String private let subsystem: String private let logger: os.Logger init(label: String, subsystem: String) { self.label = label self.subsystem = subsystem let category = Self.category(from: label, subsystem: subsystem) self.logger = os.Logger(subsystem: subsystem, category: category) } subscript(metadataKey metadataKey: String) -> Logging.Logger.Metadata.Value? { get { self.metadata[metadataKey] } set { self.metadata[metadataKey] = newValue } } // swiftlint:disable:next function_parameter_count func log( level: Logging.Logger.Level, message: Logging.Logger.Message, metadata: Logging.Logger.Metadata?, source: String, file: String, function: String, line: UInt) { let msg = Self.decorate( message: message.description, label: self.label, subsystem: self.subsystem, metadata: self.metadata, extraMetadata: metadata) switch level { case .trace: self.logger.debug("\(msg, privacy: .public)") case .debug: self.logger.debug("\(msg, privacy: .public)") case .info, .notice: self.logger.info("\(msg, privacy: .public)") case .warning: self.logger.warning("\(msg, privacy: .public)") case .error: self.logger.error("\(msg, privacy: .public)") case .critical: self.logger.fault("\(msg, privacy: .public)") } } private static func category(from label: String, subsystem: String) -> String { let prefix = subsystem + "." guard label.hasPrefix(prefix) else { return label } return String(label.dropFirst(prefix.count)) } private static func decorate( message: String, label: String, subsystem: String, metadata: Logging.Logger.Metadata, extraMetadata: Logging.Logger.Metadata?) -> String { var merged = metadata if let extraMetadata { merged.merge(extraMetadata, uniquingKeysWith: { _, new in new }) } guard !merged.isEmpty else { return message } let suffix = merged .sorted(by: { $0.key < $1.key }) .map { "\($0.key)=\($0.value)" } .joined(separator: " ") _ = label _ = subsystem return "\(message) (\(suffix))" }}#endif
#if canImport(os)
import Foundation
import Logging
import os
struct OSLogLogHandler: LogHandler {
var metadata: Logging.Logger.Metadata = [:]
var logLevel: Logging.Logger.Level = .info
private let label: String
private let subsystem: String
private let logger: os.Logger
init(label: String, subsystem: String) {
self.label = label
self.subsystem = subsystem
let category = Self.category(from: label, subsystem: subsystem)
self.logger = os.Logger(subsystem: subsystem, category: category)
}
subscript(metadataKey metadataKey: String) -> Logging.Logger.Metadata.Value? {
get { self.metadata[metadataKey] }
set { self.metadata[metadataKey] = newValue }
}
// swiftlint:disable:next function_parameter_count
func log(
level: Logging.Logger.Level,
message: Logging.Logger.Message,
metadata: Logging.Logger.Metadata?,
source: String,
file: String,
function: String,
line: UInt)
{
let msg = Self.decorate(
message: message.description,
label: self.label,
subsystem: self.subsystem,
metadata: self.metadata,
extraMetadata: metadata)
switch level {
case .trace:
self.logger.debug("\(msg, privacy: .public)")
case .debug:
self.logger.debug("\(msg, privacy: .public)")
case .info, .notice:
self.logger.info("\(msg, privacy: .public)")
case .warning:
self.logger.warning("\(msg, privacy: .public)")
case .error:
self.logger.error("\(msg, privacy: .public)")
case .critical:
self.logger.fault("\(msg, privacy: .public)")
}
}
private static func category(from label: String, subsystem: String) -> String {
let prefix = subsystem + "."
guard label.hasPrefix(prefix) else { return label }
return String(label.dropFirst(prefix.count))
}
private static func decorate(
message: String,
label: String,
subsystem: String,
metadata: Logging.Logger.Metadata,
extraMetadata: Logging.Logger.Metadata?)
-> String
{
var merged = metadata
if let extraMetadata { merged.merge(extraMetadata, uniquingKeysWith: { _, new in new }) }
guard !merged.isEmpty else { return message }
let suffix = merged
.sorted(by: { $0.key < $1.key })
.map { "\($0.key)=\($0.value)" }
.joined(separator: " ")
_ = label
_ = subsystem
return "\(message) (\(suffix))"
}
}
#endif