Eliminar las primeras N líneas de un archivo de registro activo

26

¿Hay alguna forma de eliminar las primeras Nlíneas de un registro que una aplicación está agregando activamente?

Adam Matan
fuente

Respuestas:

10

No, los sistemas operativos como Linux, y sus sistemas de archivos, no prevén la eliminación de datos desde el inicio de un archivo. En otras palabras, el punto de inicio de almacenamiento de un archivo es fijo.

La eliminación de líneas desde el inicio de un archivo generalmente se logra escribiendo los datos restantes en un archivo nuevo y eliminando el antiguo. Si un programa tiene el archivo antiguo abierto para escritura, la eliminación de ese archivo se pospone hasta que la aplicación cierre el archivo.


Como señalaron los comentaristas, por las razones dadas en mi oración anterior, generalmente necesita coordinar la poda de archivos de registro con los programas que están escribiendo los registros. La forma exacta de hacerlo depende de los programas. Algunos programas cerrarán y volverán a abrir sus archivos de registro cuando les envíe una señal (por ejemplo, HUP) y esto se puede usar para evitar que los registros se escriban en un archivo de registro 'eliminado', sin interrumpir el servicio.

Hay muchas utilidades disponibles para administrar el tamaño de los archivos de registro, por ejemplo, logrotate

Algunos programas tienen sus propias utilidades. Por ejemplo, el servidor web Apache incluye una utilidad rotatelogs .

RedGrittyBrick
fuente
3
Pero no debe hacer esto mientras algo todavía tiene el archivo abierto y aún se le agrega, porque escribiría en el archivo ahora eliminado y perdería esos mensajes de registro.
Tarnay Kálmán
Cierto. Incluso si usaste el mismo nombre de archivo.
Hennes
lástima que el sistema operativo no te permita, eso seguramente sería conveniente para que los rotadores de registros no tengan que recargar los procesos después de la rotación: |
rogerdpack
25

Creo que esta tarea se puede lograr con sed

sed -i '1,10d' myfile

eliminaría las líneas de la a la 10ª línea del archivo.

Creo que todos deberían al menos echar un vistazo a este sed 1 liners .

Tenga en cuenta que esto no funciona para los archivos de registro a los que una aplicación agrega activamente (como se indica en la pregunta).

sed -icreará un nuevo archivo y 'eliminará' el archivo en el que se está escribiendo. La mayoría de las aplicaciones continuarán escribiendo registros de registro en el archivo de registro eliminado y continuarán llenando espacio en disco. El nuevo archivo de registro truncado no se agregará. Esto solo cesará cuando la aplicación se reinicie o se indique que cierre y vuelva a abrir sus archivos de registro. En ese momento habrá un espacio (registros de registro faltantes) en el nuevo archivo de registro si ha habido alguna actividad registrable entre el uso de sed y el reinicio de la aplicación.

Una forma segura de hacerlo sería detener la aplicación, usar sed para truncar el registro y luego reiniciar la aplicación. Este enfoque puede ser inaceptable para algunos servicios (por ejemplo, un servidor web con alto rendimiento y requisitos de alta continuidad del servicio)

l1zard
fuente
2
¿Sabes qué pasa con las aplicaciones que se están agregando?
Adam Matan
1
Supongamos un controlador de archivo abierto normal que agrega líneas y vacia de vez en cuando.
Adam Matan
1
Sé mi camino alrededor de sed, y extraer líneas a un nuevo archivo es obvio con sed. El problema es mantenerlo todo en el mismo archivo.
Adam Matan
10
No, esto no debería funcionar. sed -icrea un nuevo archivo con el contenido editado y el anterior se elimina para que no esté editando el archivo activo: $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile------ Compruebe cómo sed -ifunciona. ¿Por qué esta respuesta incorrecta tiene tantos votos positivos?
pabouk
1
La pregunta dice "de un registro que una aplicación está agregando activamente". La palabra operativa es "activamente". Quizás esa aclaración se agregó después de que apareció su respuesta. Pero tal como está, los lectores que gravitan a "la mayoría de los votos" se engañarán. Solo pude votar en contra una vez.
Scott Prive
5

No. Una solución a este problema genérico del crecimiento del archivo de registro es la rotación del registro. Esto implica el movimiento regular (nocturno o semanal, típicamente) de un archivo de registro existente a otro nombre de archivo y comenzar de nuevo con un archivo de registro vacío. Después de un período, los viejos archivos de registro se descartan.

Ver: http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm

Tarnay Kálmán
fuente
2

Esta es una respuesta , no una solución. No hay solución a la pregunta. El autor de la pregunta dice claramente: "desde un registro que una aplicación está agregando activamente ". Puede seguir leyendo para comprender más y saltar hasta el final para obtener una sugerencia que haga en base a mi presunción de por qué este código no sigue las mejores prácticas de registro.

Para ser claros: otras "respuestas" aquí ofrecen la falsa promesa . Ningún cambio de nombre engañará a la aplicación para que use el nuevo archivo. La información más útil está oculta en los comentarios hechos a estas respuestas incorrectas.

