¿Cómo puedo limitar el tamaño de un archivo de registro escrito >>
a 200 MB?
$ run_program >> myprogram.log
¿Cómo puedo limitar el tamaño de un archivo de registro escrito >>
a 200 MB?
$ run_program >> myprogram.log
Respuestas:
Si su aplicación (es decir, run_program
) no admite limitar el tamaño del archivo de registro, puede verificar el tamaño del archivo periódicamente en un bucle con una aplicación o script externo.
También puede usar logrotate(8)
para rotar sus registros, tiene un size
parámetro que puede usar para su propósito:
Con esto, el archivo de registro se gira cuando se alcanza el tamaño especificado. El tamaño puede especificarse en bytes (predeterminado), kilobytes (sizek) o megabytes (sizem).
postscript
opción para que la configuración logrotate se envíe SIGHUP
al programa.
Si su programa no necesita escribir OTROS archivos que sean mayores que este límite, puede informar al núcleo de este límite utilizando ulimit
. Antes de ejecutar su comando, ejecútelo para configurar un límite de tamaño de archivo de 200 MB para todos los procesos ejecutados en su sesión de shell actual:
ulimit -f $((200*1024))
Esto protegerá su sistema, pero podría ser complicado para el programa que escribe el archivo. Como sugiere eyazici , considere configurar logrotate
para podar los archivos de registro una vez que alcancen cierto tamaño o edad. Puede descartar datos antiguos o archivarlos durante un período de tiempo en una serie de archivos comprimidos.
Puede crear una nueva imagen del sistema de archivos, montarla con un dispositivo de bucle y colocar el archivo de registro en ese sistema de archivos:
dd if=/dev/zero of=./200mb.img bs=1024 count=200000 # create new empty 200MB file
mkfs.ext2 200mb.img # or ext3, or whatever fits your needs
mkdir logs
sudo mount -t ext2 -o loop 200mb.img logs # only root can do '-o loop' by default
run_program >>logs/myprogram.log
También puede usar en tmpfs
lugar de un archivo, si tiene suficiente memoria.
Puede truncar la salida con head
:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
) una vez que haya alcanzado el límite de tamaño, en lugar de descartar los datos.
dd
magia, pero sí @ Random832 es correcto, obtendrá una SIGPIPE
como head
/ dd
/ whatever
deja caer.
trap '' SIGPIPE
?
{ head -c "$size" >> log; cat > /dev/null; }
.
En el paquete apache2-utils
se llama utilidad actual rotatelogs
, puede ser útil para usted.
Sinopsis:
rotatelogs [-l] [-L nombreenlace ] [-p programa ] [-f] [-t] [-v] [-e] [-c] [-n número de archivos ] tiempo de rotación del archivo de registro | tamaño de archivo (B | K | M | G) [ desplazamiento ]
Ejemplo:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Puede leer el manual completo en este enlace .
Estoy seguro de que el póster original ha encontrado una solución. Aquí hay otro para otros que pueden leer este hilo ...
La reducción limita el tamaño de la salida de un programa y conserva los últimos 200 MB de salida con el siguiente comando:
$ run_program | curtail -s 200M myprogram.log
NOTA: Soy el mantenedor del repositorio anterior. Simplemente compartiendo la solución ...
Como es texto, escribiría un guión en su idioma favorito y lo canalizaría a eso. Haga que maneje la E / S del archivo (o manténgalo todo en la memoria y luego vuélvalo a descargar SIGHUP
o similar). Para eso, en lugar de 200 MB, pensaría en un número 'razonable' de líneas para realizar un seguimiento.
syslog
y logrotate
.
El siguiente script debería hacer el trabajo.
LOG_SIZE=500000
NUM_SEGM=2
while getopts "s:n:" opt; do
case "$opt" in
s)
LOG_SIZE=$OPTARG
;;
n)
NUM_SEGM=$OPTARG
;;
esac
done
shift $((OPTIND-1))
if [ $# == 0 -o -z "$1" ]; then
echo "missing output file argument"
exit 1
fi
OUT_FILE=$1
shift
NUM=1
while :; do
dd bs=10 count=$(($LOG_SIZE/10)) >> $OUT_FILE 2>/dev/null
SZ=`stat -c%s $OUT_FILE`
if [ $SZ -eq 0 ]; then
rm $OUT_FILE
break
fi
echo -e "\nLog portion finished" >> $OUT_FILE
mv $OUT_FILE $OUT_FILE.n$NUM
NUM=$(($NUM + 1))
[ $NUM -gt $NUM_SEGM ] && NUM=1
done
Tiene un par de atajos obvios, pero en general hace lo que pediste. Dividirá el registro en trozos de un tamaño limitado, y la cantidad de trozos también es limitada. Todo se puede especificar a través de los argumentos de la línea de comandos. El archivo de registro también se especifica a través de la línea de comando.
Tenga en cuenta un pequeño problema si lo usa con el demonio que se bifurca en segundo plano. Usar una tubería evitará que el demonio pase al fondo. En este caso, hay una sintaxis (probablemente específica de bash) para evitar el problema:
my_daemon | ( logger.sh /var/log/my_log.log <&0 & )
Tenga en cuenta que <&0
, aunque parece redundante, no funcionará sin esto.