Здравствуйте!
Есть программа, собирающая информацию с датчиков. Опрос всех датчиков (на данный момент 6шт, но может увеличиться многократно) раз в секунду.
После опроса каждого датчика она пишет информацию в лог, например:sh-3.2# tail -F dev.log | grep TRACE
2014-02-24 14:44:07,568 TRACE [Polling thread for sensor: level_1]: Processed ''22", received '22'
2014-02-24 14:44:07,568 TRACE [Polling thread for sensor: power_1]: Processed ''0", received '0'это означает что опрос успешен, level_1 равен 22, power_1 равен 0
Но, иногда что-то случается, и опрос одного или нескольких датчиков прекращается. Почти всегда это сопровождается сообщениями со словом ERROR в логе, я ловлю это monit-ом и программа перезапускается с его помощью. Но в 10% случаев опрос прекращается молча, без ERROR-ов и тому подобного, и тут monit оказывается бессилен. Единственный способ это отследить - перестает писаться строка, относящаяся к отвалившемуся датчику.Можно ли написать скрипт, который будет делать tail -F dev.log | grep TRACE, и если в течение, например, 10 секунд не появилась каждая из заданных 6 строк, делать ./restart.sh ?
Система - OSX 10.9
Буду очень благодарен за помощь
>[оверквотинг удален]
> всегда это сопровождается сообщениями со словом ERROR в логе, я ловлю
> это monit-ом и программа перезапускается с его помощью. Но в 10%
> случаев опрос прекращается молча, без ERROR-ов и тому подобного, и тут
> monit оказывается бессилен. Единственный способ это отследить - перестает писаться строка,
> относящаяся к отвалившемуся датчику.
> Можно ли написать скрипт, который будет делать tail -F dev.log | grep
> TRACE, и если в течение, например, 10 секунд не появилась каждая
> из заданных 6 строк, делать ./restart.sh ?
> Система - OSX 10.9
> Буду очень благодарен за помощьсохраняете последнюю строку от датчика на ram-диск и через 10 сек сравниваете, сошлась значит висит, не сошлась - обнавляете строку
> сохраняете последнюю строку от датчика на ram-диск и через 10 сек сравниваете,
> сошлась значит висит, не сошлась - обнавляете строкуя тут мало чего понял, т.к. совсем не программист. Вы могли бы это реализовать? я бы в долгу не остался. на всякий случай мой маил alexey_and(-на-)mail.ru
>[оверквотинг удален]
> всегда это сопровождается сообщениями со словом ERROR в логе, я ловлю
> это monit-ом и программа перезапускается с его помощью. Но в 10%
> случаев опрос прекращается молча, без ERROR-ов и тому подобного, и тут
> monit оказывается бессилен. Единственный способ это отследить - перестает писаться строка,
> относящаяся к отвалившемуся датчику.
> Можно ли написать скрипт, который будет делать tail -F dev.log | grep
> TRACE, и если в течение, например, 10 секунд не появилась каждая
> из заданных 6 строк, делать ./restart.sh ?
> Система - OSX 10.9
> Буду очень благодарен за помощьНе совсем понял.
Все датчики пишут в один лог-файл?
Шесть датчиков формируют шесть строк?
Рестарт программы перезапустит все датчики? И рабочие и зависшие?Если просто отслеживать на появление новой строки, и если её (строки) нет,
будет ли это означать что все датчики дали сбой или какой-то один?Скрипт написать на проверку новой строки можно, например так
#!/usr/bin/perl$file = "/tmp/file.txt"; # путь к лог-файлу
$prgr = "/tmp/restart.sh"; # путь к скрипту перезапуска
$time = 10; # время ожиданияopen FH, $file or die "can't update $file: $!";
# в бесконечном цикле определяем последнюю строку файла
# запоминаем её и старую позицию, после тайм-аута возвращаемся к ней
# если строка не изменилась - перезапуск датчиков
while(1) {
sleep $time;
for ($pos = tell(FH); <FH>; $pos = tell(FH)) {$str = $_ if eof(FH);}
if ($oldstr ne $str) {$oldstr = $str;}
else {system("$prgr");}
seek(FH, $pos, 0);
}
можно проверять модификацию (изменение) файла, но это тоже не спасет от всех вариантов, см. нижеЕсли 5 датчиков нормально пишут, а шестой завис и не пишет, тогда как?
то есть, новая строка от рабочих датчиков будет писаться и скрипт не перезапустит программу.проверять все шесть последних строк? а они от всех разных датчиков?
короче, дохрена неизвестных, одни вопросы..
> Не совсем понял.
> Все датчики пишут в один лог-файл?
> Шесть датчиков формируют шесть строк?да, все датчики пишут в один файл
каждый датчик формирует несколько строк - получение, обработка, значение. плюс куча инфы от самой программы. поэтому я не вижу другого пути кроме фильтрации по паттерну "TRACE":
sh-3.2# tail -F dev.log | grep TRACE
2014-02-24 14:44:07,568 TRACE [Polling thread for sensor: level_1]: Processed ''22", received '22'
2014-02-24 14:44:07,568 TRACE [Polling thread for sensor: power_1]: Processed ''0", received '0'если информация с датчика пришла некорректно, или вообще не пришла, TRACE не появляется
например, если отвалился датчик power_1, то при tail -F dev.log | grep TRACE я не увижу строку TRACE [Polling thread for sensor: power_1]: Processed ''0", received '0'
другими словами, если я делаю tail -F dev.log | grep -e 'TRACE' -e 'power_1' , будут валиться строки
2014-02-24 14:44:07,568 TRACE [Polling thread for sensor: power_1]: Processed ''0", received '0'
раз в секунду, если этот датчик перестанет опрашиваться, строки валиться перестанут
кстати, может эту идею использовать? запустить tail на каждый датчик(создать лог для каждого датчика), и если инфа перестанет поступать - рестарт?> Рестарт программы перезапустит все датчики? И рабочие и зависшие?
рестарт программы перезапустит все датчики
> Если просто отслеживать на появление новой строки, и если её (строки) нет,
> будет ли это означать что все датчики дали сбой или какой-то один?скорее это будет означать что программа не запущена, т.к. она постоянно валит всякую инфу в лог
кстати, если это важно, лог пишется до размера 512кб, потом обнуляется, а старый лог попадает в dev.log.1
> Если 5 датчиков нормально пишут, а шестой завис и не пишет, тогда
> как?
> то есть, новая строка от рабочих датчиков будет писаться и скрипт не
> перезапустит программу.да, по обновлению файла - не выход
> проверять все шесть последних строк? а они от всех разных датчиков?
> короче, дохрена неизвестных, одни вопросы..быть может, проверять некоторое количество последних строк (видимо количество придется определить опытным путем), если они содержат слова "power_1", "power_2" и т.п., то все ок, если одно или несколько слов перестало появляться - рестарт?
вобщем, суть в том, что если отвалился например power_1, то строки с его участием просто перестают добавляться в лог
Ну, попробуйте эту незамысловатую конструкцию
#!/usr/bin/perluse IO::Handle;
my $file = "/tmp/file.txt";
my $prgr = "/tmp/restart.sh";
my $time = 10;open FH, $file or die "can't update $file: $!";
while(1) {
sleep $time;
my %pow;while(<FH>) {
chomp;
if (/power_1/) {$pow{"p1"} = 1 if !exists($pow{"p1"});}
if (/power_2/) {$pow{"p2"} = 2 if !exists($pow{"p2"});}
if (/power_3/) {$pow{"p3"} = 3 if !exists($pow{"p3"});}
if (/power_4/) {$pow{"p4"} = 4 if !exists($pow{"p4"});}
if (/power_5/) {$pow{"p5"} = 5 if !exists($pow{"p5"});}
if (/power_6/) {$pow{"p6"} = 6 if !exists($pow{"p6"});}
}system $prgr if scalar keys %pow < 6;
FH->clearerr();
}
Это, конечно, упрощённый вариант.
Он не учитывает особенности смены лог-файла. Пробуйте.
Как скрипт себя поведёт я не знаю.
Надо делать проверку на существование лог-файла и/или его размера.
Форкать скрипт или перезапускать его.
благодарю! к сожалению вчера не успел попробовать, надеюсь сегодня получится
> благодарю! к сожалению вчера не успел попробовать, надеюсь сегодня получитсяВот, попробуйте боле-менее рабочий вариант.
#!/usr/bin/perluse strict;
use warnings;
use IO::Handle;my $file = "/tmp/file.txt"; # путь к лог-файлу
my $prgr = "/tmp/restart.sh"; # путь к скрипту перезапуска
my $time = 10; # время тайм-аутаopen FH, $file or die "can't update $file: $!";
# бесконечный цикл, взлетаем ))
while(1) {
# засыпаем на время ожидания
sleep $time;# объявляем хеш %power, где отмечаем появление нужных строк
my %pow;# объявляем массив @size, куда записываем размер файла $file
my @size;# если первый элемента массива @size не существует,
# то записываем в первый элемент массива @size первоночальный размер файла $file
$size[0] = -s $file if not $size[0];
my $start_size = $size[0];# записываем в переменную $next_size текущий размер файла $file в последующем цикле
my $next_size = -s $file;# если файл $file был перемещён в $file.1 и открыт заново, то стартовый размер файла
# будет больше, чем текущий размер, если это так - очищаем массив @size и хеш %pow
if ($start_size gt $next_size) {@size=(); %pow=();}# в цикле просматриваем каждую строку, если встретилась нужная строка,
# то заносим значение в элемент хеша %pow если этого элемента хеша прежде ещё не существовало
while(<FH>) {
chomp;
if (/power_1/) {$pow{"p1"} = 1 if !exists($pow{"p1"});}
if (/power_2/) {$pow{"p2"} = 2 if !exists($pow{"p2"});}
if (/power_3/) {$pow{"p3"} = 3 if !exists($pow{"p3"});}
if (/power_4/) {$pow{"p4"} = 4 if !exists($pow{"p4"});}
if (/power_5/) {$pow{"p5"} = 5 if !exists($pow{"p5"});}
if (/power_6/) {$pow{"p6"} = 6 if !exists($pow{"p6"});}
}# проверяем количество элементов хеша %pow, если общее количество меньше 6,
# то через системный вызов запускаем скрипт рестарта программы
my $n = scalar keys %pow;
system $prgr if $n lt 6;# сбрасываем флаг ошибки ввода/вывода
FH->clearerr();
}
# всё, уходим на следующий круг ))
Синтетический тест вроде проходит и работает.
запустил скрипт, на отсутствие строк реагирует!
перезапускает прогу, и это супер!
и после этого начинает постоянно ее перезапускать
может быть перезапускать скрипт следом за прогой?
кстати, скрипт ведь смотрит на последние строки лога? или в каждом проходе цикла ищет по всему файлу?
и еще, после ротации лога - перезапускает бесконечно
видимо перестает видеть файл
>> запустил скрипт, на отсутствие строк реагирует!
>> перезапускает прогу, и это супер!
>> и после этого начинает постоянно ее перезапускать
>> может быть перезапускать скрипт следом за прогой?
>> кстати, скрипт ведь смотрит на последние строки лога?
>> или в каждом проходе цикла ищет по всему файлу?.
> и еще, после ротации лога - перезапускает бесконечно
> видимо перестает видеть файлДа, смотрит последние строки, попавшие в лог-файл в течение последнего тайм-аута - 10 секунд.
Да, это происходит из-за разрыва связи между файловым дескриптором и открытым файловым манипулятором.
Прежний файл file перемещается в file.1, то есть, фактически копируется в file.1 а затем, сам file удаляется.
После этого создаётся новый файл file, куда и происходит запись событий от датчиков.
То есть сам файл фактически новый.Ну и по этому код выше не работает. Надо делать HUP скрипту, чтобы он перечитал входные параметры и
опять связал открытый файловый манипулятор с файловым дескриптором, т.е. фактически рестартовать скрипт.Вопрос в том, как точно определить, что открыт новый лог-файл?
В perl'е не нашёл.
Нужно определить время создания файла, но всякие там atime, mtime, ctime не подходят.
Нужно именно, так сказать, время рождения inodeПришлось использовать системный stat
Надеюсь он у вас есть.
#!/usr/bin/perluse strict;
use warnings;my $file = "/tmp/file.txt"; # путь к лог-файлу
my $prgr = "/tmp/restart.sh"; # путь к скрипту перезапуска
my $time = 10; # время тайм-аутаmy @ctime; # массив, куда пишем время создания файла
my $create_time_file; # переменная в формате unixtime# весьма сомнительно!!!
# бесконечный цикл, в котором тупо ждём рождения файла
# погоды у моря можно ждать очень долго, на свой страх и риск ))
for(;;) { if (!-e $file) {sleep 1; next;} else {last;} }# открываем файловый манипулятор
open FH, $file or die "can't update $file: $!";# бесконечный цикл, взлетаем ))
while(1) {
# засыпаем на время ожидания
sleep $time;# если лог-файл существует, то записываем в переменную время его создания
if(-e $file) {$create_time_file = `/usr/bin/stat -f "%B" $file`+0;}# объявляем хеш %pow, где отмечаем появление нужных строк
my %pow;# заносим в массив время создания файла, если его (времени создания) в массиве
# ещё до этого не было, то есть это произойдёт один раз при прохождении первого цикла
$ctime[0] = $create_time_file if !exists($ctime[0]);# если время создания файла из массива вдруг стало меньше, чем текущее время создания файла
# это означает, что старый файл был перемещен в file.1 и был создан и открыт новый файл $file
# и следовательно, нужно сделать HUP, перезапустить наш скрипт - рестартимся
if ($ctime[0] < $create_time_file) {exec $0;}# в цикле просматриваем каждую строку, если встретилась нужная строка,
# то заносим значение в элемент хеша %pow если этого элемента хеша прежде ещё не существовало
while(<FH>) {
chomp;
if (/power_1/) {$pow{"p1"} = 1 if !exists($pow{"p1"});}
if (/power_2/) {$pow{"p2"} = 2 if !exists($pow{"p2"});}
if (/power_3/) {$pow{"p3"} = 3 if !exists($pow{"p3"});}
if (/power_4/) {$pow{"p4"} = 4 if !exists($pow{"p4"});}
if (/power_5/) {$pow{"p5"} = 5 if !exists($pow{"p5"});}
if (/power_6/) {$pow{"p6"} = 6 if !exists($pow{"p6"});}
}# проверяем количество элементов хеша %pow, если общее количество меньше 6,
# то через системный вызов запускаем скрипт рестарта программы
my $n = scalar keys %pow;system $prgr if $n < 6;
# сбрасываем флаг ошибки ввода/вывода
seek(FH,0,1);
}
# всё, уходим на следующий круг ))
Наверное, можно попытаться привязаться к размеру файла.
Отслеживать изменение его размера, но по времени надёжнее.
stat есть, сегодня очень постараюсь протестировать. очень благодарен!
да! вроде бы все работает четко. пока обкатываю.
а корректно делать fork() && exit; чтобы "демонизировать" скрипт?
> да! вроде бы все работает четко. пока обкатываю.
> а корректно делать fork() && exit; чтобы "демонизировать" скрипт?так просто к скрипту амперсанд добавьте ./script.pl &
и он уйдёт в сумрак, то бишь в фон ))
точно, так и сделал, работает. теперь осталось замерить максимальный аптайм )))
> теперь осталось замерить максимальный аптайм )))так пока хост keepalive, т.е пока жив, там скрипт прост как три рубля,
да ещё и висит и ждёт пока файл родится, так что пока kill его или reboot не прибьёт будет житькстати, после перезагрузки хоста или старта программы для датчиков, по-хорошему нужно
обеспечить автостарт, ну не будете же вы его ручками каждый раз запускать
> так пока хост keepalive, т.е пока жив, там скрипт прост как три
> рубля,
> да ещё и висит и ждёт пока файл родится, так что пока
> kill его или reboot не прибьёт будет житьага, понял
> кстати, после перезагрузки хоста или старта программы для датчиков, по-хорошему нужно
> обеспечить автостарт, ну не будете же вы его ручками каждый раз запускатья думаю в start.sh (скрипт, запускающий программу) его добавить
и по-хорошему, в stop.sh надо добавить kill. надо сохранить pid скрипта в отдельный файл, и kill вызывать с ним?кстати, уже нарастил до 9 сенсоров, все гуд, пропадания отрабатывает
>[оверквотинг удален]
>> рубля,
>> да ещё и висит и ждёт пока файл родится, так что пока
>> kill его или reboot не прибьёт будет жить
> ага, понял
>> кстати, после перезагрузки хоста или старта программы для датчиков, по-хорошему нужно
>> обеспечить автостарт, ну не будете же вы его ручками каждый раз запускать
> я думаю в start.sh (скрипт, запускающий программу) его добавить
> и по-хорошему, в stop.sh надо добавить kill. надо сохранить pid скрипта в
> отдельный файл, и kill вызывать с ним?
> кстати, уже нарастил до 9 сенсоров, все гуд, пропадания отрабатываетможно добавить после
use strict;
use warnings;следующее:
my $pid = $$;
my $pidfile = "/var/run/checker.pid";if ($pid) {
open PIDFILE, ">", $pidfile or die "can't write to $pidfile: $!";
print PIDFILE "$pid\n";
close PIDFILE;
}это позволит килять скрипт по pid'у
в продолжении, сразу скажу, с яблоками дел не имел,
поэтому, как там дела обстоят со старт/стоп скриптами и где они находятся - я не знаю.но, предположу, что можно запустить сразу программу и скрипт отслеживания,
причём последний в зависимости от успешного старта самой программы
типа этого
/usr/local/bin/myprograms && /usr/local/bin/checker.pl &т.е. если программа стартовала успешно, то и скрипт подтянется за ней,
если нет - то он даже и не дёрнется.разумеется, никто не мешает и не запрещает стартовать их не вместе, а порознь,
но это дело вкуса и т.д.прихлопнуть (учитывая добавленные строки в скрипт выше) можно будет так
kill `cat /var/run/checker.pid`/var/run/checker.pid путь и файл, где хранится pid запущенного скрипта.
извиняюсь за долгое молчание, только что руки дошли
да, все так и сделал, все работает
даже не знаю, как отблагодарить?
> извиняюсь за долгое молчание, только что руки дошли
> да, все так и сделал, все работает
> даже не знаю, как отблагодарить?Да, ладно!.. Делай добро и бросай его в воду!
Мультик такой помнишь? ))Хорошо, что работает. Замечательно, что скрипт помог и пригодился, но я же не windows изобрёл!
> Да, ладно!.. Делай добро и бросай его в воду!
> Мультик такой помнишь? ))да, это бессмертный шедевр, наряду с синим морем ))
> Хорошо, что работает. Замечательно, что скрипт помог и пригодился, но я же
> не windows изобрёл!кстати всплыла одна неприятность
не знаю почему, но эта прога иногда очень долго стартует. сегодня первый раз с таким столкнулся
соответственно, если она стартует дольше таймаута в скрипте, он ее прибивает и все начинается по-новой
можно с этим что-нибудь сделать?
признак того, что прога стартовала - начинают валиться строки в dev.log
>[оверквотинг удален]
> да, это бессмертный шедевр, наряду с синим морем ))
>> Хорошо, что работает. Замечательно, что скрипт помог и пригодился, но я же
>> не windows изобрёл!
> кстати всплыла одна неприятность
> не знаю почему, но эта прога иногда очень долго стартует. сегодня первый
> раз с таким столкнулся
> соответственно, если она стартует дольше таймаута в скрипте, он ее прибивает и
> все начинается по-новой
> можно с этим что-нибудь сделать?
> признак того, что прога стартовала - начинают валиться строки в dev.log1. Попробовать стартовать скрипт в зависимости от успешного старта программы,
где-то было выше
/usr/local/bin/myprogram start && /usr/local/bin/checker.pl &2. Если после старта программы создаётся pid-файл программы (ну и соответственно, он должен и корректно удаляться после её завершения),
то можно в скрипт добавить условие проверки существования этого pid-файла.
> 1. Попробовать стартовать скрипт в зависимости от успешного старта программы,
> где-то было выше
> /usr/local/bin/myprogram start && /usr/local/bin/checker.pl &наверно некорректно выразился. программа запускается, но получается большой промежуток между ее запуском и началом опроса датчиков. то есть с точки зрения консоли она стартовала. соответственно и скрипт следом пускается
> 2. Если после старта программы создаётся pid-файл программы (ну и соответственно, он
> должен и корректно удаляться после её завершения),
> то можно в скрипт добавить условие проверки существования этого pid-файла.пид есть. но он после остановки проги не удаляется сам, только если в скрипте остановки это дописать
но опять же, она стартует и долго тупит, пока опрос датчиков не начнет. странная канитель. может комп тупит, такого раньше не было... но раз прецендент произошел, значит может произойти еще, в любое время. все-таки хотелось бы учесть это
>[оверквотинг удален]
> зрения консоли она стартовала. соответственно и скрипт следом пускается
>> 2. Если после старта программы создаётся pid-файл программы (ну и соответственно, он
>> должен и корректно удаляться после её завершения),
>> то можно в скрипт добавить условие проверки существования этого pid-файла.
> пид есть. но он после остановки проги не удаляется сам, только если
> в скрипте остановки это дописать
> но опять же, она стартует и долго тупит, пока опрос датчиков не
> начнет. странная канитель. может комп тупит, такого раньше не было... но
> раз прецендент произошел, значит может произойти еще, в любое время. все-таки
> хотелось бы учесть этоТогда переписать начало скрипта так
#!/usr/bin/perl
use strict;
use warnings;my $file = "/tmp/file.txt"; # путь к лог-файлу
my $prgr = "/tmp/restart.sh"; # путь к скрипту перезапуска
my $time = 10; # время тайм-аутаmy @ctime; # массив, куда пишем время создания файла
my $create_time_file; # переменная в формате unixtime# весьма сомнительно!!!
# бесконечный цикл, в котором тупо ждём рождения файла
# погоды у моря можно ждать очень долго, на свой страх и риск ))
for(;;) { if (!-e $file) {sleep 1; next;} else {last;} }# если $file определён, то узнаём и заносим в переменную стартовый размер этого файла
my $start_size_file = -s $file if defined $file;# если стартовый размер файла определён и равен текущему размеру этого же файла, ждём 1 сек и проверяем снова
# если размеры файла не равны (а он должен стать меньше текущего), то выходим из бесконечного цикла и делаем вещи ))
for(;;) { if (defined $start_size_file == defined -s $file) {sleep 1; next;} else {last;} }# открываем фаловый хендлер
open FH, $file or die "can't update $file: $!";# бесконечный цикл, взлетаем ))
while(1) {
# засыпаем на время ожидания
sleep $time;#################
пожирненым - добавленный кусок
теперь не реагирует на пропадания строк (((
и опять я лоханулся, все-таки при такой ситуации она иногда вываливает несколько строк служебной инфы в лог и потом висит несколько минут до начала нормальной работы
так что, как это отследить пока не знаю
жаль здравой альтернативы этой проге нет, приходится бороться с глюками :(
> теперь не реагирует на пропадания строк (((
> и опять я лоханулся, все-таки при такой ситуации она иногда вываливает несколько
> строк служебной инфы в лог и потом висит несколько минут до
> начала нормальной работы
> так что, как это отследить пока не знаю
> жаль здравой альтернативы этой проге нет, приходится бороться с глюками :(Дайте первую нормальную строку после вывода служебной информации,
служебная информация всегда одна и та же, первая нормальная (рабочая) строка всегда одинаковая?Приведите и хвост служебной информации на всякий случай.
sh-3.2# cat /dev/null > dev.log
sh-3.2# tail -F dev.log
2014-03-19 12:38:11,078 INFO [main]: Initialized JUL to LOG4J Redirector.
2014-03-19 12:38:11,081 INFO [main]: Programmatically set 'useParentHandlers=false' in 'OpenRemote.Controller' log category.
2014-03-19 12:38:12,214 DEBUG [main]: Adding shutdown hook to manage unclosed DSC connections in case of controller exit.
2014-03-19 12:38:12,381 INFO [Controller Auto-Discovery]: Created IP discover multicast server !
2014-03-19 12:38:12,382 INFO [Controller Auto-Discovery]: Joined a group : 224.0.1.100:3333
2014-03-19 12:38:12,383 INFO [Controller Auto-Discovery]: Listening on 224.0.1.100:3333
2014-03-19 12:38:12,390 INFO [Cluster UDP]: UDP Server : Starting UDP server...
2014-03-19 12:38:12,391 INFO [Cluster UDP]: UDP Server : Started UDP server successfully.
2014-03-19 12:38:12,405 INFO [Cluster TCP]: TCP Server : starting for receiving groupmember urls...
2014-03-19 12:38:12,405 INFO [Cluster TCP]: TCP Server : started successfully for receiving groupmember urls...
2014-03-19 12:38:12,405 INFO [Cluster TCP]: TCP Server : Waiting for groupmember response...
2014-03-19 12:38:12,421 INFO [main]:--------------------------------------------------------------------
DEPLOYING NEW CONTROLLER RUNTIME...
--------------------------------------------------------------------
эти строки всегда одинаковые, кроме дат и времени конечно. дальше идут строки датчиков. либо не идут, если долгий старт как вчера. с этим разобрался: заглючил один из сетевых контроллеров, который опрашивала прога, ждала от него ответа, до истечения таймаута
> --------------------------------------------------------------------
> DEPLOYING NEW CONTROLLER RUNTIME...
> --------------------------------------------------------------------
> эти строки всегда одинаковые, кроме дат и времени конечно. дальше идут строки
> датчиков. либо не идут, если долгий старт как вчера. с этим
> разобрался: заглючил один из сетевых контроллеров, который опрашивала прога, ждала от
> него ответа, до истечения таймаутаВместо пожирненного из поста #24 (http://www.opennet.me/openforum/vsluhforumID9/9834.html#24)
добавить# если 3 последние строки файла $file эквивалентны заданным, то ждём 1 сек. и повторяем проверку условия,
# если ложно - вываливаемся из бесконечного цикла и двигаемся дальше
for(;;) { if(`/usr/bin/tail -3 $file` eq "DEPLOYING NEW CONTROLLER RUNTIME...\n\n--------------------------------------------------------------------\n")
{sleep 1; next;} else {last;}
}Убедитесь что в конце в файле (три последние строки) при зависоне действительно
DEPLOYING NEW CONTROLLER RUNTIME...
--------------------------------------------------------------------
то есть должно абсолютно всё совпадать
текст, в конце его три точки, перевод строки, перевод строки, определённое количество тире, перевод строки
как бы не спугнуть, но вроде бы всё работает. сымитировал ситуации - пропадание строки и долгий старт, отрабатывает
> как бы не спугнуть, но вроде бы всё работает. сымитировал ситуации -
> пропадание строки и долгий старт, отрабатываетА чё в МакОСи inotify не изобрели?
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for strerror() */
#include <unistd.h>/* function prototypes */
void diep(const char *s);int main(void)
{
struct kevent change; /* event we want to monitor */
struct kevent event; /* event that was triggered */
pid_t pid;
int kq, nev;/* create a new kernel event queue */
if ((kq = kqueue()) == -1)
diep("kqueue()");/* initalise kevent structure */
EV_SET(&change, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 5000, 0);/* loop forever */
for (;;) {
nev = kevent(kq, &change, 1, &event, 1, NULL);if (nev < 0)
diep("kevent()");else if (nev > 0) {
if (event.flags & EV_ERROR) { /* report any error */
fprintf(stderr, "EV_ERROR: %s\n", strerror(event.data));
exit(EXIT_FAILURE);
}if ((pid = fork()) < 0) /* fork error */
diep("fork()");else if (pid == 0) /* child */
if (execlp("date", "date", (char *)0) < 0)
diep("execlp()");
}
}close(kq);
return EXIT_SUCCESS;
}void diep(const char *s)
{
perror(s);
exit(EXIT_FAILURE);
}