#!/usr/bin/perl
#
# Based on loganalyzer (Sergey N. Yatskevich <syatskevich@altlinux.ru>)
#
# Обработка лога ulog-acctd и запись результатов в таблицу transfer_log
#
# При обработке лога извлекается следующая информация :
#     1) время (с детализацией по дням) обращения
#     2) протокол (1 - ICMP, 6 - TCP, 17 - UDP)	
#     3) отправитель пакета
#     4) порт отправителя
#     5) адресат пакета
#     6) порт адресата
#     7) входящий интерфейс
#     8) исходящий интерфейс
#     9) префикс ulog-acctd
#    10) количество и размер пакетов
	
# Интересует "размер пакетов"/"количество пакетов" в разрезе
# 1, 2, 3, 4, 5, 6, 7, 8, 9
#

use DBI;

$dsn	= "dbi:InterBase:dbname=billing;host=firebird;ib_dialect=3";
$user   = "sysdba";
$passwd = "system";

sub parseLogLine
{
	($time, $protocol, $source, $source_port, $destination, $destination_port, $packets, $bytes, $incoming, $outgoing, $prefix) = split (/\s+/);

	($day, $month, $year) = (localtime ($time)) [3, 4, 5];

	$month++;
	$year += 1900;

	return ("INSERT", "$year/$month/$day", $protocol, $source, $source_port, $destination, $destination_port, $packets, $bytes, $incoming, $outgoing, $prefix);
}

while (<STDIN>)
{
	($state, $date, $protocol, $source, $source_port, $destination, $destination_port, $packets, $bytes, $incoming, $outgoing, $prefix) = parseLogLine ($_);

	if ($state eq "INSERT")
	{
		$total_packets{"$date $protocol $source $source_port $destination $destination_port $incoming $outgoing $prefix"} ++;
		$total_bytes{"$date $protocol $source $source_port $destination $destination_port $incoming $outgoing $prefix"} += $bytes;
	}
}

$dbh = DBI->connect ($dsn, $user, $passwd, {AutoCommit => 0});

$sth = $dbh->prepare ("INSERT INTO transfer_log VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

foreach $key (keys %total_packets)
{
	if ($total_bytes{$key} > 0)
	{
		($date, $protocol, $source, $source_port, $destination, $destination_port, $incoming, $outgoing, $prefix) = split (/ /, $key);

		$sth->execute ($date, $protocol, $source, $source_port, $destination, $destination_port, $incoming, $outgoing, $prefix, $total_packets{$key}, $total_bytes{$key});
		if ($sth->state)
		{
			$dbh->rollback;
			$dbh->disconnect;

			die "Ошибка вставки записи, откат в начальное состояние\n";
		}
	}
}

$dbh->commit;
$dbh->disconnect;
