Як я можу обмежити розмір записаного файлу журналу >>
на 200 МБ?
$ run_program >> myprogram.log
Як я можу обмежити розмір записаного файлу журналу >>
на 200 МБ?
$ run_program >> myprogram.log
Відповіді:
Якщо ваша програма (тобто run_program
) не підтримує обмеження розміру файлу журналу, ви можете періодично перевіряти розмір файлу в циклі за допомогою зовнішньої програми або сценарію.
Ви також можете використовувати logrotate(8)
для обертання своїх журналів, у ньому є size
параметр, який ви можете використовувати для своїх цілей:
При цьому файл журналу повертається, коли досягається заданий розмір. Розмір може бути визначений в байтах (за замовчуванням), кілобайтах (sizek) або мегабайтах (sizem).
postscript
опцію, щоб конфігурація logrotate надсилала потім SIGHUP
програмі.
Якщо вашій програмі не потрібно записувати жодні ІНШІ файли, які перевищували б це обмеження, ви можете повідомити ядро про цей ліміт, використовуючи ulimit
. Перш ніж запустити команду, запустіть це, щоб встановити ліміт розміру файлу 200 Мб для всіх запущених процесів у вашому поточному сеансі оболонки:
ulimit -f $((200*1024))
Це захистить вашу систему, але програма може записати файл. Як пропонує Eyazici , подумайте про налаштування logrotate
для обрізки файлів журналів після досягнення ними певного розміру або віку. Ви можете відкинути старі дані або архівувати їх протягом певного часу в серії стислих файлів.
Ви можете створити нове зображення файлової системи, змонтувати його за допомогою циклічного пристрою та розмістити файл журналу у цій файловій системі:
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
Ви також можете використовувати tmpfs
замість файлу, якщо у вас достатньо пам'яті.
Вирізати вихід можна за допомогою head
:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
), коли вона досягне межі розміру, а не відкидає дані.
dd
магією, але так @ Random832 вірно, ви отримаєте SIGPIPE
як head
/ dd
/ скидання whatever
.
trap '' SIGPIPE
?
{ head -c "$size" >> log; cat > /dev/null; }
.
У пакеті apache2-utils
присутня утиліта, яка називається rotatelogs
, вона може бути корисною для вас.
Конспект:
rotatelogs [-l] [-L linkname ] [-p програма ] [-f] [-t] [-v] [-e] [-c] [-n число файлів ] час обертання журналу | розмір файлів (B | K | M | G) [ зміщення ]
Приклад:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Повне керівництво ви можете прочитати за цим посиланням .
Я впевнений, що оригінальний плакат знайшов рішення. Ось ще один для інших, хто може прочитати цю тему ...
Curtail обмежує розмір виходу програми і зберігає останні 200MB виводу за допомогою наступної команди:
$ run_program | curtail -s 200M myprogram.log
ПРИМІТКА: Я підтримую репортаж вище. Просто ділитися рішенням ...
Оскільки це текст, я би написав сценарій вашою улюбленою мовою і додав би його до цього. Нехай він обробляє введення / виведення файлу (або зберігає його в пам’яті, а потім скидає на нього SIGHUP
або подібне). Для цього замість 200 МБ я б придумав "розумну" кількість рядків, які слід відслідковувати.
syslog
і logrotate
.
Наступний сценарій повинен зробити цю роботу.
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
У нього є кілька очевидних скорочень, але в цілому він робить те, що ви просили. Він розділить колоду на шматки обмеженого розміру, а кількість шматочків також обмежена. Все можна вказати за допомогою аргументів командного рядка. Файл журналу також задається через командний рядок.
Зверніть увагу на маленьку готчу, якщо ви використовуєте її з демон, що виходить на другий план. Використання труби не дозволить демону перейти на другий план. У цьому випадку є (ймовірно, специфічний для bash) синтаксис, щоб уникнути проблеми:
my_daemon | ( logger.sh /var/log/my_log.log <&0 & )
Зауважте <&0
, хоча, здавалося б, зайвим, без цього не вийде.