Abstract
Using System.out or System.err rather than a dedicated
logging facility makes it difficult to monitor the behavior
of the program. It can also cause log messages accidentally
returned to the end users, revealing internal information to
attackers.
Description
Examples
The first Java program that a developer learns to write
often looks like this:
public class MyClass
public static void main(String[] args) {
System.out.println("hello world");
}
}
While most programmers go on to learn many nuances and
subtleties about Java, a surprising number hang on to this
first lesson and never give up on writing messages to
standard output using System.out.println().
The problem is that writing directly to standard output
or standard error is often used as an unstructured form of
logging. Structured logging facilities provide features like
logging levels, uniform formatting, a logger identifier,
timestamps, and, perhaps most critically, the ability to
direct the log messages to the right place. When the use of
system output streams is jumbled together with the code that
uses loggers properly, the result is often a well-kept log
that is missing critical information. In addition, using
system output streams can also cause log messages
accidentally returned to end users, revealing application
internal information to attackers.
Developers widely accept the need for structured logging,
but many continue to use system output streams in their
"pre-production" development. If the code you are reviewing
is past the initial phases of development, use of System.out
or System.err may indicate an oversight in the move to a
structured logging system.