Swiftwood

一个用于 swift 项目的日志记录包。(“swiftwood”是“driftwood”(浮木)的双关语,因为日志就像浮木一样,经常被随意丢进事件流中,容易在其中迷失。)

深受 SwiftyBeaver 的启发,但更加简洁。此外,还支持(半)自动敏感数据审查功能。

目前尚未包含远程日志记录目标。创建一个并不困难,只需实现 SwiftwoodDestination 协议,批量处理日志,然后将它们发送到您的服务器。我计划在未来有时间的话,添加一个通用的实现/示例。 这对于贡献者来说是一个不错的贡献方向。

初始设置

public typealias log = Swiftwood
fileprivate let setupLock = NSLock()
fileprivate var loggingIsSetup = false

func setupLogging() {
	setupLock.lock()
	defer { setupLock.unlock() }
	guard loggingIsSetup == false else { return }
	loggingIsSetup = true

	let consoleDestination = ConsoleLogDestination(maxBytesDisplayed: -1)
	consoleDestination.minimumLogLevel = .verbose
	log.appendDestination(consoleDestination)
}

然后在应用生命周期早期调用 setupLogging()

用法

log.verbose("Something small happened")
//10/04/2022 00:49:40.107 💜 VERBOSE SwiftwoodTests.swift testLogging():19 - Something small happened
log.debug("Some minor update")
//10/04/2022 00:49:40.109 💚 DEBUG SwiftwoodTests.swift testLogging():20 - Some minor update
log.info("Look at me")
//10/04/2022 00:49:40.111 💙 INFO SwiftwoodTests.swift testLogging():21 - Look at me
log.warning("uh oh")
//10/04/2022 00:49:40.113 💛 WARNING SwiftwoodTests.swift testLogging():22 - uh oh
log.error("Failed successfully")
//10/04/2022 00:49:40.115 ❤️ ERROR SwiftwoodTests.swift testLogging():23 - Failed successfully

敏感数据审查

只需使任何你想审查的内容实现 CensoredLogItem 协议,当你*单独*记录该项,并且目标启用了审查功能时,它将在日志中显示为 **CENSORED**

示例

struct CensoredPassword: CensoredLogItem, RawRepresentable {
	let rawValue: String
}

let consoleDestination = ConsoleLogDestination(maxBytesDisplayed: -1, shouldCensor: true) // Console destinations default to `false` censorship
let fileDestination = try FilesDestination(logFolder: URL(pretend this is a valid url), shouldCensor: true) // File destinations default to `true` censorship

let password = CensoredPassword(rawValue: "password1234!")
log.info("regular string", password) // regular string CensoredPassword: **CENSORED*
log.info("regular string \(password)") // regular string CensoredPassword(rawValue: "password!1234")

注意,如果使用字符串插值,审查功能将失效!

或者,如果你想对信息进行模糊处理但又想显示一部分,你可以提供自定义的 censoredDescription

struct CensoredKey: CensoredLogItem, RawRepresentable, CustomStringConvertible {
	let rawValue: String

	var description: String { rawValue }
	var censoredDescription: String {
		guard
			rawValue.count > 10,
			let start = rawValue.index(rawValue.endIndex, offsetBy: -3, limitedBy: rawValue.startIndex)
		else { return "***" }
		return "***" + String(rawValue[start..<rawValue.endIndex])
	}
}

let key = CensoredKey(rawValue: "thisisalongkey")
log.info("My key is:", key) // My key is: ***key
log.info("My key is: \(key)") // My key is: thisisalongkey

请务必不要对想要审查的值使用字符串插值!

查看测试以了解更多用法细节和示例。