The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Рестартовать программу, если в лог не пишутся нужные строки"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Shell скрипты)
Изначальное сообщение [ Отслеживать ]

"Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 03-Мрт-14, 15:30 
Здравствуйте!
Есть программа, собирающая информацию с датчиков. Опрос всех датчиков (на данный момент 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
Буду очень благодарен за помощь

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от reader (ok) on 03-Мрт-14, 16:37 
>[оверквотинг удален]
> всегда это сопровождается сообщениями со словом ERROR в логе, я ловлю
> это monit-ом и программа перезапускается с его помощью. Но в 10%
> случаев опрос прекращается молча, без ERROR-ов и тому подобного, и тут
> monit оказывается бессилен. Единственный способ это отследить - перестает писаться строка,
> относящаяся к отвалившемуся датчику.
> Можно ли написать скрипт, который будет делать tail -F dev.log | grep
> TRACE, и если в течение, например, 10 секунд не появилась каждая
> из заданных 6 строк, делать ./restart.sh ?
> Система - OSX 10.9
> Буду очень благодарен за помощь

сохраняете последнюю строку от датчика на ram-диск и через 10 сек сравниваете, сошлась значит висит, не сошлась - обнавляете строку

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 04-Мрт-14, 15:29 
> сохраняете последнюю строку от датчика на ram-диск и через 10 сек сравниваете,
> сошлась значит висит, не сошлась - обнавляете строку

я тут мало чего понял, т.к. совсем не программист. Вы могли бы это реализовать? я бы в долгу не остался. на всякий случай мой маил alexey_and(-на-)mail.ru

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 04-Мрт-14, 21:10 
>[оверквотинг удален]
> всегда это сопровождается сообщениями со словом 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 датчиков нормально пишут, а шестой завис и не пишет, тогда как?
то есть, новая строка от рабочих датчиков будет писаться и скрипт не перезапустит программу.

проверять все шесть последних строк? а они от всех разных датчиков?
короче, дохрена неизвестных, одни вопросы..

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

4. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 04-Мрт-14, 21:57 
> Не совсем понял.
> Все датчики пишут в один лог-файл?
> Шесть датчиков формируют шесть строк?

да, все датчики пишут в один файл
каждый датчик формирует несколько строк - получение, обработка, значение. плюс куча инфы от самой программы. поэтому я не вижу другого пути кроме фильтрации по паттерну "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, то строки с его участием просто перестают добавляться в лог

Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

5. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 05-Мрт-14, 15:12 
Ну, попробуйте эту незамысловатую конструкцию

#!/usr/bin/perl

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;
    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();
}


Это, конечно, упрощённый вариант.
Он не учитывает особенности смены лог-файла. Пробуйте.
Как скрипт себя поведёт я не знаю.
Надо делать проверку на существование лог-файла и/или его размера.
Форкать скрипт или перезапускать его.
Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 06-Мрт-14, 13:07 
благодарю! к сожалению вчера не успел попробовать, надеюсь сегодня получится
Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

7. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 06-Мрт-14, 14:08 
> благодарю! к сожалению вчера не успел попробовать, надеюсь сегодня получится

Вот, попробуйте боле-менее рабочий вариант.


#!/usr/bin/perl

use 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();
}
# всё, уходим на следующий круг ))


Синтетический тест вроде проходит и работает.
Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 07-Мрт-14, 23:47 
запустил скрипт, на отсутствие строк реагирует!
перезапускает прогу, и это супер!
и после этого начинает постоянно ее перезапускать
может быть перезапускать скрипт следом за прогой?
кстати, скрипт ведь смотрит на последние строки лога? или в каждом проходе цикла ищет по всему файлу?
Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

9. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 08-Мрт-14, 01:26 
и еще, после ротации лога - перезапускает бесконечно
видимо перестает видеть файл
Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

10. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 11-Мрт-14, 14:53 
>> запустил скрипт, на отсутствие строк реагирует!
>> перезапускает прогу, и это супер!
>> и после этого начинает постоянно ее перезапускать
>> может быть перезапускать скрипт следом за прогой?
>> кстати, скрипт ведь смотрит на последние строки лога?
>> или в каждом проходе цикла ищет по всему файлу?

.
> и еще, после ротации лога - перезапускает бесконечно
> видимо перестает видеть файл

Да, смотрит последние строки, попавшие в лог-файл в течение последнего тайм-аута - 10 секунд.
Да, это происходит из-за разрыва связи между файловым дескриптором и открытым файловым манипулятором.
Прежний файл file перемещается в file.1, то есть, фактически копируется в file.1 а затем, сам file удаляется.
После этого создаётся новый файл file, куда и происходит запись событий от датчиков.
То есть сам файл фактически новый.

Ну и по этому код выше не работает. Надо делать HUP скрипту, чтобы он перечитал входные параметры и
опять связал открытый файловый манипулятор с файловым дескриптором, т.е. фактически рестартовать скрипт.

