Как я могу ограничить размер файла журнала, записанного с >>
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
файлов журнала, когда они достигнут определенного размера или возраста. Вы можете удалить старые данные или заархивировать их на некоторое время в виде ряда сжатых файлов.
Вы можете создать новый образ файловой системы, смонтировать его с помощью устройства loop и поместить файл журнала в эту файловую систему:
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
as 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 ограничивает размер вывода программы и сохраняет последние 200 МБ вывода с помощью следующей команды:
$ 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
, несмотря на внешнюю избыточность, без этого не получится.