ios logger_iOS 14的新Logger API与OSLog

ios logger

开始吧 (Let’s Start)

We will go through in short with migration from existing print logging to the new Apple Logging API.

我们将简要介绍从现有的print日志到新的Apple Logging API的迁移。

Then we will revisit the OSLog API and check differences between existing old OSLog and new iOS 14 Logger APIs.

然后,我们将重新访问OSLog API,并检查现有的旧OSLog和新的iOS 14 Logger API之间的区别。

To start off, let’s convert a simple print statement from this, which we use often in our project to log messages:


print(“Start network call”)

to this:


let log = OSLog.init(subsystem: "com.mandy.loggingdemo", category: "main")
os_log("Start network call", log: log)

Remember to use os_log API for this; you have to write import os.log statement. The unified logging system has been Apple’s standard for logging since iOS 10. (It was announced at WWDC 2016.)

请记住为此使用os_log API; 您必须编写import os.log语句。 自iOS 10以来,统一日志记录系统一直是Apple的日志记录标准(已在WWDC 2016上宣布 )。

You can consider subsystem as a unique bundle id of your app and category as app modules.


Now, in iOS 14, Apple has introduced a new Logger API. To use this API, we have to write same import os.log statement, but the syntax is quite different to os_log API.

现在,在iOS 14中,Apple引入了新的Logger API。 要使用此API,我们必须编写相同的import os.log语句,但是语法与os_log API完全不同。

let logger = Logger.init(subsystem: "com.mandy.loggingdemo", category: "main")
logger.debug("Start network call")

You can view the os_log and Logger logs in Xcode console in debug mode and also in the Mac Console app.

您可以在Xcode控制台中以调试模式以及在Mac Console应用程序中查看os_logLogger日志。

The Console app is very powerful; I would recommend using it as you can filter the values using subsystem and category and debug your app more extensively.

控制台应用程序非常强大; 我建议您使用它,因为您可以使用子系统类别过滤值,并更广泛地调试应用程序。

It also helps when you want to debug issues of device and export the logarchive. The archive file opens in Console and helps you determine the issue. Below is an example in which we have logged iPhone 11 Pro and filtered the simple log with subsystem com.mandy.loggingdemo.

当您要调试设备问题并导出logarchive时,它也有帮助。 存档文件在控制台中打开,可帮助您确定问题。 下面是一个示例,其中我们记录了iPhone 11 Pro,并使用子系统com.mandy.loggingdemo过滤了简单日志

Image for post

Both os_log and Logger API have most of the same benefits compared to print statements. In this article we will mainly focus on their usage and the differences between the two APIs. I have also added some good references at the end of article to walk you through os_log and Logger API. Let’s deep dive into it.

print语句相比, os_logLogger API都具有大多数相同的优点。 在本文中,我们将主要关注它们的用法以及两个API之间的区别。 我还在文章的末尾添加了一些很好的参考,以带您了解os_logLogger API。 让我们深入研究它。

统一日志API的好处 (Benefits of Unified Logging API)

  • Low performance overhead;

  • String interpolation (starting from iOS 14, os_log also supports this feature);

    字符串插值(从iOS 14开始, os_log也支持此功能);

  • Different logging type (debug, info, warning, error, fault, notice) for different usage;

  • Persistent and efficient logging — we can debug even the rare case scenarios bugs from devices and fix them;

  • Many formatting and expressive options with no cost at run time; and

    许多格式和表达方式选项,运行时无需花费任何费用; 和
  • Visibility options.


Let’s look at some key differences in action.


字符串插补和格式化字符串 (String Interpolation and Formatting Strings)

os_log accept formatted strings prior to iOS 14:

os_log接受iOS 14之前的格式化字符串:

let count = 0
let log = OSLog.init(subsystem: "com.mandy.loggingdemo", category: "main")
os_log("Start %d network call", log: log, type: OSLogType.debug, count)

Note: All string interpolation methods are also available in os_log, starting from iOS 14 onwards.

注意 从iOS 14开始 os_log 中也提供了所有字符串插值方法

The new Logger API supports string interpolation out of box, more like Swift-style compared to old C- style formatting. Some examples are

