Ловушки Perl
Истории-страшилки про Perl-программиста, с подсказками и разоблачениями
Главная
О блоге
Об авторах
Почему?
rss
@perltrapcom
Подписка по email
Администратор захотел подсчитать статистику по access-логу своего веб-сервера (Apache). Статистика: сколько запросов обработаны с тем или иным http-статусом, и сколько байт суммарно было отдано с каждым статусом.
Пример лога:
> head access.log
192.168.0.113 - - [08/Feb/2009:13:10:41 +0300] "GET /Books?v=td3 HTTP/1.1" 200 15600
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "POST /Login HTTP/1.1" 302 182
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /HomePage?cache=517 HTTP/1.1" 200 12987
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /themes/my_tabs/icons/role.gif HTTP/1.1" 200 84
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /themes/my_tabs/icons/key.gif HTTP/1.1" 200 94
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /themes/my_tabs/icons/bookmark.gif HTTP/1.1" 200 144
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /themes/my_tabs/icons/tabr1del.gif HTTP/1.1" 200 572
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /themes/my_tabs/icons/del.gif HTTP/1.1" 200 600
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /themes/my_tabs/icons/tabl1del.gif HTTP/1.1" 200 357
192.168.0.113 - - [08/Feb/2009:13:14:32 +0300] "GET /themes/my_tabs/icons/tabbgdel.gif HTTP/1.1" 200 152
Программа:
#!/usr/bin/perl
my %stat;
while(<>){
/^.*(\d+) (\d+)$/;
$stat{$1}->{count}++;
$stat{$1}->{bytes} += $2;
}
print "$_: $stat{$_}->{count}, $stat{$_}->{bytes} bytes\n" for sort keys %stat;
Все хорошо? Конечно, нет!
Вывод программы оказался примерно таким:
0: 9, 30590 bytes
2: 1, 182 bytes
А хотелось-то примерно такого:
200: 9, 30590 bytes
302: 1, 182 bytes
Квантификатор *
– жадный, поэтому в регулярном выражении ^.*(\d+) (\d+)$
в .*
попадает как можно более длинная строка, в том числе и первые цифры из http-статуса.
Кстати, регулярное выражение
^.*(\d+) (\d+)$
даст осечку еще и на 304-ых статусах:
192.168.0.114 - - [08/Feb/2009:13:06:08 +0300] "GET /something HTTP/1.1" 304 -