Вопрос в том, как точно определить, что открыт новый лог-файл?
В perl'е не нашёл.
Нужно определить время создания файла, но всякие там atime, mtime, ctime не подходят.
Нужно именно, так сказать, время рождения inode

Пришлось использовать системный stat
Надеюсь он у вас есть.


#!/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;} }

# открываем файловый манипулятор
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);
}
# всё, уходим на следующий круг ))


Наверное, можно попытаться привязаться к размеру файла.
Отслеживать изменение его размера, но по времени надёжнее.

Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

11. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 11-Мрт-14, 15:10 
stat есть, сегодня очень постараюсь протестировать. очень благодарен!
Ответить | Правка | ^ к родителю #10 | Наверх | Cообщить модератору

12. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 13-Мрт-14, 00:51 
да! вроде бы все работает четко. пока обкатываю.
а корректно делать fork() && exit; чтобы "демонизировать" скрипт?
Ответить | Правка | ^ к родителю #11 | Наверх | Cообщить модератору

13. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 13-Мрт-14, 06:19 
> да! вроде бы все работает четко. пока обкатываю.
> а корректно делать fork() && exit; чтобы "демонизировать" скрипт?

так просто к скрипту амперсанд добавьте ./script.pl &
и он уйдёт в сумрак, то бишь в фон ))

Ответить | Правка | ^ к родителю #12 | Наверх | Cообщить модератору

14. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 13-Мрт-14, 12:47 
точно, так и сделал, работает. теперь осталось замерить максимальный аптайм )))
Ответить | Правка | ^ к родителю #13 | Наверх | Cообщить модератору

15. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 13-Мрт-14, 13:38 
> теперь осталось замерить максимальный аптайм )))

так пока хост keepalive, т.е пока жив, там скрипт прост как три рубля,
да ещё и висит и ждёт пока файл родится, так что пока kill его или reboot не прибьёт будет жить

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

Ответить | Правка | ^ к родителю #14 | Наверх | Cообщить модератору

16. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 13-Мрт-14, 14:42 
> так пока хост keepalive, т.е пока жив, там скрипт прост как три
> рубля,
> да ещё и висит и ждёт пока файл родится, так что пока
> kill его или reboot не прибьёт будет жить

ага, понял

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

я думаю в start.sh (скрипт, запускающий программу) его добавить
и по-хорошему, в stop.sh надо добавить kill. надо сохранить pid скрипта в отдельный файл, и kill вызывать с ним?

кстати, уже нарастил до 9 сенсоров, все гуд, пропадания отрабатывает

Ответить | Правка | ^ к родителю #15 | Наверх | Cообщить модератору

17. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 13-Мрт-14, 17:24 
>[оверквотинг удален]
>> рубля,
>> да ещё и висит и ждёт пока файл родится, так что пока
>> 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'у

Ответить | Правка | ^ к родителю #16 | Наверх | Cообщить модератору

18. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 13-Мрт-14, 20:01 
в продолжении, сразу скажу, с яблоками дел не имел,
поэтому, как там дела обстоят со старт/стоп скриптами и где они находятся - я не знаю.

но, предположу, что можно запустить сразу программу и скрипт отслеживания,
причём последний в зависимости от успешного старта самой программы
типа этого
/usr/local/bin/myprograms && /usr/local/bin/checker.pl &

т.е. если программа стартовала успешно, то и скрипт подтянется за ней,
если нет - то он даже и не дёрнется.

разумеется, никто не мешает и не запрещает стартовать их не вместе, а порознь,
но это дело вкуса и т.д.

прихлопнуть (учитывая добавленные строки в скрипт выше) можно будет так
kill `cat /var/run/checker.pid`

/var/run/checker.pid путь и файл, где хранится pid запущенного скрипта.


Ответить | Правка | ^ к родителю #16 | Наверх | Cообщить модератору

19. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 17-Мрт-14, 01:50 
извиняюсь за долгое молчание, только что руки дошли
да, все так и сделал, все работает
даже не знаю, как отблагодарить?
Ответить | Правка | ^ к родителю #18 | Наверх | Cообщить модератору

20. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 17-Мрт-14, 05:59 
> извиняюсь за долгое молчание, только что руки дошли
> да, все так и сделал, все работает
> даже не знаю, как отблагодарить?

Да, ладно!.. Делай добро и бросай его в воду!
Мультик такой помнишь? ))

Хорошо, что работает. Замечательно, что скрипт помог и пригодился, но я же не windows изобрёл!

Ответить | Правка | ^ к родителю #19 | Наверх | Cообщить модератору

21. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 18-Мрт-14, 15:46 
> Да, ладно!.. Делай добро и бросай его в воду!
> Мультик такой помнишь? ))

да, это бессмертный шедевр, наряду с синим морем ))

> Хорошо, что работает. Замечательно, что скрипт помог и пригодился, но я же
> не windows изобрёл!

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