新的Logger API支持开箱即用的字符串内插,与旧的C样式格式相比,更像Swift样式。 一些例子是

  • Numeric data type such as Int and Double;

  • Objective-C objects with description; and

    带描述的Objective-C对象; 和
  • Any type conforming to CustomStringConvertible.


let count = 0
let logger = Logger.init(subsystem: “com.mandy.loggingdemo”, category: “main”)
logger.debug(“Start \(count) network call”)

不同的记录类型 (Different Logging Types)

Both os_log and Logger support different logging types. Below are some examples of types and their purposes.

os_logLogger支持不同的日志记录类型。 以下是一些类型及其用途的示例。

Image for post

Prior to iOS 14, we used os_log to declare it with type parameter. It was OSLogType enum:

在iOS 14之前,我们使用os_logtype参数声明它。 它是OSLogType枚举:

let count = 0
let log = OSLog.init(subsystem: "com.mandy.loggingdemo", category: "main")
os_log("Start %d network call", log: log, type: OSLogType.debug, count)

From iOS 14 onward, Apple has made the Logger API more developer-friendly, direct, and simple to promote its usage.

从iOS 14开始,Apple使Logger API对开发人员更加友好,直接和简单,以促进其使用。

Image for post
let count = 0
let logger = Logger.init(subsystem: “com.mandy.loggingdemo”, category: “main”)
logger.debug(“Start \(count) network call”)

While we are on this topic, let’s look at the different properties of these logging types, which will come in handy when using them in your app.


持久的 (Persistent)

These log messages are stored in disks based on their type. Debug is not persisted, info is only persisted during log collect option, and the rest are persisted until storage limit.

这些日志消息根据其类型存储在磁盘中。 调试不会持久化,信息只会在log collect选项期间持久化,其余的持久化直到存储限制。

Image for post

性能 (Performance)

Image for post

能见度 (Visibility)

As messages are logged, even when app is deployed, they can be viewed if a person has physical access to the device. Therefore, it’s the developer’s responsibility to not mark this sensitive info public.

记录消息后,即使有人部署了应用程序,只要有人可以物理访问设备,就可以查看消息。 因此,开发者有责任不将此敏感信息标记为公开。

In os_log we can set visibility with formatting options like the one below. We have set %{private}s as private in the same way we can set this as public. By default in os_log, dynamic values are private.

os_log我们可以使用以下格式设置选项来设置可见性。 我们已经将%{private}s设置为私有,就像我们可以将其设置为公开一样。 默认情况下,在os_log ,动态值是私有的。

let log = OSLog.init(subsystem: “com.mandy.loggingdemo”, category: “main”)
os_log(“Bank account number %{private}s, “, log: log, type: .info, 00011112222)

Let’s look in Logger. This API gives us some more customization options apart from visibility option. By default in Logger, dynamic values are private.

让我们看看Logger 。 除了可见性选项之外,此API还为我们提供了更多自定义选项。 在Logger ,默认情况下,动态值是私有的。

We can set the value as public or private with the help of privacy parameters like os_log.


logger.log(“Bank account number \(XXXXXXXX, privacy: .private)”)

We can also mask the sensitive info:


logger.log(“Bank account number \(XXXXXXXX, privacy: .private(mask: .hash))”)

日志档案 (Log Archives)

Consider a scenario in which you want to debug some rare-case scenario error or bug that doesn’t occur on your desktop computer or while debugging. Let say your QA has faced some unique issue, and he doesn’t know the exact steps to reproduce it.

考虑一个您要调试一些罕见情况下的错误或台式机或调试时不会发生的错误的方案。 假设您的质量检查人员遇到了一些独特的问题,他不知道重现此问题的确切步骤。

We can connect his device, export the log archive of your app from the time when the error occurred, and open in Console to debug this scenario, provided we have added appropriate logging in our app.


命令导出存档 (Command to export the archive)

log collect --device --start '

Open this archive in Console and filter using subsystem and category to find the issue.


I hope this article will help you understand the power of Logger API and helps you realize that now is the time we should switch our projects from traditional logging mechanisms to new Apple APIs for better and reliable debugging.

我希望本文能帮助您了解Logger API的功能,并帮助您认识到现在是时候将我们的项目从传统的日志记录机制切换到新的Apple API,以进行更好,更可靠的调试了。

参考书目和优秀读物 (References and Good Reads)


ios logger

已标记关键词 清除标记
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页