There is no one-size fits all answer here. Logging tends to go in the location that can give the appropriate details.
For example, if you don't just want to log that your Document is invalid, but you want to log why it is invalid, you're going to want the logging to be done by DocumentValidator itself, rather than the DocumentService which only receives back a boolean from the validator.
On the other hand, if you dig too deep, you lose the context of your call stack. For example, if you really need to know whose document failed, DocumentValidator might not know that, if it only knows how to handle Document objects.
If DocumentService has a reference to a myPerson (who has a Documents property), then the service is the most informed site to write log messages pertaining to both the person and their invalid document.
So it's clear that logging doesn't just belong in one site, it can belong in multiple sites. So how do you implement this? There are several ways of doing it:
- At a very basic level, you could have a statically available logger that everyone can access.
- At a more advanced level, you could pass a logger down through the methods, so that all involved dependencies can write their own messages into the same logger.
- Your objects can define their own logger in their constructor and each write to their own logger.
- You could rely on DI and an IoC container to inject your loggers for you.
It won't surprise you that there are multiple ways of achieving the same thing, so it's a matter of looking for what suits you best. There are cases where I prefer the ability to pass a single logger between a few dependencies (i.e. so that logger can encapsulate all those messages in a unique location), but it's more common to simply have each class log to their own log.
This depends on the technology you want to use, and the kind of software you're building. I use completely different logging libraries based on the type of project I'm working on.
ThingDoer, so the caller has some control (should it log at all, or not?), and the callee can take care of logging for itself – Alexander Feb 19 '21 at 03:10