1

I want to add logging to quite few classes in my program. Do I need to add lines to define a logger to each class that needs a logger (I want to avoid passing logger object around my program.

public class SomeClass {
  static Logger logger = Logger.getLogger(SomeClass.class);
  .......

If I do this, can I get this call to "know" its class (something like this.class Or are there alternative ways of doing this

justintime
  • 3,601
  • 4
  • 22
  • 37
  • 1
    Use Eclipse Code Templates: http://stackoverflow.com/questions/1028858/useful-eclipse-java-code-templates/1029304#1029304 – palacsint Oct 17 '11 at 21:01

3 Answers3

2

One alternative that I find handy is to make an abstract class that creates Loggers for you:

public abstract class AbstractLoggingThing {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    protected Logger getLog() {
        return log;
    }
}

Then by convention, every class that inherits from it has a properly-configured Logger, and you don't have to have that same, stupid code all over the place. Most of your classes in a project can easily include this in their inheritance hierarchy, and for the ones that can't, for whatever reason, you can still fall back to the old style. You can also add nice convenience methods like:

    protected void info(String message, Object... args) {
        // What goes here depends on your logging library
    }
Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • I wouldn't do that. It may do well in a language with multiple inheritance, but in Java it leads to creating god objects and code tightly coupled to the base class. It may be fine as a convenience method in a package, but certainly not for the whole application. – MaDa Oct 18 '11 at 08:17
  • @MaDa: Not at all. If it's good for a package, why not at a wider scope? Think of it as more of a poor man's mixin. If I were using AspectJ, I'd probably weave this code in rather than inheriting it. Besides, I'm successfully using this approach on a good-sized project with no detrimental side effects. It's treated more like an alternative to Object than anything else. It's extremely helpful and has the additional benefit that all (most) logging is centrally managed. For those still using commons logging or log4j, it can also remove the need for those crazy `if (log.isXxxEnabled()` calls... – Ryan Stewart Oct 18 '11 at 14:12
  • We also used this pattern in a Java project that had extreme restrictions against using external libraries - it worked fine, but over the years the temptation to add yet another method to this super-duper base class was irresistible, and it grew to a monstrous size. I'd definitely oppose untamed use of this pattern. AspectJ is better, but it's quite advanced. – MaDa Oct 18 '11 at 14:55
1

Yes you need to add lines to each class. If your logger is static (as is your example) you need to specify the class each time like you did (SomeClass.class). If you make your logger non-static then you can use this.getClass() which would be more cut-n-paste friendly:

public class SomeClass {
  private Logger logger = Logger.getLogger(this.getClass());
  .......
pakman
  • 1,676
  • 3
  • 23
  • 41
  • Note that this has the effect that if someone creates a `public class SubClass extends SomeClass`, then every method that `SubClass` inherits from `SomeClass` will get a logger for `SubClass` - which may or may not be the desired outcome. – Aasmund Eldhuset Oct 17 '11 at 20:15
  • It's also not true that you have to add it to each class. The fact that this has so many upvotes seems to indicate that that's not common knowledge. – Ryan Stewart Oct 17 '11 at 21:17
1

No, you don't need to do this, but this is an accustomed practice, and a good one. Log4j has been constructed around this assumption in mind, that people will use it this way. It gives you for free the location of the place where a log event was issued, as well as easy administration of log level for the whole branches of loggers.

Theoretically, you could share a logger among multiple classes, or even have only one global; Logger is thread safe, and it needs to synchronize upon appending object anyway, so your performance would not suffer. You can also name it anything you want, don't need to use the class name. It's not advised, though, for the reason I stated above.

Also, you don't need to make the reference static, as log4j sees to it that you can only create one logger with a given name, you don't waste memory by having it stored in an instance variable.

MaDa
  • 10,511
  • 9
  • 46
  • 84