Помогите составить запрос
Модератор: terminus
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
- alex3
- лейтенант
- Сообщения: 872
- Зарегистрирован: 2006-11-20 16:47:56
- Откуда: Переславль
- Контактная информация:
Помогите составить запрос
Сделал trafd по статье Лиса. Надо посчитать общий трафик за вычетом некоторых сетей провайдера. У меня загруз. Тупо перебирать номера не хочется, как это сделать элегантно... Сеть, например такая ххх.ххх.128.0-ххх.ххх.159.255....ломал голову, весь mysql.ru перечитал в части регекспов - так ни до чего не допер. предложение сделать что-то вроде "regexp 'ххх.ххх.1[2-5][0-9].[0-9]*'" не катит, поскольку сеть ххх.ххх.120.0 тоже удовлетворяет данному регекспу, но не является сеткой прова.
Если ipfw можно считать речью обычного человека, то pf - речь политика. За каждой ошибкой -ядерный песец.
Услуги хостинговой компании Host-Food.ru
Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/
-
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Re: Помогите составить запрос
я это делал с помощью временных таблиц и inet_aton, просто и красиво правда в итоге при разборе гиговых логов пришлось писать скрипт на C, уж больно много мускуль жрал ресурсовalex3 писал(а):Сделал trafd по статье Лиса. Надо посчитать общий трафик за вычетом некоторых сетей провайдера. У меня загруз.
- dikens3
- подполковник
- Сообщения: 4856
- Зарегистрирован: 2006-09-06 16:24:08
- Откуда: Нижний Новгород
- Контактная информация:
Re: Помогите составить запрос
Может поможет выделенное?#!/bin/sh
# Спам от провайдера NIS
echo "use exim; SELECT log.size,log.src_ip,log.time,log.hostname,log.helo,log.src_email,log.dst_email,textlog.text FROM log JOIN textlog ON log.action = textlog.id WHERE (src_ip BETWEEN '212.67.0.0' AND '212.67.31.255') AND (size IS NULL) ORDER BY log.time;" | \
mysql -u root -p$password > spamnis
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.
-
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Re: Помогите составить запрос
Код: Выделить всё
#!/usr/local/bin/php
<?
$argc = $argc;
$argv = $argv;
$errors = array();
$log_name = '';
$stderr = fopen('php://stderr', 'w');
$output_log = '';
$output_sum = '';
$date = date('Y-m-d');
if ( !_get_params() ) _exit_becouse_error( 'Illegal parameters' );
if ( $show_help || !$log_name ) exit(_show_help());
$log_name = realpath( $log_name );
// --------------
// Part two
// --------------
define('DB_CONNECT', true);
include('db.tables.inc.php');
include('db.config.inc.php');
$nets = prepare_nets();
//$nets = optimize_layers( $nets );
if ( !$nets ) _exit_becouse_error( 'No nets for ips' );
if ( !preg_match('/^\d{4}-\d\d-\d\d$/', $date) ) _exit_becouse_error( 'Illegal date' );
// Временная таблица масок сетей
// , PRIMARY KEY (`first_ip`,`last_ip`,`net_id`)
$sql = "CREATE TEMPORARY TABLE `t1` ( `first_ip` int(1) unsigned NOT NULL default '0', `last_ip` int(1) unsigned NOT NULL default '0', `net_id` tinyint(1) unsigned NOT NULL default '0', PRIMARY KEY (`first_ip`, `last_ip`) ) ENGINE = HEAP";
mysql_query( $sql );
$vals = array();
while ( list( , $net ) = each( & $nets ) )
{
$vals[] = '('. $net[ TBL_NMS_FIRST_IP ] .','. $net[ TBL_NMS_LAST_IP ] .','. $net[ TBL_NMS_NET_ID ] .')';
}
$sql = 'INSERT INTO t1 VALUES '. join(',',$vals);
if ( !mysql_query( $sql ) ) echo "error: can't insert nets\n" ;
unset($nets);
unset($vals);
// Временная таблица лога
$sql = "CREATE TEMPORARY TABLE `t` (`ip_sour` INT( 1 ) UNSIGNED NOT NULL ,`ip_dest` INT( 1 ) UNSIGNED NOT NULL ,`bytes` BIGINT( 1 ) UNSIGNED NOT NULL ,`net_id` SMALLINT( 1 ) UNSIGNED NOT NULL , `dogovor_id` SMALLINT( 1 ) UNSIGNED NOT NULL ) ENGINE=HEAP";
my_query( $sql );
timer();
$sql = "LOAD DATA INFILE '". realpath( $log_name ) ."' INTO TABLE t (ip_sour, ip_dest, bytes)";
if ( !mysql_query( $sql ) )
{
// Увы.. памяти не хватило... :(((
$fp = fopen('/usr/system/bin/MEMORY_LACK', "a+");
fputs($fp, date('Y-m-d H:i:s '). "log $log_name, size ". filesize( $log_name ). "\n");
fclose($fp);
// Придётся создавать временную таблицу в файле
my_query( 'DROP TABLE t' );
my_query( "CREATE TEMPORARY TABLE `t` (`ip_sour` INT( 1 ) UNSIGNED NOT NULL ,`ip_dest` INT( 1 ) UNSIGNED NOT NULL ,`bytes` BIGINT( 1 ) UNSIGNED NOT NULL ,`net_id` SMALLINT( 1 ) UNSIGNED NOT NULL , `dogovor_id` SMALLINT( 1 ) UNSIGNED NOT NULL )" );
my_query( $sql );
}
fputs($stderr, sprintf( 'Load time %.3f'."\n", timer() ));
timer();
// Привязка типа трафика к ip
$sql = 'update t, t1 set t.net_id = t1.net_id where t.ip_sour between t1.first_ip and t1.last_ip';
my_query( $sql );
fputs($stderr, sprintf( 'Update time %.3f'."\n", timer() ));
timer();
// Временная таблица IP
$sql = 'CREATE TEMPORARY TABLE `ips` ( `'. TBL_UIP_IP .'` INT( 1 ) UNSIGNED NOT NULL , `'. TBL_UIP_DOGOVOR_ID .'` SMALLINT( 1 ) UNSIGNED NOT NULL, PRIMARY KEY ( `'. TBL_UIP_IP .'` ) ) ENGINE=HEAP ;';
my_query( $sql );
// Заполняем IP
$sql = 'INSERT IGNORE INTO `ips` SELECT '. TBL_UIP_IP .', '. TBL_UIP_DOGOVOR_ID .' FROM '. TBL_N_USERS_IPS .' WHERE '. TBL_UIP_UDATE .' <= "'. $date .'" ORDER BY '. TBL_UIP_UDATE .' DESC';
my_query( $sql );
// Привязка ip к договорам
$sql = 'UPDATE t, ips SET t.dogovor_id=ips.'. TBL_UIP_DOGOVOR_ID .' WHERE t.ip_dest=ips.'. TBL_UIP_IP .'';
my_query($sql);
fputs($stderr, sprintf( 'IP\'s time %.3f'."\n", timer() ));
$tmp_log = tempnam('/tmp', 'aspdo');
@unlink( $tmp_log );
timer();
$sql = 'select ip_sour, ip_dest, bytes, net_id, if(dogovor_name is null, "NULL", dogovor_name) dogovor_name INTO OUTFILE "'. $tmp_log .'" from t left join billing_dogovors using(dogovor_id)';
$res = my_query( $sql );
if ( $output_log )
{
if ( is_file( $output_log ) ) @unlink( $output_log );
rename( $tmp_log, $output_log );
}
else
{
readfile( $tmp_log );
}
if ( file_exists( $tmp_log ) ) unlink( $tmp_log );
if ( $output_sum )
{
$sql = 'select if(dogovor_name is null, "NULL", dogovor_name), net_id, sum(bytes) INTO OUTFILE "'. $tmp_log .'" from t left join billing_dogovors using(dogovor_id) group by t.dogovor_id, net_id';
$res = my_query( $sql );
if ( file_exists( $output_sum ) ) @unlink( $output_sum );
rename( $tmp_log, $output_sum );
}
if ( file_exists( $tmp_log ) ) unlink( $tmp_log );
fputs($stderr, sprintf( 'Output time %.3f'."\n", timer() ));
mysql_close();
exit(0);
// ======================================
function _show_help ()
{
?>
Log parser, bind net_id to traffic
USAGE <?=basename(__FILE__)?> LOG_NAME [-o file] [-O file] [-d date]
-o Write data into file
-O Write summary data in file
-d Date like 2006-11-07
--help Show this message
<?
}
function _get_params ()
{
for ( $i = 1; $i < $GLOBALS['argc']; $i++ )
{
switch ( $GLOBALS['argv'][$i] )
{
case '--help':
$GLOBALS['show_help'] = true;
break;
case '-o':
$GLOBALS['output_log'] = @$GLOBALS['argv'][++$i];
break;
case '-O':
$GLOBALS['output_sum'] = @$GLOBALS['argv'][++$i];
break;
case '-d':
$GLOBALS['date'] = @$GLOBALS['argv'][++$i];
break;
default:
if ( !$GLOBALS['log_name'] )
{
$GLOBALS['log_name'] = $GLOBALS['argv'][$i];
}
else
{
return false;
}
}
}
return true;
}
function _exit_becouse_error ( $error )
{
echo 'Error: ', $error, "\n";
exit(-1);
}
function parse_hours ( $hours )
{
$parts = preg_split('/,/', $hours);
$result = array();
if ( $parts )
{
foreach ( $parts as $part )
{
if ( preg_match('/^(\d+)-(\d+)/', $part, $arr) )
{
// iterate HH-HH
$hour1 = $arr[1];
$hour2 = $arr[2];
if ( preg_match('/^(0+)/', $hour1, $arr) )
{
$padding = $arr[1];
$pad_len = strlen( $hour1 );
}
else
{
$padding = false;
$pad_len = 0;
}
$hour1 = (int) $hour1;
$hour2 = (int) $hour2;
for ( $i = $hour1; $i <= $hour2; $i += 1 )
{
if ( $pad_len )
{
$result[] = str_pad( $i, $pad_len, $padding, STR_PAD_LEFT );
}
else
{
$result[] = $i;
}
}
}
else
{
$result[] = $part;
}
}
}
$result = array_unique( $result );
sort( $result );
return $result;
}
function my_ip2long ( $ip )
{
if ( preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $ip) ) return sprintf('%u', ip2long( $ip ));
return $ip;
}
function get_nets ()
{
$sql = '
SELECT
nms.'. TBL_NMS_NET_ID .',
nms.'. TBL_NMS_Z_ORDER .',
nms.'. TBL_NMS_FIRST_IP .',
nms.'. TBL_NMS_LAST_IP .'
FROM
'. TBL_N_NETS_MASKS .' nms
ORDER BY
'. TBL_NMS_Z_ORDER .' ASC
';
$res = mysql_query( $sql );
$result = array();
if ( !$res ) return false;
while ( $row = mysql_fetch_assoc( $res ) )
{
$result[] = $row;
}
return $result;
}
function prepare_nets ( )
{
if ( ! ($nets = get_nets()) ) return false;
$net_layers = array();
foreach ( $nets as $net )
{
$net_layers[ $net[ TBL_NMS_Z_ORDER ] ][] = $net;
}
ksort( $net_layers );
// Пока есть хотя бы два слоя... будем крутиться
while ( count( $net_layers ) > 1 )
{
$layer1 = array_shift( $net_layers );
$layer2 = array_shift( $net_layers );
array_unshift( $net_layers, merge_layers($layer1, $layer2) );
}
return array_pop( $net_layers );
}
function merge_layers ( $layer1, $layer2 )
{
while ( list(, $net1) = each( & $layer1 ) )
{
reset( $layer2 );
while ( list($net2_id, $net2) = each( & $layer2 ) )
{
// Ситуация ?1 - первая маска левее второй
// mmmmm
// xxxxxx
// ========================================
if ( $net1[ TBL_NMS_LAST_IP ] < $net2[ TBL_NMS_FIRST_IP ] )
{
// Решение - первая маска должна просто добавится, но сначала надо проверить все сегменты
continue 1;
}
// Ситуация ?2 - первая маска частично залазит на вторую слева
// mmmmm
// xxxxxx
// ========================================
if (
$net1[ TBL_NMS_FIRST_IP ] <= $net2[ TBL_NMS_FIRST_IP ]
and
$net1[ TBL_NMS_LAST_IP ] >= $net2[ TBL_NMS_FIRST_IP ]
and
$net1[ TBL_NMS_LAST_IP ] < $net2[ TBL_NMS_LAST_IP ]
) {
// Решение - вторая маска урезается по краю второй
$layer2[ $net2_id ][ TBL_NMS_FIRST_IP ] = $net1[ TBL_NMS_LAST_IP ] + 1;
continue 1;
}
// Ситуация ?3 - первая маска поностью покрывает вторую
// mmmmmmmmmmmmmm
// xxxxxxxxx
// ========================================
if (
$net1[ TBL_NMS_FIRST_IP ] <= $net2[ TBL_NMS_FIRST_IP ]
and
$net1[ TBL_NMS_LAST_IP ] >= $net2[ TBL_NMS_LAST_IP ]
) {
// Решение - вторая маска анулируется
unset( $layer2[ $net2_id ] );
continue 1;
}
// Ситуация ?4 - первая маска делит вторую на две
// mmmmm
// xxxxxxxxxx
// ========================================
if (
$net1[ TBL_NMS_FIRST_IP ] > $net2[ TBL_NMS_FIRST_IP ]
and
$net1[ TBL_NMS_LAST_IP ] < $net2 [ TBL_NMS_LAST_IP ]
)
{
// Решение обрезать вторую маску по левой границе первой и добавить новый сегмент
$layer2[ $net2_id ][ TBL_NMS_LAST_IP ] = $net1[ TBL_NMS_FIRST_IP ] - 1;
$new_segment = $net2;
$new_segment[ TBL_NMS_FIRST_IP ] = $net1[ TBL_NMS_LAST_IP ] + 1;
$layer2[] = $new_segment;
continue 1;
}
// Ситуация ?5 - первая маска частично перекрывает вторую справа
// mmmmmmmmmmm
// xxxxxxx
// ========================================
if (
$net1[ TBL_NMS_FIRST_IP ] > $net2[ TBL_NMS_FIRST_IP ]
and
$net1[ TBL_NMS_FIRST_IP ] <= $net2[ TBL_NMS_LAST_IP ]
and
$net1[ TBL_NMS_LAST_IP ] >= $net2[ TBL_NMS_LAST_IP ]
) {
// Решение - урезать вторую маску справа по границе первой
$layer2[ $net2_id ][ TBL_NMS_LAST_IP ] = $net1[ TBL_NMS_FIRST_IP ] - 1;
continue 1;
}
// Ситуация ?6 - первая маска правее второй
// mmmmmmmmmmm
// xxxxxxxx
// ========================================
if ( $net1[ TBL_NMS_FIRST_IP ] > $net2[ TBL_NMS_LAST_IP ] )
{
// Решение - просто продолжать смотреть сегменты
continue 1;
}
}
$layer2[] = $net1;
}
return $layer2;
}
function my_query ( $sql )
{
$res = mysql_query( $sql );
if ( !$res )
{
$str = "MYSQL ERROR: #". mysql_errno(). ' '. mysql_error(). "\n";
$str .= $sql. "\n";
if ( $GLOBALS['stderr'] ) fputs( $GLOBALS['stderr'], $str ); else $str;
exit(-1);
}
return $res;
}
function timer ( $name = 'default' , $unset_timer = true )
{
static $timers = array();
if ( !isset( $timers[ $name ] ) )
{
$timers[ $name ] = microtime();
return true;
}
list($s_sec, $s_mic) = split(' ', $timers[ $name ]);
list($e_sec, $e_mic) = split(' ', microtime());
$elapsed = $e_sec - $s_sec + ( $e_mic - $s_mic );
if ( $unset_timer ) unset( $timers[ $name ] );
return $elapsed;
}
function & optimize_layers ( & $nets )
{
$opti = $nets;
$chng = array();
reset( $nets );
while ( list( $i, $net ) = each( & $nets ) )
{
reset( $opti );
while ( list($i2, $met) = each( & $opti ) )
{
if ( $net[ TBL_NMS_NET_ID ] === $met[ TBL_NMS_NET_ID ] )
{
$result1 = $net[ TBL_NMS_LAST_IP ] - $met[ TBL_NMS_FIRST_IP ];
$result2 = $net[ TBL_NMS_FIRST_IP ] - $met[ TBL_NMS_LAST_IP ];
// Ситуация #1 - первая маска бок о бок стоит слева от второй
// nnnn mmmm
if ( $result1 == -1 )
{
// Решение - сместить правую границу $net и анулировать $met
$chng[] = array( $net, $met );
$opti[ $i ][ TBL_NMS_LAST_IP ] = $opti[ $i2 ][ TBL_NMS_LAST_IP ];
$opti[ $i2 ][ TBL_NMS_NET_ID ] = 0;
}
// Ситуация #2 - левая граница маски граничит с такой же сетью
// mmmm nnnn
elseif ( $result2 == 1 )
{
// Решение - сместить левую границу маски и анулировать $met
$chng[] = array( $net, $met );
$opti[ $i ][ TBL_NMS_FIRST_IP ] = $opti[ $i2 ][ TBL_NMS_FIRST_IP ];
$opti[ $i2 ][ TBL_NMS_NET_ID ] = 0;
}
}
}
}
reset( $opti );
while ( list( $i, $net ) = each( & $opti ) )
{
if ( $net[ TBL_NMS_NET_ID ] == 0 ) unset( $opti[ $i ] );
}
reset( $opti );
return $opti;
}
?>
-
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Re: Помогите составить запрос
Короче прога, которая из логов вида
может делать следующие логи
Формат вызова , где
юзай
Код: Выделить всё
IP-Источник IP-получатель Кол-во
IP-Источник IP-получатель Кол-во
IP-Источник IP-получатель Кол-во
...
Код: Выделить всё
IP-источник IP-получатель Кол-во Тип трафика Договор
IP-источник IP-получатель Кол-во Тип трафика Договор
IP-источник IP-получатель Кол-во Тип трафика Договор
.............
Код: Выделить всё
logh -n nets.txt -g dogovory.txt logfile.txt
Код: Выделить всё
nets.txt
---------------
# Net1
* 1
1.2.3.4/32
1.2.3.4/32
1.2.3.4/32
# Net2
* 2
2.3.4.5/32
2.3.4.5/32
2.3.4.5/32
# Net3
* 3
2.3.4.5/32
2.3.4.5/32
2.3.4.5/32
.....
Код: Выделить всё
dogovory.txt
----------------
1.2.3.4 Dogovor1
1.2.3.5 Dogovor2
....
- Вложения
-
- logh.gz
- Скомпилирована на freebsd6.1
- (5.51 КБ) 23 скачивания
- Alex Keda
- стреляли...
- Сообщения: 35466
- Зарегистрирован: 2004-10-18 14:25:19
- Откуда: Made in USSR
- Контактная информация:
- alex3
- лейтенант
- Сообщения: 872
- Зарегистрирован: 2006-11-20 16:47:56
- Откуда: Переславль
- Контактная информация:
Re: Помогите составить запрос
Лис, ты как всегда краток
Если ipfw можно считать речью обычного человека, то pf - речь политика. За каждой ошибкой -ядерный песец.
- Alex Keda
- стреляли...
- Сообщения: 35466
- Зарегистрирован: 2004-10-18 14:25:19
- Откуда: Made in USSR
- Контактная информация:
Re: Помогите составить запрос
ну, я помню что умеет - читал в книжке, а подробностей не помню.
И потом, я всегда оставляю простор для полёта творческой фантазии
И потом, я всегда оставляю простор для полёта творческой фантазии
Убей их всех! Бог потом рассортирует...