Make non-emitted logs cheaper
- Dominant language
- Swift
- Stars
- 4k
- Forks
- 344
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 5
Description
Looking at some perf traces today, I stumbled upon the fact that swift-log appears to be failing at its goal of making non-issued logs approximately free. Consider this code:
```swift
public func whyThough(_ logger: Logger) {
logger.trace("Hello, world!")
}
```
In an ideal world, in release builds this code would execute almost no instructions when the log level is higher than trace: it would check the log level, and then return.
In practice what it does is:
- Call `swift_beginAccess`
- Call `outlined init with copy of Logging.LogHandler`, which includes calling through the VWT for the LogHandler to execute its copy constructor
- Call `swift_project_boxed_opaque_existential_1`
- Call `swift_destroy_boxed_opaque_existential_1`
This appears to all boil down to the fact that the `logLevel` is held on the `LogHandler`, not the `Logger`, so we have to touch the existential in order to load the log level.
In some cases this may not be excessive, but if anyone has inserted trace level logs in hot code paths the cost can spiral quite badly. We’re seeing it take up to 10% of the CPU time in some of our high packet rate benchmarks.
Now, we can resolve this issue by just deleting the trace logging, but I wanted to ask: do we think swift-log should be this expensive? Are we interested in making it faster? We could make it faster by moving the log level to the Logger, not the LogHandler, but conceptually that could break existing code if they were playing weird tricks, and it could cause things that used to fit safely into existentials to not fit. How do we feel?
Contributor guide
Research direction
Start by examining how Logger accesses logLevel through LogHandler, then reproduce the whyThough example in a release build and inspect the disabled-trace instructions. Compare possible Logger and LogHandler changes against existential compatibility; done means non-emitted trace logs avoid the reported copying and existential operations without breaking existing handlers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- observability-sre
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100