util practices logger example create best java logging backend

java - practices - No use System.out.println en el código del lado del servidor



log4j (9)

  1. El programa esperará hasta que finalice la impresión. Los madereros usan la cola de mensajes y escriben solo si no hay otra salida.
  2. System.out.println (SOP) no son seguros para subprocesos (es decir, asíncronos) Los registradores son seguros para subprocesos (es decir, síncronos)
  3. Los madereros son altamente configurables a. Formateo, limitación del contenido del registro que pueden obtener los madereros b. Múltiples registros de destino: archivo, consola, base de datos
  4. Los SOP escriben registros en los archivos de registro del Servidor. Necesitamos mantener los registros de las aplicaciones separados de los registros del Servidor, ya que esto puede llevar a una Falla del Servidor
  5. Las aplicaciones de servidor que manejan 1700 transacciones por segundo se reducen a solo 800 cuando se insertan un único SOP con una cadena de arreglos en cada una

Escuché que usar System.out.println para fines de registro es una práctica muy mala y esto puede forzar al servidor a fallar.

No uso este enfoque, pero estoy muy interesado en saber por qué System.out.println podría hacer cosas tan malas cuando se usa en código back-end.


Eche un vistazo al article Adam Biens en la edición de la revista Java noviembre / diciembre sobre pruebas de estrés en las aplicaciones JEE6: es gratuito en online , solo tiene que suscribirse.

En la página 43 muestra que las aplicaciones de servidor que manejan 1700 transacciones por segundo se reducen a solo 800 cuando se inserta un único System.out.println con System.out.println String en cada una.


Es una mala práctica porque cuando su aplicación entra en Producción, no puede separar los registros de la aplicación de los registros del servidor.

Los equipos Prod quieren que separes los registros producidos por tu aplicación de los del servidor de la aplicación (tomcat, websphere, etc ...): quieren poder monitorear el servidor de aplicaciones de forma diferente a la aplicación misma.

Además, al usar System.out, no puede definir el nivel de registro: en Production, no desea imprimir información de depuración.


La razón no es que el servidor pueda fallar, pero podría ser difícil encontrar tal salida en el servidor. Siempre debe usar algún tipo de estructura de registro con un comportamiento definido y un archivo de salida.


Por un lado, tener múltiples solicitudes de llegar a su servidor e imprimir el registro en System.out no es una buena práctica.

  1. Todos los registros se imprimen en la pantalla (descriptor de archivo). No hay forma de retroceder y leer el registro.
  2. System.out no está sincronizado. Debe haber una administración de concurrencia para administrar la impresión a través de System.out
  3. No puede determinar los niveles de registro a través de System.out . No puede separar sus niveles de registro en salidas separadas sobre la marcha.

Espero que esto ayude.


Se considera que es malo porque System.out.println(); Come más CPU y, por lo tanto, la producción llega lenta, lo que perjudica el rendimiento. (En realidad, cada operación de E / S come CPU).


System.out.println es una operación IO y, por lo tanto, lleva mucho tiempo. El problema al usarlo en su código es que su programa esperará hasta que la impresión haya finalizado. Esto puede no ser un problema con sitios pequeños, pero tan pronto como reciba carga o muchas iteraciones, sentirá el dolor.

El mejor enfoque es usar un marco de registro. Utilizan una cola de mensajes y escriben solo si no hay otra salida.

Y otra ventaja es que puede configurar archivos de registro separados para diferentes propósitos. Algo por lo que tu equipo Ops te amará.

Leer más aquí:


Una razón más es que System.out y err son PrintStreams, que están consumiendo todas las IOExcepciones subyacentes. Vea este método de 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; }

Por lo tanto, una excepción IOException de la transmisión subyacente SIEMPRE se consume, y normalmente las personas nunca invocan checkError on System, por lo que ni siquiera saben que algo sucedió.


Usar la salida estándar es una mala práctica. Sin embargo, si tiene una biblioteca o código que usa System.out y System.err, puede escribir su propio PrintStream que registra el nombre del hilo y la información () y el error () en su lugar. Una vez que haya hecho esto, puede estar más relajado sobre el uso de System.out, ya que escribirá en los registros, por ejemplo, log4j.

Lo ideal sería utilizar los registros adecuados directamente esp para el registro de nivel de depuración. En mi humilde opinión no tiene que importar mucho, siempre que no uses el System.out / err integrado. (Una gran suposición es cierto)

Ya sea que use System.out el cual es redirigido a un archivo o use log4j o Java Logger para escribir en un archivo, el rendimiento es casi el mismo.