Apple recommends utilizing OSLog
`Logger. It’s promoted on WWDC al least since 2020 (for instance see WWDC 2023 Session 10226 Debug with structured logging).
It’s alleged to be tremendous environment friendly and so forth.
It biggest limitation is that:
iOS has very restricted amenities for studying the system log. At present,
an iOS app can solely learn entries created by that particular course of,
utilizing .currentProcessIdentifier scope. That is annoying if, say, the
app crashed and also you wish to know what it was doing earlier than the crash.
What you want is a approach to get all log entries written by your app (r.
57880434).
Supply: Your Pal the System Log
To let customers ship logs for a sure interval even in case of crashes I could not discover a higher answer however to duplicate logging to a set of information with rotation. If Logger
had some form of delegate that might appear to be the best choice to do some additional work at proper time, however sadly it does not.
For interoperability I made a decision to create a logger that has precisely the identical operate signatures because the system one OSLog
Logger
.
Since Logger
is a struct
I can not inherit it and override its capabilities to inject file logging together with inherited system logging.
So I made a decision to wrap Logger
into one other struct
HybrydLogger
and simply replicate unique capabilities with their signatures like this:
public func error(_ message: OSLogMessage) {
osLogger.error("(message.description)")
fileLogger.log(degree: .error, message.description)
}
There are only some strategies to reimplement, akin to (debug
, fault
, and related).
However I stumbled upon a limitation which appears to be intentional.
Once I name HybridLogger.shared.error("Configuration failed: (res, privateness: .public)")
, I get error: “String interpolation can’t be used on this context; if you’re calling an os_log
operate, attempt a distinct overload.“
Appears prefer it has one thing to take care of the be aware within the doc.
You don’t create situations of OSLogMessage instantly. As an alternative, the
system creates them for you when writing messages to the unified
logging system utilizing a Logger.
From the Swift discussion board:
The logging APIs use particular compiler options to guage the privateness
degree at compile time. Because the diagnostic says, you should use a static
(i.e., recognized at compile time) methodology or property of ‘OSLogPrivacy’; it
can’t be a variable that’s evaluated at run time. The implication is
that you could’t create your individual wrapper for these APIs with out utilizing
compiler-internal options.