application (“now I'm processing task A,” “now I'm doing task B,” and so on). Particularly
for applications that are heavily threaded and scalable (including Java EE application serv-
ers), that much logging will have a detrimental effect on performance (not to mention run-
ning the risk of being too chatty to be useful). Don't be afraid to use the lower-level logging
Similarly, when code is checked into a group repository, consider the needs of the user of the
project rather than your needs as a developer. We'd all like to have a lot of good feedback
about how our code works once it is integrated into a larger system and run through a battery
of tests, but if a message isn't going to make sense to an end user or system administrator,
it's not helpful to enable it by default. It is merely going to slow down the system (and con-
fuse the end user).
The second principle is to use fine-grained loggers. Having a logger per class can be tedious
to configure, but having greater control over the logging output often makes this worthwhile.
Sharing a logger for a set of classes in a small module is a good compromise. The point to
keep in mind is that production problems—and particularly production problems that occur
under load or are otherwise performance related—are tricky to reproduce if the environment
changes significantly. Turning on too much logging often changes the environment such that
the original issue no longer manifests itself.
Hence, you must be able to turn on logging only for a small set of code (and, at least initially,
a small set of logging statements at the FINE level, followed by more at the FINER and
FINEST levels) so that the performance of the code is not affected.
Between these two principles, it should be possible to enable small subsets of messages in a
production environment without affecting the performance of the system. That is usually a
requirement anyway: the production system administrators probably aren't going to enable
logging if it slows the system down, and if the system does slow down, then the likelihood of
reproducing the issue is reduced.
The third principle to keep in mind when introducing logging to code is to remember that it
is quite easy to write logging code that has unintended side effects, even if the logging is not
enabled. This is another case where “prematurely” optimizing code is a good thing: as the
example from Chapter 1 shows, remember to use the isLoggable() method anytime the in-
formation to be logged contains a method call, a string concatenation, or any other sort of al-
location (for example, allocation of an Object array for a MessageFormat argument).