提问人:nhgrif 提问时间:8/20/2021 更新时间:8/26/2021 访问量:442
如何从 Swift 在 CocoaLumberJack 中实现自定义日志级别?
How to implement Custom Log Levels in CocoaLumberJack from Swift?
问:
我正在将 CocoaLumberjack 用于 Swift 项目。我想实现自定义日志级别/标志,因为我想使用 6 而不是默认的 5,并且更喜欢不同的名称。
执行此操作的文档没有帮助。它只是 Objective-C 的一个解决方案。
DDLogFlag
被定义为 NS_OPTIONS
这一事实意味着我实际上可以简单地忽略此处的预定义值,创建我自己的常量,然后编写一些包装代码以从一个常量转换为另一个常量。
但是,DDLogLevel
被定义为 NS_ENUM
,这意味着 Swift 不会对我尝试实例化要说的东西感到非常满意,这不是枚举中的现有值。如果它是 ,就像 ,我可以忽略库中预先存在的定义,并使用我想要的任何有效值。0b111111
NS_OPTIONS
DDLogFlag
UInt
据我所知,我只需要编写一些 Objective-C 代码来定义我自己的替换 ,并编写一个自定义函数来将其传递给并访问 上的这些属性。但这感觉很糟糕。DDLogLevel
DDLogFlag
DDLogMessage
如何在 Swift 中将我自己的自定义日志记录级别与 CocoaLumberjack 一起使用?
答:
这确实目前只在 Objective-C 中实现 - 而且也仅适用于 Log 宏。即便如此,我也可以想象“现代”ObjC 编译器会警告传递给 .#define
DDLogMessage
这里的文档确实有点过时了,并且源于 Objective-C 更接近 C 的时代,而不是现在的 Swift...... :-)
尽管如此,最终 和 都存储为 .这意味着理论上它可以取任何值(也就是在 Swift 中)。DDLogLevel
DDLogFlag
NSUInteger
NSUInteger
UInt
要定义自己的级别,只需创建一个,然后编写自己的日志记录函数。
这些函数实际上可以转发到现有函数:enum MyLogLevel: UInt { /*...*/ }
extension DDLogFlag {
public static let fatal = DDLogFlag(rawValue: 0x0001)
public static let failure = DDLogFlag(rawValue: 0x0010)
}
public enum MyLogLevel: UInt {
case fatal = 0x0001
case failure = 0x0011
}
extension MyLogLevel {
public static var defaultLevel: MyLogLevel = .fatal
}
@inlinable
public func LogFatal(_ message: @autoclosure () -> Any,
level: MyLogLevel = .defaultLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous async: Bool = asyncLoggingEnabled,
ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(), level: unsafeBitCast(level, to: DDLogLevel.self), flag: .fatal, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
}
这里有效,因为最终它只是一个并且不会切换关卡,而是对 .unsafeBitCast
UInt
_DDLogMessage
flag
免責聲明:我自己是 CocoaLumberjack 的维护者。
我们不建议在 Swift 中使用自定义日志级别。它没有太大的好处,像 swift-log 这样的日志框架也使用预定义的日志级别。
但是,我个人也可以想象用 而不是 .OSLog Swift 覆盖层还使用可扩展的 OSLogType。
如果这是您希望看到的内容,请打开一个 PR,以便我们与团队讨论。我们需要对 API 兼容性有点小心,但就像我说的,这是完全可行的。DDLogLevel
NS_OPTIONS
NS_ENUM
顺便说一句:请问您需要自定义关卡做什么?
评论
NS_ENUM
NS_OPTIONS
DDLogLevel
评论