【发布时间】:2019-08-15 12:48:36
【问题描述】:
我正在使用 XCode 10.3 构建一个 Swift 5 应用程序。为此,我有一个框架,其中包含日志系统的实现(用于调试目的)。此日志系统的默认实现基于 OSLog/os_log。在消费应用程序中使用系统时,控制台应用程序中不会出现任何日志。但是,在放置断点时,我可以看到到达 os_log 语句(参见下面的代码示例)并且正确的参数被传递给 os_log 函数。但是,当我在宿主应用程序中使用 os_log 或 NSLog 时,它们会显示出来。
我已验证 LogSystem / DefaultLogImplementation 类型没有问题,因为所有需要命中的断点都已命中,并且所有单元测试都是绿色的。此外,到达并执行了os_log 语句,但没有出现日志。我已经验证所有消息都显示在控制台应用程序中,我已经验证我选择了正确的设备,我已经尝试了多个过滤器(甚至在没有启用过滤器的情况下挖掘了所有日志)......
任何人都可以帮助/指出问题可能是什么吗?我目前怀疑是OSLog/os_log的实现有bug。
代码示例
App 端代码,它使用类似于下面提供的示例的代码
class SomeClass {
private let logSystem = LogSystem()
func doSomethingImportant() {
// Do important stuff and log the result
logSystem.debug("Finished process with result \(result)")
}
}
应用程序使用的框架端代码
public class LogSystem {
private let logImplementation: LogImplementation
init(_ logImplementation: LogImplementation = DefaultLogImplementation()) {
self.logImplementation = logImplementation
}
public func debug(_ message: String) {
logImplementation.log(message, type: .debug) // And some other parameters...
}
public func error(_ message: String) {
// Similar to debug(:)...
}
}
public protocol LogImplementation {
func log(_ message: String, type: LogType, ...other parameters...)
}
public class DefaultLogImplementation: LogImplementation {
func log(_ message: String, type: LogType, ...other parameters...) {
let parsedType = parseLogType(type) // Function that parses LogType to OSLogType
let log = OSLog(subsystem: "my.subsystem.domain", category: "myCategory")
os_log("%{private}@", log: log, type: parsedType, message) // Breakpoint here is reached, but log does not appear in console app (even with debugger attached, which should remove the effect of "%{private}%". Either way, at the very least censored logs should still appear in console app.
}
}
其他信息
Swift 版本:5.0
XCode 版本:10.3
目标设备:iOS 12.2 iPhone X 模拟器
NSLog 出现在控制台应用程序中:是
在控制台应用程序中选择了正确的设备:是
正确的过滤器:是
更新 2019-08-16 13:00(阿姆斯特丹时间)
似乎只有 .debug 级别的消息没有出现在控制台应用程序中。将任何模拟器设备与 OSLog 结合使用时会出现此错误。我已经尝试了几个命令来解决这个问题:
sudo log config --mode level:debug,persist:debug
sudo log config --subsystem my.reverse.domain.name --mode level:debug,persist:debug
他们都没有解决这个问题。事实上,控制台应用程序中没有显示任何一条模拟器的调试级别消息(甚至来自 iOS 本身)。是的,显示 .info 和 .debug 级别消息的选项已启用。
我尝试通过以下命令专门为模拟器设置日志级别:
xcrun simctl spawn booted log config --mode level:debug
但这会导致错误:
log: Simulator unable to set system mode
【问题讨论】:
-
您是否在正确的子系统上进行过滤?
-
@matt 绝对是。我在由其中一个框架制作的 os_log 之上使用了一个包装器,当我使用该包装器时,我自己的应用程序的日志也不会显示。 (包装器也是我自己写的)。
-
那么听起来包装器有问题。但你还没有表现出来。您没有显示任何代码或提供任何信息来说明我们如何重现您遇到的问题。
-
@matt 我没有展示它,因为我知道包装器没有错。我断点了它的废话。我可以看到使用所有预期参数调用包装函数,并且我可以看到 os_log 也被正确调用。但它们不会出现在调试控制台或控制台应用程序中。事实上,当我将确切的包装器复制到我的项目时,它甚至可以工作。我还验证了包装器所在的框架不会禁用日志记录或包装器。对我来说,这似乎是 Swift 或编译器中的一个错误,但我想验证在做出这个假设之前我没有遗漏任何东西。
-
好吧,除非你能提供 一些 类可重现的例子,否则很难“验证”任何东西,而且你根本不清楚你为什么要问这个问题。继续假设吧。 :) 如果您认为您有需要向 Apple 报告错误的案例,请提交。