2010-06-04 10 views
8

Primero algunos antecedentes. Tengo un proceso java por lotes que se ejecuta desde un script por lotes de DOS. Todo el registro de Java pasa a stdout, y el script por lotes redirige el stdout a un archivo. (Esto es bueno para mí porque puedo ECHO desde el script y se mete en el archivo de registro, así puedo ver todos los args de la línea de comandos JVM de Java, lo cual es genial para la depuración.) No puedolog-back y terceros escribiendo en stdout. Cómo evitar que se intercalen

Uso slf4j API, y para el backend solía usar log4j, pero recientemente cambié a logback-classic.

Aunque todo el código de mi aplicación usa slf4j, tengo una biblioteca de terceros que hace su propio registro (sin utilizar una API estándar) que también se escribe en stdout.

El problema es que a veces las líneas de registro se mezclan y no aparecen limpiamente en líneas separadas. Aquí está un ejemplo de parte de la producción en mal estado:

2010-05-28 18:00:44.783 [thread-1  ] INFO CreditCorrelationElementBuilderImpl - Bump parameters exist for scenario, now attempting bumping. [indexDisplayName=STANDARD_S1_v300] 
2010-05-28 18:01:43.517 [thread-1  ] INFO CreditCorrelationElementBuilderImpl - Found adjusted point in data, now applying bump. [point=0.144040000000000] 
2010-05-28 18:01:58.642 [thread-1  ] DEBUG com.company.request.Request   - Generated request for [dealName=XXX_20050225_01[5],dealType=GENERIC_XXX,correlationType=2,copulaType=1] in 73.8 s, Simon Stopwatch: [sys1.batchpricer.reqgen.gen INHERIT] total 1049 s, counter 24, max 74.1 s, min 212 ms 
2010-05-28 18:05/28/10 18:02:20.236 INFO: [ServiceEvent] SubmittedTask:BC-STRESS_04_FZBC-2010-05-21-545024448189310126-23 
01:58.658 [req-writer-2b ] INFO .c.g.r.o.OptionalFileDocumentOutput - Writing request XML to \\filserver\dir\file1.xml - write time: 21.4 ms - Simon Stopwatch: [sys1.batchpricer.reqgen.writeinputfile INHERIT] total 905 ms, counter 24, max 109 ms, min 10.8 ms 
2010-05-28 18:02:33.626 [ResponseCallbacks-1: DriverJobSpace$TakeJobRunner$1] ERROR c.c.s.s.D.CalculatorCallback  - Id:23 no deal found !! 
2010-0505/28/10 18:02:50.267 INFO: [ServiceEvent] CompletedTask:BC-STRESS_04_FZBC-2010-05-21-545024448189310126-23:Total:24 

Ahora comparando de nuevo a los archivos de registro más antiguos, parece que el problema no se produce cuando se utiliza log4j como backend de registro. Entonces logback debe estar haciendo algo diferente.

El problema parece ser que aunque PrintStream.write(byte buf[], int off, int len) está sincronizado, sin embargo, puedo ver que en ch.qos.logback.core.joran.spi.ConsoleTarget that System.out.write(int b) es el único método de escritura llamado.

Entonces, entre el logback que da salida a cada byte, la biblioteca de terceros está logrando escribir una cadena completa en la salida estándar. (Esto no solo me causa un problema, ¿pero también debe ser un poco ineficiente?)

¿Hay alguna otra solución a este problema de intercalación que aplicarle el código a ConsoleTarget para que implique los otros métodos de escritura? Cualquier buen trabajo alrededor. ¿O debería simplemente presentar un informe de error?

Aquí es mi logback.xml:

<configuration> 
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     <encoder> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-16thread] %-5level %-35.35logger{30} - %msg%n</pattern> 
     </encoder> 
    </appender> 
    <root level="DEBUG"> 
     <appender-ref ref="STDOUT" /> 
    </root> 
</configuration> 

estoy usando logback 0.9.20 con Java 1.6.0_07.

+0

Hmm, mis bloques de código con formato previo vienen a través de una sola línea, pero estaban bien en la vista previa! Humpf! –

+0

David, puedes volver a editar esta pregunta, usar literalmente si es necesario. –

+0

¿Tiene una referencia o ejemplo al pie de la letra? ¿Quiere decir usar un bloque sin código? –

Respuesta

0

Parece que tiene dos configuraciones de registro diferentes escribiendo en STDOUT. El patrón de estos dos parece ser muy diferente cuando se trata de decodificar el desorden:

2010-05-28 18:01:58.658 [req-writer-2b ] INFO .c.g.r.o.OptionalFileDocumentOutput - Writing request XML to \\filserver\dir\file1.xml - write time: 21.4 ms - Simon Stopwatch: [sys1.batchpricer.reqgen.writeinputfile INHERIT] total 905 ms, counter 24, max 109 ms, min 10.8 ms 
05/28/10 18:02:20.236 INFO: [ServiceEvent] SubmittedTask:BC-STRESS_04_FZBC-2010-05-21-545024448189310126-23 

La segunda línea parece estar usando el patrón predeterminado en lugar de su definición. ¿Hay un registrador cargado en alguna parte que usa la configuración predeterminada en lugar de tu configuración XML?

+0

El otro patrón proviene de la lib de terceros. Pero no es el patrón lo que me molesta, son las líneas arruinadas. No importa, he corregido el logback para solucionar el problema ahora. Gracias. –

2

En tal caso, pasaría por System.setOut (PrintStream out) para la lib proporcionada por terceros que no se comporta. Implemente un hilo que lea esta secuencia de registro divídalo por una línea nueva y escúpelo a la solución de registro que utilice. Sólo tenga cuidado de no empezar a leer y escribir en el mismo hilo :-) esto es lo que hace:

  • Usted recibe la corriente System.out guardar a un lado
  • de configurar el registrador para utilizar este stream see OutputStreamAppender
  • Crea un hilo que drena una secuencia que asigna como nuevo sistema.(tu lib tercera parte escribirá allí) y enviar la salida de un formato correcto en el registro

Usted se tiene un registro bonita que en sincronía más o menos con lo que sucede en el sistema

+0

Gracias Boris, tenías una buena idea allí, desafortunadamente fue más trabajo solucionar el problema del código. He votado a favor, pero no he aceptado tu respuesta. –

Cuestiones relacionadas