2016-12-18 15 views
3

Я делаю некоторые эксперименты с моей операционной системой Linux (CentOS), и я хочу отслеживать все журналы инструментов, созданные в одной и той же среде, инструмент генерирует соответствующие журналы (.log extn) для отслеживания этих изменений. Я написал наблюдателя perl, который фактически контролирует каталог, который я установил, и когда новый файл будет создан, он будет отображаться на выходе, но это потребляет много памяти и использования ЦП, так как я установил 2сек в качестве периода ожидания.Как получить имя файла вместе с абсолютным путем к файлу, всякий раз, когда новый файл создается с использованием inode в Linux?

МОЙ ВОПРОС «Есть ли способ сделать это?» Я думал об использовании таблицы inode для отслеживания всех изменений в системе. может ли это решить мою проблему? и если да, то может, пожалуйста, сообщите нам об этом решение?

+0

zdim, это здорово услышать об этих модулях. Vikas, не уверен, что вы ищете общий монитор файловой системы, который предлагает zdim. Если вы можете поделиться своим кодом Perl, возможно, мы сможем понять, почему он потребляет столько памяти и процессора. – codeforester

ответ

9

Кажется, что вы хотите контролировать каталог изменений. Это сложная работа, но для которой есть хорошие модули. Проще всего рекомендовать, вероятно, Linux::Inotify2

Этот модуль реализует интерфейс для Linux 2.6.13 и более поздних версий. Система уведомлений об изменении файла/каталога Inotify.

Это похоже на то, что вы хотели.

Любой такой монитор нуждается в дополнительной обработке событий. В этом примере используется AnyEvent.

use warnings; 
use strict; 
use feature 'say'; 

use AnyEvent; 
use Linux::Inotify2; 

my $dir = 'dir_to_watch'; 

my $inotify = new Linux::Inotify2 or die "Can't create inotify object: $!"; 

$inotify->watch($dir, IN_MODIFY | IN_CREATE, sub { 
    my $e = shift; 
    my $name = $e->fullname; 
    say "$name modified" if $e->IN_MODIFY; # Both show the new file 
    say "$name created" if $e->IN_CREATE; # but see comments below 
}); 

my $inotify_w = AnyEvent->io (
    fh => $inotify->fileno, poll => 'r', cb => sub { $inotify->poll } 
); 

1 while $inotify->poll; 

Если вы только заботиться о новых файлов, то вам нужно всего лишь одну константу выше. Для обоих типов событий у $name есть имя нового файла. Из man inotify на моей системе

... в name поле в возвращаемом inotify_event структуры определяет имя файла в каталоге.

Структура inotify_event представлена ​​в виде объекта Linux::Inotify2::Watcher.

Использование IN_CREATE представляется очевидным решением для вашей цели. Я протестировал, создав два файла, с двумя перенаправленными командами echo, разделенными точкой с запятой в той же командной строке, а также на touch - с файлом. Письменные файлы обнаруживаются как отдельные события, а также файл touch.

Использование IN_MODIFY также может работать, так как он контролирует (в $dir)

... любой объект файловой системы в наблюдаемом объекте (всегда каталог), то есть файлы, каталоги, символические ссылки, узлы устройств и т.д. ...

Как и в случае с испытаниями, оба файла, написанные echo, как указано выше, сообщаются как отдельные события. Но touch -ed файл не сообщил, что данные не изменились (файл не был записан в).

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

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

Некоторые другие важные рамки для программирования, управляемые событиями, - это POE и IO::Async.

File::Monitor выполняет эту работу тоже.

+0

В моем сценарии я использую File :: Monitor для просмотра файлов, но если я запустил свой скрипт более 3 дней, тогда он будет потреблять больше использования ЦП. Я хочу, чтобы мы могли отслеживать индексный дескриптор Linux, чтобы при создании нового индексного дескриптора я мог легко получить имя файла с помощью этого inode. Итак, есть ли способ отслеживать индекс inode –

+0

@vikaschib Спасибо за отзыв! Вот почему я сначала рекомендовал этот модуль_ - он внедряет систему 'inotify', о которой вы и просите. Я бы не рекомендовал делать это вручную (за исключением забавы.) Что касается увеличения использования ЦП ... похоже, что это может быть проблема этого модуля? Я бы предложил: (1) Попробуйте это (2) Можете ли вы запланировать, чтобы сценарий не запускался так долго? Возможно, выйдите и перезапустите (по заданию cron?) (3) Если проблема не устранена, отправьте другой вопрос, так как это что-то еще. – zdim