Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Обработка log-файла


Автор: Aleksandr123 4.5.2008, 21:03
Доброго времени суток!!!!!!!! Требуется помощь специалистов!!!! Буду благодарен!!
Попытаюсь подробно объяснить задание - существует лог файл. В нем грубо говоря указываются типы подключений и количество переданных байт за соединение. Задача состоит в обработке этого лог файла и сохранение необходимой информации в текстовом документе в виде таблицы.
Ниже привожу отрывок этого лог файла.
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built outbound TCP connection 29658131 for outside:87.218.38.186/44433 (87.218.38.186/44433) to inside:Vela/3863 (213.142.196.31/3863) 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built outbound TCP connection 29658132 for outside:213.142.196.31/23861 (213.142.196.31/23861) to inside:Vela/3864 (213.142.196.31/3864) 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302014: Teardown TCP connection 29658028 for outside:92.113.96.10/6861 to inside:Vela/3815 duration 0:00:30 bytes 0 SYN Timeout 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-7-609002: Teardown local-host outside:92.113.96.10 duration 0:00:30 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-7-609001: Built local-host outside:84.50.160.85 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built inbound TCP connection 29658133 for outside:84.50.160.85/64626 (84.50.160.85/64626) to inside:Vela/23861 (213.142.196.31/23861) 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-7-609001: Built local-host outside:82.116.115.126 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built outbound TCP connection 29658134 for outside:82.116.115.126/63368 (82.116.115.126/63368) to inside:Vela/3865 (213.142.196.31/3865) 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-7-609001: Built local-host outside:91.124.134.21 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built outbound TCP connection 29658135 for outside:91.124.134.21/8080 (91.124.134.21/8080) to inside:Vela/3866 (213.142.196.31/3866) 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302014: Teardown TCP connection 29658124 for outside:85.106.167.149/4357 to inside:Rainbow/25 duration 0:00:05 bytes 1330 TCP FINs 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-7-609002: Teardown local-host outside:85.106.167.149 duration 0:00:05 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-6-302014: Teardown TCP connection 29658133 for outside:84.50.160.85/64626 to inside:Vela/23861 duration 0:00:00 bytes 1072 TCP Reset-I 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-7-609002: Teardown local-host outside:84.50.160.85 duration 0:00:00 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-7-609001: Built local-host outside:84.50.160.85 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-6-106015: Deny TCP (no connection) from 84.50.160.85/64626 to 213.142.196.31/23861 flags ACK  on interface outside 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-7-609002: Teardown local-host outside:84.50.160.85 duration 0:00:00 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-7-609001: Built local-host outside:88.245.216.136 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-6-302013: Built inbound TCP connection 29658137 for outside:88.245.216.136/4569 (88.245.216.136/4569) to inside:Rainbow/25 (Rainbow-outside/25) 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-7-609001: Built local-host outside:193.151.254.103 
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-6-302013: Built inbound TCP connection 29658138 for outside:193.151.254.103/4115 (193.151.254.103/4115) to inside:Vela/23861 (213.142.196.31/23861) 

В текстовом документе должно содержаться три столбца.. первый столбец количество переданной исходящей информации в байтах.... второй столбец - количество переданной входящей информации и третий столбец - Сервер(он же внутренний ip адрес)...  Для начала нужно определить какой соединение было - иходящее или входящее (outbound или intbound), это возможно сделать по номеру соединения(при открытии соединения создается номер, к примеру Built inbound TCP connection "29658138"- вот этот номер ) затем определить количество переданных байт за соединение, это возможно определить в строке при закрытии соединения к примеру Teardown TCP connection 29658133 for outside:84.50.160.85/64626 to inside:Vela/23861 duration 0:00:00 bytes "1072" вот количество байт....и нужно определить сервер,который тоже указывается в строке при закрытии соединения всегда после слов to inside: ... к примеру to inside:Vela/23861,  to inside:Rainbow/25
Буду очень благодарен если вы поможете мне разобобраться с этим заданием!

Автор: ramus 4.5.2008, 22:19
требуется уточнение:
1. лог файл статичен? либо в него постоянно дописываются новые строки? тогда как он отрезается?
2. большой ли лог файл? так как надо сохранять номер соединения, а потом спустя время при закрытии соединения ссылаться на него. Так как номер соединения пока он активен - уникальный (я так думаю) то его удобно хранить в хеше, например
Код

my %destination;
$destination{29658138}=inbound;


3. привели много "мусора" например 
Built inbound TCP connection "29658138"- вот этот номер
Teardown TCP connection 29658133 for outside:84.50.160.85/64626 to inside:Vela/23861 duration 0:00:00 bytes "1072"
тут номера соединений не совпадают !!! Я не спец в данном вопросе, но мне кажется лучше бы приводить связанную информацию

как пример кода можно начать с (это именно болванка, не готовый код!!!)
Код

use warnings;

my (@entry, %hm, @mms, $i, $d);

open( FILE,"tcp.log") or die ("Cannot open file tcp.log $!");
#Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-7-609002: Teardown local-host outside:84.50.160.85 duration 0:00:00 

