Как ограничить лог-файл до последних N строк?

376
Bora M. Alper

У меня есть, ./programкоторый выводит много сообщений журнала, а также имеет очень ограниченное пространство для хранения на моем VPS:

Я хотел бы мой лог-файл содержит только самые последние строки ˝n˝ все время (или, вернее, когда я прекратить ^Cсвою программу или когда он выходит из строя ... )

А. Я не хочу следующее:

  1. Msgstr "Перенаправить вывод в (log-) файл, а затем использовать, tailчтобы сохранить только последние N строк."

    Ну, файл журнала все равно будет занимать драгоценное место, пока я не буду tailна нем работать, что делает его бессмысленным ... Я могу настроить cronjob, чтобы делать это периодически, если у меня нет другого выбора, но я хотел бы изучить возможности первый.

  2. «Используйте logrotate».

    logrotate кажется правильным решением проблемы, но это слишком хлопотно, и я хочу что-то попроще, желательно то, что я могу сделать с каналами и перенаправлениями.

Б. Я пробовал следующее:

(заменено ./programна seq 1000000if для тестирования)

  1. seq 1000000 | tee /dev/fd/2 | tail -n 10 > logfile

    Прекрасно работает, когда он завершается сам по себе, но когда я ^Cсам его прерываю, он logfileпуст (тогда как я ожидаю, что он будет содержать последние 10 строк, которые будут напечатаны на экране tee)

  2. mkfifo fifo; tail fifo -n 10 > logfile & seq 1000000 | tee fifo

    Работает прекрасно, когда она заканчивается сама по себе, но когда я прерываю ^Cего сам, то logfileэто не пустой, но и не содержит немного последних записей журнала, которые печатаются на экране:

,

$ tail fifo -n 10 > logfile & seq 1000000 | tee fifo [1] 2616 1 2 3 ⋮ 480178 480179 480180 480181 480182 480183 ^C [1]+ Done tail fifo -n 10 > logfile $ cat logfile 479297 479298 479299 479300 479301 479302 479303 479304 479305 

Здесь вы можете увидеть, что последние записи на 480 тысяч, а последняя запись в logfile составляет 479 305 ... то есть я пропускаю 878 последних строк! Я думаю, что это как-то связано с буферизацией, но я не уверен.

Может кто-нибудь показать мне, как это сделать, используя только оболочку и (желательно стандартные) утилиты Linux? Спасибо!

0
Лично я использую cron, который запускается каждый день в 12:12:12 для очистки файлов журнала ... так как они ежедневно сокращаются до размера, который никогда не становится большим, этот cron генерирует html-файл для файла, который включается в личную страницу статуса (смесь php и html), которая позволяет мне быстро следить за вещами. Tyson 5 лет назад 0

1 ответ на вопрос

0
Alex

Самым простым решением для вашего случая, вероятно, является круговой журнал, который имеет фиксированный размер.

Если вы работаете в Linux, вы можете попробовать модуль ядра emlog

Модуль ядра emlog реализует простой символьный драйвер устройства. Драйвер действует как именованный канал с конечным круговым буфером. Размер буфера легко настраивается. Когда в буфер записывается больше данных, самые старые данные отбрасываются. Процесс, который читает с устройства emlog, сначала прочтет существующий буфер, а затем увидит новый текст в том виде, в котором он написан, аналогично мониторингу файла журнала с использованием tail -f. (Неблокирующее чтение также поддерживается, если процессу необходимо получить текущее содержимое журнала без блокировки, чтобы дождаться новых данных.)

О системах BSD см. CLOG(8)

Похожие вопросы