Los archivos ACTIVE no son algún tipo de contenedor en el que simplemente colocas datos. Un nombre de archivo apunta a UN inodo (inicio del archivo) y cada inodo tiene un puntero a otro inodo (si hay más datos). Eso significa que un archivo escrito continuamente tiene un flujo constante de inodos agregados, y lo que usted piensa de un "archivo" es en realidad una secuencia de registro de inodos.

Imagina que estás rastreando a alguien en Google Maps, y esa persona podría teletransportarse a cualquier parte del mundo, en cualquier momento, e intentar conectar estos puntos.

La herramienta de Linux "truncar" puede descartar datos al final del archivo, simplemente recorriendo el árbol de inodo y (en la ubicación / tamaño que designe) descartará todos los punteros posteriores en la pila. Hacer lo contrario, descartar datos al comienzo del archivo, sería un proceso tan terriblemente complejo y arriesgado de reescribir el árbol de inodo en tiempo real que nadie escribirá tales herramientas para el público, porque a menudo fallarían y conducirían a pérdida de datos. La wiki de Inodes es corta pero explica algunos de estos conceptos.

** Mi consejo: cambie este problema: ¿POR QUÉ esta aplicación se comporta de esta manera? Hay muchas mejores prácticas de registro, pero a menudo están vinculadas a lo que realmente es su sistema de registro (syslog, etc.). En el núcleo, se espera que una aplicación "libere" su identificador para el archivo, por lo que logrotate (etc.) puede manejar el procesamiento posterior de los datos antiguos.

Cada vez que escucho "a un archivo de registro ACTIVO", inmediatamente le pido a esa persona que me cuente la "historia especial" detrás de esta aplicación. Por lo general, es "el desarrollador renunció, y no podemos cambiar el código. Esto es en realidad lo contrario de la seguridad, tiene su propio conjunto de riesgos. Pero creo que quiere una solución que evite tocar el código fuente. Si este es el caso, se necesita una pregunta más específica.

Scott Prive
fuente
0

Abrir en texto sublime Eliminar las líneas y guardar el archivo funciona de alguna manera, incluso si el archivo se agrega, pero vine aquí para buscar la solución para una solución de línea de comandos, ¡así que dejaría esta solución funcional pero inútil aquí!

Ashok Kumar Sahoo
fuente
-1

¿Quizás copiar, truncar, ajustar la copia de nuevo al tamaño = 0 truncamiento y eliminar la copia?

Mejor aún, de cola a copia, trunca el original, concat copia en el original.

Obtiene líneas en el registro a la longitud de la cola, así que es mejor que un límite de longitud de bytes.

Detalles modificativos del comentario:

Primero tenemos un script de registro en Python3 lo que quieras

from time import sleep

idx = 0
while 1 == 1:
    idx = (idx + 1)
    lf = open('tailTrunc.log', 'a')
    lf.write("line to file " + str(idx) + '\n')
    lf.close()
    sleep(0.01)

Entonces tenemos nuestro truncador

#!/usr/bin/env bash

trap "kill 0" EXIT

rm tailTrunc.log
touch tailTrunc.log

python3 logLoop.py &
loggerPID=$!
sleep 1

kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1

trimEnd.log muestra 80 a 89

registro muestra 90 para finalizar

De todos modos, donde hay voluntad hay un camino.

Muchos ejemplos más complicados de consolidadores y cómo se abre o cierra la secuencia de escritura pueden necesitar un ajuste por núcleo de CPU, etc. Simplemente detenga la escritura y la cola si puede en su registrador del proceso de registro, etc.

El maestro james
fuente
"de un registro que una aplicación está agregando activamente". El problema que su solución pasa por alto es que el archivo de registro está "permanentemente" en uso por la aplicación, lo que significa que el inodo del archivo de registro permanece en juego. Su solución "realiza una copia de seguridad" de los datos del archivo de registro, que pueden tener usos fuera de esta pregunta.
Scott Prive
Gracias por tu comentario y voto negativo? Modifiqué un ejemplo rápido y barato como alimento para pensar que tendrás que pensar más profundamente sobre tu situación, pero donde hay voluntad hay una manera.
Maestro James
No piense que fue mi voto negativo, pero creo que el punto fue abordado en los comentarios de la otra respuesta: SI copia un archivo de registro, entonces ya no es el archivo de registro activo ... no importa lo que haga. El identificador de archivo de la aplicación siempre apuntará al inodo del archivo de registro original. Piénselo de esta manera: tiene una aplicación que utiliza funciones de registro no estándar y agrega continuamente bytes al archivo que tiene abierto.
Scott Prive
1
Derecho perdón por inferir. Sí, el inodo debe permanecer igual, por eso el ejemplo / prueba dado se trunca, y nuevamente depende de la situación (las opciones para todos aparentemente se esconden en un sitio plano).
Maestro James