SimpleLogging

一个简单、跨平台、轻量级的日志框架,由 Swift 的内置功能(如 printFileHandle)驱动。

此框架旨在提供开箱即用的简便性(当您只需要日志记录时)以及强大的可扩展性(当您的企业应用程序具有特定的日志记录需求时)。

术语

示例

严重性

此包中定义了六个严重性级别,但您可以根据需要定义更多

此软件包还将这些与一些方便的全局范围函数配对,以便快速记录日志

log(verbose: "Starting...")
log(debug: "TODO: Implement startup procedure")
log(info: "Startup done")
log(warning: "Future versions won't support the `--magically-work` flag")

if username == "BenLeggiero" {
    log(error: "You aren't allowed in here")
    return
}

if system.environment.isInvalid {
    log(fatal: "Environment is invalid")
    fatalError()
}

示例输出,使用允许所有消息的通道

2020-05-19 22:30:06.362Z 💬 Starting...
2020-05-19 22:30:06.362Z 👩🏾‍💻 TODO: Implement statup procedure
2020-05-19 22:30:06.362Z ℹ️ Startup done
2020-05-19 22:30:06.362Z ⚠️ Future versions won't support the `--magically-work` flag
2020-05-19 22:30:06.362Z 🚨 Environment is invalid

如果需要,您还可以显式指定这些(以及您创建的任何内容)

log(severity: .trace, "\(i) iterations so far")
log(severity: .critical, "The system is down!")

默认情况下,严重性由表情符号表示(例如,info 为 ℹ️,error 为 🆘),以便人们可以更轻松地浏览日志。 每个也可以用纯文本字符或长名称表示(例如,debug 的名称为 👩🏾‍💻、"d""debug")。 您可以按通道设置此项,以防您的通道无法处理 UTF-16,或者您只是不喜欢它。

通道

默认情况下,这只会记录到与 Swift 的 print 语句相同的位置。 因为企业应用程序具有不同的需求,所以它也可以记录到 stdoutstderr、任何 FileHandle 或自定义函数。 可以同时运行任意多个这些。 您还可以为每个日志调用或所有日志调用指定此项。

如果未指定任何内容,则默认通道过滤器会丢弃低于 info 严重性的消息,因为这是用户在查看日志但未调试代码本身时可能关心的最低内置严重性。

LogManager.defaultChannels += [
    try LogChannel(name: "General Log File", location: .file(path: "/tmp/com.acme.AwesomeApp/general.log")),
    try LogChannel(name: "Debug Log File", location: .file(path: "/tmp/com.acme.AwesomeApp/debug.log"), lowestAllowedSeverity: .debug),
    try LogChannel(name: "Error Log File", location: .file(path: "/tmp/com.acme.AwesomeApp/errors.log"), lowestAllowedSeverity: .error, logSeverityNameStyle: .short),
]

在上面的示例中,info 及以上的日志消息将发送到 Swift 的 print 目标和一个常规日志文件,而 error 及以上的日志消息将发送到特定的错误日志文件(不包含表情符号),并且 debug 日志消息(及以上)发送到特定的调试日志文件。 所有通道将接收所有 error 及以上的日志消息。 例如

log(verbose: "This is thrown away")
log(debug: "This only goes to the debug log channel")
log(info: "This goes to most of the log channels")
log(warning: "Same here")
log(error: "This is the first item in the error log; everything gets this")
log(fatal: "Everything gets this too")

上面的行将导致这些日志

Swift 的 print 通常去往的任何地方
2020-05-19 22:30:06.362Z ℹ️ This goes to most of the log channels
2020-05-19 22:30:06.362Z ⚠️ Same here
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too
/tmp/com.acme.AwesomeApp/general.log
2020-05-19 22:30:06.362Z ℹ️ This goes to most of the log channels
2020-05-19 22:30:06.362Z ⚠️ Same here
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too
/tmp/com.acme.AwesomeApp/debug.log
2020-05-19 22:30:06.362Z 👩🏾‍💻 This only goes to the debug log channel
2020-05-19 22:30:06.362Z ℹ️ This goes to most of the log channels
2020-05-19 22:30:06.362Z ⚠️ Same here
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too
/tmp/com.acme.AwesomeApp/errors.log
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too

日志记录范围的进入/退出

在日志中跟踪代码时,通常会在进入范围和退出范围时放置日志语句。 这个框架使这样的行为成为一流的,并且非常容易

func notable() {
    logEntry(); defer { logExit() }
    
    MyApp.notableOperation()
}
func longAsyncOperation() {
    logEntry(); defer { logExit() }
    
    DispatchQueue.main.async {
        logEntry(); defer { logExit() }
        
        longOperation()
    }
}