Превращение файла журнала в своего рода кольцевой буфер

22

Люди, есть ли решение * nix, которое сделало бы файл журнала действовать как кольцевой буфер? Например, я хотел бы, чтобы в файлах журналов сохранялось максимум 1 ГБ данных и удалялись старые записи после достижения предела.

Это вообще возможно? Я считаю, чтобы добиться того, чтобы файл журнала был превращен в какое-то специальное устройство ...

PS Я знаю о разных инструментах logrotating, но это не то, что мне нужно. Logrotating требует большого количества операций ввода-вывода, обычно происходит один раз в день, в то время как мне нужно решение «времени выполнения».

Pachanga
источник
3
Я не уверен, почему вы думаете, что ротация журнала потребует много ввода-вывода. Вращение 10 лог-файлов - это 10 операций переименования и HUP сервиса. Не совсем убийственная операция ... И это стандартное решение вашей проблемы :)
pehrs
2
Можно запустить скрипт / исполняемый файл, который не очень хорошо работает с HUP.
Скотт
1
Это должно предоставить другой вариант использования вашего вопроса. У меня есть демонизированный музыкальный проигрыватель. Мне нужен журнал длиной всего в несколько строк, чтобы я мог видеть, что играет, а что играло до этого. А tail -f somefileсделал бы это. Я только что попробовал с повернутыми журналами и tail -fне работает с ними.
Vorac

Ответы:

14

В Linux есть кольцевой буфер ядра. Вы можете использовать dmesgдля отображения .

Или вот модуль ядра Linux, который, кажется, делает то, что вы хотите.

Что такое эмлог?

emlog - это модуль ядра Linux, который позволяет легко получить доступ к самым последним (и только самым последним) выводам процесса. Он работает так же, как "tail -f" в файле журнала, за исключением того, что необходимое хранилище никогда не увеличивается. Это может быть полезно во встроенных системах, где недостаточно памяти или дискового пространства для хранения полных файлов журнала, но иногда требуются самые последние сообщения отладки (например, после появления ошибки).

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

Приостановлено до дальнейшего уведомления.
источник
1
Спасибо за ссылку! Кстати, на домашней странице emlog есть ссылка на ulogbufd, что, вероятно, является для меня даже более подходящим решением.
пачанга
Emlog модуль ядра теперь поддерживается на GitHub: github.com/nicupavel/emlog
dbernard
4

Самая близкая вещь, о которой я могу думать, - это RRDTools, но, вероятно, это не то, что вы ищете. Другим решением было бы отслеживать файл журнала (скажем, каждую секунду или в Linux с inotify), например, вы пишете скрипт вроде:

while :; do
  if [[ $(stat -c %s $FILE) -gt 10000 ]]; then
    # rotate the log
  fi
  sleep 1
done

с inotify:

while :; do
  if inotifywait [some options] $FILE; then
    # check size and rotate the file
  fi
done
Дэн Андреатта
источник
+1 за упоминание RRDtool, реального примера регистрации структуры кольцевых данных.
Кори J
Спасибо за пример, показывающий использование команды оболочки inotifywait
pachanga
4

Вы можете использовать multilog из Daemontools в djb. Вы перенаправляете свой лог в него. Да, это ротация логов, но ротации это просто:

ln current $tai64nlocaltimestamp

Который практически на любой современной файловой системе Linux - это супер быстрая операция. Вы можете указать, сколько журнальных файлов вы хотите, сколько вы хотите их. создайте файлы размером 10 x 1024 Мб, и вы получите кольцевой буфер объемом 1 Гб.

Обратите внимание, что из-за автоматического поворота это один источник для каждого экземпляра мультилога. Но вы можете обойти это, написав простую оболочку с Netcat или вручную.

Джейсон
источник
Спасибо за чаевые! Я определенно собираюсь иметь на multilog также.
Пачанга
1

Вы можете создать канал FIFO, а затем прочитать его, используя скрипт, который вставляется в базу данных. Когда счетчик достигнет 1000, перезапустите идентификатор, вставляемый в базу данных. Конечно, не подходит для размера, но вы использовали это в качестве примера, так что я предполагаю, что это теоретический вопрос.

sinping
источник
1

Интересный вопрос; Вы обычно не видите это как дизайн. У меня есть программа, которая использует слегка похожую технику для записи истории, но она использует двоичный формат. «Файл журнала» состоит из четырех частей, все они представлены в машинно-нейтральном формате:

  1. Заголовок, содержащий магическое число и (максимальное) количество записей в используемом списке и свободном списке, порядковый номер для следующей записи в истории, фактическое количество записей в используемом списке, фактическое количество записей в свободном списке и длина файла (каждый из которых составляет 4 байта).
  2. Используемый список, каждая запись дает смещение и длину (4 байта для каждой части каждой записи).
  3. Свободный список, каждая запись аналогична используемой записи списка.
  4. Основные данные, каждая запись истории, состоящая из непрерывного набора байтов, оканчивающихся нулевым завершающим байтом.

Когда выделяется новая запись, если в свободном списке есть место, тогда она перезаписывает запись там (необязательно используя все это - в этом случае фрагмент остается в свободном списке). Когда в свободном списке нет места, в конце выделяется новое место. Когда старая запись вращается, ее пространство перемещается в свободный список и объединяется с любыми соседними бесплатными записями. Он предназначен для обработки операторов SQL, поэтому записи могут быть распределены по многим строкам. Этот код работает с указанным количеством записей. Он не ограничивает размер файла как такового (хотя сделать это будет несложно).

Основной код истории кода находится в двух файлах history.c и history.h, доступных из источника для программы SQLCMD (моя версия, а не Microsoft; моя существовала за десять или более лет до Microsoft), которую можно загрузить с архив программного обеспечения Международной группы пользователей Informix . Существует также программа для выгрузки файла истории (histdump.c) и тестер истории (histtest.ec - он претендует на то, чтобы быть ESQL / C, но сам по себе является кодом C; одна из функций поддержки, которую он вызывает, использует некоторый Informix ESQL / C библиотечные функции). Свяжитесь со мной, если вы хотите экспериментировать без использования Informix ESQL / C - смотрите мой профиль. Существуют некоторые тривиальные изменения, которые необходимо сделать, чтобы он скомпилировал историю за пределами его среды проектирования, плюс вам нужен make-файл.

Джонатан Леффлер
источник
0

Я согласен с комментариями pehrs на ваш вопрос. Вращение журнала не так сложно. Вы можете настроить logrotate или другой скрипт для периодической проверки вашего файла журнала, даже если вам так хочется, каждую минуту. Когда он обнаруживает, что ваш файл достигает 1 ГБ, он просто выполняет переименование, которое не требует ввода-вывода. Во время переименования процесс продолжает запись файла журнала. Журнал ротатор может отправить HUP на ваш демон системного журнала (ваш демон будет логирование через системный журнал, верно? Если нет, то он должен поддерживать сигнал HUP , если это хорошо написано ...) , чтобы он повторно открыть исходный путь к файлу , В этот момент он начнет запись в новый файл по первоначальному пути, и вы сможете удалить повернутую версию.

Камил Кисиэль
источник