I'd question if wrapping OSLog is really a good idea. That circumvents all performance advantages OSLog offers and also, I think if you'd log something with logger.trace("\(s)") OSLogs privacy level is private by default, meaning that your log message would be entirely redacted.
You won‘t have much luck wrapping Logger (and you probably also shouldn’t) but luckily you don‘t have to. You can get a disabled logger instance like this: Logger(.disabled). disabled | Apple Developer Documentation.
As others have mentioned, wrapping Logger is a bad idea because it defeats the compiler integration that gives the system log its runtime efficiency. One potential option here is to create a macro that wraps the API. I’ve seen folks try to tackle that but I’ve not seen anyone pull it off. If I had infinite time on my hands…
Anyway, another drawback to wrapping this is that you lose the private data support.
As to your high-level goal, why are you trying to enable and disable logging at this level? The general intention of the system log API — and the reason why efficiency is so important — is that you should leave your logs enabled in production code. Then select a log level whose default disposition matches the level of logging you expect. Finally, you can use outside mechanism to enable the more intense logging if necessary.
I have found it useful to sometimes disable logs in unit tests. I use a similar technique to what Robert posted above, but with a dependency injection framework around it.
Another use case where it is desired to disable most logging is when developing a closed source SDK. The internal details contained in log messages should not be spilled to SDK users, and only select log messages should be produced.
Thank you @eskimo for your input!
I am happy to share my use case with you: I have an elaborate processing of a single piece of data, and use extensive logging in it.
Occasionally, I need to use it in a batch processing, for millions of records. Even using Filter in Xcode's output, the digging through those records is not really practical, so I wanted to disable logging for that batch.
I got everyone's point about wrapping, and I no longer do that.
Thank you @robert.ryan , again, for your help!
I like this idea the best for its flexibility. Will use a Bool parameter to control enablement so that I can make this decision at run time.
Would you have a suggestion on how to expand this approach to control log verbosity? Like only emit error and fault?
@VladFein – Personally, I would use the filter bar in the Xcode console (in the lower right corner of the Xcode 16 console) for that. For example, enter “type:fault”, hit return and then enter “type:error” and then change the default “ALL” option to “ANY”. That will show you:
Unfortunately, this filter bar only lets you choose “ANY” or “ALL”, but not compound expressions.
@eskimo Do you have examples of macro wrapping that you have seen at all? This is such a tiresome thing. "Don't wrap logs because we couldn't think of a way that allows you to centralize your logging needs."
Do you have examples of macro wrapping that you have seen at all?
No. My only experience with this is that I’ve talked with someone who tried to get it to work and failed. I don’t think there’s any fundamental reason why it’s impossible, but I don’t have time to go down that rabbit hole myself.
Fact of the matter is, os_log is really only designed to be used by Apple, in Apple systems. It can't be wrapped because their performance requirements are so high due to the fact they use it for everything, everywhere. You'll be much better served by using your own logging package, as I doubt Apple will ever release a version that properly allows wrapping while losing a tiny bit of performance that doesn't matter to 90% of app devs.
Given the number of WWDC sessions dedicated to how we use it in our own code (e.g., Explore logging in Swift, Debug with structured logging, etc.), it is a little strong to suggest that it is “only designed to be used by Apple.”
That having been said, it certainly is designed for a very specific use-cases and you may well want to use different logging solutions for a broader array of needs. Unified logging offers some unique features not available elsewhere, but those other logging solutions likewise have features that Apple’s unified logging cannot match, either.
Note that saying "only designed to be used by Apple, in Apple systems" doesn't say anything about Apple's intent or what they imagine the community needs or wants. It's simply a statement on the utility of the system as designed.