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

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

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

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

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

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

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

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

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

  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? Спасибо!

1 ответ1

0

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .