- 
                Notifications
    
You must be signed in to change notification settings  - Fork 329
 
Description
In addition to resolving #377, it would be valuable to have ways to make log lines even cheaper in context where they aren't necessary. .trace and .debug logs, in particular, impose costs even when they aren't taken:
- if we applied Make non-emitted logs cheaper #377, we'd still have to execute a few instructions and a branch
 - we still eat the code size increase for the log, even if we never have any plans to execute it
 - the code size increases affect the inlining thresholds for other methods and can cause the compiler to do worse
 
These costs are unfortunate to pay in contexts where we might statically know we have no intention to ever emit the logs. And we could avoid paying them in at least some contexts by doing something like this:
@inlinable
public func trace(
    _ message: @autoclosure () -> Logger.Message,
    metadata: @autoclosure () -> Logger.Metadata? = nil,
    source: @autoclosure () -> String? = nil,
    file: String = #fileID,
    function: String = #function,
    line: UInt = #line
) {
    #if DEBUG || SWIFT_LOG_ALLOW_TRACE_IN_RELEASE
    self.log(
        level: .trace,
        message(),
        metadata: metadata(),
        source: source(),
        file: file,
        function: function,
        line: line
    )
    #endif
}We could do this once for each log level.
We could then define a trait for each of these log levels that is defaulted to on, and sets the SWIFT_LOG_ALLOW_X_IN_RELEASE variable to allow them. This preserves the existing behaviour, but allows application packages to suppress that trait and so turn off logs that they have no intention to allow, while re-enabling it if they want to. All the logs would also be preserved in debug builds.