Reputation: 2416
I heard that using System.out.println
for logging purposes is a very bad practice and this may force the server to fail.
I don't use this approach but I am very interested in knowing why System.out.println could make so trash things when used in backend code.
Upvotes: 63
Views: 34174
Reputation: 47
a.
Formatting, Limiting log content achievable by loggers
b.
Multiple destination logging –file, console, DBUpvotes: 3
Reputation: 9776
One more reason is that System.out and err are PrintStreams, which are consuming all underlying IOExceptions. See this methods of PrintStreams:
/**
* Writes the specified byte to this stream. If the byte is a newline and
* automatic flushing is enabled then the <code>flush</code> method will be
* invoked.
*
* <p> Note that the byte is written as given; to write a character that
* will be translated according to the platform's default character
* encoding, use the <code>print(char)</code> or <code>println(char)</code>
* methods.
*
* @param b The byte to be written
* @see #print(char)
* @see #println(char)
*/
public void write(int b) {
try {
synchronized (this) {
ensureOpen();
out.write(b);
if ((b == '\n') && autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
/**
* Flushes the stream and checks its error state. The internal error state
* is set to <code>true</code> when the underlying output stream throws an
* <code>IOException</code> other than <code>InterruptedIOException</code>,
* and when the <code>setError</code> method is invoked. If an operation
* on the underlying output stream throws an
* <code>InterruptedIOException</code>, then the <code>PrintStream</code>
* converts the exception back into an interrupt by doing:
* <pre>
* Thread.currentThread().interrupt();
* </pre>
* or the equivalent.
*
* @return <code>true</code> if and only if this stream has encountered an
* <code>IOException</code> other than
* <code>InterruptedIOException</code>, or the
* <code>setError</code> method has been invoked
*/
public boolean checkError() {
if (out != null)
flush();
if (out instanceof java.io.PrintStream) {
PrintStream ps = (PrintStream) out;
return ps.checkError();
}
return trouble;
}
So an IOException from the underlying stream is ALWAYS consumed, and usually the people never call checkError on System out, so they are not even knowing that something happened.
Upvotes: 1
Reputation: 533530
Using standard out is bad practice. However if you have a library, or code which uses System.out and System.err you can write your own PrintStream which logs the thread name and info() and error() the text instead. Once you have done this, you may be more relaxed about using System.out as it will write to the logs e.g. log4j.
Ideally you will use the proper logs directly esp for debug level logging. IMHO its doesn't have to matter that much, provided you don use the built-in System.out/err! (A big assumption admittedly)
Whether you use System.out which is re-directed to a file or use log4j or Java Logger to write to a file, the performance is almost exactly the same.
Upvotes: 1
Reputation: 6939
Check out Adam Biens article in the Java Magazine edition November/Dezember about stress testing JEE6 applications - it's free online, you only have to subscribe to it.
On page 43 he shows, that a server applications which manages to handle 1700 transactions per second falls down to only 800 when inserting a single System.out.println
with fix String in each.
Upvotes: 28
Reputation: 59660
It is considered to be bad because System.out.println();
eats more cpu and thus output comes slow means hurts the performance. (Actually every I/O operation eats cpu).
Upvotes: 6
Reputation: 1121
System.out.println is an IO-operation and therefor is time consuming. The Problem with using it in your code is, that your program will wait until the println has finished. This may not be a problem with small sites but as soon as you get load or many iterations, you'll feel the pain.
The better approach is to use a logging framework. They use a message queue and write only if no other output is going on.
And another benefit is that you can configure separate log files for different purposes. Something your Ops team will love you for.
Read more here:
Upvotes: 71
Reputation: 89169
For one, having multiple requests hitting your server and printing the log on System.out
isn't good practice.
System.out
isn't synchronized. There must be a concurrency management to manage printing via System.out
System.out
. You can't separate your log levels to separate outputs on the fly.I hope this helps.
Upvotes: 3
Reputation: 10379
The reason is not that the server might fail but it might be hard to find such output on the server. You should always use some kind of logging framework with a defined behaviour and output file.
Upvotes: 4
Reputation: 3525
It's a bad practice because when your application goes in Production, you can't separate application logs from server logs.
Prod teams want that you separate logs produced by your application from the ones from the app server (tomcat, websphere, etc...) : they want to be able to monitor the app server diffrently from the application itself.
Moreover, using System.out, you can't define the log level : in Production, you don't want to print debug information.
Upvotes: 25