فهرست منبع

fixed traffic reports in web
fixed hour's user stat

Dmitriev Roman 3 ماه پیش
والد
کامیت
da3e8cf830

+ 6 - 3
docs/databases/mysql/en/create_db.sql

@@ -425,7 +425,10 @@ CREATE TABLE `user_stats` (
   `auth_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
   `ts` datetime NOT NULL DEFAULT current_timestamp(),
   `byte_in` bigint(20) NOT NULL DEFAULT 0,
-  `byte_out` bigint(20) NOT NULL DEFAULT 0
+  `byte_out` bigint(20) NOT NULL DEFAULT 0,
+  `pkt_in` int(11) NOT NULL DEFAULT 0,
+  `pkt_out` int(11) NOT NULL DEFAULT 0,
+  `step` int(11) NOT NULL DEFAULT 3600
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
 CREATE TABLE `user_stats_full` (
@@ -435,8 +438,8 @@ CREATE TABLE `user_stats_full` (
   `ts` datetime NOT NULL DEFAULT current_timestamp(),
   `byte_in` bigint(20) NOT NULL DEFAULT 0,
   `byte_out` bigint(20) NOT NULL DEFAULT 0,
-  `pkt_in` int(11) DEFAULT NULL,
-  `pkt_out` int(11) DEFAULT NULL,
+  `pkt_in` int(11) NOT NULL DEFAULT 0,
+  `pkt_out` int(11) NOT NULL DEFAULT 0,
   `step` int(11) NOT NULL DEFAULT 600
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 

+ 6 - 3
docs/databases/mysql/ru/create_db.sql

@@ -425,7 +425,10 @@ CREATE TABLE `user_stats` (
   `auth_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
   `ts` datetime NOT NULL DEFAULT current_timestamp(),
   `byte_in` bigint(20) NOT NULL DEFAULT 0,
-  `byte_out` bigint(20) NOT NULL DEFAULT 0
+  `byte_out` bigint(20) NOT NULL DEFAULT 0,
+  `pkt_in` int(11) NOT NULL DEFAULT 0,
+  `pkt_out` int(11) NOT NULL DEFAULT 0,
+  `step` int(11) NOT NULL DEFAULT 3600
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
 CREATE TABLE `user_stats_full` (
@@ -435,8 +438,8 @@ CREATE TABLE `user_stats_full` (
   `ts` datetime NOT NULL DEFAULT current_timestamp(),
   `byte_in` bigint(20) NOT NULL DEFAULT 0,
   `byte_out` bigint(20) NOT NULL DEFAULT 0,
-  `pkt_in` int(11) DEFAULT NULL,
-  `pkt_out` int(11) DEFAULT NULL,
+  `pkt_in` int(11) NOT NULL DEFAULT 0,
+  `pkt_out` int(11) NOT NULL DEFAULT 0,
   `step` int(11) NOT NULL DEFAULT 600
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 

+ 6 - 3
docs/databases/postgres/en/create_db.sql

@@ -553,7 +553,10 @@ router_id BIGINT DEFAULT 0,
 auth_id BIGINT NOT NULL DEFAULT 0,
 ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
 byte_in BIGINT NOT NULL DEFAULT 0,
-byte_out BIGINT NOT NULL DEFAULT 0
+byte_out BIGINT NOT NULL DEFAULT 0,
+pkt_in INTEGER NOT NULL DEFAULT 0,
+pkt_out INTEGER NOT NULL DEFAULT 0,
+step SMALLINT NOT NULL DEFAULT 3600
 );
 COMMENT ON TABLE user_stats IS 'Aggregated user traffic statistics';
 
@@ -565,8 +568,8 @@ auth_id BIGINT NOT NULL DEFAULT 0,
 ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
 byte_in BIGINT NOT NULL DEFAULT 0,
 byte_out BIGINT NOT NULL DEFAULT 0,
-pkt_in INTEGER,
-pkt_out INTEGER,
+pkt_in INTEGER NOT NULL DEFAULT 0,
+pkt_out INTEGER NOT NULL DEFAULT 0,
 step SMALLINT NOT NULL DEFAULT 600
 );
 COMMENT ON TABLE user_stats_full IS 'Detailed user traffic statistics';

+ 30 - 19
html/admin/reports/index-full.php

@@ -24,40 +24,50 @@ print_reports_submenu($page_url);
 
 <?php
 
+$traffic_stat_table = 'user_stats_full';
+if ($days_shift >= $config["traffic_ipstat_history"]) { $traffic_stat_table = 'user_stats'; }
+
 $sort_sql=" ORDER BY tin DESC";
 
 if (!empty($sort_field) and !empty($order)) { $sort_sql = " ORDER BY $sort_field $order"; }
 
 $gateway_list = get_gateways($db_link);
 
-$trafSQL = "SELECT 
-user_list.login,user_list.ou_id,user_auth.user_id, user_auth.ip, user_stats_full.auth_id, 
-user_stats_full.router_id, SUM( byte_in ) AS tin, SUM( byte_out ) AS tout, MAX(ROUND(pkt_in/step)) as pin, MAX(ROUND(pkt_out/step)) as pout 
-FROM user_stats_full,user_auth,user_list WHERE user_list.id=user_auth.user_id 
-AND user_stats_full.auth_id = user_auth.id 
-AND user_stats_full.ts>='$date1' 
-AND user_stats_full.ts<'$date2' 
-";
+$sql_params=[];
+
+$trafSQL = "SELECT user_auth.id, ".$traffic_stat_table.".router_id,
+SUM( byte_in ) AS tin, SUM( byte_out ) AS tout, MAX(ROUND(pkt_in/step)) as pin, MAX(ROUND(pkt_out/step)) as pout 
+FROM ".$traffic_stat_table.",user_auth,user_list WHERE user_list.id=user_auth.user_id 
+AND ".$traffic_stat_table.".auth_id = user_auth.id 
+AND ".$traffic_stat_table.".ts>= ? AND ".$traffic_stat_table.".ts< ?";
+
+array_push($sql_params,$date1);
+array_push($sql_params,$date2);
 
 if ($rou !== 0) {
-    $trafSQL = $trafSQL . " AND user_list.ou_id=$rou";
+    $trafSQL = $trafSQL . " AND user_list.ou_id=?";
+    array_push($sql_params,$rou);
 }
 
-if ($rgateway == 0) {
-    $trafSQL = $trafSQL . " GROUP by user_auth.id,user_stats_full.router_id";
-} else {
-    $trafSQL = $trafSQL . " AND user_stats_full.router_id=$rgateway GROUP by user_auth.id,user_stats_full.router_id";
+if ($rgateway >0) {
+    $trafSQL = $trafSQL . " AND ".$traffic_stat_table.".router_id= ?";
+    array_push($sql_params,$rgateway);
 }
 
+$trafSQL = $trafSQL . " GROUP by user_auth.id,".$traffic_stat_table.".router_id";
+
 $countSQL = "SELECT Count(*) FROM ($trafSQL) A";
-$count_records = get_single_field($db_link,$countSQL);
+$count_records = get_single_field($db_link,$countSQL,$sql_params);
+
 $total=ceil($count_records/$displayed);
 if ($page>$total) { $page=$total; }
 if ($page<1) { $page=1; }
 $start = ($page * $displayed) - $displayed;
 
 #set sort
-$trafSQL=$trafSQL ." $sort_sql LIMIT $displayed OFFSET $start";
+$trafSQL=$trafSQL ." $sort_sql LIMIT ? OFFSET ?";
+array_push($sql_params,$displayed);
+array_push($sql_params,$start);
 
 print_navigation($page_url,$page,$displayed,$count_records,$total);
 
@@ -76,7 +86,7 @@ print "</tr>\n";
 $total_in = 0;
 $total_out = 0;
 
-$traf = get_records_sql($db_link, $trafSQL);
+$traf = get_records_sql($db_link, $trafSQL, $sql_params);
 
 foreach ($traf as $row) {
     if ($row['tin'] + $row['tout'] == 0) { continue; }
@@ -84,10 +94,11 @@ foreach ($traf as $row) {
     $total_out += $row['tout'];
     $s_router = !empty($gateway_list[$row['router_id']]) ? $gateway_list[$row['router_id']] : '';
     $cl = $row['tout'] > 2 * $row['tin'] ? "nb" : "data";
-    
+    $a_SQL='SELECT ip,U.login FROM user_auth, user_list as U where user_auth.user_id=U.id and user_auth.id=?';
+    $auth_record = get_record_sql($db_link,$a_SQL,[$row['id']]);
     print "<tr align=center class=\"tr1\" onmouseover=\"className='tr2'\" onmouseout=\"className='tr1'\">\n";
-    print "<td align=left class=\"$cl\">" . $row['login'] . "</td>\n";
-    print "<td align=left class=\"$cl\"><a href=authday.php?id=" . $row['auth_id'] . "&date_start=$date1&date_stop=$date2>" . $row['ip'] . "</a></td>\n";
+    print "<td align=left class=\"$cl\">" . $auth_record['login'] . "</td>\n";
+    print "<td align=left class=\"$cl\"><a href=authday.php?id=" . $row['id'] . "&date_start=$date1&date_stop=$date2>" . $auth_record['ip'] . "</a></td>\n";
     print "<td align=left class=\"$cl\">$s_router</td>\n";
     print "<td class=\"$cl\">" . fbytes($row['tin']) . "</td>\n";
     print "<td class=\"$cl\">" . fbytes($row['tout']) . "</td>\n";

+ 79 - 27
html/admin/reports/index.php

@@ -23,14 +23,9 @@ print_reports_submenu($page_url);
 </form>
 
 <?php
-print "<br><br>\n";
-print "<table class=\"data\">\n";
-print "<tr class=\"info\">\n";
-print "<td ><b><a href=index.php?sort=login&order=$new_order>".WEB_cell_login."</a></b></td>\n";
-print "<td ><b>".WEB_cell_gateway."</b></td>\n";
-print "<td ><b><a href=index.php?sort=tin&order=$new_order>".WEB_title_input."</a></b></td>\n";
-print "<td ><b><a href=index.php?sort=tout&order=$new_order>".WEB_title_output."<a></b></td>\n";
-print "</tr>\n";
+
+$traffic_stat_table = 'user_stats_full';
+if ($days_shift >= $config["traffic_ipstat_history"]) { $traffic_stat_table = 'user_stats'; }
 
 $sort_sql=" ORDER BY tin DESC";
 
@@ -38,30 +33,58 @@ if (!empty($sort_field) and !empty($order)) { $sort_sql = " ORDER BY $sort_field
 
 $gateway_list = get_gateways($db_link);
 
-$trafSQL = "SELECT 
-user_list.login,user_list.ou_id,user_auth.user_id, user_stats.auth_id, 
-user_stats.router_id, SUM( byte_in ) AS tin, SUM( byte_out ) AS tout 
-FROM user_stats,user_auth,user_list WHERE user_list.id=user_auth.user_id 
-AND user_stats.auth_id = user_auth.id 
-AND user_stats.ts>='$date1' 
-AND user_stats.ts<'$date2' 
-";
+$sql_params=[];
 
-if ($rou !== 0) { $trafSQL = $trafSQL . " AND user_list.ou_id=$rou"; }
+$trafSQL = "SELECT user_auth.user_id,".$traffic_stat_table.".router_id,
+SUM( byte_in ) AS tin, SUM( byte_out ) AS tout, MAX(ROUND(pkt_in/step)) as pin, MAX(ROUND(pkt_out/step)) as pout 
+FROM ".$traffic_stat_table.",user_auth,user_list WHERE user_list.id=user_auth.user_id 
+AND ".$traffic_stat_table.".auth_id = user_auth.id 
+AND ".$traffic_stat_table.".ts>= ? AND ".$traffic_stat_table.".ts< ?";
 
-if ($rgateway == 0) {
-    $trafSQL = $trafSQL . " GROUP by user_auth.user_id,user_stats.router_id";
-    } else {
-    $trafSQL = $trafSQL . " AND user_stats.router_id=$rgateway GROUP by user_auth.user_id,user_stats.router_id";
-    }
+array_push($sql_params,$date1);
+array_push($sql_params,$date2);
+if ($rou !== 0) {
+    $trafSQL = $trafSQL . " AND user_list.ou_id=?";
+    array_push($sql_params,$rou);
+}
+
+if ($rgateway >0) {
+    $trafSQL = $trafSQL . " AND ".$traffic_stat_table.".router_id= ?";
+    array_push($sql_params,$rgateway);
+}
+
+$trafSQL = $trafSQL . "  GROUP by user_auth.user_id,".$traffic_stat_table.".router_id";
+
+$countSQL = "SELECT Count(*) FROM ($trafSQL) A";
+$count_records = get_single_field($db_link,$countSQL,$sql_params);
+
+$total=ceil($count_records/$displayed);
+if ($page>$total) { $page=$total; }
+if ($page<1) { $page=1; }
+$start = ($page * $displayed) - $displayed;
 
 #set sort
-$trafSQL=$trafSQL ." $sort_sql";
+$trafSQL=$trafSQL ." $sort_sql LIMIT ? OFFSET ?";
+array_push($sql_params,$displayed);
+array_push($sql_params,$start);
+
+print_navigation($page_url,$page,$displayed,$count_records,$total);
+
+print "<br><br>\n";
+print "<table class=\"data\">\n";
+print "<tr class=\"info\">\n";
+print "<td ><b><a href=index.php?sort=login&order=$new_order>".WEB_cell_login."</a></b></td>\n";
+print "<td ><b>".WEB_cell_gateway."</b></td>\n";
+print "<td ><b><a href=index.php?sort=tin&order=$new_order>".WEB_title_input."</a></b></td>\n";
+print "<td ><b><a href=index.php?sort=tout&order=$new_order>".WEB_title_output."<a></b></td>\n";
+print "<td ><b><a href=index.php?sort=pin&order=$new_order>".WEB_title_maxpktin."</a></b></td>\n";
+print "<td ><b><a href=index.php?sort=pout&order=$new_order>".WEB_title_maxpktout."<a></b></td>\n";
+print "</tr>\n";
 
 $total_in = 0;
 $total_out = 0;
 
-$traf = get_records_sql($db_link, $trafSQL);
+$traf = get_records_sql($db_link, $trafSQL,$sql_params);
 
 foreach ($traf as $row) {
     if ($row['tin'] + $row['tout'] == 0) { continue; }
@@ -69,12 +92,16 @@ foreach ($traf as $row) {
     $total_out += $row['tout'];
     $s_router = !empty($gateway_list[$row['router_id']]) ? $gateway_list[$row['router_id']] : '';
     $cl = $row['tout'] > 2 * $row['tin'] ? "nb" : "data";
-    
+
+    $u_SQL='SELECT * FROM user_list WHERE id=?';
+    $user_record = get_record_sql($db_link,$u_SQL,[$row['user_id']]);
     print "<tr align=center class=\"tr1\" onmouseover=\"className='tr2'\" onmouseout=\"className='tr1'\">\n";
-    print "<td align=left class=\"$cl\"><a href=userday.php?id=" . $row['user_id'] . "&date_start=$date1&date_stop=$date2>" . $row['login'] . "</a></td>\n";
+    print "<td align=left class=\"$cl\"><a href=userday.php?id=" . $row['user_id'] . "&date_start=$date1&date_stop=$date2>" . $user_record['login'] . "</a></td>\n";
     print "<td align=left class=\"$cl\">$s_router</td>\n";
     print "<td class=\"$cl\">" . fbytes($row['tin']) . "</td>\n";
     print "<td class=\"$cl\">" . fbytes($row['tout']) . "</td>\n";
+    print "<td class=\"$cl\">" . fpkts($row['pin']) . "</td>\n";
+    print "<td class=\"$cl\">" . fpkts($row['pout']) . "</td>\n";
     print "</tr>\n";
 }
 
@@ -82,9 +109,34 @@ print "<tr align=center class=\"tr1\" onmouseover=\"className='tr2'\" onmouseout
 print "<td class=\"data\" colspan=2><b>".WEB_title_itog."</b></td>\n";
 print "<td class=\"data\"><b>" . fbytes($total_in) . "</b></td>\n";
 print "<td class=\"data\"><b>" . fbytes($total_out) . "</b></td>\n";
+print "<td class=\"data\"><b></b></td>\n";
+print "<td class=\"data\"><b></b></td>\n";
 print "</tr>\n";
 ?>
-  </table>
+</table>
+
+<?php
+print_navigation($page_url,$page,$displayed,$count_records,$total);
+?>
+
+<script>
+document.getElementById('ou').addEventListener('change', function(event) {
+  const buttonApply = document.getElementById('btn_filter');
+  buttonApply.click();
+});
+
+document.getElementById('rows').addEventListener('change', function(event) {
+  const buttonApply = document.getElementById('btn_filter');
+  buttonApply.click();
+});
+
+document.getElementById('gateway').addEventListener('change', function(event) {
+  const buttonApply = document.getElementById('btn_filter');
+  buttonApply.click();
+});
+
+</script>
+
 <?php
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/footer.php");
 ?>

+ 9 - 9
html/inc/common.php

@@ -2980,15 +2980,13 @@ function get_vendor($db, $mac)
     $mac5 = substr($mac, 0, 14);
     $mac4 = substr($mac, 0, 11);
     $mac3 = substr($mac, 0, 8);
-    $vendor = get_record_sql($db, 'SELECT companyName,companyAddress FROM mac_vendors WHERE oui="' . $mac . '"');
-    if (empty($vendor)) {
-        $vendor = get_record_sql($db, 'SELECT companyName,companyAddress FROM mac_vendors WHERE oui="' . $mac5 . '"');
-    }
-    if (empty($vendor)) {
-        $vendor = get_record_sql($db, 'SELECT companyName,companyAddress FROM mac_vendors WHERE oui="' . $mac4 . '"');
-    }
-    if (empty($vendor)) {
-        $vendor = get_record_sql($db, 'SELECT companyName,companyAddress FROM mac_vendors WHERE oui="' . $mac3 . '"');
+    
+    $vendor = null;
+    foreach ([$mac, $mac5, $mac4, $mac3] as $oui) {
+        $vendor = get_record_sql($db, 'SELECT companyName, companyAddress FROM mac_vendors WHERE oui = ?', [$oui]);
+        if (!empty($vendor)) {
+            break;
+        }
     }
     $result = '';
     if (!empty($vendor)) {
@@ -3776,6 +3774,8 @@ $config["snmp_default_version"] = get_option($db_link, 9);
 $config["snmp_default_community"] = get_option($db_link, 11);
 $config["auto_mac_rule"] = get_option($db_link, 64);
 
+$config["traffic_ipstat_history"] = get_option($db_link, 56);
+
 $config["cacti_url"] = rtrim(get_option($db_link, 58), '/');
 if (preg_match('/127.0.0.1/', $config["cacti_url"])) {
     $config["cacti_url"] = NULL;

+ 29 - 10
scripts/eye-statd.pl

@@ -758,10 +758,10 @@ undef %saved_netflow;
 #save statistics
 
 #start stat time
-my $hour_date1 = sprintf "%04d-%02d-%02d %02d:00:00",$year+1900,$month+1,$day,$hour;
+#my $hour_date1 = sprintf "%04d-%02d-%02d %02d:00:00",$year+1900,$month+1,$day,$hour;
 #end hour
-($hour,$day,$month,$year) = (localtime($last_time+3600))[2,3,4,5];
-my $hour_date2 = sprintf "%04d-%02d-%02d %02d:00:00",$year+1900,$month+1,$day,$hour;
+#($hour,$day,$month,$year) = (localtime($last_time+3600))[2,3,4,5];
+#my $hour_date2 = sprintf "%04d-%02d-%02d %02d:00:00",$year+1900,$month+1,$day,$hour;
 
 my @batch_user_stats=();
 my @batch_user_stats_update=();
@@ -781,6 +781,7 @@ foreach my $user_ip (keys %user_stats) {
     my ($sec,$min,$hour,$day,$month,$year) = (localtime($user_stats{$user_ip}{last_found}))[0,1,2,3,4,5];
     #flow time string
     my $flow_date = sprintf "%04d-%02d-%02d %02d:%02d:%02d",$year+1900,$month+1,$day,$hour,$min,$sec;
+    my $flow_hour_start = sprintf "%04d-%02d-%02d %02d:00:00", $year + 1900, $month + 1, $day, $hour;
 
     #last found timestamp
     push @batch_auth_status, [ $flow_date, $flow_date, $auth_id ];
@@ -807,22 +808,40 @@ foreach my $user_ip (keys %user_stats) {
     	    $timeshift ];
 	#hour stats
 	# get current stats
-	my $sql = "SELECT id, byte_in, byte_out FROM user_stats WHERE ts >= ? AND ts < ? AND router_id = ? AND auth_id = ?";
+	my $sql = "SELECT byte_in, byte_out, pkt_in, pkt_out  FROM user_stats WHERE ts = ? AND router_id = ? AND auth_id = ?";
 	my $hour_stat = get_record_sql($hdb, $sql, 
-	    $hour_date1,
-	    $hour_date2,
+	    $flow_hour_start,
 	    $router_id,
 	    $auth_id
 	    );
 	if (!$hour_stat) {
-            push @batch_user_stats, [ $flow_date, $auth_id, $router_id, $user_stats{$user_ip}{$router_id}{in}, $user_stats{$user_ip}{$router_id}{out} ];
+            push @batch_user_stats, [ 
+            $flow_hour_start,
+            $auth_id, 
+            $router_id, 
+            $user_stats{$user_ip}{$router_id}{in}, 
+            $user_stats{$user_ip}{$router_id}{out},
+            $user_stats{$user_ip}{$router_id}{pkt_in},
+            $user_stats{$user_ip}{$router_id}{pkt_out}, 
+            3600 ];
 	    next;
 	    }
 	if (!$hour_stat->{byte_in}) { $hour_stat->{byte_in}=0; }
 	if (!$hour_stat->{byte_out}) { $hour_stat->{byte_out}=0; }
+	if (!$hour_stat->{pkt_in}) { $hour_stat->{pkt_in}=0; }
+	if (!$hour_stat->{pkt_out}) { $hour_stat->{pkt_out}=0; }
 	$hour_stat->{byte_in} += $user_stats{$user_ip}{$router_id}{in};
 	$hour_stat->{byte_out} += $user_stats{$user_ip}{$router_id}{out};
-        push @batch_user_stats_update, [ $hour_stat->{byte_in}, $hour_stat->{byte_out}, $auth_id, $router_id ];
+	$hour_stat->{pkt_in} += $user_stats{$user_ip}{$router_id}{pkt_in};
+	$hour_stat->{pkt_out} += $user_stats{$user_ip}{$router_id}{pkt_out};
+        push @batch_user_stats_update, [ 
+            $hour_stat->{byte_in}, 
+            $hour_stat->{byte_out}, 
+            $hour_stat->{pkt_in}, 
+            $hour_stat->{pkt_out}, 
+	    $flow_hour_start,
+            $auth_id, 
+            $router_id ];
 	}
     }
 
@@ -861,10 +880,10 @@ batch_db_sql_cached($tSQL,\@batch_auth_status);
 $tSQL="INSERT INTO user_stats_full (ts,auth_id,router_id,byte_in,byte_out,pkt_in,pkt_out,step) VALUES( ?, ?, ?, ?, ?, ?, ?, ?)";
 batch_db_sql_cached($tSQL,\@batch_user_stats_full);
 
-$tSQL="INSERT INTO user_stats (ts,auth_id,router_id,byte_in,byte_out)  VALUES( ?, ?, ?, ?, ?, ?)";
+$tSQL="INSERT INTO user_stats (ts,auth_id,router_id,byte_in,byte_out,pkt_in,pkt_out,step) VALUES( ?, ?, ?, ?, ?, ?, ? ,?)";
 batch_db_sql_cached($tSQL,\@batch_user_stats);
 
-$tSQL="UPDATE user_stats SET byte_in= ?, byte_out= ? WHERE id= ? AND router_id= ?";
+$tSQL="UPDATE user_stats SET byte_in= ?, byte_out= ?, pkt_in = ?, pkt_out = ? WHERE ts = ? AND auth_id= ? AND router_id= ?";
 batch_db_sql_cached($tSQL,\@batch_user_stats_update);
 
 $tSQL="INSERT INTO wan_stats (ts,router_id,interface_id,bytes_in,bytes_out,forward_in,forward_out) VALUES( ?, ?, ?, ?, ?, ?, ?)";

+ 9 - 0
scripts/updates/3-0-1/migration.msql

@@ -96,3 +96,12 @@ ALTER TABLE dns_queue       CHANGE COLUMN `type` operation_type VARCHAR(10) NOT
 ALTER TABLE filter_list     CHANGE COLUMN `type` filter_type SMALLINT NOT NULL DEFAULT 0;
 
 UPDATE user_auth SET mac_found = last_found WHERE last_found IS NOT NULL;
+
+-- user_stats - add pkt counters
+
+ALTER TABLE `user_stats` ADD COLUMN `pkt_in` int(11) NOT NULL DEFAULT 0;
+ALTER TABLE `user_stats` ADD COLUMN `pkt_out` int(11) NOT NULL DEFAULT 0;
+ALTER TABLE `user_stats` ADD COLUMN `step` int(11) NOT NULL DEFAULT 3600;
+
+ALTER TABLE `user_stats_full` MODIFY COLUMN `pkt_in` int(11) NOT NULL DEFAULT 0;
+ALTER TABLE `user_stats_full` MODIFY COLUMN `pkt_out` int(11) NOT NULL DEFAULT 0;

+ 16 - 0
scripts/updates/3-0-1/migration.psql

@@ -84,3 +84,19 @@ ALTER TABLE dns_queue RENAME COLUMN type TO operation_type;
 ALTER TABLE filter_list RENAME COLUMN type TO filter_type;
 
 UPDATE user_auth SET mac_found = last_found WHERE last_found IS NOT NULL;
+
+-- user_stats - set default value 0
+
+ALTER TABLE user_stats ADD COLUMN pkt_in integer NOT NULL DEFAULT 0;
+ALTER TABLE user_stats ADD COLUMN pkt_out integer NOT NULL DEFAULT 0;
+ALTER TABLE user_stats ADD COLUMN step integer NOT NULL DEFAULT 3600;
+
+-- Сначала обновите NULL-значения на 0 (если они есть)
+UPDATE user_stats_full SET pkt_in = 0 WHERE pkt_in IS NULL;
+UPDATE user_stats_full SET pkt_out = 0 WHERE pkt_out IS NULL;
+
+-- Затем измените столбцы
+ALTER TABLE user_stats_full ALTER COLUMN pkt_in SET NOT NULL;
+ALTER TABLE user_stats_full ALTER COLUMN pkt_in SET DEFAULT 0;
+ALTER TABLE user_stats_full ALTER COLUMN pkt_out SET NOT NULL;
+ALTER TABLE user_stats_full ALTER COLUMN pkt_out SET DEFAULT 0;