如何使用 OSLog 进行日志记录

1,811 阅读4分钟

前言

我们都知道,print 是开发人员最常用和最有用的调试工具。尽管我们还有断点调试,但在代码中添加一些 print 语句进行调试更加直观和有趣。当然,当我们打印的信息过多时,只需添加一些有用的前缀即可。但是,如果我告诉你,只需几行代码就可以做得更好呢?你可以将打印的信息发送到更多地方,设置优先级等。当然,这就不能简单的称其为打印了,而是称其为日志记录。

日志记录是收集应用程序重要数据的关键方法。从简单的调试字符串到记录整个事件链,良好的日志记录策略可以帮助你在 Xcode 中编写应用程序时调试问题,并且在将应用程序发布到商店后也能提供帮助。

本文将展示如何在应用程序中设置 OSLog 框架的 Logger,以及如何使用它记录消息,以帮助调试应用程序并了解用户遇到的问题。

设置 Logger 对象

要设置 Logger 对象非常简单,只需导入 OSLog 并创建一个 Logger 实例即可:

import OSLog

let logger = Logger()

@main
struct SwiftUIDemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

这种方法创建了一个全局的 Logger 对象,你可以在应用程序的任何地方使用它。由于没有传递任何自定义配置,Logger 将使用默认参数记录消息。不过,最好提供两个配置参数:

  • 子系统(subsystem)
  • 分类(category)

通过提供这两个参数,可以更轻松地过滤日志消息,并允许将多个 Logger 的消息分组。例如,我喜欢创建一个数据模型调试器,用于记录与数据模型相关的信息。以下是创建这种 Logger 的方法:

let modelLogger = Logger(subsystem: "cn.com.fengzhihao.SwiftUIDemo.models", category: "SwiftUIDemo.debugging")

Apple 官方建议我们使用反向 DNS 表示法命名子系统,例如,cn.com.fengzhihao.SwiftUIDemo.models 用于包含应用程序中模型的子系统。你可以为应用程序中的每个模块创建 Logger,并为每个模块提供自己的子系统。这样,你可以轻松地确定哪个模块生成了哪些日志消息。

第二个参数 category 用于将相关消息分组,即使它们来自不同的子系统。苹果没有为 category 提供任何命名约定,因此你可以自由选择命名。

在应用程序中使用多个 Logger 是完全可以接受的。你可以为单个子系统创建多个 Logger,以便提供不同的分类。使用命名良好的子系统和分类在应用程序中创建范围明确的 Logger,将极大地改善调试体验。

一旦创建了 Logger 实例并找到合适的位置保存它(我通常喜欢将其作为全局常量,但你可能希望注入或包装在你自己的类中),就可以开始发送第一个日志消息了。

记录你的第一条消息

通过 Logger 实例记录消息时,这些消息将根据你使用的日志级别最终出现在不同的位置。我们稍后将讨论日志级别,现在先使用简单的 log 方法记录消息。

让我们在 SwiftUI 中响应按钮点击事件记录一个简单的 “这是一条 info 日志” 消息:

struct ContentView: View {
    var body: some View {
        VStack {
            Button {
                modelLogger.info("这是一条 info 日志")
            } label: {
                Text("记录日志")
            }
        }
        .padding()
    }
}

调用 Logger 实例的 log 方法将导致消息在 Xcode 控制台中打印,就像使用 print 一样。然而,由于我们使用的是 Logger,可以让 Xcode 显示更多信息。效果图如下:

截屏2024-06-13 13.55.18.png 相比之下,使用 print 打印相同字符串时,没有额外信息,因此无法确定消息的具体打印时间、由哪个子系统生成,以及我们尝试进行的调试类型。

截屏2024-06-13 13.56.12.png

总结

调试和分析应用程序对于应用程序的成功至关重要。日志记录是一种不可或缺的工具,你可以在开发应用程序时使用它来替换标准的 print 调用,并且在生产环境中也能很好地扩展。通过开始用 Logger 替换 print 语句,你将能够应用更好的过滤和搜索。

此外,可以为应用程序的不同部分创建多个 Logger,通过子系统和分类进行过滤非常有用,使调试和追踪日志更加容易。