Страница 1 из 2
[PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-11 23:49:32
Alex Keda
имею такой лог нгинкс (примерно)
Код: Выделить всё
77.221.149.162 - aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - www.aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - bbb.aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - bbb.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - xxx.ccc.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
интересен третий параметр (по пробелам) - домен
есть список владельцев доменов, такого вида
Код: Выделить всё
aaa.su:1033:user1
bbb.su:1043:user2
ccc.su:1043:user2
распарсить всё по отдельности - не проблема.
проблема что на выходе мне надо знать сколько строк в логе для user1 и сколько для user2
перебирать два файла и сравнивать - это тупо, в одном мильён записей, в другом 2000 - это будет 2 триллиона операций...
на сейчас допилился до такого:
Код: Выделить всё
srv1# cat /root/scripts/stat/count.user.dynamics.pages.pl
#!/usr/bin/perl
# подсчёт числа динамических страниц от сайтов юзера
# по логам nginx
# функции
do "/root/scripts/stat/includes/perl.functions.pl";
# достаём имя файла - параметр вызова файла
if(!defined(@ARGV)){
print "Error: missing 1 parameter - log file name\n";
exit 1;
} # закрытие - аргументы вызова не заданы
# проверяем что файл существует
if ( ! -f @ARGV[0]){
print "Error: file '" . @ARGV[0] . "' does not exists\n";
exit 1;
} # закрытие проверки существования файла с логом
# открываем файл лога и дёргаем его в массив
open (MYLOG, @ARGV[0]);
# сохраняем в массив содержимое - построчно
@my_log = <MYLOG>;
# закрываем
close MYLOG;
# считываем файл с владельцами
open (MYTMP, "/root/scripts/exim/domain.owners.txt");
# сохраняем содержимое в массив
@my_owners = <MYTMP>;
# закрываем
close MYTMP;
# перебираем построчно владельцев
foreach $stroka (@my_owners)
{
# разбираем строчку на составлюящие
($domain, $uid, $user) = split(':', trim($stroka));
#print "$domain, $uid, $user \n";
}
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-11 23:52:27
ProFTP
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:01:35
Alex Keda
третий параметр я и регуляркой выдерну
наверно даже быстрей будет чем этой хренью.
вопрос в том что надо проводить кучу сравнений - а хочется красивого решения.
может даже греп в итоге быстрей будет чем перл

Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:06:50
Гость
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:11:09
hizel
засунь "список владельцев доменов" в хэш и потом парси собстно лог и по хэшу сравнивай
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:11:33
ProFTP
Код: Выделить всё
# перебираем построчно владельцев
foreach my $log (@my_log)
{
foreach $stroka (@my_owners)
{
# разбираем строчку на составлюящие
($domain, $uid, $user) = split(':', trim($stroka));
#print "$domain, $uid, $user \n";
print '11' if ($log eq $domain);
}
}
сделай как-то так....
а в чем медленность?
этот файл $ARGV[0] какого размера?
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:14:44
Alex Keda
~200 метров
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:17:27
hizel
Лис хъши великая вещь
Код: Выделить всё
do "/root/scripts/stat/includes/perl.functions.pl";
ыыы, иии, этошта!1?
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:20:36
ProFTP
тогда так:
убери вот это
@my_log = <MYLOG>;
ты 200 метров в массив записываешь... не понятно нафига
Код: Выделить всё
while ( my $log = <MYLOG> )
{
foreach $stroka (@my_owners)
{
# разбираем строчку на составлюящие
($domain, $uid, $user) = split(':', trim($stroka));
#print "$domain, $uid, $user \n";
print '11' if ($log eq $domain);
}
}
и сделать так как посоветовали сделать с файла доменов хэш, чтобы лишниый цикл не ставить
как оно будет - надо сомтреть....
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 0:25:34
hizel
Код: Выделить всё
my %h;
foreach $stroka (@my_owners)
{
($domain, $uid, $user) = split(':', trim($stroka));
$h{$domain} = ($uid, $user);
}
foreach my $log (@my_log)
{
($ip, $domain,$blabla) = some_parse($log);
if(defined($h{$domain})){
print 'uid=' . $h{$domain}[0];
} else {
print 'fail :(';
}
}
как так, тебе не в падлу все грузить в память кстате?
блин залип
http://perldoc.perl.org/functions/exists.html
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 9:13:02
Alex Keda
hizel писал(а):Лис хъши великая вещь
Код: Выделить всё
do "/root/scripts/stat/includes/perl.functions.pl";
ыыы, иии, этошта!1?
хэшами пользоватсья не умею - не понимаю их.
а 'do' - это инклюдинг моих функций и переменных - я их использую почти во всех своих скритах (коннекты к базам, парсинг некоторых конфигов и т.п.)
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 9:13:41
Alex Keda
что касается 200 метров и в память - мне не жалко - рамы на серверах хватает.
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 9:19:09
Alex Keda
да, и помоему вы все забыли что домен
www.aaa.su и домен aaa.su имеют одного владельца.
вот тока в списке овнеров будет лишь aaa.su а в логе нгинкса - оба.
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 9:27:01
ProFTP
lissyara писал(а):что касается 200 метров и в память - мне не жалко - рамы на серверах хватает.
может быть...оно скорее всего грузит процессор... хотя может и нет
а что ты хочешь сделать?
можно суперпозицию использовать и запутаность Шрёдингера
http://www.opennet.ru/docs/RUS/perl_obz ... ntium.html
Код: Выделить всё
use Quantum::Superpositions;
unless ( $type eq any(@types) ) {
}
$type - не равняется тем элементам которые в массиве
ты хочешь какую-то статистику? я бы написал бы демона и складывал бы все в mysql каждые 30 сек. (не повторяя), а потом красивую статистику какую захочешь... я про это писал в FAQ
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 9:39:13
hizel
lissyara писал(а):hizel писал(а):Лис хъши великая вещь
Код: Выделить всё
do "/root/scripts/stat/includes/perl.functions.pl";
ыыы, иии, этошта!1?
хэшами пользоватсья не умею - не понимаю их.
а 'do' - это инклюдинг моих функций и переменных - я их использую почти во всех своих скритах (коннекты к базам, парсинг некоторых конфигов и т.п.)
господя кашмар какой, на чем ты учился программировать?

ты всетаки про хэши прочитай один раз, там ничего сложного
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 9:50:17
ProFTP
ну вот как вариант из
simplemail admin который я писал (и потом кто-то еще писал)
можешь записывать логи в mysql из файлика лога не повторяя то что уже записано, и сохранаяя позиции в сам файл которые уже записаны в mysql
(только нужно подправить переменные и пути, ну или взять конфиг файл из simplemail admin и там тоже подправить)
это из postfix/exim
Код: Выделить всё
#!/usr/bin/perl
## This file is part of the Simplemail project.
# Copyright (c) 2008 the Simplemail Team (see authors).
#
# For the full copyright and license information, please view the COPYING
# file that was distributed with this source code. You can also view the
# COPYING file online at http://unixforum.org.ua/misc/COPYING.txt
#
# @copyright (c) the authors
# @author Dmitriy <rtyug@ukr.net>
# @license GPLv2 http://unixforum.org.ua/misc/COPYING.txt
# @package Panel Mailbox
# @version $Id: $
use strict;
use DBI;
use Fcntl ':flock';
use File::Pid;
my $pidfile = File::Pid->new( { file => '/var/run/simplemail.pid', } );
# my $pid = $pidfile->pid;
# print $pid;
# use POSIX 'getpid';
# my $pid_script = &getpid;
# print $pid_script;
# my $num = $pidfile->running;
# if ($pid_script == $num) {
# die "Already running: $num\n";
# }
my $pid = $pidfile->running;
die "Service already running: $pid\n" if $pid;
$pidfile->write;
our $se;
require "/home/mydm/www/simplemail/lib/config.pl";
unless ( -e ( $se->{'maildir'} ) ) {
print "error dir mail from config.pl";
exit;
}
open LOG, '<', $se->{maillog} or die "Can't open $se->{maillog}: $!\n";
flock( LOG, LOCK_EX );
my $pos = 0;
$pos = do { chomp; $_ } while <DATA>;
seek LOG, $pos, 0 if $pos <= -s $se->{maillog};
my $dbh = DBI->connect(
"DBI:$se->{db_type}:database=$se->{db_name};host=$se->{db_host}",
$se->{db_user}, $se->{db_pass}, { RaiseError => 1 } )
|| die $DBI::errstr;
while ( my $line = <LOG> ) {
my ( $month, $day, $time, $hostname, $servicename ) = split / /, $line,
5;
my $timedata = $month . ' ' . $day . ' ' . $time;
my $text = $hostname . ' ' . $servicename;
$dbh->do( qq{INSERT INTO maillog (data,text) VALUES(?,?)},
undef, $timedata, $text );
}
$dbh->disconnect;
$pos = tell LOG;
flock( LOG, LOCK_UN );
close LOG;
$pidfile->remove; #or warn "Couldn't unlink pid file\n";
exec qw(perl -0777 -i -pe), 's/$/\n' . $pos . '/', $0;
exit;
$pidfile->remove; #or warn "Couldn't unlink pid file\n";
exit;
__DATA__
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 10:22:14
Alex Keda
hizel писал(а):господя кашмар какой, на чем ты учился программировать?

на шелле.
=====
а как сделать инклюд одного и того же?
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 10:36:04
hizel
через модули и use Some;
и поимей привычку использовать use strict;
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 10:43:23
thefree
Исходные данные
Код: Выделить всё
77.221.149.162 - aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - www.aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - bbb.aaa.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - bbb.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
77.221.149.162 - xxx.ccc.su [10/Jan/2010:00:00:16 +0300] "GET / HTTP/1.0" 200 612 "-" "ApacheStats/0.4 wget/1.8"
и
Код: Выделить всё
aaa.su:1033:user1
bbb.su:1043:user2
ccc.su:1043:user2
Сам скрипт (про оперативку вы Сами заикнулись, хотя думаю нагрузки не много)
Код: Выделить всё
#!/usr/bin/perl -w
use strict;
my %users;
my $user_list = 'lissyara_user.txt';
open(FILE, "< $user_list") or die "Can't open $user_list : $!";
while (my $line = <FILE>) {
my ($domain, $uid, $user) = split(/:/, &trim($line));
$users{$domain} = [$domain, $uid, $user, 0];
}
close FILE;
my $log_file = 'lissyara_log.txt';
open(FILE, "< $log_file") or die "Can't open $log_file : $!";
while (my $line = <FILE>) {
my @tmp = split(/\s/, &trim($line));
my @tmp_d = split(/\./, $tmp[2]);
$tmp[2] = $tmp_d[$#tmp_d - 1].".".$tmp_d[$#tmp_d];
if (exists($users{$tmp[2]})) {
$users{$tmp[2]}[3] += 1;
}
}
close FILE;
foreach my $key (sort keys %users) {
print "Domain: $users{$key}[0] User's: $users{$key}[2] Uid: $users{$key}[1] Found line: $users{$key}[3]\n";
}
sub trim() {
my ($s) = @_;
$s =~ s/^\s+//sg;
$s =~ s/\s+$//sg;
return $s;
}
Результат
Код: Выделить всё
# ./lissyara.pl
Domain: aaa.su User's: user1 Uid: 1033 Found line: 4
Domain: bbb.su User's: user2 Uid: 1043 Found line: 1
Domain: ccc.su User's: user2 Uid: 1043 Found line: 1
Думаю как-то так.
===
Использовать
do для инклуд то же не проблема.
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 10:45:21
Alex Keda
та имел я эту привычку...
мне больше делать нечего смотреть при каждом запуске что это убожество ворчит про переменыне которые поюзаны по его мнению один раз.
а то что иначе в нём не напишешь кроме как с использованием бесполезных переменных или они юзаются внутри вызова do - оно не понимает.
дополз до такого
Код: Выделить всё
my %h;
# строим хэш по владельцам
foreach $stroka (@my_owners)
{
($domain, $uid, $user) = split(':', trim($stroka));
$h{$domain} = $user;
$h{$domain}{"counter"} = 0;
}
# пеербираем лог
foreach my $log (@my_log)
{
($tmp0, $tmp1, $domain, $tmp2) = split(" ",$log);
# bootv домен
if(defined($h{$domain})){ # домен в хэше есть
$h{$domain}{"counter"} = $h{$domain}{"counter"} + 1;
}else{ # домен есть в хэше --> нет домена в хэше
# обрезаем домен по точке слева
$pos = index($domain, '.');
# находим субдомен
$domain1 = substr($domain, $pos + 1);
# ищщем домен
if(defined($h{$domain1})){ # есть домен в хэше - 2
$h{$domain1}{"counter"} = $h{$domain1}{"counter"} + 1;
}else{ # есть домен в хэше 2 --> нет домена в хэше 2
print "$domain $domain1\n";
} # закрытие - нет домена в хэше 2
} # закрытие - нет домена в хэше
} # закрытие пеербора лога
#print $h{"vkhacker.ru"} . "\n";
#print $h{"vkhacker.ru"}{"counter"} . "\n";
#exit;
работает, но - пока есть тока сумма по доменам.
надо как-то ещё по владельцам просуммировать домены.
======
бля, насколько удобней работа с массивами в php...
кабы я не считал плохим тоном писать системные скрипты на php - уже всё бы давно было напсиано и работало.
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 10:47:58
Alex Keda
2 thefree
у меня тот же путь, тока на мой взгляд читабельней

)
======
щас попробую объединить
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 10:54:16
thefree
lissyara писал(а):2 thefree
у меня тот же путь, тока на мой взгляд читабельней

)
======
щас попробую объединить
не буду спорить но у меня я думаю правильнее я то 200Мб в оперативку не загружаю.
======
Теперь еще необходим вывод по владельцам?
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 10:56:11
Alex Keda
thefree писал(а):lissyara писал(а):2 thefree
у меня тот же путь, тока на мой взгляд читабельней

)
======
щас попробую объединить
не буду спорить но у меня я думаю правильнее я то 200Мб в оперативку не загружаю.
======
Теперь еще необходим вывод по владельцам?
у меня минимум гиг свободный, всегда, на всех серверах. чтоб не дёргаться.
а операция одноразовая - раз в сутки ночью.
======
кстати, считываемый файл лежит на tmpfs - так что он дважды в памяти получается

)
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 11:00:10
thefree
Эх, у меня линейка меньше (:
На самом дели я проста не могу понять зачем еще в хеши делать еще один хешь? не проще указатель на массив?
====
Выборку сделать по пользователям?
Re: [PERL] туплю - разборка лога нгинкса
Добавлено: 2010-01-12 11:03:58
hizel
сделай второй хэш для юзеров, делов то
