Версия скрипта снятия трафика с trafd, тупо переписанная на PERL - для учета интернет-трафика. Преимущество перед shell-версией: работает на одном коннекте к базе, потому процесс записи происходит в разы быстрее.
Кроме Perl (который установлен по дефолту) для работы скрипта необходимо установить:
*/5 * * * * /root/trafd_count.pl 1>/tmp/trafd_count 2>&1
#!/usr/bin/perl -W use DBI; # Адрес MySQL сервера $MySQL_host="sqlserver.local"; # или тупо по айпи $MySQL_host="192.168.0.254"; # Имя пользователя для доступа к БД в которой храниться траффик $user_name="trafdusr"; # Пароль пользователя MySQL $user_passw="trafdpassword"; # Имя базы данных $db_name="trafd"; # коннект unless($dbh = DBI->connect("DBI:mysql:$db_name:$MySQL_host",$user_name,$user_passw)) { die("Cannot connect to SQL-server."); } # текущие дата-время use Time::localtime; $tm = localtime; # Сегодяшний день, месяц, год ($day, $month, $year) = ($tm->mday, sprintf("%02d", $tm->mon+1), $tm->year+1900); $curr_date = $year . "-" . $month . "-" . $day; # Текущее время (секунды специально сделаны 00 - иногда cron запускает скрипт не # в 00 секунд а позже). $curr_time = $tm->hour . ":" . $tm->min . ":00"; # создаем временную таблицу для промежуточной обработки $dbh->do(" CREATE TABLE IF NOT EXISTS `traffic_tmp` ( `date` DATE NOT NULL, `time` TIME NOT NULL, `from_IP` CHAR(16) NOT NULL, `port_from_IP` CHAR(8) NOT NULL, `to_IP` CHAR(16) NOT NULL, `port_to_IP` CHAR(8) NOT NULL, `protocol` ENUM('icmp','tcp','udp') NOT NULL, `bytes` int(16) NOT NULL, `all_bytes` int(16) NOT NULL ) TYPE=MyISAM COMMENT='tmp_table'"); # Директория в которой будут храниться текстовые файлы с логами trafd $NewDir="/var/traffic/$year/$month"; # Пытаемся создать эту самую директорию на случай если это первый запуск # или произошла смена месяца (года) `mkdir -p $NewDir`; # Считываем строку из файла /etc/rc.conf с целью извлечь оттуда # названия интерфейсов по которым работает trafd $ifs = `. /etc/rc.conf ; echo \$trafd_ifaces`; # теперь по интерфейсам в цикле foreach $iface(split(' ', $ifs)) { # Сохраняем статистику по текущему интерфейсу `/usr/local/bin/trafsave $iface`; # Преобразуем логи из двоичного в текстовый формат. Сохраняются они в # папке /tmp в виде файлов summary.* c расширением по имени интерфейса `/usr/local/bin/traflog -i $iface -a -n -s > /tmp/summary.$iface 2>/dev/null`; # Очищаем файл с логами в двоичном формате `cat /dev/null > /usr/local/var/trafd/trafd.$iface`; # Дозаписываем логи в текстовый файл (пусть лежат на всякий случай...) `cat /tmp/summary.$iface >> $NewDir/summary.$iface`; # очищаем временную таблицу $dbh->do("TRUNCATE TABLE `traffic_tmp`;"); # открываем временный файл логов для чтения open(TLOG,"</tmp/summary.${iface}"); @strs = <TLOG>; close(TLOG); foreach $str(@strs) { @args = split(/[\s]+/, $str); # Загоняем полученную строку во временную таблицу $dbh->do(" INSERT INTO `traffic_tmp` ( `date`, `time`, `from_IP`, `port_from_IP`, `to_IP`, `port_to_IP`, `protocol`, `bytes`, `all_bytes` ) values ( '${curr_date}', '${curr_time}', '$args[0]', '$args[1]', '$args[2]', '$args[3]', '$args[4]', '$args[5]', '$args[6]' );"); } # Стираем пустые строки, с нулем байт и технической инфой $dbh->do(" DELETE FROM `traffic_tmp` WHERE (`from_IP`='' AND `port_from_IP`='' AND `to_IP`='' AND `port_to_IP`='' AND `protocol`='') OR `all_bytes`='0' OR `from_IP`='';"); # Создаём таблицу для окончательного хранения траффика $dbh->do(" CREATE TABLE IF NOT EXISTS `${iface}_${year}-${month}` ( `unic_id` INT(16) NOT NULL AUTO_INCREMENT, `date` DATE NOT NULL, `time` TIME NOT NULL, `from_IP` CHAR(16) NOT NULL, `port_from_IP` CHAR(8) NOT NULL, `to_IP` CHAR(16) NOT NULL, `port_to_IP` CHAR(8) NOT NULL, `protocol` ENUM('icmp','tcp','udp') NOT NULL, `bytes` int(16) NOT NULL, `all_bytes` int(16) NOT NULL, PRIMARY KEY (`unic_id`), KEY `date`(`date`) ) TYPE=MyISAM COMMENT='${iface} ${year}-${month}'; "); print "\n-- do INSERT --\n"; # Перекидываем траффик из временной таблицы в окончательную, при этом # объединяем строки в которых совпадает ВСЁ кроме числа байт. $dbh->do(" INSERT INTO `${iface}_${year}-${month}` ( `date`, `time`, `from_IP`, `port_from_IP`, `to_IP`, `port_to_IP`, `protocol`, `bytes`, `all_bytes` ) SELECT `date`, `time`, `from_IP`, `port_from_IP`, `to_IP`, `port_to_IP`, `protocol`, SUM(`bytes`) as `bytes`, SUM(`all_bytes`) as `all_bytes` FROM `traffic_tmp` GROUP BY `date`, `time`, `from_IP`, `port_from_IP`, `to_IP`, `port_to_IP`, `protocol`;"); } # Очищаем файл c логами о том когда и по какому интерфейсу сохранялась статистика `cat /dev/null > /var/log/traffic.log`; # вроде усе $dbh->disconnect;