while ( <FILE> ) {
   next if ( $_ eq "\n" );  # propusk pustyh strok
   my ($mon,$day,$hms,$ip,$hz1,$hz2,$msg);
   ($mon,$day,$hms,$ip,$hz1,$hz2,$msg) = split (/\s/,$_,7);
   @entry=parseEntry( $msg );
   next unless (defined($entry[0]));
   ... тут анализ с записью в файл
   $hm{$entry[0]} = [ @entry ];
} 
close( FILE ) or die ("Cannot close: $!");

sub parseEntry
{
  my $entry = shift;
  
  if ( $entry =~ /^Teardown TCP connection\s*(\d*)/ ) {
      return ( 'down', $1 );
   }
  if ( $entry =~ /^Built inbound TCP connection\s*(\d*)/ ) {
      return ( 'up_inbound', $1 );
   }
   if ( $entry =~ /this is header/ ) {  return undef; }

   warn "Not parsed string:\n$entry\n";
   return undef;
}




Автор: sir_nuf_nuf 5.5.2008, 08:33
мм.. немного не в тему - просто предостережение вам:
понятие входящего и исходящего TCP соединений никак не связано с тем в какую сторону больше трафика передается

Например у HTTPD передает наружу большой трафик по входящим соединениям.

Не ошибитесь =)

Автор: Bulat 5.5.2008, 09:32
Aleksandr123, какой размер лога??

Автор: Aleksandr123 5.5.2008, 20:31
Лог файлы создаются каждый день. Т.е. для каждого дня - новый лог файл.
Запись информации в лог файл совершается постоянно в течении суток с появлением новых соединений.
И к концу рабочего дня размер не заархивированного файла составляет около 200мб. В архиве файл весит в среднем 15мб. 
По сути нам нужны из всего лог файла только две строчки. Первая строка которая создается при открытии соединения - Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built inbound TCP connection 29658133 for outside:84.50.160.85/64626 (84.50.160.85/64626) to inside:Vela/23861 (213.142.196.31/23861)  - из этой строки нам нужен номер соединения, т.е. 29658133(номера уникальный) и информация о типе соединение inbound или outbound(входящее или исходящее)
и вторая строка которая создается при закрытии соединения - Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-6-302014: Teardown TCP connection 29658133 for outside:84.50.160.85/64626 to inside:Vela/23861 duration 0:00:00 bytes 1072 TCP Reset-I  - в этой строке нас интересует по сути только количество переданной информации за сеанс и имя сервера(но хотя имя сервера так же указывается в строке при открытии соединения).
Вот такая не легкая задача встала на моем по пути и без ваших знаний и опыта мне не обойтись!

Автор: ramus 5.5.2008, 21:22
1. То есть обработка файла происходит на следующий день, когда в него уже ничего не пишется?

2. "29658133(номер уникальный)"  - то есть в пределах одного файла двух РАЗНЫХ записей например на установление соединения с ОДИНАКОВЫМ номером не может быть?

Размер 200МБ нормально, у меня на персоналке обработка таких файлов занимает от 20-30 секунд до 2-3 минут в зависимости от масштаба обработки.

Для примера содержимое файла day.log 
Код

Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built outbound TCP connection 29658131 for outside:87.218.38.186/44433 (87.218.38.186/44433) to inside:Vela/3863 (213.142.196.31/3863) 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built outbound TCP connection 29658132 for outside:213.142.196.31/23861 (213.142.196.31/23861) to inside:Vela/3864 (213.142.196.31/3864) 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302014: Teardown TCP connection 29658028 for outside:92.113.96.10/6861 to inside:Vela/3815 duration 0:00:30 bytes 0 SYN Timeout 
Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-7-609002: Teardown local-host outside:92.113.96.10 duration 0:00:30 

Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built inbound TCP connection 29658133 for outside:84.50.160.85/64626 (84.50.160.85/64626) to inside:Vela/23861 (213.142.196.31/23861)
Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-6-302014: Teardown TCP connection 29658133 for outside:84.50.160.85/64626 to inside:Vela/23861 duration 0:00:00 bytes 1072 TCP Reset-I



вот код (естественно можно написать круче smile но в качестве примера пойдет )

Код

#!/usr/bin/perl

use strict;

my (@entry, %hm, @mms, $i, $d);
open( FILE,"day.log") or die ("Cannot open file day.log $!");

# Хеш для хранения типа соединение inbound или outbound
my %htype;

# Хеш для хранения переданной информации за сеанс 
my %hsend;

# Хеш для хранения имя сервера
my %hserver;

