13

Many forums and stackoverflow questions suggest that the recommended approach for creating loggers is to create them per class.

A quick look at the Log4j's Logger getLogger(String name) implementation suggests that, all the loggers are stored in a static map.

I wonder if we have thousands of classes in an application and a logger is defined in each class, wouldn't it cause memory/performance issues.

Alternatively, why cant we define some standard loggers (based on some functional criteria) in the application and have the developers use them in the classes. I understand that having a separate logger allows us to change its logging level, but I believe its not big issue if there are sufficient predefined loggers.

I looked at the questions Is a logger per class or is a set of loggers that are accessed by the entire application perferred? and Log4J: Strategies for creating Logger instances but they dont seem to cover this topic.

Community
  • 1
  • 1
Naresh Vavilala
  • 598
  • 4
  • 14

1 Answers1

4

You don't have to, it's just easier to manage. Loggers follow parent-child relationship. Children pretty much inherit everything from their parents. This way you can define very specific logging behavior or have it inherited generically.

Alternatively, why cant we define some standard loggers (based on some functional criteria) in the application and have the developers use them in the classes. I understand that having a separate logger allows us to change its logging level, but I believe it's not big issue if there are sufficient predefined loggers.

This would require some pretty intense dependency injection to make those loggers available to every type, also potentially adding an extra dependency.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • How about creating a custom logger class that contains all other categories as static members. public class CustomLogger { public final static Logger customlog = LoggerFactory.getLogger("customlog"); } and we call CustomLogger.customlog.infor(""); – Naresh Vavilala Sep 12 '14 at 21:21
  • @NareshVavilala What do you gain by doing that? You now have to do `CustomLogger.customlog.debug(..)` to log your message. – Sotirios Delimanolis Sep 12 '14 at 21:23
  • With this, I can limit the number of loggers used in the system, and reduce the number entries stored in the map managed by logging provider – Naresh Vavilala Sep 12 '14 at 21:27
  • @NareshVavilala The `Logger` instance are all managed by your logging framework. You can still do `LoggerFactory.getLogger("random");` in some class not called `random`. By keeping the `private static` field in each class just makes it easier to use internally. – Sotirios Delimanolis Sep 12 '14 at 21:30
  • I understand that. But there is no way to track the logger names if we use names other than class names. Having all the loggers declared in a separate class makes the application classes independent of logging code. Once we have this setup we can use custom loggers just like 'System.out' and 'System.err' – Naresh Vavilala Sep 12 '14 at 21:41
  • @NareshVavilala (You can use backticks `\`` for code fragments.) The only logging code you should have is `debug(..)`, `info(..)`, and others. And that code should very much be dependent on the class that uses it (and vice versa). The fact is, you don't need your custom class to get a reference to another logger. `LoggerFactory.getLogger(..)` gives you access to ALL loggers managed by your library. Your configuration is the only access point. – Sotirios Delimanolis Sep 12 '14 at 21:51