Java Reference
In-Depth Information
Do not follow the common antipattern of logging everything you can think of just in
case someone might need it someday. In practice, programmers are terrible at guessing
in advance which log messages they might need for debugging production problems.
Once a problem occurs, it is sometimes obvious what messages you need; but it is rare
to be able to anticipate this in advance. Adding “just in case” messages to logfiles usually
means that when a problem does occur, you're frantically hunting for the relevant mes‐
sages in an even bigger sea of irrelevant data.
How to Log
Many legacy programs dating back to Java 1.3 and earlier still use third-party logging
libraries such as log4j or Apache Commons Logging, but the
java.util.logging
package available since Java 1.4 suffices for most needs. Choosing it avoids a lot of
complex third-party dependencies.
Although you can load a logger on demand, it's usually easiest to just create one per
class like so:
private
final
static
Logger
auditLogger
=
Logger
.
getLogger
(
"requests"
);
Loggers are thread safe, so there's no problem storing them in a shared static field.
Indeed, they almost have to be because even if the
Logger
object were not shared between
threads, the logfile or database would be. This is important in highly multithreaded
servers.
This example outputs to a log named “requests.” Multiple
Logger
objects can output to
the same log, but each logger always logs to exactly one log. What and where the log is
depends on external configuration. Most commonly it's a file, which may or may not be
named “requests”; but it can be a database, a SOAP service running on a different server,
another Java program on the same host, or something else.
Once you have a logger, you can write to it using any of several methods. The most basic
is
log()
. For example, this
catch
block logs an unexpected runtime exception at the
highest level:
catch
(
RuntimeException
ex
)
{
logger
.
log
(
Level
.
SEVERE
,
"unexpected error "
+
ex
.
getMessage
(),
ex
);
}
Including the exception instead of just a message is optional but customary when log‐
ging from a
catch
block.
There are seven levels defined as named constants in
java.util.logging.Level
in
descending order of seriousness:
•
Level.SEVERE
(highest value)
•
Level.WARNING