swift-log
swift-log copied to clipboard
RFC: Add capability to configure loggers inline
Adds initializers and methods to create Logger instances with metadata inline.
Motivation:
Frequently it's needed to create copies of loggers, or a new logger, with attached metadata or specific log levels, but the current method requires first creating an instance, as a var
, and then configuring the instance.
This leaves you to have a mutable value existing in the scope even if you don't want to.
This particularly has issues with async code when capturing the instance in a Task
because it's non-isolated
var logger = Logger(label: "\(#function)")
logger[metadataKey: metadataKey] = "original"
Task {
logger.trace("won't work")
// ^^^^^ Reference to captured var 'logger' in concurrently-executing code
}
The best way to get around this is either
// 1 immediately invoked closure
let logger = {
let inner = Logger(...)
// configuration
return inner
}()
// 2 variable rebinding
let retainedLogger = logger
Task {
retainedLogger.trace("will work")
}
// 3 explicit capture
Task { [logger] in
logger.trace("will also work")
}
Modifications:
- Add:
makeCopy(with:mergePolicy:)
to allow just setting inline the metadata you want the new instance to have, with control on how to merge with existing metadata keys - Add:
makeCopy(_:)
which passes aninout
reference to the new instance, allowing you to set more options such aslogLevel
as part of creation - Add:
init(label:metadata:)
that allows creation of instances directly inline that directly sets the metadata - Add:
init(label:_:)
that allows creation of instances with a reference to the object for inline configuration much likemakeCopy(_:)
Result:
Developers will now be able to make Logger
instances, or "children" copies, directly inline with full control over the value's mutability - making it safe to send across Task
boundaries
let logger = Logger(label: "myLabel") {
$0.logLevel = .info
$0[metadataKey: "my_key"] = "my value"
}
Task {
logger.info("this works")
}
Can one of the admins verify this patch?