Convertir un archivo de registro en una especie de búfer circular

22

Amigos, ¿hay una solución * nix que haría que el archivo de registro actúe como un búfer circular? Por ejemplo, me gustaría que los archivos de registro almacenen un máximo de 1 Gb de datos y descarten las entradas más antiguas una vez que se alcanza el límite.

¿Es posible en absoluto? Creo que para lograr que un archivo de registro se convierta en algún tipo de dispositivo especial ...

PD: Estoy al tanto de las herramientas de rotación misceláneas, pero esto no es lo que necesito. La rotación requiere mucha IO, ocurre generalmente una vez al día mientras necesito una solución de "tiempo de ejecución".

pachanga
fuente
3
No estoy seguro de por qué crees que la rotación de registros necesitaría mucha IO. Rotar 10 archivos de registro es 10 operaciones de cambio de nombre y un HUP del servicio. No es exactamente una operación asesina ... Y es la solución estándar a su problema :)
pehrs
2
Uno puede estar ejecutando un script / ejecutable que no funciona bien con HUP.
Scott
1
Esto es para proporcionar otro caso de uso para su pregunta. Tengo un reproductor de música demonizado. Quiero un registro de longitud de solo varias líneas, para poder ver qué se está reproduciendo y qué se jugó antes de eso. A tail -f somefileharía eso. Acabo de probar con registros rotados y tail -fno funciona con ellos.
Vorac

Respuestas:

14

Linux tiene un buffer de anillo de kernel. Puedes usar dmesgpara mostrarlo .

O aquí hay un módulo de kernel de Linux que parece hacer lo que quieres.

¿Qué es el emlog?

emlog es un módulo de kernel de Linux que facilita el acceso a la salida más reciente (y solo la más reciente) de un proceso. Funciona igual que "tail -f" en un archivo de registro, excepto que el almacenamiento requerido nunca crece. Esto puede ser útil en sistemas embebidos donde no hay suficiente memoria o espacio en disco para mantener archivos de registro completos, pero a veces se necesitan los mensajes de depuración más recientes (por ejemplo, después de observar un error).

El módulo del kernel emlog implementa un controlador de dispositivo de caracteres simple. El controlador actúa como una tubería con nombre que tiene un buffer circular finito. El tamaño del búfer es fácilmente configurable. A medida que se escriben más datos en el búfer, se descartan los datos más antiguos. Un proceso que lee desde un dispositivo de registro primero leerá el búfer existente, luego verá el nuevo texto tal como está escrito, similar a monitorear un archivo de registro usando "tail -f". (Las lecturas sin bloqueo también son compatibles, si un proceso necesita obtener el contenido actual del registro sin bloquear para esperar nuevos datos).

Pausado hasta nuevo aviso.
fuente
1
Gracias por el enlace! Por cierto, la página de inicio de emlog tiene un enlace a ulogbufd, que probablemente sea una solución más apropiada para mí.
pachanga
El módulo del kernel emlog ahora se mantiene en github: github.com/nicupavel/emlog
dbernard
4

Lo más parecido que se me ocurre es RRDTools, pero probablemente no sea lo que está buscando. Otra solución sería monitorear el archivo de registro (digamos cada segundo o en Linux con inotify), por ejemplo, escribe un script como:

while :; do
  if [[ $(stat -c %s $FILE) -gt 10000 ]]; then
    # rotate the log
  fi
  sleep 1
done

con inotify:

while :; do
  if inotifywait [some options] $FILE; then
    # check size and rotate the file
  fi
done
Dan Andreatta
fuente
+1 por mencionar RRDtool, un ejemplo real de registro de estructura de datos en anillo.
Cory J
Gracias por ejemplo mostrando el uso del comando de shell inotifywait
pachanga
4

Puede utilizar multilog de daemontools de djb. Canaliza su salida de registro en él. Sí, es rotación de registros, pero las rotaciones son simplemente:

ln current $tai64nlocaltimestamp

