LINUX.ORG.RU

Проблема с парсингом логов


0

1

Здравствуйте!
Возникла проблема с парсингом логов - некоторые данные почему-то теряются и не попадают в базу.
Как все сделано:
Запущен nginx. Делается запрос вида

hostname.ru/s?e=1&r=2&p=3&u=4
Все такие запросы попадают в access.log
Затем, раз в 10 минут выполняется скрипт:
#!/bin/sh
# date (day)
#DATE=`date '+%d%m%y'`
DATE=`date --date='next day' "+%d%m%y"`

# date (with minutes)
DATEM=`date --date='next day' "+%d%m%y_%H%M"`

# rename logs file to '<filename>.<DATEM>'
mv /var/virtual/hostname.ru/logs/access.log /var/virtual/hostname.ru/logs/access.log.$DATEM

# reload nginx
/etc/init.d/nginx reload

# parse logs file
/var/virtual/hostname.ru/cron/parser_new.pl </var/virtual/hostname.ru/logs/access.log.$DATEM >/var/virtual/hostname.ru/logs/parser_new.log

# add DATEM-file log to the end of the DATE-file log
cat /var/virtual/hostname.ru/logs/access.log.$DATEM >> /var/virtual/hostname.ru/logs/access.log.$DATE

# remove temporary file
rm /var/virtual/hostname.ru/logs/access.log.$DATEM

Т.е. происходит следующее:
- файл с логами переименовывается - к названию добавляется дата с указанием числа,месяца,года,часа,минут.
- перезапускается nginx (и создается новый access.log)
- запускается парсер на файл с 10-минутными логами
- логи за 10 минут копируются в общий файл логов (который в конце дня bzip2'ается)
- файл 10-минутных логов удаляется

И так каждые 10 минут.

Как работает скрипт парсера (Perl):
1. построчно считывает файл логов
2. регексами разбивает строку - отбирает значения r,p,e,u
3. пишет в базу связку u-r

$query="INSERT INTO p${p}r (u,r,timestamp) VALUES ('$u','$r','$time') ON DUPLICATE KEY UPDATE timestamp='$time'";
$dbh->do($query);
if ($dbh->err()) {
    Debug("($query) SQL ERROR: $DBI::errstr\n");
    next;
};	
4. записывает r-p-e в хеш-таблицу:
if (!defined($VALUE{$r}{$p}{$e})) { $VALUE{$r}{$p}{$e}=0; };
$VALUE{$r}{$p}{$e}++;
5. затем собранные данные пишет в базу:
foreach $r (keys %VALUE) {
  foreach $p (keys %{$VALUE{$r}}) {
    foreach $e (keys %{$VALUE{$r}{$p}}) {
      print "r=$r p=$p e=$e $VALUE{$r}{$p}{$e}\n";
      $query="INSERT INTO table (p,e,r,value,timestamp) VALUES ('$p','$e','$r','$VALUE{$r}{$p}{$e}','$day_start') ON DUPLICATE KEY UPDATE value=value+$VALUE{$r}{$p}{$e}";
      $dbh->do($query);
      if ($dbh->err()) {
        Debug("($query) SQL ERROR: $DBI::errstr\n");
        next;
      };
    };
  };
};

Проблема:
Теряются некоторые запросы.
Причем, связка u-r записывается в базу ВСЕГДА (парсер, шаг 3). НО на шаге 4, судя по всему, почему-то не все записывается в хеш-таблицу (если верить print «r=$r p=$p e=$e $VALUE{$r}{$p}{$e}\n»;).
Если же потом, например, повторно делаю запросы - тогда они вполне могут пройти и попасть в базу.
Получается, что иногда считается, иногда нет. Где может быть косяк?

PS: Названия немного поменял.
PPS: Варианты «Да у тебя одни костыли, надо все по-другому с нуля переписать» не предлагать.

★★★★★

Ответ на: комментарий от anonymous

В том и дело, что судя по всему ошибка в парсере, ибо:

foreach $r (keys %VALUE) {
foreach $p (keys %{$VALUE{$r}}) {
foreach $e (keys %{$VALUE{$r}{$p}}) {
print "r=$r p=$p e=$e $VALUE{$r}{$p}{$e}\n";
на print он не выводит даже их, т.е. будто не попадают в хеш-таблицу. Почему?

kovrik ★★★★★ ()
Ответ на: комментарий от kovrik

>В том и дело, что судя по всему ошибка в парсере
Так ищи её, блджад! Или ждёшь телепатов, которые читают и диагностируют код по аватарке?

anonymous ()
Ответ на: комментарий от anonymous

Так я вот и спрашиваю где там может быть ошибка?
Несколько одинаковых запросов, одни проходят, другие - нет.
Если я правильно понимаю, то они не попадают в хеш-таблицу:

if (!defined($VALUE{$r}{$p}{$e})) { $VALUE{$r}{$p}{$e}=0; };
$VALUE{$r}{$p}{$e}++;
Как этот код может не работать для одних значений и работать для других???

kovrik ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.