I think your conclusion is supporting evidence for just not doing it in the source program in the first place. Whatever complexity makes it not easy is better encapsulated elsewhere. The application isn't a log broker itself, but giving it this functionality makes it a business logic concern that should not exist.
Apart from that, I agree that in principle programs that do their own complex logging have a place. (See OP's response WRT MQTT being the primary log destination.)
The good news is that we are beginning to unravel the actual question. "How to log in an embedded environment" is an important component of that question. And I might add, it's a component missing from the original question as posed. My previous answer does not make sense with this additional context, but then I would not have proposed it had I been given the context in the first place.
simplelogger::WriteLogger
is not meant to use Write
implementations that themselves use the logger. It's meant more for actual stream implementations, like File
or TcpStream
. AFAICT, paho_mqtt
doesn't provide any streams that implement Write
, but it stands to reason you might want to use it to create one.
You may be able to break the recursion by creating an app-specific logger instead of installing it globally. But then you miss all logs that use the global logger, including logs from the mqtt crate. Not that you will want them, but presumably they exist for a reason, i.e., debugging.
Filtering might be another option. Again at the expense of logs from the mqtt crate.
I think there is still something to be learned from the 12 factor app methodology. Namely that there is no good reason to throw away logs from the MQTT implementation simply because you want to use it for shipping logs. For this to work, you need to break the coupling. 12 factor imposes a constraint that logs should be treated as streams instead of destinations and formats. This nicely solves the problem because a pure stream doesn't need to log anything - it's just a sequence of data, not behavior over some data.
Concretely, a stream is something like a channel. Implying that writing to the stream is just the operation of sending to a channel, and some other process is responsible for consuming from the stream and sending it elsewhere, using MQTT for instance. The MQTT library can send its own logs to the stream. These are not recursive calls; The consumer will just pick up the new log on the next iteration. It means that you still need some filtering to avoid log amplification filling the channel. But otherwise it helps break the recursion.
Anyway, looking over paho_mqtt
, I'm surprised you have the standard library in your embedded system. Does this mean you also have threads? A stream consumer in its own thread can install a no-op thread-local logger and not deal with any logs generated on its own thread. Do you have processes? Process isolation is even better! Is it possible to use a different mqtt protocol library with the standard library TcpStream
? Etc, etc.