Ответить | Правка | ^ к родителю #20 | Наверх | Cообщить модератору

22. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 18-Мрт-14, 17:21 
>[оверквотинг удален]
> да, это бессмертный шедевр, наряду с синим морем ))
>> Хорошо, что работает. Замечательно, что скрипт помог и пригодился, но я же
>> не windows изобрёл!
> кстати всплыла одна неприятность
> не знаю почему, но эта прога иногда очень долго стартует. сегодня первый
> раз с таким столкнулся
> соответственно, если она стартует дольше таймаута в скрипте, он ее прибивает и
> все начинается по-новой
> можно с этим что-нибудь сделать?
> признак того, что прога стартовала - начинают валиться строки в dev.log

1. Попробовать стартовать скрипт в зависимости от успешного старта программы,
где-то было выше
/usr/local/bin/myprogram start && /usr/local/bin/checker.pl &

2. Если после старта программы создаётся pid-файл программы (ну и соответственно, он должен и корректно удаляться после её завершения),
то можно в скрипт добавить условие проверки существования этого pid-файла.

Ответить | Правка | ^ к родителю #21 | Наверх | Cообщить модератору

23. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 18-Мрт-14, 17:31 
> 1. Попробовать стартовать скрипт в зависимости от успешного старта программы,
> где-то было выше
> /usr/local/bin/myprogram start && /usr/local/bin/checker.pl &

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

> 2. Если после старта программы создаётся pid-файл программы (ну и соответственно, он
> должен и корректно удаляться после её завершения),
> то можно в скрипт добавить условие проверки существования этого pid-файла.

пид есть. но он после остановки проги не удаляется сам, только если в скрипте остановки это дописать

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

Ответить | Правка | ^ к родителю #22 | Наверх | Cообщить модератору

24. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 18-Мрт-14, 18:22 
>[оверквотинг удален]
> зрения консоли она стартовала. соответственно и скрипт следом пускается
>> 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;

#################
пожирненым - добавленный кусок

Ответить | Правка | ^ к родителю #23 | Наверх | Cообщить модератору

25. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 19-Мрт-14, 03:11 
теперь не реагирует на пропадания строк (((
и опять я лоханулся, все-таки при такой ситуации она иногда вываливает несколько строк служебной инфы в лог и потом висит несколько минут до начала нормальной работы
так что, как это отследить пока не знаю
жаль здравой альтернативы этой проге нет, приходится бороться с глюками :(
Ответить | Правка | ^ к родителю #24 | Наверх | Cообщить модератору

26. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 19-Мрт-14, 05:19 
> теперь не реагирует на пропадания строк (((
> и опять я лоханулся, все-таки при такой ситуации она иногда вываливает несколько
> строк служебной инфы в лог и потом висит несколько минут до
> начала нормальной работы
> так что, как это отследить пока не знаю
> жаль здравой альтернативы этой проге нет, приходится бороться с глюками :(

Дайте первую нормальную строку после вывода служебной информации,
служебная информация всегда одна и та же, первая нормальная (рабочая) строка всегда одинаковая?

Приведите и хвост служебной информации на всякий случай.

Ответить | Правка | ^ к родителю #25 | Наверх | Cообщить модератору

27. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 19-Мрт-14, 12:44 
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...

--------------------------------------------------------------------

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


Ответить | Правка | ^ к родителю #26 | Наверх | Cообщить модератору

28. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от михалыч (ok) on 19-Мрт-14, 16:19 
> --------------------------------------------------------------------
>   DEPLOYING NEW CONTROLLER RUNTIME...
> --------------------------------------------------------------------
> эти строки всегда одинаковые, кроме дат и времени конечно. дальше идут строки
> датчиков. либо не идут, если долгий старт как вчера. с этим
> разобрался: заглючил один из сетевых контроллеров, который опрашивала прога, ждала от
> него ответа, до истечения таймаута

Вместо пожирненного из поста #24 (https://www.opennet.ru/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...

--------------------------------------------------------------------

то есть должно абсолютно всё совпадать
текст, в конце его три точки, перевод строки, перевод строки, определённое количество тире, перевод строки

Ответить | Правка | ^ к родителю #27 | Наверх | Cообщить модератору

29. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от alexey_and (ok) on 20-Мрт-14, 01:43 
как бы не спугнуть, но вроде бы всё работает. сымитировал ситуации - пропадание строки и долгий старт, отрабатывает
Ответить | Правка | ^ к родителю #28 | Наверх | Cообщить модератору

30. "Рестартовать программу, если в лог не пишутся нужные строки"  +/
Сообщение от pavlinux (ok) on 23-Мрт-14, 06:03 
> как бы не спугнуть, но вроде бы всё работает. сымитировал ситуации -
> пропадание строки и долгий старт, отрабатывает

А чё в МакОСи 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);
}


Ответить | Правка | ^ к родителю #29 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру