[英]Do not use System.out.println in server side code
我听说使用System.out.println
进行日志记录是一种非常糟糕的做法,这可能会迫使服务器失败。
我不使用这种方法,但我非常有兴趣知道为什么System.out.println在后端代码中使用时会产生垃圾。
System.out.println是一个IO操作,因此非常耗时。 在代码中使用它的问题是,程序将等到println完成。 对于小型网站来说这可能不是问题,但是只要你加载或多次迭代,你就会感受到痛苦。
更好的方法是使用日志框架。 它们使用消息队列并仅在没有其他输出的情况下写入。
另一个好处是您可以为不同目的配置单独的日志文件。 你的Ops团队会爱你的东西。
在这里阅读更多:
这是一种不好的做法,因为当您的应用程序进入生产时,您无法将应用程序日志与服务器日志分开。
Prod团队希望您将应用程序生成的日志与应用程序服务器(tomcat,websphere等)中生成的日志分开:他们希望能够从应用程序本身监视应用程序服务器。
而且,使用System.out,您无法定义日志级别:在生产中,您不希望打印调试信息。
它被认为是坏的,因为System.out.println();
吃更多的CPU,因此输出变慢意味着损害性能。 (实际上每个I / O操作都会占用cpu)。
原因不是服务器可能会失败,但可能很难在服务器上找到这样的输出。 您应该始终使用某种带有已定义行为和输出文件的日志记录框架。
a.
格式化,限制记录器可实现的日志内容b.
多个目标logging -file,console,DB 首先,有多个请求命中您的服务器并在System.out
上打印日志不是一个好习惯。
System.out
未同步。 必须有并发管理才能通过System.out
管理打印 System.out
确定日志级别。 您无法动态将日志级别分离为单独的输出。 我希望这有帮助。
另一个原因是System.out和err是PrintStreams,它们消耗所有底层IOExceptions。 请参阅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;
}
因此,总是消耗来自底层流的IOException,并且通常人们从不在System out上调用checkError,因此他们甚至不知道发生了什么。
使用标准输出是不好的做法。 但是,如果您有一个库或使用System.out和System.err的代码,您可以编写自己的PrintStream,它会记录线程名称和info()以及error()文本。 完成此操作后,您可能会更放松地使用System.out,因为它会写入日志,例如log4j。
理想情况下,您将直接使用正确的日志esp进行调试级别日志记录。 恕我直言,如果你不使用内置的System.out / err,它就没那么重要了! (一个很大的假设)
无论您使用重定向到文件的System.out还是使用log4j或Java Logger写入文件,性能几乎都是一样的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.