Logrotate Exitoso, el archivo original vuelve al tamaño original

11

¿Alguien ha tenido algún problema con logrotate antes que haga que un archivo de registro se gire y luego vuelva al mismo tamaño que originalmente? Aquí están mis hallazgos:

Logrotate Script:

/var/log/mylogfile.log {
    rotar 7
    diario
    comprimir
    olddir / log_archives
    missingok
    notifempty
    copytruncate
}

Salida detallada de Logrotate:

copiando /var/log/mylogfile.log a /log_archives/mylogfile.log.1
truncando /var/log/mylogfile.log
registro de compresión con: / bin / gzip
eliminar el registro antiguo /log_archives/mylogfile.log.8.gz

El archivo de registro después de truncar ocurre

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 parte1 parte1 0 11 de enero 17:32 /var/log/mylogfile.log

Literalmente segundos después:

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 parte1 parte1 3.5G 11 de enero 17:32 /var/log/mylogfile.log

Versión RHEL:

[root @ server ~] # cat / etc / redhat-release 
Red Hat Enterprise Linux ES versión 4 (Nahant Update 4)

Versión Logrotate:

[raíz @ DAA21529WWW370 ~] # rpm -qa | grep logrotate
logrotate-3.7.1-10.RHEL4

Pocas notas:

  • El servicio no se puede reiniciar sobre la marcha, por eso estoy usando copytruncate
  • Los registros rotan todas las noches, de acuerdo con el olddirdirectorio que contiene archivos de registro de cada noche.
Drewrockshard
fuente

Respuestas:

18

Esto probablemente se deba a que aunque trunca el archivo, el proceso de escritura en el archivo continuará escribiendo en cualquier desplazamiento que haya sido por fin. Entonces, lo que sucede es que logrotate trunca el archivo, el tamaño es cero, el proceso vuelve a escribir en el archivo, continúa en el desplazamiento que dejó, y ahora tiene un archivo con NULL-bytes hasta el punto donde lo truncó más el nuevo entradas escritas en el registro.

od -c después de truncar + crecimiento repentino, salida generada en las líneas de:

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

Lo que esto dice es que desde el desplazamiento 0 hasta 33255657600 su archivo consta de bytes nulos y luego algunos datos legibles. Llegar a este estado no lleva la misma cantidad de tiempo que tomaría escribir todos esos bytes nulos. Los sistemas de archivos ext {2,3,4} admiten algo llamado archivos dispersos, por lo que si busca más allá de una región de un archivo que no contiene nada, se supondrá que esa región contiene bytes nulos y no ocupará espacio en el disco Esos bytes nulos en realidad no se escribirán, solo se supone que están allí, por lo tanto, el tiempo que lleva ir de 0 a 3.5 GB no toma mucho tiempo. (Puede probar la cantidad de tiempo que lleva haciendo algo como dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1esto, esto debería generar un archivo de más de 3GB en unos pocos milisegundos).

Si ejecuta ls -lsen sus archivos de registro después de que se hayan truncado y haya tenido un crecimiento repentino nuevamente, ahora debe informar un número al comienzo de la línea que representa el tamaño real (en bloques ocupados en el disco), que probablemente sea de órdenes de magnitud más pequeño que el tamaño reportado por just ls -l.

Kjetil Joergensen
fuente
No lo creo, en segundos, el archivo de registro va de 0 bytes a 3.5GB. El tiempo total que tarda el logrotate en completarse es de aproximadamente 5 minutos. Los archivos de registro no se escriben tan rápido Y el tamaño es siempre el tamaño original, lo que parece demasiado casual.
drewrockshard
Debería haber una manera fácil de verificar esto, inspeccionar el archivo y ver si realmente hay algo en él. Comience ejecutando od -c filename | head -n 100. Lo más probable es que le diga en pocas líneas que hay una gran cantidad de bytes nulos, más las últimas entradas de registro.
Kjetil Joergensen
Si este es el caso, ¿podemos probar si cat / dev / null> /var/log/mylogfile.log trunca el archivo de una manera que resuelva este problema, en lugar de usar logrotate integrado en copytruncate?
mtinberg
2
El problema no radica en la forma en que se trunca el archivo, sino en cómo el programa escribe el archivo de registro. Para truncar el archivo de registro para que sea un enfoque viable, tendrá que hacer que el programa escriba en el archivo de registro de alguna manera busque la posición 0. Es posible que un sistema de archivos que no admita archivos dispersos no tenga este problema, aunque no No tengo ninguna forma de probar eso en este momento.
Kjetil Joergensen
1
Esta respuesta final en realidad tenía más sentido y la solución probablemente será reiniciar la aplicación.
drewrockshard el
2

Estoy extremadamente seguro de que Kjetil lo ha golpeado. Drew, puede que aún no estés convencido por su explicación, pero te insto a que leas detenidamente lo que ha dicho.

Si lo acepta, la solución es detener y reiniciar su aplicación cuando se rotan los registros, o usar una herramienta como "rotatelogs" de apache, donde alimenta la salida del registro a la herramienta a través de una tubería, y la herramienta se encarga de girando el archivo de registro de vez en cuando. Por ejemplo, una de mis instancias de apache se registra con

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

lo que causa muchos archivos de registro con nombres como

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

aparecer sin reiniciar apache; Luego puedo comprimirlos manualmente después del hecho. Tenga en cuenta cómo se realiza la rotación cada semana, que es cada 604800 segundos, siendo ese el argumento al que se pasó rotatelogs.

Si no puede detener y reiniciar la aplicación, y no puede iniciar sesión a través de una tubería, entonces creo que tiene un problema real. Quizás otros tengan sugerencias.

MadHatter
fuente
0

sería realmente genial si pudieras enviar todo el logrotate.

¿Por qué intentar usar kill -HUP? Método (recarga clásica no reiniciando ).

Además ... verifique lsof quién está accediendo al archivo.

Nikolaidis Fotis
fuente
No se puede usar, kill -HUPya que esta aplicación no se puede tocar de ninguna manera: es una aplicación confidencial que no es de mi propiedad (ni siquiera la administro, solo administro el lado del sistema operativo), por lo que necesito poder hacer las logrotations esto camino.
Drewrockshard
1
Lo sentimos, el mensaje original se envió temprano, aquí está el resto de mi mensaje original: inicié sesión en el sistema esta mañana y el archivo vuelve a la normalidad después de que /etc/cron.dailyse inició la rotación programada . Pregunta para todos: ¿Hay algo que el script logrotate haga de manera diferente que ejecutar logrotate manualmente? Mi script de logrotate literalmente se ve así /usr/sbin/logrotate /etc/logrotate.conf. Esto es bastante desconcertante.
drewrockshard el
-1

Simplemente use ">>", que significa agregar en lugar de ">", que significa crear a partir de sus scripts que escriben en este archivo. Tuve exactamente el mismo problema y lo solucioné usando append en mi script.

SomeScript.sh >> output.txt

Espero que sea más claro.

usuario578558
fuente
No hay indicios de que la escritura en el archivo de registro se realice >desde un script. Además, esta respuesta es confusa porque hay una gran diferencia entre >y >( )en los scripts. Finalmente, si el código que realiza la escritura se actualiza, sería mucho mejor que simplemente comience a escribir en el nuevo archivo de registro después de logrotatehaber hecho lo suyo.
Kasperd
Edito mi respuesta para que sea más clara.
user578558