Most loggers are thread safe, and creating instances of them has very little overhead, both in terms of time and memory. So the real question needs to be what makes sense from a programming and maintainability standpoint.
On the one hand, since the logger is conceptually tied to your class, and not to the instance of the class, a lot of people prefer to keep it static. That's a perfectly valid argument. For example, if HelloWorldJob
extends HelloJob
, I think most people would expect the log message written by code in HelloJob
to be tied to the HelloJob
class, even though you have a more specific subclass instance. It's also nice to be able to access your logger from static methods, which wouldn't be possible if it's not on a static field.
On the other hand, there is no reason that your HelloJob should be responsible for getting its own logger instance. There's a lot to be said for using dependency injection instead (unit testability, additional configurability, and simpler code). So I personally suggest having your logger injected by a DI framework, in which case it would need to be referenced on a per-instance field.
public class HelloJob : IJob
{
private readonly ILog _log;
public HelloJob(ILog log)
{
_log = log;
}
...
}
Your DI framework can set up the logger based on details it knows at run-time, or you can provide a fake or mocked logger in your unit tests to make sure the expected log messages are produced. Note that even though you are referring to a per-instance field, you're perfectly free to still use a per-class (or even a singleton) instance--those are just details that don't need to be part of this class's concern.
Update
Over time I've shifted my opinion more in the direction of using a static logger. More specifically, I really like using Fody Anotar libraries to generate the static logger (and other helpful code) for me, so all I have to write in my source code is logging statements like:
LogTo.Info("This is a message");