Před nějakým časem jsem slíbil vlastni skript pro uložení informací o stažených datech jednotlivých userů. Skript je jen jeden, spouštím ho přes .bat soubor ve Win - jakási náhrada cronu.
SQL pro vytvoření tabulek:
--
-- Struktura tabulky `ip_acc`
--
CREATE TABLE `ip_acc` (
`id` int(8) unsigned NOT NULL auto_increment,
`ip` varchar(15) collate cp1250_czech_cs NOT NULL,
`date` date NOT NULL,
`up` bigint(20) unsigned NOT NULL,
`up_packet` int(11) unsigned NOT NULL,
`down` bigint(20) unsigned NOT NULL,
`down_packet` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1250 COLLATE=cp1250_czech_cs;
-- --------------------------------------------------------
--
-- Struktura tabulky `ip_log`
--
CREATE TABLE `ip_log` (
`id` int(9) NOT NULL auto_increment,
`src_ip` varchar(15) collate cp1250_czech_cs NOT NULL,
`dst_ip` varchar(15) collate cp1250_czech_cs NOT NULL,
`date` datetime NOT NULL,
`data` int(6) NOT NULL,
`packet` int(6) NOT NULL,
PRIMARY KEY (`id`),
KEY `date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1250 COLLATE=cp1250_czech_cs;
-- --------------------------------------------------------
--
-- Struktura tabulky `uzivatele` (osekal jsem nepodstatne sloupce, kazdy si doplni informace, ktere potrebuje)
--
CREATE TABLE `uzivatele` (
`id` int(11) NOT NULL auto_increment,
`ip` varchar(16) collate cp1250_czech_cs NOT NULL default '',
`jmeno` varchar(64) collate cp1250_czech_cs NOT NULL default '',
`dtLast` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1250 COLLATE=cp1250_czech_cs;
"CRON" je velmi primitivní:
:cyklus
@ECHO OFF
CALL php.exe c:/Home/netmon/collector.php
ping -n 1 -w 750 192.168.1.254 > nul
GOTO cyklus
A nakonec samotný skript pro zpracování dat z RB. Snažil jsem se okomentovat důležité části.
<?
// pripojeni k databazi
require_once("conn.php");
// nacteni relace
$session = file("session.tmp");
$time = trim($session[0]);
$interval = trim($session[1]);
$rozdil = time() - $time;
if($rozdil < $interval) {
exit;
}
// vytazeni IP adres vsech uzivatelu site
$sql = mysql_query("select ip from uzivatele");
while($ip = mysql_fetch_row($sql)) {
$ips[] = $ip[0];
}
list($max_id) = mysql_fetch_row(mysql_query("select max(id) from ip_log"));
// nacteni informaci z RB
$ip_router = "192.168.1.1";
$filename = "http://".$ip_router."/accounting/ip.cgi";
$file = file($filename);
// zpracovani
foreach ($file as $line_num => $line) {
list($src_ip, $dst_ip, $data, $packet) = explode(" ", $line);
$q_log = "INSERT INTO ip_log (src_ip, dst_ip, date, data, packet) VALUES ('$src_ip', '$dst_ip', NOW(), '$data', '$packet')";
$res_log = mysql_query($q_log);
if($src_ip != $dst_ip) {
if(in_array($src_ip, $ips)) $src = true;
else $src = false;
if(in_array($dst_ip, $ips)) $dst = true;
else $dst = false;
if ($src == true){
$query = "SELECT id, up, up_packet FROM ip_acc WHERE ip = '$src_ip' and date = CURDATE() limit 1";
$result = mysql_query($query);
if($row = mysql_fetch_array($result)) {
$id = $row['id'];
$up = $data + $row['up'];
$up_packet = $packet + $row['up_packet'];
$query2 = "UPDATE ip_acc SET up = '$up', up_packet = '$up_packet' WHERE id = '$id' limit 1";
}
else {
$query2 = "INSERT INTO ip_acc (ip, up, up_packet, date) VALUES ('$src_ip', '$data', '$packet', CURDATE())";
}
mysql_query($query2);
}
if ($dst == true){
$query = "SELECT id, down, down_packet FROM ip_acc WHERE ip = '$dst_ip' and date = CURDATE() limit 1";
$result = mysql_query($query);
if($row = mysql_fetch_array($result)) {
$id = $row['id'];
$down = $data + $row['down'];
$down_packet = $packet + $row['down_packet'];
$query2 = "UPDATE ip_acc SET down = '$down', down_packet = '$down_packet' WHERE id = '$id' limit 1";
}
else {
$query2 = "INSERT INTO ip_acc (ip, down, down_packet, date) VALUES ('$dst_ip', '$data', '$packet', CURDATE())";
}
mysql_query($query2);
}
unset($data, $packet);
}
}
// zaktualizujeme cas posledni aktivity uzivatele (pro zobrazeni uzivatelu, kteri jsou prave online)
$sql = mysql_query("select src_ip, dst_ip, date from ip_log where id > '$max_id' order by id desc");
while($radek = mysql_fetch_assoc($sql)) {
if(in_array($radek["src_ip"], $ips) or in_array($radek["dst_ip"], $ips)) {
foreach($ips as $key => $value) {
if($value == $radek["src_ip"] or $value == $radek["dst_ip"]) {
mysql_query("update uzivatele set dtLast = '$radek[date]' where ip = '$value' limit 1");
unset($ips[$key]);
break;
}
}
}
}
$pocet = sizeof($file);
// vypocteni intervalu pro dalsi stazeni dat z RB
if($interval <= 15) {
if($pocet < 50) $interval+=2;
elseif($pocet < 100) $interval++;
}
if($pocet > 250) {
if($interval > 5) $interval=5;
else $interval-=2;
}
elseif($pocet > 200) {
if($interval > 10) $interval=8;
else $interval-=3;
}
elseif($pocet > 150) {
if($interval > 10) $interval-=6;
elseif($interval > 7) $interval-=3;
else $interval--;
}
// ulozeni relace
file_put_contents("session.tmp", time()."\n".$interval);
mysql_close();
?>
S daty v tabulkách se pak již dá celkem solidně pracovat - generovat statistiky jednotlivých uživatelů podle dnů/týdnů..., generovat seznam právě připojených klientů, pro fajnšmekry jde zobrazovat datové toky v síti. Ve fantazii se meze nekladou ;-)