Делаем статистику на основе get_hf_direct

Технические вопросы по UTM 5.0
Ответить
Oleg_121
Сообщения: 81
Зарегистрирован: Пн апр 14, 2008 21:09

Делаем статистику на основе get_hf_direct

Сообщение Oleg_121 »

Делаем статистику на основе get_nf_direct и разработке Магнума raw_fd_scrupt.
Большое спасибо Магнуму за его разработку по извлечению статистики из файлов xx.utm все сделанно на основе ее. Однако возникла идея сделать статистику для Личного кабинета используя статисктику которая храниться в в файлах utm . Все данные извлекаются из этих файлов с использованием немного доработанной разработки Магнума, причем все данные о детальной статистики так и храняться в архивных файлах для каждого пользователя , однако из файлов utm также извлекается статистика для каждого пользователя за день , и заносится в таблицу MySQL stat__daily которая имеет поля date ip bytes direction. Имя базы данных может быть в принципе любое – какое вам нравится.
1. Задаем модуль my в этом модуле обозначаем имя базы данных

package SYB::MY;

use base 'Class::DBI';

SYB::MY->connection('dbi:mysql:stat', 'login', 'pass');

в этом модуле stat – имя БД , логин и пароль соответственно для доступа к БД.
Сохраняем этот модуль под именем my.pm в директории SYB

2.Создаем модуль для доступа к таблице где будут храниться данные ( естественно вам необходимо перед этим создать как базу так и таблицу с полями)

package SYB::MY::stat::daily;

use base SYB::MY;

SYB::MY::stat::daily->table('stat__daily');
SYB::MY::stat::daily->columns( All => qw/id date ip bytes direction/ );

этот модуль должен лежать в директории SYB/MY/stat – в принципе вы можете поменять все пути исправив соответственно пути в файлах
Сохраняем его как daily.pm. Поля таблици date, ip, bytes, direction.

3. Кладем модуль raw_fd_scrupt в директорию /netup/utm/bin и прописываем путь до него в админке.
Вот сам немного исправленный модуль

#!/usr/bin/perl

use SYB::MY::stat::daily;
use Compress::Zlib;
use Socket;
sub loger;

$fileUTM = shift;
$home = "/var/flowstat";
$logdir = "/var/log";
$log = $logdir."/ds.log";
opendir( DIRHANDLE, $logdir ) || die "Mount ERROR!";

if ( $fileUTM eq "" ) {
loger "No parametr!", "ERROR";
}
loger "$fileUTM", "START";
$size = ( stat( $fileUTM ) )[7];
if ( $size % 76 != 0 ) {
loger "Error UTM file!", "ERROR";
}
$rec = $size/76;
loger "Size: $size Record: $rec", "INFO";
open ( FH, "< $fileUTM" ) or loger " Error open file $fileUTM", "ERROR";

for ( $i=1; $i<=$rec; $i++ ) {
read ( FH, $t, 4 ); # 1-4
read ( FH, $src_ip, 4 ); # 5-8
read ( FH, $dst_ip, 4 ); # 9-12
read ( FH, $t, 8 ); # 13-20
read ( FH, $packets, 4 ); # 21-24
read ( FH, $bytes, 4 ); # 25-28
read ( FH, $time1, 4 ); # 29-32
read ( FH, $time2, 4 ); # 33-36
read ( FH, $src_port, 2 ); # 37-38
read ( FH, $dst_port, 2 ); # 39-40
read ( FH, $t, 16 ); # 41-56
read ( FH, $account_id, 4 ); # 57-60
read ( FH, $t, 4 ); # 61-64
read ( FH, $t_class, 4 ); # 65-68
read ( FH, $timestamp, 4 ); # 69-72
read ( FH, $t, 4 ); # 73-76

$tc = unpack ( "%32I" , $t_class );
$account_id = unpack ( "%32I" , $account_id );
if ( $tc == 0 ) {
$account_id = "a";
}
$t_class = pack ( "S" , $tc );

@time = localtime( unpack ( "%32I" , $timestamp ) );
$dirs=( $time[5]+1900 )."-".sprintf( "%02d", $time[4]+1 );

# 4 4 4 4 2 2 2 4 = 26
$arr{$account_id}{$dirs} .= "$src_ip$dst_ip$packets$bytes$src_port$dst_port$t_class$timestamp";

# by J.C.
my $date = sprintf "%04d-%02d-%02d", ($time[5]+1900,$time[4]+1,$time[3]);
my $dst = inet_ntoa ( pack ( "N", unpack ( "%32l" , $dst_ip ) ) );
$traf{$date}->{$dst} += unpack ( "%32I" , $bytes );
# end of 'by J.C.'
}
close FH;

# by J.C.
print STDERR "$fileUTM:\n";
foreach my $date ( sort keys %traf )
{
foreach my $dst ( sort keys %{$traf{$date}} )
{
next if ( $dst !~ /^10\.255/ );
print STDERR "$date\t$dst:\t".$traf{$date}->{$dst}."\n";
my $rec = SYB::MY::stat::daily->retrieve( ip => $dst, date => $date, direction => 'in' );

if ( $rec ) { $rec->bytes($rec->bytes+$traf{$date}->{$dst}); $rec->update; }
else
{
my $rec = SYB::MY::stat::daily->insert
({
date => $date,
ip => $dst,
bytes => $traf{$date}->{$dst},
direction => 'in',
});
}
}
}
# end of 'by J.C.'

$i=0;

foreach $k ( keys %arr ) {
foreach $d ( keys %{$arr{$k}} ) {
$dir = $home.$d;
opendir( DIRHANDLE, $dir ) || mkdir( $dir, 0755 );
open FH, ">>$dir/$k.ds.gz" or loger " Error open file $home/$k.utm\n", "ERROR";
print FH Compress::Zlib::memGzip( $arr{$k}{$d} );
close FH;
$i++;
}
}
loger "account: $i", "OK";
exit 0;

sub loger {
$mess = shift;
$error= shift;
@time = localtime();
$t = ( $time[5]+1900 ) . "-" . sprintf( "%02d", $time[4]+1 ) . "-" . sprintf( "%02d", $time[3] ) . " $time[2]:$time[1]:$time[0]";
open ( FH, ">> $log" );
print FH "$error: $t\n";
print FH "$mess\n";
close FH;
if ( $error eq "ERROR" )
{
exit 0;
}
}


Что делает этот модуль:
1. Разбирает статистику по Магнуму – единственное поменяли директорию – счас все кладется в /var/flowstat и логи в /var/log
2. Записывает в базу данных stat в таблицу stat__daily информацию о трафике пользователей за день. Как дальше этим распорадится решайте сами! Мы но основе этого сделали статистику по дням для пользователей. Открывается очень быстро.

kara
Сообщения: 125
Зарегистрирован: Вс мар 21, 2010 21:02

Сообщение kara »

Запилил себе, вроде работает, спасибо.

Только не пойму как можно запросом в бд выбрать детализацию по трафику определенного ip-адреса, который не привязан ни к одному аккаунту(услуге передача ip-трафика)?

Ответить