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

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

tail -f /path/to/serverLog | grep "server is up" ...(now, eg, wget on server)? 

Каков наилучший способ сделать это?

6 Solutions collect form web for “Лучший способ следить за журналом и выполнять команду, когда в журнале появляется текст”

Простым способом будет awk.

 tail -f /path/to/serverLog | awk '/Printer is on fire!/ { system("shutdown -h now") } /new USB high speed/ { system("echo New USB" | mail admin")' 

И да, оба они являются реальным сообщением из журнала ядра. Perl может быть немного более изящным для использования для этого и может также заменить потребность в хвосте. Если использовать perl, он будет выглядеть примерно так:

 open(my $fd, "<", "/path/to/serverLog") or die "Can't open log"; while(1) { if(eof $dataFd) { sleep 1; $fd->clearerr; next; } my $line = <$fd>; chomp($line); if($line =~ /Printer is on fire!/) { system("shutdown -h now"); } elsif($line =~ /new USB high speed/) { system("echo New USB" | mail admin"); } } 

На этот вопрос уже ответили, но я думаю, что есть лучшее решение.

Вместо tail | whatever tail | whatever , я думаю, что вы действительно хотите, это swatch . Swatch – это программа, специально разработанная для выполнения ваших запросов, просмотра файла журнала и выполнения действий на основе строк журнала. Использование tail|foo потребует, чтобы у вас был активный терминал для этого. Swatch, с другой стороны, работает как демон и всегда будет следить за вашими журналами. Swatch доступен во всех дистрибутивах Linux,

Я призываю вас попробовать. Хотя вы можете набить гвоздь с задней стороны отвертки, это не значит, что вам нужно.

Лучший 30-секундный учебник по образцу, который я могу найти, находится здесь: http://www.campin.net/newlogcheck.html

Если вы ищете только одну возможность и хотите оставаться в основном в оболочке, а не с помощью awk или perl, вы можете сделать что-то вроде:

 tail -F /path/to/serverLog | grep --line-buffered 'server is up' | while read ; do my_command ; done 

… который будет запускать my_command каждый раз, когда в файле журнала появляется «сервер вверх». Для нескольких возможностей вы можете отказаться от grep и вместо этого использовать case в течение while .

Капитал -F сообщает tail чтобы посмотреть, как файл журнала будет повернут; т.е. если текущий файл будет переименован, а другой файл с тем же именем займет свое место, tail переключится на новый файл.

Опция --line-buffered сообщает grep чтобы очистить буфер после каждой строки; в противном случае my_command может быть недоступен своевременно (при условии, что в журналах есть строки с разумным размером).

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

  1. Если хвост журнала уже содержит «сервер вверх».
  2. Автоматическое завершение хвостового процесса после его обнаружения.

Я использую что-то вроде этого:

 RELEASE=/tmp/${RANDOM}$$ ( trap 'false' 1 trap "rm -f ${RELEASE}" 0 while ! [ -s ${RELEASE} ]; do sleep 3; done # You can put code here if you want to do something # once the grep succeeds. ) & wait_pid=$! tail --pid=${wait_pid} -F /path/to/serverLog \ | sed "1,10d" \ | grep "server is up" > ${RELEASE} 

Он работает, удерживая tail открытым до тех пор, пока файл ${RELEASE} содержать данные.

Как только grep преуспеет в этом:

  1. записывает вывод в ${RELEASE} который будет
  2. завершите процесс ${wait_pid} чтобы
  3. выйти из tail

Примечание. Команда sed может быть более сложной, чтобы фактически определить количество tail линии, которое будет производиться при запуске, и удалить этот номер. Но в целом, это 10.

Странно, что никто не упомянул о multitail утилите, которая имеет эту функциональность из коробки. Один из примеров использования:

Покажите результат команды ping, и если она отображает тайм-аут, отправьте сообщение всем пользователям, которые в настоящее время вошли в систему

 multitail -ex timeout "echo timeout | wall" -l "ping 192.168.0.1" 

См. Также примеры использования multitail .

Баш мог выполнить работу сам

Давайте посмотрим, насколько простым и понятным это может быть:

 mylog() { echo >>/path/to/myscriptLog "$@" } while read line;do case "$line" in *"Printer on fire"* ) mylog Halting immediately shutdown -h now ;; *DHCPREQUEST* ) [[ "$line" =~ DHCPREQUEST\ for\ ([^\ ]*)\ ]] mylog Incomming or refresh for ${BASH_REMATCH[1]} $HOME/SomethingWithNewClient ${BASH_REMATCH[1]} ;; * ) mylog "untrapped entry: $line" ;; esac done < <(tail -f /path/to/logfile) 

Хотя вы не используете regex bash, это может остаться очень быстрым!

Но bash + sed – очень эффективный и интересный тандем

Но для сервера с высокой нагрузкой, и, как мне нравится, потому что он очень быстрый и очень масштабируемый, я часто использую это:

 while read event target lost ; do case $event in NEW ) ip2int $target intTarget ((count[intTarget]++)) ... esac done < <(tail -f /path/logfile | sed -une ' s/^.*New incom.*from ip \([0-9.]\+\) .*$/NEW \1/p; s/^.*Auth.*ip \([0-9.]\+\) failed./FAIL \1/p; ... ') 
Interesting Posts

Как ограничить пропускную способность, используемую процессом?

Недопустимое MIT-Magic-Cookie на собственной машине с каждым новым Wi-Fi-соединением

Как я могу диагностировать и исправлять недостающее место на диске?

Команда tar генерирует ошибку в сценарии оболочки

Byobu – Новое окно с той же сессией ssh?

Получение полного имени пути к заданному каталогу

Есть ли способ ограничить общее потребление ЦП?

Shell сценарий синтаксические ошибки messsages "неожиданный конец файла" и "неожиданный EOF при поиске соответствия` "'"

Кнопки мультимедиа для наушников как вход HID

Удалите последний символ перед другим символом

Вставить в таблицу Oracle в цикле

Почему многозначительно игнорируют мои подстановочные знаки?

Какова реальная точка опции -f на rm?

Как создать псевдоним для двух команд Git, которые используют параметр?

Как я могу настроить sudo только для одной попытки?

Linux и Unix - лучшая ОС в мире.