Puppy
🐶
Puppy 是一个由 Swift 实现的灵活日志库它支持多种传输介质(控制台、文件、syslog 和 oslog)作为日志记录器。它不仅可以独立工作,还可以作为 apple/swift-log 的后端。
此外,它具有文件日志轮换功能,您还可以自定义日志格式。它还支持 跨平台(Darwin、Linux 和 Windows)。
功能
- 使用 Swift 编写。
- 支持跨平台(Darwin、Linux 和 Windows)。
- 支持控制台、文件、syslog 和 oslog 作为记录器。
- 支持文件记录器的自动日志轮换。
- 同时也可以作为
apple/swift-log
的后端。
示例
基本使用
将日志记录到多个传输方式(例如控制台和文件)。建议将每个日志记录器的前一个参数设置为唯一的反向顺序FQDN,因为它还用于内部DispatchQueue的标签。
import Puppy
let console = ConsoleLogger("com.example.yourapp.console", logLevel: .info)
let fileURL = URL(fileURLWithPath: "./foo.log").absoluteURL
let file = FileLogger("com.example.yourapp.file",
logLevel: .info,
fileURL: fileURL,
filePermission: "600") // Default permission is "640".
var log = Puppy()
log.add(console)
log.add(file)
log.debug("DEBUG message") // Will NOT be logged.
log.info("INFO message") // Will be logged.
log.error("ERROR message") // Will be logged.
使用文件日志轮转
将日志记录到文件并使用日志轮转功能。
import Puppy
class ViewController: UIViewController {
let fileURL = URL(fileURLWithPath: "./logs/foo.log").absoluteURL
let rotationConfig = RotationConfig(suffixExtension: .date_uuid,
maxFileSize: 10 * 1024 * 1024,
maxArchivedFilesCount: 3)
let delegate = SampleFileRotationDelegate()
let fileRotation = try! FileRotationLogger("com.example.yourapp.filerotation",
fileURL: fileURL,
rotationConfig: rotationConfig,
delegate: delegate)
override func viewDidLoad() {
super.viewDidLoad()
var log = Puppy()
log.add(fileRotation)
log.info("INFO message")
log.warning("WARNING message")
}
}
class SampleFileRotationDelegate: FileRotationLoggerDelegate {
func fileRotationLogger(_ fileRotationLogger: FileRotationLogger,
didArchiveFileURL: URL, toFileURL: URL) {
print("didArchiveFileURL: \(didArchiveFileURL), toFileURL: \(toFileURL)")
}
func fileRotationLogger(_ fileRotationLogger: FileRotationLogger,
didRemoveArchivedFileURL: URL) {
print("didRemoveArchivedFileURL: \(didRemoveArchivedFileURL)")
}
}
apple/swift-log一起使用
与作为apple/swift-log的后端,将日志记录到多个传输方式(例如控制台和syslog)。
import Puppy
let console = ConsoleLogger("com.example.yourapp.console")
let syslog = SystemLogger("com.example.yourapp.syslog")
var puppy = Puppy()
puppy.add(console)
puppy.add(syslog)
LoggingSystem.bootstrap {
var handler = PuppyLogHandler(label: $0, puppy: puppy)
// Set the logging level.
handler.logLevel = .trace
return handler
}
var log = Logger(label: "com.example.yourapp.swiftlog")
log.trace("TRACE message") // Will be logged.
log.debug("DEBUG message") // Will be logged.
这里是一个使用Vapor和apple/swift-log内部集成的实际例子,后者使用了Puppy。
import App
import Vapor // Vapor 4.67.4
import Puppy
let fileURL = URL(fileURLWithPath: "./server-logs/bar.log").absoluteURL
let rotationConfig = RotationConfig(suffixExtension: .numbering,
maxFileSize: 30 * 1024 * 1024,
maxArchivedFilesCount: 5)
let fileRotation = try FileRotationLogger("com.example.yourapp.server",
fileURL: fileURL,
rotationConfig: rotationConfig)
var puppy = Puppy()
puppy.add(fileRotation)
// https://docs.vapor.codes/basics/logging/
var env = try Environment.detect()
try LoggingSystem.bootstrap(from: &env) { (logLevel) -> (String) -> LogHandler in
return { label -> LogHandler in
var handler = PuppyLogHandler(label: label, puppy: puppy)
handler.logLevel = .info
return handler
}
}
let app = Application(env)
defer { app.shutdown() }
try configure(app)
try app.run()
自定义日志格式
使用Formattable
协议自定义日志格式。例如将日志记录到oslog。
import Puppy
class ViewController: UIViewController {
let logFormat = LogFormatter()
let oslog = OSLogger("com.yourapp.oslog", logFormat: logFormat)
override func viewDidLoad() {
super.viewDidLoad()
var log = Puppy()
log.add(oslog)
log.info("INFO message")
log.warning("WARNING message")
}
}
struct LogFormatter: LogFormattable {
private let dateFormat = DateFormatter()
func formatMessage(_ level: LogLevel, message: String, tag: String, function: String,
file: String, line: UInt, swiftLogInfo: [String : String],
label: String, date: Date, threadID: UInt64) -> String {
let date = dateFormatter(date, withFormatter: dateFormat)
let fileName = fileName(file)
let moduleName = moduleName(file)
return "\(date) \(threadID) [\(level.emoji) \(level)] \(swiftLogInfo) \(moduleName)/\(fileName)#L.\(line) \(function) \(message)".colorize(level.color)
}
}
创建自定义日志记录器
您还可以创建您自己的自定义日志记录器。自定义日志记录器需要符合Loggerable
协议。
@preconcurrency import Dispatch
import Puppy
public struct CustomLogger: Loggerable {
public let label: String
public let queue: DispatchQueue
public let logLevel: LogLevel
public let logFormat: LogFormattable?
public init(_ label: String, logLevel: LogLevel = .trace, logFormat: LogFormattable? = nil) {
self.label = label
self.queue = DispatchQueue(label: label)
self.logLevel = logLevel
self.logFormat = logFormat
}
public func log(_ level: LogLevel, string: String) {
// Implements the logging feature here.
}
}
许可证
Puppy可在MIT许可证下获得。有关详细信息,请参阅LICENSE文件。