Как я могу рассматривать много файлов журнала как один виртуальный файл в Perl?

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

access.log.1284642120
access.log.1284687600
access.log.1284843260

По сути, журналы "чередуются" Apache в день, поэтому их можно сортировать по порядку.

Я пытаюсь "читать их один за другим", чтобы их можно было рассматривать как один файл журнала.

my @logs = glob('logs/access.log.*');

Приведенный выше код будет уничтожать все журналы, но я не уверен:

  • В каком порядке будут организованы журналы в алфавитном порядке?
  • если я хочу проверить "последнее время доступа с уникального IP", как я могу это сделать?

У меня есть Perl-скрипт, который может читать один журнал доступа и легко это проверять (мой алгоритм состоит в том, чтобы иметь большой хеш, который использует IP-адрес в качестве ключа и время доступа в качестве значения, и просто продолжать выдавать пары ключ / значение в него...). Но я не хочу просто объединять все файлы доступа в один временный файл только для этого процесса.

Какие-либо предложения? Спасибо заранее.

2 ответа

Решение

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

 my @files = sort { ... } glob( ... );

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

 my @files = sort glob( ... );

Чтобы прочитать их как один über-файл, я хотел бы использовать local @ARGV так что я могу использовать алмазный оператор, который на самом деле просто волшебство ARGV указатель_на_файл. Когда он доходит до конца одного файла в @ARGV, он переходит к следующему. Это подделка, указав все файлы в командной строке, назначив @ARGV внутри программы:

 {
 local @ARGV = sort { ... } glob( ... );

 while( <> ) {
      ...;
      }
 }

Если вам нужно знать файл, который вы сейчас обрабатываете, посмотрите в $ARGV,

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

В среде Unix-y вы можете использовать оболочку для группировки ваших файлов:

my @files = glob("$dir/access.log.*");
open my $one_big_logfile, "-|", "cat @files" or die ...;
while (<$one_big_logfile>) {
   ...
}
Другие вопросы по тегам