LogDog
友好的日志。
使用方法
数据存储器
格式化
let sink = LogSinks.firstly
.format {
"\($0.entry.level.uppercased) \($0.entry.message)\n"
}
// Output:
//
// DEBUG hello
内置格式化器
let short = LogSinks.BuiltIn.short
// Output:
//
// E: bad response
// C: can not connect to db
let medium = LogSinks.BuiltIn.medium
// Output:
//
// 20:40:56.850 E/App main.swift.39: bad response url=/me, status_code=404
// 20:40:56.850 C/App main.swift.41: can not connect to db
let long = LogSinks.BuiltIn.long
// Output:
//
// ╔════════════════════════════════════════════════════════════════════════════════
// ║ 2020-11-15 20:46:31.157 App ERROR (main.swift:39 run(_:))
// ╟────────────────────────────────────────────────────────────────────────────────
// ║ bad response
// ╟────────────────────────────────────────────────────────────────────────────────
// ║ url=/me
// ║ status_code=404
// ╚════════════════════════════════════════════════════════════════════════════════
前缀 & 后缀
let sink = LogSinks.BuiltIn.short
.prefix("🎈 ")
// Output:
//
// 🎈 E: bad response
let sink = LogSinks.BuiltIn.short
.suffix(" 🎈")
// Output:
//
// E: bad response 🎈
编码
let sink = LogSinks.firstly
.encode(JSONEncoder())
压缩
let sink = LogSinks.firstly
.encode(JSONEncoder())
.encrypt(using: key, cipher: .ChaChaPoly)
加密
let sink = LogSinks.firstly
.encode(JSONEncoder())
.compress(.COMPRESSION_LZFSE)
过滤
let sink = LogSinks.firstly
.filter {
$0.entry.source != "LogDog"
}
// logs from `LogDog` won't be outputted.
领域特定语言(DSL)
let sink = LogSinks.BuiltIn.short
.when(.path)
.contains("private")
.deny
let sink = LogSinks.BuiltIn.short
.when(.level)
.greaterThanOrEqualTo(.error)
.allow
连接
let sink = LogSinks.Builtin.short
.prefix("🎈 ")
.suffix(" 🎈")
.when(.path).contains("private").deny
// ...
let sink = LogSinks.firstly
.encode(JSONEncoder())
.encrypt(using: key, cipher: .ChaChaPoly)
.compress(.COMPRESSION_LZFSE)
计划
let sink = LogSinks.firstly
.sink(on: dispatchQueue)
.encode(JSONEncoder())
.encrypt(using: key, cipher: .ChaChaPoly)
.compress(.COMPRESSION_LZFSE)
钩子
由于存在计划,下沉可能是不一致的。因此你不应该在下沉时获取上下文。
你应该使用带有 entry.parameters
的 hook
来捕获并存储上下文。
private struct CustomSinkContext: LogParameterKey {
typealias Value = CustomSinkContext
let date = Date()
let thread = LogHelper.thread
}
let customSink: AnyLogSink<Void, String> = .init {
$0.parameters[CustomSinkContext.self] = .init()
} sink: { record, next in
record.sink(next: next) { (record) -> String? in
guard let context = record.entry.parameters[CustomSinkContext.self] else {
return nil
}
let time = LogHelper.format(context.date, using: "HH:mm:ss.SSS")
let thread = context.thread
// ...
}
}
附录器
内置格式化器
OSLogAppender
将字符串追加到底层的 OSLog
。
let appender = OSLogAppender(osLog)
TextLogAppender
将字符串追加到底层的 TextOutputStream
。
let appender = TextLogAppender(stream)
let stdout = TextLogAppender.stdout
let stderr = TextLogAppender.stderr
MultiplexLogAppender
将输出追加到底层追加器。
let appender = MultiplexLogAppender(concurrent: true, a, b, c, d/*, ...*/)
FileLogAppender(WIP)
SugarLogHandler
创建一个 SugarLogHandler
。
let sink = LogSinks.Builtin.short
let appender = TextLogAppender.stdout
var handler = SugarLogHandler(label: label, sink: sink, appender: appender) { error in
print("error: \(error)")
}
handler.dynamicMetadata["userId"] = {
AuthService.shared.userId
}
使用预定义的日志处理器创建记录器。
let logger = Logger.sugar("worker:a")
使用预定义的记录器。
sugar.debug("hi")
社区
除了上面提到的sinks/appenders以外,你还可以在LogDogCommunity找到更多集成!
LogDogChalk
为LogDog的输出着色。
LogDogCryptoSwift
加密LogDog的输出。
LogDogCocoaLumberjack
将LogDog的输出附加到CocoaLumberjack。
你没有想要的sinks/appenders?欢迎贡献!
安装
Swift包管理器
.package(url: "https://github.com/apple/swift-log.git", from: "0.2.0"),
CocoaPods
pod 'LogDog', '~> 0.2.0'