Logging, Exceptions and the PSR logger


(Christian Müller) #1

This is a bit of an explanation because people keep wondering about logException and logThrowable after the PSR logging changes in Flow 5.0.

On the technical level it is relevant to note that logging is a defined field, even outside of PSR-3.
Typical loggers like papertrail, graylog etc. all do one specific thing. Save a list of line-based entries (events), typically with a timestamp. That’s how we know logs from literally everywhere.

Our exception “logs” are not logs. They are incident documents or debugging information depending on how you want to call it. They are separate documents describing one specific event in detail, unlike a log entry which is a short information about an event. The exception documents are not the same as logging and do not fit into common logging paradigms. Most typical log handlers would have difficulties with handling those. In Flow it was technically separated all along but the public interface was mashed up in the Logger. That was probably a mistake. While you could create custom logging backends all along even before PSR that never worked for exception documents because they were handled differently on a technical level (because they do not behave like logs).

With the technical and API separation of logging and throwable storage we can now store both anywhere we would like. Yes it means I need two injections to store throwables but if you separate the two responsibilities in your head you quickly see that it makes sense.

On a more “philosophical” level we have users (developers) and architecture.
Obviously it’s very practical to just have one object do both, BUT there are two main points against that:
First of all, the mentioned technical separation that already exists. It seems quite confusing for me that even if I configure a graylog adapter for logging my exceptions, they still end up on the local file system.
The strong technical separation into two separate responsibilities shows this boundary clearly to the user. So you will need two adapters to store both in ELK.
At some point we might carefully re-introduce some syntactic sugar to Flow to make that easier, BUT that would most likely contradict the benefit of using the generic PSR LoggerInterface so I am hesitant.
Additionally the second point for me speaks against it. As user of Flow you should rarely want to log exceptions.
Basically there are two types of exceptions. The ones that are unexpected and not caught by you. Those end up in the ExceptionHandler and are correctly stored and logged there, so you don’t need to bother with exception storage. And then “planned” exceptions that you catch. In this case you might want to log something about that exception, BUT you probably don’t need a full-blown exception document with stacktrace (as you already know that exception might happen there) but just a log entry that it happened and for that again the PSR LoggerInterface is enough. Therefore I see the need for actual exception storage rarely on the user side. I personally had that usecase about 1 time in the last two years and in that exceptional (all pun intended) case I can then use my two objects (Logger & Storage).

tl;dr; as end user of Flow use the PSR LoggerInterface and just do normal log entries for catched exceptions.