while ( my $str =<FILE> ) {

  #Jan 31 23:45:02 172.16.0.253 PIX1 %PIX-6-302013: Built inbound TCP connection 29658133
  #for outside:84.50.160.85/64626 (84.50.160.85/64626) to inside:Vela/23861 (213.142.196.31/23861)
  # надо -> %htype{29658133} = inbound
  if ( $str =~ /Built inbound TCP connection\s*(\d*)/ ) {
      $htype{$1} = "inbound";
      next;
  }
  if ( $str =~ /Built outbound TCP connection\s*(\d*)/ ) {
      $htype{$1} = "outbound";
      next;
  }

  #Jan 31 23:45:03 172.16.0.253 PIX1 %PIX-6-302014: Teardown TCP connection 29658133 
  #for outside:84.50.160.85/64626 to inside:Vela/23861 duration 0:00:00 bytes 1072 TCP Reset-I
  # надо -> %hsend{29658133}   = 1072
  #         %hserver{29658133} = Vela
  if ( $str =~ /Teardown TCP connection\s*(\d*).*to inside:(\w+).*duration.*bytes\s*(\d*)/ ) {
      $hserver{${1}} = "${2}";
      $hsend{${1}}   = "${3}";
  }

} 
close( FILE ) or die ("Cannot close: $!");

# Вывод
foreach (keys (%htype)) {
  print "$_ -> type=$htype{$_} send=$hsend{$_} server=$hserver{$_}\n";

}


выводит на экран с этими данными:
Код

29658133 -> type=inbound send=1072 server=Vela
29658132 -> type=outbound send= server=
29658131 -> type=outbound send= server=


Автор: Aleksandr123 5.5.2008, 23:06
Да, обработка файла происходит на следующий день, когда в него уже ничего не пишется. В пределах одного файла двух Одинаковых номеров соединения быть не может. - да это так.  Номера для каждого нового соединения уникальны. 
Большое Спасибо за предоставленный код) попробую разобраться..

Автор: Bulat 6.5.2008, 09:03
Aleksandr123, вариантов как распарсить данный лог очень много. Лично я в таких случаях предпочитаю создавать классы(наборы данных) к примеру можешь посмотреть данную тему http://forum.vingrad.ru/forum/topic-174886/hl/%25D0%25BA%25D0%25BB%25D0%25B0%25D1%2581%25D1%2581%25D0%25AB/index.html, т.е. объекты которые будут хранить всю нужную информацию во время прасинга, как парсить с помощью регулярных выражений - тут и так достаточно примеров, если уж по этому и будут вопросы то лишь если где-то что-то конкретное не срабатывает. 

Автор: Aleksandr123 6.5.2008, 23:01
Большое спасибо всем за помощь! вроде почти все получается! Только хотелось бы еще узнать, имеется ли возможность посчитать отдельно общее количество переданной и отдельно общее количество полученной информации во всем логе?

Автор: shamber 7.5.2008, 08:19
ну вы же их празделяете когда регуляркой разбираете?
вот и сложите в конце.

Автор: Bulat 7.5.2008, 08:34
Aleksandr123, обрати внимание, я тебе не зря дал ссылку на классы. Ты можешь создать свой класс, который будет хранить в одном поле число - количество байт(если я не ошибаюсь) с каждой распарсенной строки. Далее сложить все значения в цикле smile

Автор: Aleksandr123 7.5.2008, 13:12
Ок, всем большое спасибо!!!!!!!!!

Автор: Aleksandr123 30.5.2008, 14:51
Доброго времени суток!!!!!!!!! Требуется еще небольшая помощь - как сделать так чтобы результаты сохранялись в текстовом файле????? очень нужна помошь!!!!1

Автор: shamber 30.5.2008, 15:20
Цитата(Aleksandr123 @  30.5.2008,  14:51 Найти цитируемый пост)
сохранялись в текстовом файле???

это как?


типа этого?
Код

open(FILE,>."somefile.txt");
print FILE $var; #var записан в файл
close FILE;


Добавлено через 38 секунд
ЗЫ для нового вопроса новая тема

Автор: Aleksandr123 30.5.2008, 17:17
Зачем создавать новую тему, ведь вопрос в этой же теме..... 
У меня почему то сохраняется в текстовике информация только по первому соединению...хм...

Автор: shamber 30.5.2008, 17:20
кусок кода в студию!
А вопрос о другом и поиск был бы легче.

Автор: Aleksandr123 30.5.2008, 17:48
# Вывод
   open(OF, ">666.txt");
foreach (keys (%htype)) {
  print OF "$_ -> type=$htype{$_} send=$hsend{$_} server=$hserver{$_}\n";
close (OF);
}

Автор: Bulat 30.5.2008, 18:52
Aleksandr123, а вокруг. Как ты в хэше все сохраняешь??

Автор: ginnie 30.5.2008, 21:33
Уважаемый Aleksandr123, обратите внимание, что Вы закрываете файл внутри цикла на первой итерации. Поэтому больше одной строки в файле с этим кодом у Вас не будет никогда  smile

Код

open(OF, ">666.txt");
foreach (keys (%htype)) {
    print OF "$_ -> type=$htype{$_} send=$hsend{$_} server=$hserver{$_}\n";
}
close (OF);

Автор: tolkien 30.5.2008, 21:51
И результат открытия файла всегда проверяй. А то потом придется тебе спрашивать" чего он не открывается?"

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)