Lo cual, en casi cualquier sistema de archivos de Linux moderno es una operación súper rápida. Puede especificar cuántos archivos de registro desea, qué tamaño desea. crea archivos de 10 x 1024 mb y tendrás tu búfer de anillo de 1 gb.

Tenga en cuenta que, debido a la rotación automática, es una fuente por instancia de multilog. Pero puede solucionarlo escribiendo un contenedor simple con netcat o a mano.

Jason
fuente
¡Gracias por el consejo! Definitivamente voy a tener en multilog también.
pachanga
1

Puede hacer una tubería FIFO y luego leerla usando un script que se inserta en una base de datos. Cuando el contador llegue a 1,000, reinicie el número de identificación que se está insertando en la base de datos. No funcionaría por tamaño, por supuesto, pero lo usaste como un ejemplo, así que supongo que esta es una pregunta teórica.

sinping
fuente
1

Interesante pregunta; normalmente no se ve eso como un diseño. Tengo un programa que usa una técnica ligeramente similar para registrar el historial, pero usa un formato binario. El 'archivo de registro' tiene cuatro partes, todas en un formato neutral para la máquina:

  1. Un encabezado que contiene el número mágico y el número (máximo) de entradas en la lista usada y lista libre, el número de secuencia para la siguiente entrada del historial, el número real de entradas en la lista usada, el número real de entradas en la lista libre , y la longitud del archivo (cada uno de los cuales es de 4 bytes).
  2. La lista utilizada, cada entrada proporciona un desplazamiento y una longitud (4 bytes para cada parte de cada entrada).
  3. La lista libre, cada entrada similar a la entrada de la lista utilizada.
  4. Los datos principales, cada registro histórico que consiste en un conjunto contiguo de bytes terminados en un byte terminador nulo.

Cuando se asigna un nuevo registro, si hay espacio en la lista libre, sobrescribe una entrada allí (no necesariamente usándolo todo, en cuyo caso el fragmento permanece en la lista libre). Cuando no hay espacio en la lista libre, se asigna nuevo espacio al final. Cuando un registro antiguo gira, su espacio se mueve a la lista libre y se fusiona con cualquier registro libre adyacente. Está diseñado para manejar declaraciones SQL para que los registros se puedan distribuir en muchas líneas. Este código funciona en un número específico de registros. No limita el tamaño del archivo per se (aunque no sería difícil hacerlo).

El código principal del historial del código está en dos archivos, history.c e history.h, disponibles en la fuente del programa SQLCMD (mi versión, no la de Microsoft; la mía existía una década o más antes que la de Microsoft), que se puede descargar desde el archivo de software del grupo internacional de usuarios Informix . También hay un programa de volcado de archivos de historial (histdump.c) y un probador de historial (histtest.ec; afirma que es ESQL / C, pero en sí mismo es realmente un código C; una de las funciones de soporte que llama utiliza algunos Informix ESQL / C funciones de biblioteca). Póngase en contacto conmigo si desea experimentar sin utilizar Informix ESQL / C; consulte mi perfil. Hay algunos cambios triviales para que compile histtest fuera de su entorno de diseño, además de que necesita un archivo MAKE.

Jonathan Leffler
fuente
0

Estoy de acuerdo con el comentario de pehrs a su pregunta. La rotación de registros no es tan difícil. Puede configurar logrotate u otro script para verificar periódicamente su archivo de registro, incluso con la frecuencia que cada minuto si lo desea. Cuando detecta que su archivo alcanza 1 GB de tamaño, simplemente realiza un cambio de nombre, que casi no requiere E / S. Durante el cambio de nombre, el proceso continúa escribiendo el archivo de registro. El rotador de registros puede enviar un HUP a su demonio syslog (su demonio está registrando a través de syslog, ¿verdad? Si no, debería admitir la señal HUP si está bien escrito ...) para que vuelva a abrir la ruta original del archivo . En este punto, comenzará a escribir en un nuevo archivo en la ruta original y puede eliminar la versión rotada.

Kamil Kisiel
fuente