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.
複数の宛先ロギング–ファイル、コンソール、DB1つは、サーバーに複数のリクエストを送信し、System.out
にログを出力することは良い習慣ではありません。
System.out
は同期されていません。 System.out
を介して印刷を管理するには、同時実行管理が必要です。System.out
を使用してログレベルを決定することはできません。ログレベルをその場で個別の出力に分離することはできません。これがお役に立てば幸いです。
もう1つの理由は、System.outとerrがPrintStreamsであり、基礎となるすべてのIOExceptionを消費していることです。 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は常に消費され、通常、システム出力時にcheckErrorを呼び出すことはないため、何かが起こったことさえ知らないのです。
標準出力の使用は悪い習慣です。ただし、System.outおよびSystem.errを使用するライブラリまたはコードがある場合は、代わりにスレッド名とinfo()およびerror()を記録する独自のPrintStreamを作成できます。これを行うと、System.outを使用してログに書き込むため、System.outの使用についてよりリラックスできます。 log4j。
理想的には、適切なログを直接デバッグレベルのログ記録に使用します。私見では、組み込みのSystem.out/errを使用しない限り、それほど重要ではありません! (確かに大きな仮定)
ファイルにリダイレクトされるSystem.outを使用する場合でも、log4jまたはJava Loggerを使用してファイルに書き込む場合でも、パフォーマンスはほぼ同じです。