[英]Do not use System.out.println in server side code
I heard that using System.out.println
for logging purposes is a very bad practice and this may force the server to fail. 我听说使用
System.out.println
进行日志记录是一种非常糟糕的做法,这可能会迫使服务器失败。
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. 我不使用这种方法,但我非常有兴趣知道为什么System.out.println在后端代码中使用时会产生垃圾。
System.out.println is an IO-operation and therefor is time consuming. System.out.println是一个IO操作,因此非常耗时。 The Problem with using it in your code is, that your program will wait until the println has finished.
在代码中使用它的问题是,程序将等到println完成。 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.
你的Ops团队会爱你的东西。
Read more here: 在这里阅读更多:
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. 查看关于压力测试JEE6应用程序的Java杂志11月/ Dezember的Adam Biens 文章 - 它是免费在线的 ,你只需订阅它。
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. 在第43页上,他显示,当插入单个
System.out.println
并在每个事件中添加了修复字符串时,设法处理每秒1700个事务的服务器应用程序仅降至800。
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. Prod团队希望您将应用程序生成的日志与应用程序服务器(tomcat,websphere等)中生成的日志分开:他们希望能够从应用程序本身监视应用程序服务器。
Moreover, using System.out, you can't define the log level : in Production, you don't want to print debug information. 而且,使用System.out,您无法定义日志级别:在生产中,您不希望打印调试信息。
It is considered to be bad because System.out.println();
它被认为是坏的,因为
System.out.println();
eats more cpu and thus output comes slow means hurts the performance. 吃更多的CPU,因此输出变慢意味着损害性能。 (Actually every I/O operation eats cpu).
(实际上每个I / O操作都会占用cpu)。
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.
您应该始终使用某种带有已定义行为和输出文件的日志记录框架。
a.
a.
Formatting, Limiting log content achievable by loggers b.
b.
Multiple destination logging –file, console, DB For one, having multiple requests hitting your server and printing the log on System.out
isn't good practice. 首先,有多个请求命中您的服务器并在
System.out
上打印日志不是一个好习惯。
System.out
isn't synchronized. System.out
未同步。 There must be a concurrency management to manage printing via System.out
System.out
管理打印 System.out
. System.out
确定日志级别。 You can't separate your log levels to separate outputs on the fly. I hope this helps. 我希望这有帮助。
One more reason is that System.out and err are PrintStreams, which are consuming all underlying IOExceptions. 另一个原因是System.out和err是PrintStreams,它们消耗所有底层IOExceptions。 See this methods of PrintStreams:
请参阅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. 因此,总是消耗来自底层流的IOException,并且通常人们从不在System out上调用checkError,因此他们甚至不知道发生了什么。
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.
但是,如果您有一个库或使用System.out和System.err的代码,您可以编写自己的PrintStream,它会记录线程名称和info()以及error()文本。 Once you have done this, you may be more relaxed about using System.out as it will write to the logs eg log4j.
完成此操作后,您可能会更放松地使用System.out,因为它会写入日志,例如log4j。
Ideally you will use the proper logs directly esp for debug level logging. 理想情况下,您将直接使用正确的日志esp进行调试级别日志记录。 IMHO its doesn't have to matter that much, provided you don use the built-in System.out/err!
恕我直言,如果你不使用内置的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. 无论您使用重定向到文件的System.out还是使用log4j或Java Logger写入文件,性能几乎都是一样的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.