When writing a new application or infrastructure, do you consider logging right from the start? And thus have a lot of classes importing/using an ILogger interface (inside constructor for injection) for example?
What if you alrea开发者_StackOverflowdy have (most of) your application in place, but didn't think of logging in most or all of your classes. How would you end up adding logging to them?
My concern with adding afterwards is that if you need logging deep down into your dependency chain, you might end up having to add an ILogger interface to many classes.
I always consider logging from the start.
Firstly there is the decision of which logging framework to use, but that is generally a quick choice. I personally often use log4net, which means each class uses the static LogManager.GetLogger to get an instance of a logger. The actual behaviours of each log call is then defined in config (where should I log too, what level should I log at, etc).
However, more importantly, you should be thinking of what needs logging as you are actually developing your application. There is no point at which you are more tuned into your code than when you are writing it, and you probably have a better idea of what needs logging then than at any other time. It is far easier to retrospectively remove overly verbose logging that you don't need that add logging that should be there.
So yes - always think about logging as you start your application, don't try and retro-fit it if you can help it.
[EDIT: In response to your question about how to inject]
Possibly the simplest approach (assuming you are not using an IoC container) is to go down the route of property or constructor injection. Personally, I much prefer the latter for this sort of thing, so I would end up with something like this for log4net:
public class MyClass
{
private readonly ILog _logger;
// usually I don't supply a logger directly,
// hence I let this ctor get a logger from the log manager.
public MyClass() : this (LogManager.GetLogger(typeof(MyClass)))
{
}
// this ctor only gets called directly if I want to mock out logging
public MyClass(ILog logger)
{
_logger = logger;
}
}
Why would you have "many" classes implement ILogger
? It should be enough to have one or two classes implement it, e.g. "DatabaseLogger" and "FileLogger". An instance of the ILogger implementation needs to be passed around, that's right, This can be done by a singleton or by dependency injection.
I normally use a singleton class for logging. This class can be configured to write to a log file, a database table or the Windows event log.
精彩评论