URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8957
[ Назад ]

Исходное сообщение
"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"

Отправлено yooo , 08-Дек-10 19:07 
Есть файл в который какой-то демон постояно пишет лог ($log). Я с помощью своего скрипта через pipе (tail -f) присасываюсь к этому лог файлу. Теперь внимание вопрос! как мне моим скриптом отловить переоткрытие $log файла при чтение его через pipe (tail -f). Другими словами мне нужно при неприрывном чтении файла определить, что "ЧТО-ТО" его переоткрыло.


---------- пример моего не работающего кода --------
my $log = /tmp/file.log;

$SIG{PIPE} = sub { undef $ok };
open (PIPE,"tail -f $log |") or die "ERROR: $!\n";
select PIPE; $|=1; select STDOUT;

while ( <FH> ){
    print "$ok => ",$_;
}
print "EXIT \n";


Содержание

Сообщения в этом обсуждении
"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено hizel , 09-Дек-10 10:53 
есть ня File::Tail, во всяком случае mailgraph использует его и

resetafter
The number of seconds after last change when File::Tail decides the file may have been closed and reopened. The default is adjustafter*maxinterval.

есть такой параметр, значит вашу ситуацию обрабатывает


"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено yooo , 09-Дек-10 14:31 
> есть ня File::Tail, во всяком случае mailgraph использует его и
> resetafter
> The number of seconds after last change when File::Tail decides the file
> may have been closed and reopened. The default is adjustafter*maxinterval.
> есть такой параметр, значит вашу ситуацию обрабатывает

Простите возможно за глупый вопрос, но всё же я не понял как мне определить, что файл был переоткрыт? Что мне использовать в качестве ЧТО-ТО (см. код ниже)


------------ код см. условие if () ---------------
use File::Tail;

my $flog = '/var/log/access.log';
my $file=File::Tail->new(name=>$log, adjustafter=>3, maxinterval => 2);

while ( 1 ) {
        if (ЧТО-ТО){
            print "Файл $log был переоткрыт!"
        }

        print $file->read;
        print "[ ",$file," ]\n";
        print "[ ",${$file}{resetafter}," ]\n";
        print "[ ",${$file}{reset_tail}," ]\n";
}



"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено hizel , 09-Дек-10 14:45 
>> есть ня File::Tail, во всяком случае mailgraph использует его и
>> resetafter
>> The number of seconds after last change when File::Tail decides the file
>> may have been closed and reopened. The default is adjustafter*maxinterval.
>> есть такой параметр, значит вашу ситуацию обрабатывает
> Простите возможно за глупый вопрос, но всё же я не понял как
> мне определить, что файл был переоткрыт? Что мне использовать в качестве
> ЧТО-ТО (см. код ниже)

гм, такого нет, подпилить под себя и будет ок


"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено yooo , 09-Дек-10 17:14 
>>> есть ня File::Tail, во всяком случае mailgraph использует его и
>>> resetafter
>>> The number of seconds after last change when File::Tail decides the file
>>> may have been closed and reopened. The default is adjustafter*maxinterval.
>>> есть такой параметр, значит вашу ситуацию обрабатывает
>> Простите возможно за глупый вопрос, но всё же я не понял как
>> мне определить, что файл был переоткрыт? Что мне использовать в качестве
>> ЧТО-ТО (см. код ниже)
> гм, такого нет, подпилить под себя и будет ок

Эх! :( еслиб знал, что пилить. Щас смотрю man на функцию stat, но что-то пока не помогает.
P.S если у вас есть какое либо предложение, то я готов его выслушать :)  


"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено ACCA , 10-Дек-10 23:20 
Сильно зависит от системы. Под Linux есть :

http://search.cpan.org/~twerner/Linux-Inotify-0.05/lib/Linux...
http://search.cpan.org/dist/Linux-Inotify2/Inotify2.pm

Для ядер старее 2.6.13 есть

http://search.cpan.org/~gwyn/POEx-DirNotify/


"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено yooo , 13-Дек-10 19:57 
> Сильно зависит от системы. Под Linux есть :
> http://search.cpan.org/~twerner/Linux-Inotify-0.05/lib/Linux...
> http://search.cpan.org/dist/Linux-Inotify2/Inotify2.pm
> Для ядер старее 2.6.13 есть
> http://search.cpan.org/~gwyn/POEx-DirNotify/

ОС FreeBSD. Спасбо за интересные ссылки.


"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено yooo , 09-Дек-10 17:37 
>>> есть ня File::Tail, во всяком случае mailgraph использует его и
>>> resetafter
>>> The number of seconds after last change when File::Tail decides the file
>>> may have been closed and reopened. The default is adjustafter*maxinterval.
>>> есть такой параметр, значит вашу ситуацию обрабатывает
>> Простите возможно за глупый вопрос, но всё же я не понял как
>> мне определить, что файл был переоткрыт? Что мне использовать в качестве
>> ЧТО-ТО (см. код ниже)
> гм, такого нет, подпилить под себя и будет ок

ЭВРИКА! вроде есть зацепка, нужно следить за INODE (см. функцию stat)


"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено cryo , 13-Дек-10 14:52 
Вы на правильном пути. Только надо было сформулировать вопрос понятнее.

Вам нужно не отловить ситуацию когда один и тот же файл переоткрывается, а когда текущий файл А переименовывается в Б (при этом его inode не меняется и открытые хэндлы продолжают указывать на этот переименованный файл) и вместо него создается новый файл с именем А (logrotate, да? :).

Да, в этой ситуации самое надежное следить за inode файла А.

ваше что-то будет выглядеть как-то так:

my (undef, $inode, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef) =
      stat("А");
if  ($old_inode != $inode) {
  $old_inode = $inode;
  print "Ooop! The file A is recreated!\n";
}

>[оверквотинг удален]
>>>> есть ня File::Tail, во всяком случае mailgraph использует его и
>>>> resetafter
>>>> The number of seconds after last change when File::Tail decides the file
>>>> may have been closed and reopened. The default is adjustafter*maxinterval.
>>>> есть такой параметр, значит вашу ситуацию обрабатывает
>>> Простите возможно за глупый вопрос, но всё же я не понял как
>>> мне определить, что файл был переоткрыт? Что мне использовать в качестве
>>> ЧТО-ТО (см. код ниже)
>> гм, такого нет, подпилить под себя и будет ок
> ЭВРИКА! вроде есть зацепка, нужно следить за INODE (см. функцию stat)


"Perl, open(), pipe. Как поймать сигнал переоткрытия файла ?"
Отправлено yooo , 13-Дек-10 19:55 
> Вы на правильном пути. Только надо было сформулировать вопрос понятнее.
> Вам нужно не отловить ситуацию когда один и тот же файл переоткрывается,
> а когда текущий файл А переименовывается в Б (при этом его
> inode не меняется и открытые хэндлы продолжают указывать на этот переименованный
> файл) и вместо него создается новый файл с именем А (logrotate,
> да? :).

Спасибо за ответ! видно я "криво" выразился, вы правы  мне нужно отловить logrotate :).
P.S мой код получился похожим на ваш :). Еще раз спасибо за подробный ответ.