2011-12-02 20 views
12

Me encontré con un problema extraño al usar la opción de registro de recolección de elementos no utilizados de JVM con el comando logrotate de Linux. Cuando se ejecuta la rotación, llena los valores NUL (^ @) de la primera línea del archivo dada como argumento para la JVM.La rotación de archivos del registro del recolector de basura (loggc) con logrotate no funciona correctamente

Digamos que esta es la llamada Java (Test.class se encuentra en/home/test /):

java -Xloggc: /home/test/test.log cp/home/test/prueba

La configuración de logrotate para este archivo es el siguiente:

/home/test/test.log {
      gire 56
      missingok
      notifempty
      copytruncate
      nocreate
      NOMAIL
}

que también tienen una entrada crontab de registro cada minuto para propósitos de prueba:

*/1 * * * */usr/sbin/logrotate -f /etc/logrotate.d/gcLog

Llegué a la conclusión de que JVM escribe en el modo de adición y mantiene algún tipo de desplazamiento utilizado para escribir la siguiente línea en el archivo relacionado, incluso si el archivo está truncado por logrotate (puedo estar equivocado).


Mi siguiente idea fue intentar y redirigir el archivo stdout a test.log. utilicé esta llamada java y se mantiene la misma configuración de logrotate y cron:

java -verbose: gc-cp/home/test/prueba> /home/test/test.log

Una vez más, cuando test.log es truncado por logrotate, el nuevo archivo creado se llena con valores NUL (^ @) en la primera línea.


No hace falta decir que no he encontrado nada útil al usar google. Encontré otra pregunta relacionada con stackoverflow, pero no pude configurar Java Script Wrapper, así que esto no funciona.

¿Alguien se ha encontrado con este problema? ¿Alguna idea de por qué está sucediendo esto? Mejor, ¿alguna solución o solución? Necesito tratar de canalizar la llamada a la aplicación a un script que lee la salida y tal vez mirar la forma en que Tomcat registra y rotar stdout en catalina.out (aquí también se apreciará algo de ayuda)

+0

Mi trabajo sería hacer menos basura, menos GC y registros más cortos que no necesitan ser rotados. ;) –

+0

Estoy de acuerdo con eso. Sin embargo, no es el punto de vista de mi jefe. – Hyb

+0

Como mínimo, puede asegurarse de tener suficiente espacio en disco para iniciar sesión, de modo que no sea necesario rotarlo. Un TB no cuesta eso hoy en día. –

Respuesta

6

Tuvimos el mismo problema en nuestro lugar ejecutando Jboss7 y Java6, obteníamos NULL en el archivo GC y seguían creciendo.

solución era sólo tiene que entrar por la salida estándar de GC y luego anexar la salida estándar a un archivo:

ejemplo simple:

java -verbose:gc >> console.log 

usando parecer append (>>) se deshace de la Java "puntero "a una posición en el archivo. Con la ventaja adicional de no reiniciar los registros de GC por reinicio del servidor para que podamos tener algunas estadísticas a lo largo del tiempo.

Al menos la herramienta IBM PMAT no tiene problemas para analizar el sysout con salida de GC.

La solución más simple es a veces la mejor :)

Aunque me gustaría Java apoyaría la rotación de registros GC, como veo que alguien ha estado discutiendo antes: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2011-April/002061.html

+0

De hecho, no pensé en eso. Es más fácil que usar la solución Tee :) – Hyb

4

Para explicar los nulos, Java mantiene una referencia interna que cuenta la posición para la indentación, y a medida que mueve el archivo hace que los caracteres nulos se escriban en el registro.

He visto alterar los archivos de registro de GC para provocar el bloqueo del sistema, el aborto causado mientras se escribe en el archivo de registro se ignora (vea el código aquí http://pastebin.com/HWkNv3PM) haciendo que la JVM continúe ignorando el error.

A medida que se vuelve a abrir el archivo, creo que el contador de posición no se está restableciendo.

En cuanto a otras ideas sobre cómo tirar los archivos de registro - ver también: Rolling garbage collector logs in java

3

Una solución sencilla podría ser cambiar el Java llamada que utilicé en mi pregunta:

java -Xloggc: /home/test/test.log cp/home/test/prueba

a

java -verbose: gc -cp/home/test/Test | tee -a/home/test/test/log

La configuración de logrotate y cron podría permanecer igual (incluso si se aumentara el período cron).

Vea mi comentario debajo de la pregunta para obtener un enlace que proporciona más detalles sobre el logrotate y los manejadores de archivos en Linux. Ver también brainzzy's explanations en el comportamiento de Java.

0

en lugar de java -verbose: gc> > console.log puedo hacer: java -Xloggc: logs/gc.log >> console.log para que la salida se guarde en un archivo y luego también gire a console.log?

+0

Tendría que canalizar la salida a la T si quería tener dos archivos. De lo contrario, Java simplemente se registrará en gc.log. –

Cuestiones relacionadas