Thanks Quinn the Eskimo!
I don't like that quite as much, because then all logs from my lib will be at the same level (the one passed in by the user of the lib).
The something-is-very-broken logs would be drowned out in a sea of debug logs. For example, there are debug logs that emit on each audio buffer coming from the mic, containing the sample count in the buffer. These are frequent and only meant to be 'turned on' when I'm trying to debug an issue.
I'll share what I ended up doing. It makes log lines a little cumbersome for me, but thankfully users of my lib don't have to deal with that.
import OSLog
public enum AIProxyLogLevel: Int {
case debug
case info
case warning
case error
case critical
func isAtOrAboveThresholdLevel(_ threshold: AIProxyLogLevel) -> Bool {
return self.rawValue >= threshold.rawValue
}
}
internal var aiproxyCallerDesiredLogLevel = AIProxyLogLevel.warning
internal let aiproxyLogger = Logger(
subsystem: Bundle.main.bundleIdentifier ?? "UnknownApp",
category: "AIProxy"
)
// Why not create a wrapper around OSLog instead of forcing log callsites to include an `if ll(<level>)` check?
// Because I like the Xcode log feature that links to the source location of the log.
// If you create a wrapper, even one that is inlined, the Xcode source feature always links to the wrapper location.
@inline(__always)
internal func ll(_ logLevel: AIProxyLogLevel) -> Bool {
return logLevel.isAtOrAboveThresholdLevel(aiproxyCallerDesiredLogLevel)
}
And then my lib adds log lines like so:
if ll(.warning) { aiproxyLogger.warning("this is a warning log") }
if ll(.debug) { aiproxyLogger.debug("this is a debug log") }
...
And I expose a simple interface to the user of the lib that internally sets aiproxyCallerDesiredLogLevel.
It's a little unorthodox, but it's getting the job done for me, and Xcode's link-to-log-source functionality still works.
Big fan of your work. Every time I stumble on a great forum or technical note thread it always has your name on it.
ps. long live macnetworkprog!
Lou