Как я могу рассматривать много файлов журнала как один виртуальный файл в 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>) {
...
}