Периодически получать новые строки из файла, возможно, зависания

Я ищу довольно простой способ (никакого развития не было – я мог бы написать это на Python, но я надеюсь, что есть что-то уже там).

У меня есть файл журнала (в моем случае написан rsyslogd). Для целей аналитики я хочу читать его каждые 1 минуту и ​​вычислять показатели за последнюю минуту, например, сколько страниц попадает на мой HTTP-сервер. Мои 2 требования:

1) Я только хочу посмотреть строки, которые были добавлены с момента последнего чтения файла. (Мне нужна только последняя минута или около того, и файл слишком большой, чтобы перечитывать и фильтровать каждую минуту).

2) Один раз в день файл получает logrorate'd. В первый раз после вращения журнала мне нужны все строки из предыдущего файла, который я еще не читал, плюс все строки из нового файла.

Я полагаю, что теперь я единственный, у кого такие требования – что делают другие?

One Solution collect form web for “Периодически получать новые строки из файла, возможно, зависания”

Предполагая, что your-filter читает данные из stdin:

 while your-filter; do sleep 60 done < file.log 

Это предполагает, что your-filter просто считывает данные и, например, не пытается просмотреть его.

Теперь, чтобы решить проблему вращения журнала, если в Linux (где, вопреки большинству других систем, /dev/fd/n являются символическими ссылками на фактические файлы), с помощью ksh , bash , zsh , dash , yash (большинство оболочек POSIX, кроме самые педантичные POSIX, такие как posh как -ef , не POSIX):

 while your-filter; do if [ file.log -ef /dev/stdin ]; then sleep 60 else exec < file.log fi done < file.log 

При вращении журнала, который будет вызывать your-filter дважды, если вы хотите, чтобы его вызывали один раз с конкатенацией старого и нового:

 while if [ file.log -ef /dev/stdin ]; then your-filter else exec 3<&0 < file.log (cat <&3; cat) | your-filter && exec 3<&- fi do sleep 60 done < file.log 

Теперь при вращении журнала может быть время, когда старый файл.log был переименован, но новый file.log не создан, и в этом случае вышеуказанное не будет выполнено, если оно выполнено exec < file.log при этом момент. Тогда вы можете исправить это с помощью:

 while if [ file.log -ef /dev/stdin ] || ! command exec 3< file.log; then your-filter else (cat; cat <&3) | your-filter && exec <&3 3<&- fi do sleep 60 done < file.log 

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

command необходима, чтобы избежать выполнения exec чтобы заставить оболочку выйти, когда она терпит неудачу (как требует POSIX). Это не нужно с zsh или bash когда он не находится в режиме sh .

Теперь мы спим в течение 60 секунд в цикле, и your-filter может занять несколько секунд. Если важно, чтобы your-filter запускался каждую минуту в среднем, с ksh , bash или zsh , вы могли бы изменить его на:

 t=$SECONDS while if [ file.log -ef /dev/stdin ] || ! command exec 3< file.log; then your-filter else (cat; cat <&3) | your-filter && exec <&3 3<&- fi do t=$(($t + 60)) sleep "$((t - SECONDS))" done < file.log 

С ksh93 и zsh , и если ваш sleep принимает аргументы с плавающей запятой, вы можете запустить typeset -F SECONDS .

  • Как я могу напечатать вторую в последнюю строку множество файлов в один файл?
  • $ (tail) в переменную удаления \ n
  • Интерактивный, скрытый живой хвост из нескольких файлов?
  • Время, необходимое для вывода трубы на голову / хвост
  • Как сделать «хвост -f» файлов с чередованием логов?
  • Можно ли «перевернуть» символическую ссылку на новый файл, не затрагивая никаких открытых дескрипторов файлов?
  • как я перенаправляю вывод из файла tailf & grep в файл
  • Как я могу использовать Awk для преобразования временной отметки unix для чтения человеком при создании файла журнала Tail-f?
  • Перенаправление вывода GREP в разные текстовые файлы в зависимости от содержимого захвата
  • Как я могу контролировать файл, который полностью воссоздается во время его запуска?
  • Как извлечь количество физических процессоров и потоков на ядро? (Нет текста, только номер для использования в качестве входных данных в другом месте)
  • Linux и Unix - лучшая ОС в мире.