So begrenzen Sie die Größe der Protokolldatei mit >>

24

Wie kann ich die Größe einer mit >>200 MB geschriebenen Protokolldatei begrenzen?

$ run_program >> myprogram.log
David
quelle
1
Möchten Sie, dass das Programm nach 200 MB beendet wird? Oder willst du die letzten 200MB mit allem was älter ist im Bit Bucket?
Aaron D. Marasco
Nein, der Prozess kann nicht aufhören, bis manuell getötet
David
entschied sich für logrotate, danke allen für die wertvollen eingaben
david

Antworten:

9

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 sizeParameter, 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.

Emre Yazici
quelle
1
+1 Logfiles mit wiederholten Informationen können oft in Größenordnungen komprimiert werden.
Benutzer unbekannt
Schneidet logrotate Dateien ab oder kopiert oder verschiebt es sie einfach? Denn dies funktioniert nur, wenn die mit dem fd verknüpfte Datei abgeschnitten ist. Wenn es mv'd ist, wird die Datei weiter wachsen, wenn es nicht verbunden ist, wird es einfach offen gehalten und wächst weiter, bis der Prozess beendet wird ... IIRC logrotate kopiert, löst die Verbindung und erstellt eine neue Datei Deshalb muss man oft SIGHUP an Dæmons senden, wenn ihre Protokolle gedreht wurden.
Michael Trausch
Beachten Sie, dass selbst wenn es abgeschnitten ist, ein Problem besteht, wenn die Datei nicht im Anhänge-Modus geöffnet wurde (Protokolldateien sollten immer im Anhänge-Modus geöffnet werden, aber meiner Erfahrung nach häufig nicht)
Random832
Logrotate kann rotieren, sobald die Datei eine bestimmte Größe erreicht hat, täglich, wöchentlich usw. Es kann auch komprimiert werden, und Sie können die postscriptOption verwenden, um die Logrotate-Konfiguration dann SIGHUPan das Programm senden zu lassen.
Laebshade
12

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.

Caleb
quelle
Dies begrenzt die Größe jeder vom Programm geschriebenen Datei
Kim
Wahr. Wenn das Programm andere große Dateien schreiben müsste, bräuchten Sie eine andere Lösung.
Caleb
6

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 tmpfsanstelle einer Datei verwenden, wenn Sie über genügend Arbeitsspeicher verfügen.

Alex
quelle
Kreative Idee ... das überlässt es dem Programm, was zu tun ist, wenn es ausgeht.
Aaron D. Marasco
6

Sie können die Ausgabe abschneiden mit head:

size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
Smoking
quelle
Sehr kreativ. Nur ein Hinweis, dass dies nur dazu dient, das Schreiben von NEUEN Daten in die Datei einzuschränken. Dabei wird nicht berücksichtigt, wie groß oder klein die Datei bereits ist.
Caleb
2
Beachten Sie, dass das Programm (mit SIGPIPE) wahrscheinlich beendet wird, sobald es die Größenbeschränkung erreicht hat, anstatt die Daten zu verwerfen.
Random832
1
Ich war mit einer ähnlich denken ddMagie aber ja @ Random832 richtig ist , werden Sie eine bekommen SIGPIPEals head/ dd/ whateveres fällt.
Aaron D. Marasco
Was ist es mit einem zu ignorieren trap '' SIGPIPE?
Smoking
Oder pfeife stattdessen nach { head -c "$size" >> log; cat > /dev/null; }.
Stéphane Chazelas
5

In Paket apache2-utilsist 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 .

PRIHLOP
quelle
Der Link ist nicht vorhanden.
Alexander Gonchiy
1

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

Verweise

HINWEIS: Ich bin der Betreuer des obigen Repos. Einfach die Lösung teilen ...

Dave Wolaver
quelle
Ich liebe die Idee der Kürzung. Ich bin nicht so vertraut mit C, also gibt es eine Chance, eine Binärdatei dafür bereitzustellen? oder zumindest detaillierte Anweisungen zur Installation?
Felipe
0

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 SIGHUPoder ähnlichem). Dafür würde ich mir anstelle von 200 MB eine "vernünftige" Anzahl von Zeilen überlegen, um den Überblick zu behalten.

Aaron D. Marasco
quelle
Das Speichern von 200 MB Protokolldaten aus keinem anderen Grund als zum Abschneiden ist eine sehr gute Verwendung der Systemressourcen. Es wird auch keine Zeilenzählung für eine große Protokolldatei durchgeführt. Ich würde die Verwendung von Tools empfehlen, die für diese Art syslogund Weise erstellt wurden logrotate.
Caleb
0

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 <&0Sie, dass es ohne diese scheinbar redundante Funktion nicht möglich ist.

stsp
quelle