How to write your own custom logger using Combine.
Introduction
Loggers allow you to direct log messages wherever you want. DDLog.messagePublisher() wraps the API with a Combine publisher. Allowing you to use common Operators to transform these messages to your needs.
For general information about loggers, see the architecture page.
Publisher
DDLog.messagePublisher() returns MessagePublisher, which will never stop sending DDLogMessages while there is an active subscriber and doesn’t emit errors. Note that it’ll create a DDLogger for each subscription unless you use the share() operator.
Example
Here is an example of how you could use it display the last 1000 message in a log viewer.
var messages = [String]()
private var subscriptions = Set<AnyCancellable>()
func setup() {
DDLog.sharedInstance.messagePublisher() //messagePublisher emits `DDLogMessage`
.map(\.message) //Emits `String`. You could do the formating here if you wanted.
.scan([], { (messages, newMessage) in
var messages = messages
messages.insert(newMessage, at: 0)
return Array(messages.prefix(1000))
}) //Emits `[String]`. Up to 1000 messages, most recent message is first.
.receive(on: DispatchQueue.main) //Emits `[String]` on Main Queue
.sink(receiveValue: { [weak self] self?.messages = $0 }) //Sets `[String]` to local storage avoiding retain cycle.
.store(in: &subscriptions) //stores the subscription or it'll stop emitting events right away
}
You could add different operators to write the messages to disk, or to forward the messages to another API.
View on GitHub
CombineLoggers Reference