Comment puis-je limiter la taille d'un fichier journal écrit >>
à 200 Mo?
$ run_program >> myprogram.log
Comment puis-je limiter la taille d'un fichier journal écrit >>
à 200 Mo?
$ run_program >> myprogram.log
Réponses:
Si votre application (c.-à-d. run_program
) Ne prend pas en charge la limitation de la taille du fichier journal, vous pouvez vérifier périodiquement la taille du fichier en boucle avec une application ou un script externe.
Vous pouvez également utiliser logrotate(8)
pour faire pivoter vos journaux, il a un size
paramètre que vous pouvez utiliser pour votre objectif:
Avec cela, le fichier journal pivote lorsque la taille spécifiée est atteinte. La taille peut être spécifiée en octets (par défaut), kilo-octets (sizek) ou mégaoctets (sizem).
postscript
option pour que la configuration logrotate soit envoyée SIGHUP
au programme.
Si votre programme n'a pas besoin d'écrire d'autres fichiers qui seraient plus grands que cette limite, vous pouvez informer le noyau de cette limite en utilisant ulimit
. Avant d'exécuter votre commande, exécutez ceci pour configurer une limite de taille de fichier de 200 Mo pour tous les processus exécutés dans votre session shell actuelle:
ulimit -f $((200*1024))
Cela protégera votre système, mais cela pourrait être gênant pour le programme qui écrit le fichier. Comme le suggère eyazici , envisagez de configurer la logrotate
taille des fichiers journaux une fois qu'ils atteignent une certaine taille ou un certain âge. Vous pouvez supprimer les anciennes données ou les archiver pendant une période de temps dans une série de fichiers compressés.
Vous pouvez créer une nouvelle image de système de fichiers, la monter à l'aide d'un périphérique de boucle et placer le fichier journal sur ce système de fichiers:
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
Vous pouvez également utiliser à la tmpfs
place d'un fichier, si vous avez suffisamment de mémoire.
Vous pouvez tronquer la sortie avec head
:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
) une fois qu'il a atteint la taille limite, plutôt que de supprimer les données.
dd
chose avec de la magie, mais oui, @ Random832 a raison, vous obtiendrez un SIGPIPE
as head
/ dd
/ whatever
drops it.
trap '' SIGPIPE
?
{ head -c "$size" >> log; cat > /dev/null; }
.
Dans le package apache2-utils
est un utilitaire appelé rotatelogs
, il peut être utile pour vous.
Synopsis:
rotatelogs [-l] [-L linkname ] [-p program ] [-f] [-t] [-v] [-e] [-c] [-n nombre-de-fichiers ] logfile rotationtime | taille du fichier (B | K | M | G) [ décalage ]
Exemple:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Manuel complet que vous pouvez lire sur ce lien .
Je suis certain que l'affiche originale a trouvé une solution. Voici un autre pour ceux qui peuvent lire ce fil ...
Curtail limite la taille de la sortie d'un programme et préserve les 200 derniers Mo de sortie avec la commande suivante:
$ run_program | curtail -s 200M myprogram.log
REMARQUE: je suis le responsable du dépôt ci-dessus. Partageons simplement la solution ...
Puisqu'il s'agit de texte, j'écrirais un script dans votre langue préférée et le dirigerais vers cela. Demandez-lui de gérer les E / S du fichier (ou conservez-les tous en mémoire, puis videz-le SIGHUP
ou similaire). Pour cela, au lieu de 200 Mo, je pense à un nombre «raisonnable» de lignes à suivre.
syslog
et logrotate
.
Le script suivant devrait faire le travail.
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
Il a quelques raccourcis évidents, mais dans l'ensemble, il fait ce que vous avez demandé. Il divisera le journal en morceaux d'une taille limitée et la quantité de morceaux est également limitée. Tout peut être spécifié via les arguments de la ligne de commande. Le fichier journal est également spécifié via la ligne de commande.
Notez un petit problème si vous l'utilisez avec le démon qui passe en arrière-plan. L'utilisation d'un pipe empêchera le démon de passer en arrière-plan. Dans ce cas, il existe une syntaxe (probablement spécifique à bash) pour éviter le problème:
my_daemon | ( logger.sh /var/log/my_log.log <&0 & )
Notez <&0
que, bien qu'apparemment redondant, cela ne fonctionnera pas sans cela.