ISP`s IT Аутсорсинг
Быстрый переход: Главная блога Главная сайта Форум
Если Вы чего то недопоняли или не нашли - задайте
вопрос на нашем форуме и мы попробуем Вам помочь.
Subnets.ru Регистрация IP и Автономных систем mega-net.ru

Trafd — демон учета трафика в FreeBSD.

Вопрос:

Я обнаружил, что у меня trafd сбрасывает инфу в /usr/local/var/trafd.
При попытке посмотреть traflog -i xl0 пишется :

traflog: WARNING: table too big to fit into memory

Подскажите как довести до ума работу trafd ?

Ответ:

По умолчанию сохраняется в /usr/local/var/trafd.

Для traflog нужны файлы которые получаются после того как отрабатывает:

trafdump IFACE_NAME
trafsave IFACE_NAME

После выполнения этих команд файлы и сохраняются в /usr/local/var/trafd

Например:

bge1 — название интерфейса на котором trafd собирает трафик (IFACE_NAME)
/usr/local/var/trafd/trafd.bge1 — полученный бинарный файл с трафиком
extnew — секция конфига /usr/local/etc/traflog.format в которой описан шаблон вывода бинарных данных в текстовый вид, например:

extnew {
    from:"%-18.18s " sport:"%-6.6s "        to:"%-18.18s " dport:"%-6.6s "
    proto:"%-4.4s " bytes:"%9ld " psize:"%10ld" ftime:" %Y-%m-%d %T" ltime:" %Y-%m-%d %T\n"
};

/usr/local/bin/traflog -o extnew -i /usr/local/var/trafd/trafd.bge1 -a -n > /usr/local/var/trafd/trafd.bge1.log

Таким образом разобранный трафик окажется в файле /usr/local/var/trafd/trafd.bge1.log

Команды trafdump и trafsave необходимо выполнять довольно часто, особенно при большом кол-ве трафика проходящего через этот интерфейс, чтобы избежать потом ошибки traflog: WARNING: table too big to fit into memory при обработке трафика.

Выход:

В файл /etc/crontab дописать:

*/5 * * * * * * root /usr/local/bin/trafdump IFACE_NAME; sleep 2; /usr/local/bin/trafsave IFACE_NAME

заменив IFACE_NAME на имя интерфейса на котором слушает trafd

Потом использовать небольшой скриптик на PERL:

/usr/local/sbin/scripts/trafd_move.pl

#!/usr/bin/perl

$srclogdir="/usr/local/var/trafd";
$dstdir="/usr/local/var/trafd/log";
$passeddir="/usr/local/var/trafd/passed";
$filemask=".IFACE_NAME";
($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=localtime(time());

opendir DIR,$srclogdir or die "Can't open logdir\n";
my @sorted=grep /$filemask/, readdir DIR;# or print "Trafd's logdir is empty\n";
closedir DIR or print "Can't close logdir\n";
@sorted=sort @sorted;
if ($#sorted >= 0){
   for($loop=0;$loop<=$#sorted;$loop++){
     #В этом месте мы можем делать с бинарным файлом все что угодно,
     #например натравить на него traflog, а затем переместить его в другую директорию
     $newname=sprintf("trafd_%02d%02d%02d_%02d%02d%02d_%02d.log",$year+1900,$mon+1,$day,$hour,$min,$sec,$loop);
     $cmd=sprintf("/usr/local/bin/traflog -o extnew -i %s/%s -a -n > %s/%s.passed",$srclogdir,$sorted[$loop],$passeddir,$newname);
     print "$cmd\n";
     system($cmd);
     $cmd=sprintf("/bin/mv %s/%s %s/%s",$srclogdir,$sorted[$loop],$dstdir,$newname);
     print "$cmd\n";
     system($cmd);
  }
}

Не забываем делать perl скрипт исполняемым:

chmod a+x perl_script_name.pl

Данный скрипт считает все файлы с маской $filemask в директории $srclogdir, затем он выполнит traflog и результат положит в $passeddir, а затем переместит бинарный файл с логами в $dstdir

Имена итоговых файлов будут такими:

  1. trafd_годмесяцдень_часыминутысукунды_номерфайла.log
  2. trafd_годмесяцдень_часыминутысукунды_номерфайла.log.passed

Пример: trafd_20080530_100830_02.log

Теперь можно поправить /ect/crontab:

*/5 * * * * * * root /usr/local/bin/trafdump IFACE_NAME; sleep 2; /usr/local/bin/trafsave IFACE_NAME sleep 2; /usr/local/sbin/scripts/trafd_move.pl

Не забыв поменять IFACE_NAME на имя своего интерфейса, а так же это должно быть написано одной строкой, без переносов на новую строчку конфига /ect/crontab.

З.Ы. Если кому-нить интересно, то можем привести пример с сохранением трафика в БД Mysql и код на PHP для просмотра статистики.

Вопрос:

trafd выдает bytes и psize. psize всегда больше. Что такое bytes в trafd ? Как считает провайдер ?

Ответ:

Смотрим в /usr/local/etc/traflog.format

# bytes number of data bytes
# psize number of all bytes

Итак bytes — это счетчик только данных, а psize это все переданные данные, включая технические (установка сессии и т.п.).

Провайдеры всегда берут psize, т.к. это включает в себя весь трафик переданный от или к пользователю.

Авторы:
Николаев Дмитрий (virus (at) subnets.ru)
Панфилов Алексей (lehis (at) subnets.ru)

Похожие статьи:

    Не найдено

Прочитано: 8 358 раз(а)
Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 2, среднее: 5,00 из 5)
Загрузка...
Отправить на почту Отправить на почту

комментария 3

  1. simple123 сказал:

    З.Ы. Если кому-нить интересно, то можем привести пример с сохранением трафика в БД Mysql и код на PHP для просмотра статистики.

    А выложите пожалуйста эти скрипты, буду очень признателен!!!
    Спасибо!

  2. admin сказал:

    SQL:

    CREATE TABLE `all_traf` (
      `id` bigint(20) NOT NULL auto_increment,
      `src_ip` bigint(20) NOT NULL default '0',
      `src_port` varchar(20) NOT NULL default '',
      `dst_ip` bigint(20) NOT NULL default '0',
      `dst_port` varchar(20) NOT NULL default '',
      `proto` varchar(20) NOT NULL default '',
      `start_time` datetime NOT NULL default '0000-00-00 00:00:00',
      `end_time` datetime NOT NULL default '0000-00-00 00:00:00',
      `bytes` bigint(20) NOT NULL default '0',
      `data_bytes` bigint(20) NOT NULL default '0',
      KEY `id` (`id`),
      KEY `src_ip` (`src_ip`),
      KEY `dst_ip` (`dst_ip`),
      KEY `s_t` (`start_time`),
      KEY `e_t` (`end_time`),
      KEY `complex` (`src_ip`,`dst_ip`,`start_time`,`end_time`)
    ) TYPE=MyISAM;
    

    PERL:

    #!/usr/bin/perl
    my $database="DB_NAME";
    my $host="localhost";
    my $user="USER";
    my $password="PASSWORD";
    my $port="3306";
    
    my $dsn = "DBI:mysql:database=$database;host=$host;port=$port";
    my $dbh = DBI->connect($dsn, $user, $password);
    
    sub mys {
            my $q=shift;
            my $a;
            $a = $dbh->prepare($q);
            $a->execute;
            return $a;
    }
    
    $logs_dir="/usr/local/var/trafd";
    $filelog="/usr/local/sbin/xxx";
    opendir DIR,$logs_dir;
    @files=grep  /(w{1,}).([0-0]{1,4})/, readdir DIR;
    closedir dir;
    @sorted=grep /(w{1,}).(w{2,})([0-0]{1})/,@files;
    print "Sorted: @sortedn";
    $dim=scalar(@sorted);
    print "Begin...n$dimn";
    for($loop=0;$loop< =$#sorted;$loop++){
            $file=$sorted[$loop];
            print "$loop: Processing :".$file."n";
            @if=split('.',$file);
            $s=sprintf("/usr/local/bin/traflog -o ext -i %s/%s -a -n >>%s",$logs_dir,$file,$filelog);
            system("$s");
            count ($filelog,"all_traf",@if[1]);
    }
    sub count {
            $file=$_[0];
            $table=$_[1];
            $iface=$_[2];
            $lines=0;
            open (f,$file);
            $total_lines=0;
            while (){
                    $total_lines++;
            }
            close f;
            open (f,"$file");
            open (log_file,">>/usr/local/var/shit.log");
            $str="";
            while ($str=){
                    if($str=~/^(d{1,}.d{1,}.d{1,}.d{1,})s+(S{1,})s+(d{1,}.d{1,}.d{1,}.d{1,})s+(S{1,})s+(S{1,})s+(d{1,})s+(d{1,})s+(S{1,})s+(S{1,})s+(S{1,})s+(S{1,})/){
                            if($lines%100==0){printf("%d of %dn",$lines,$total_lines);}
                            $lines++; 
                            $src_ip=$1;
                            $src_port=$2;
                            $dst_ip=$3;
                            $dst_port=$4;
                            $proto=$5;
                            $data_bytes=$6;
                            $bytes=$7;
                            $s_t_in=sprintf ("%s %s",$8,$9);
                            $e_t_in=sprintf ("%s %s",$10,$11);
                            if ($data_bytes <0) {$data_bytes=0;}
                            if ($bytes <0) {$bytes=0;}
                            $s_t_in=~/(d{4})D(d{1,2})D(d{1,2}).(d{1,2}):(d{1,2}):(d{1,2})/;
                            $s_t=sprintf ("%d-%02d-%02d %02d:%02d:%02d",$1,$2,$3,$4,$5,0);
                            $s_t1=sprintf ("%d-%02d-%02d %02d:%02d:%02d",$1,$2,$3,$4,0,0);
                            $e_t_in=~/(d{4})D(d{1,2})D(d{1,2}).(d{1,2}):(d{1,2}):(d{1,2})/;
                            $e_t=sprintf ("%d-%02d-%02d %02d:%02d:%02d",$1,$2,$3,$4,$5,0);
                            while( ! (mys("INSERT into $table (src_ip,src_port,dst_ip,dst_port,proto,data_bytes,bytes,start_time,end_time) VALUES(INET_ATON('$src_ip'),'$src_po
    rt',INET_ATON('$dst_ip'),'$dst_port','$proto','$data_bytes','$bytes','$s_t','$e_t')") )){
                                            print "nretrying ($Mysql::db_errstr)...n";
                                            sleep 3;
                                    }
                    }else{
                            print log_file "$strn";
                    }
            }
            close log_file;
            close f;
            `rm $file`;
            ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time-86400);
            $newname0 = sprintf("%02d%02d%02d%02d%02d.%s", 100-$year, $mon+1, $mday+1, $hour, $min, $iface);
            system("mv /usr/local/var/trafd/trafd.$iface /usr/local/var/stats/$newname0");
    }
    

    и дописать в файл traflog.format:

    ext {
    
    from:"%-18.18s " sport:"%-6.6s "        to:"%-18.18s " dport:"%-6.6s "
                    proto:"%-4.4s " bytes:"%9ld " psize:"%10ld" ftime:" %Y-%m-%d %T" ltime:" %Y-%m-%d %Tn"
    
    }; 

Добавить комментарий

Вам следует авторизоваться для размещения комментария.