Wie kann ich die Größe einer mit >>
200 MB geschriebenen Protokolldatei begrenzen?
$ run_program >> myprogram.log
Wie kann ich die Größe einer mit >>
200 MB geschriebenen Protokolldatei begrenzen?
$ run_program >> myprogram.log
Antworten:
Wenn Ihre Anwendung (d. H. run_program
) Die Beschränkung der Größe der Protokolldatei nicht unterstützt, können Sie die Dateigröße regelmäßig in einer Schleife mit einer externen Anwendung oder einem externen Skript überprüfen.
Sie können auch verwenden logrotate(8)
, um Ihre Protokolle zu drehen, es hat size
Parameter, die Sie für Ihren Zweck verwenden können:
Damit wird die Protokolldatei gedreht, wenn die angegebene Größe erreicht ist. Die Größe kann in Byte (Standardeinstellung), Kilobyte (Größe k) oder Megabyte (Größe m) angegeben werden.
postscript
Option verwenden, um die Logrotate-Konfiguration dann SIGHUP
an das Programm senden zu lassen.
Wenn Ihr Programm keine ANDEREN Dateien schreiben muss, die dieses Limit überschreiten, können Sie den Kernel über dieses Limit informieren ulimit
. Bevor Sie Ihren Befehl ausführen, führen Sie diesen Befehl aus, um eine maximale Dateigröße von 200 MB für alle in Ihrer aktuellen Shell-Sitzung ausgeführten Prozesse festzulegen:
ulimit -f $((200*1024))
Dadurch wird Ihr System geschützt, es kann jedoch sein, dass das Programm die Datei schreibt. Wie eyazici vorschlägt , sollten Sie in Betracht ziehen logrotate
, Protokolldateien zu bereinigen , sobald sie eine bestimmte Größe oder ein bestimmtes Alter erreicht haben. Sie können alte Daten verwerfen oder für einen bestimmten Zeitraum in einer Reihe komprimierter Dateien archivieren.
Sie können ein neues Dateisystem-Image erstellen, es mit einem Loop-Gerät mounten und die Protokolldatei auf diesem Dateisystem ablegen:
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
Sie können auch tmpfs
anstelle einer Datei verwenden, wenn Sie über genügend Arbeitsspeicher verfügen.
Sie können die Ausgabe abschneiden mit head
:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
) wahrscheinlich beendet wird, sobald es die Größenbeschränkung erreicht hat, anstatt die Daten zu verwerfen.
dd
Magie aber ja @ Random832 richtig ist , werden Sie eine bekommen SIGPIPE
als head
/ dd
/ whatever
es fällt.
trap '' SIGPIPE
?
{ head -c "$size" >> log; cat > /dev/null; }
.
In Paket apache2-utils
ist vorhandenes Dienstprogramm genannt rotatelogs
, es kann für Sie hilfreich sein.
Zusammenfassung:
rotatelogs [-l] [-L Linkname ] [-p Programm ] [-f] [-t] [-v] [-e] [-c] [-n Anzahl Dateien ] Logdatei- Rotationszeit | Dateigröße (B | K | M | G) [ Versatz ]
Beispiel:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Vollständiges Handbuch können Sie auf diesem Link lesen .
Ich bin sicher, das Originalplakat hat eine Lösung gefunden. Hier ist noch eine für andere, die diesen Thread lesen können ...
Mit dem folgenden Befehl wird die Größe der Programmausgabe begrenzt und die letzten 200 MB werden beibehalten:
$ run_program | curtail -s 200M myprogram.log
HINWEIS: Ich bin der Betreuer des obigen Repos. Einfach die Lösung teilen ...
Da es sich um Text handelt, würde ich ein Skript in Ihrer Lieblingssprache schreiben und es dazu weiterleiten. Lassen Sie es die Datei-E / A handhaben (oder speichern Sie alles im Speicher und sichern Sie es anschließend auf SIGHUP
oder ähnlichem). Dafür würde ich mir anstelle von 200 MB eine "vernünftige" Anzahl von Zeilen überlegen, um den Überblick zu behalten.
syslog
und Weise erstellt wurden logrotate
.
Das folgende Skript sollte den Job erledigen.
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
Es hat ein paar offensichtliche Abkürzungen, aber insgesamt macht es, was Sie gefragt haben. Das Protokoll wird in Blöcke mit einer begrenzten Größe aufgeteilt, und die Anzahl der Blöcke ist ebenfalls begrenzt. Alle können über die Befehlszeilenargumente angegeben werden. Die Protokolldatei wird auch über die Befehlszeile angegeben.
Beachten Sie ein kleines gotcha, wenn Sie es mit dem Dämon verwenden, der in den Hintergrund verzweigt. Die Verwendung einer Pipe verhindert, dass der Dämon in den Hintergrund wechselt. In diesem Fall gibt es eine (wahrscheinlich bash-spezifische) Syntax, um das Problem zu vermeiden:
my_daemon | ( logger.sh /var/log/my_log.log <&0 & )
Beachten <&0
Sie, dass es ohne diese scheinbar redundante Funktion nicht möglich ist.