Jak mogę ograniczyć rozmiar zapisanego pliku dziennika >>
do 200 MB?
$ run_program >> myprogram.log
Jak mogę ograniczyć rozmiar zapisanego pliku dziennika >>
do 200 MB?
$ run_program >> myprogram.log
Odpowiedzi:
Jeśli twoja aplikacja (tj. run_program
) Nie obsługuje ograniczania rozmiaru pliku dziennika, możesz okresowo sprawdzać rozmiar pliku w pętli za pomocą zewnętrznej aplikacji lub skryptu.
Możesz także użyć logrotate(8)
do obracania dzienników, ma size
parametr, którego możesz użyć do swoich celów:
Dzięki temu plik dziennika jest obracany po osiągnięciu określonego rozmiaru. Rozmiar można określić w bajtach (domyślnie), kilobajtach (sizek) lub megabajtach (sizem).
postscript
opcji, aby konfiguracja logrotate została wysłana SIGHUP
do programu.
Jeśli twój program nie musi zapisywać INNYCH plików, które byłyby większe niż ten limit, możesz poinformować jądro o tym limicie za pomocą ulimit
. Przed uruchomieniem polecenia uruchom to, aby ustawić limit wielkości pliku 200 MB dla wszystkich procesów uruchomionych w bieżącej sesji powłoki:
ulimit -f $((200*1024))
To ochroni twój system, ale może być niebezpieczne dla programu zapisującego plik. Jak sugeruje eyazici , rozważ skonfigurowanie logrotate
plików dziennika do przycinania, gdy osiągną określony rozmiar lub wiek. Możesz odrzucić stare dane lub zarchiwizować je na pewien czas w szeregu skompresowanych plików.
Możesz utworzyć nowy obraz systemu plików, zamontować go za pomocą urządzenia pętli i umieścić plik dziennika w tym systemie plików:
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
Możesz również użyć tmpfs
zamiast pliku, jeśli masz wystarczającą ilość pamięci.
Możesz obciąć dane wyjściowe za pomocą head
:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
) po osiągnięciu limitu rozmiaru, zamiast odrzucania danych.
dd
magią, ale tak @ Random832 ma rację, dostaniesz SIGPIPE
as head
/ dd
/ whatever
upuszcza.
trap '' SIGPIPE
?
{ head -c "$size" >> log; cat > /dev/null; }
.
W pakiecie apache2-utils
znajduje się narzędzie o nazwie rotatelogs
, może być dla Ciebie pomocne.
Streszczenie:
rotatelogs [-l] [-L linkname ] [-p program ] [-f] [-t] [-v] [-e] [-c] [-n liczba plików ] czas rotacji pliku dziennika | rozmiar pliku (B | K | M | G) [ offset ]
Przykład:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Pełny podręcznik można przeczytać pod tym linkiem .
Jestem pewien, że oryginalny plakat znalazł rozwiązanie. Oto kolejny dla innych, którzy mogą przeczytać ten wątek ...
Curtail ogranicza rozmiar danych wyjściowych programu i zachowuje ostatnie 200 MB danych wyjściowych za pomocą następującego polecenia:
$ run_program | curtail -s 200M myprogram.log
UWAGA: Jestem opiekunem powyższego repozytorium. Po prostu udostępniam rozwiązanie ...
Ponieważ jest to tekst, napisałbym skrypt w twoim ulubionym języku i dopasowałem go do tego. Niech poradzi sobie z plikiem I / O (lub zachowa to wszystko w pamięci, a następnie zrzuci na SIGHUP
lub podobne). W tym celu zamiast 200 MB pomyślałbym o „rozsądnej” liczbie wierszy do śledzenia.
syslog
i logrotate
.
Poniższy skrypt powinien wykonać zadanie.
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
Ma kilka oczywistych skrótów, ale ogólnie robi to, o co prosiłeś. Podzielą dziennik na kawałki o ograniczonym rozmiarze, a ilość kawałków jest również ograniczona. Wszystkie można określić za pomocą argumentów wiersza polecenia. Plik dziennika jest również określany za pomocą wiersza polecenia.
Zwróć uwagę na małą gotcha, jeśli używasz jej z demonem, który rozwidla się w tle. Użycie potoku uniemożliwi przejście demona w tło. W tym przypadku istnieje składnia (prawdopodobnie specyficzna dla bash), aby uniknąć problemu:
my_daemon | ( logger.sh /var/log/my_log.log <&0 & )
Zwróć uwagę, że <&0
choć pozornie zbędne, nie będzie działać bez tego.