From c48bb3b4394462608eaeac925b8082865ee618e1 Mon Sep 17 00:00:00 2001 From: Sergey Dvoriancev Date: Fri, 11 May 2012 23:49:43 +0400 Subject: SQStat 1 --- config/lightsquid/sqstat.class.php | 1286 ++++++++++++++++-------------------- 1 file changed, 580 insertions(+), 706 deletions(-) (limited to 'config/lightsquid/sqstat.class.php') diff --git a/config/lightsquid/sqstat.class.php b/config/lightsquid/sqstat.class.php index 1ba15c8b..228aecfe 100644 --- a/config/lightsquid/sqstat.class.php +++ b/config/lightsquid/sqstat.class.php @@ -1,708 +1,582 @@ +sqstat_version = SQSTAT_VERSION; + + $this->squidhost = '127.0.0.1'; + $this->squidport = '3128'; + + $This->group_by = 'host'; + $this->resolveip = true; + $this->hosts_file = ''; + $this->autorefresh = 0; + $this->cachemgr_passwd = ''; + + $errno = 0; + $errstr = ''; + + if (!function_exists("preg_match")) { $this->errorMsg(5, 'You need to install PHP pcre extension to run this script'); + $this->showError(); + exit(5); + } + + // we need session support to gather avg. speed + if (function_exists("session_start")){ + $this->use_sessions=true; + } + + } + + function formatXHTML($body, $refresh, $use_js = false){ + $text=''."\n". + ''."\n" + .'' + .'' + .''; + if($refresh) $text.=''; + $text.='SqStat '.SQSTAT_VERSION.'' + .($use_js?'':'').'' + .($use_js?'
':'') + .$body.''; + return $text; + } + + function showError(){ + $text='

SqStat error

'. + '

Error ('.$this->errno.'): '.$this->errstr.''; + echo $this->formatXHTML($text,0); + } + + function connect($squidhost, $squidport){ + $this->fp = false; + # connecting to the squidhost + $this->fp = @fsockopen($squidhost, $squidport, $this->errno, $this->errstr, 10); + if (!$this->fp) { + # failed to connect + return false; + } + return true; + } + + # based @ (c) moritz at barafranca dot com + function duration ($seconds) { + $takes_time = array(604800,86400,3600,60,0); + $suffixes = array("w","d","h","m","s"); + $output = ""; + foreach ($takes_time as $key=>$val) { + ${$suffixes[$key]} = ($val == 0) ? $seconds : floor(($seconds/$val)); + $seconds -= ${$suffixes[$key]} * $val; + if (${$suffixes[$key]} > 0) { + $output .= ${$suffixes[$key]}; + $output .= $suffixes[$key]." "; + } + } + return trim($output); + } + + /** + * Format a number of bytes into a human readable format. + * Optionally choose the output format and/or force a particular unit + * + * @param int $bytes The number of bytes to format. Must be positive + * @param string $format Optional. The output format for the string + * @param string $force Optional. Force a certain unit. B|KB|MB|GB|TB + * @return string The formatted file size + */ + function filesize_format($bytes, $format = '', $force = '') + { + $force = strtoupper($force); + $defaultFormat = '%01d %s'; + if (strlen($format) == 0) + $format = $defaultFormat; + $bytes = max(0, (int) $bytes); + $units = array('b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'); + $power = array_search($force, $units); + if ($power === false) + $power = $bytes > 0 ? floor(log($bytes)/log(1024)) : 0; + return sprintf($format, $bytes / pow(1024, $power), $units[$power]); + } + + function makeQuery($pass = ""){ + $raw = array(); + # sending request + if(!$this->fp) + die("Please connect to server"); + + $out = "GET cache_object://localhost/active_requests HTTP/1.0\r\n"; + if ($pass != "") + $out .= "Authorization: Basic ".base64_encode("cachemgr:$pass")."\r\n"; + $out .= "\r\n"; + + fwrite($this->fp, $out); + + while (!feof($this->fp)) { + $raw[] = trim(fgets($this->fp, 2048)); + } + fclose($this->fp); + + if ($raw[0]!="HTTP/1.0 200 OK") { $this->errorMsg(1, "Cannot get data. Server answered: $raw[0]"); + return false; + } + + # parsing output; + $header = 1; + $connection = 0; + $parsed["server_version"] = "Unknown"; + foreach($raw as $key=>$v){ + # cutoff http header + if ($header==1 && $v=="") $header=0; + if ($header) { + if(substr(strtolower($v),0,7) == "server:") { # parsing server version + $parsed["server_version"] = substr($v,8); + } + } + else { + if(substr($v,0,11) == "Connection:") { # parsing connection + $connection = substr($v,12); + } + if ($connection) { + # username field is avaible in Squid 2.6 stable + if(substr($v,0,9) == "username ") $parsed["con"][$connection]["username"] = substr($v, 9); + if(substr($v,0,5) == "peer:") $parsed["con"][$connection]["peer"] = substr($v, 6); + if(substr($v,0,3) == "me:") $parsed["con"][$connection]["me"] = substr($v, 4); + if(substr($v,0,4) == "uri ") $parsed["con"][$connection]["uri"] = substr($v, 4); + if(substr($v,0,10) == "delay_pool") $parsed["con"][$connection]["delay_pool"] = substr($v, 11); + + if (preg_match('/out.offset \d+, out.size (\d+)/', $v, $matches)) { + $parsed["con"][$connection]["bytes"] = $matches[1]; + } + if (preg_match('/start \d+\.\d+ \((\d+).\d+ seconds ago\)/', $v, $matches)){ + $parsed["con"][$connection]["seconds"] = $matches[1]; + } + } + } + } + return $parsed; + } + + function implode_with_keys($array, $glue) { + foreach ($array as $key => $v){ + $ret[] = $key . '=' . htmlspecialchars($v); + } + return implode($glue, $ret); + } + + function makeHtmlReport($data, $resolveip = false, $hosts_array = array(), $use_js = true) { + global $group_by; + if($this->use_sessions){ + session_name('SQDATA'); + session_start(); + } + + $total_avg = $total_curr = 0; + // resort data array + $users=array(); + switch($group_by){ + case "host": + $group_by_name="Host"; + $group_by_key='return $ip;'; + break; + case "username": + $group_by_name="User"; + $group_by_key='return $v["username"];'; + break; + default: + die("wrong group_by!"); + } + + foreach($data["con"] as $key => $v){ + if(substr($v["uri"],0,13)=="cache_object:") continue; // skip myself + $ip=substr($v["peer"],0,strpos($v["peer"],":")); + if(isset($hosts_array[$ip])){ + $ip=$hosts_array[$ip]; + } + // i use ip2long() to make ip sorting work correctly + elseif($resolveip){ + $hostname=gethostbyaddr($ip); + if($hostname==$ip) $ip=ip2long($ip);// resolve failed + else $ip=$hostname; + } + else{ + $ip=ip2long(substr($v["peer"],0,strpos($v["peer"],":"))); + } + $v['connection'] = $key; + if(!isset($v["username"])) $v["username"]="N/A"; + $users[eval($group_by_key)][]=$v; + } + ksort($users); + $refresh=0; + if(isset($_GET["refresh"]) && !isset($_GET["stop"])) $refresh=(int)$_GET["refresh"]; + $text=''; + if(count($GLOBALS["configs"])==1) $servers=$GLOBALS["squidhost"].':'.$GLOBALS["squidport"]; + else{ + $servers=''; + } + $text.='
'. + 'Squid RealTime stat for the '.$servers.' proxy server ('.$data["server_version"].').
'. + 'Auto refresh: sec. Created at: '.date("h:i:s d/m/Y").'
'. + '
'. + ''. + ''. + ''. + ($this->use_sessions?'':''). + ''. + ''; + $ausers=$acon=0; + unset($session_data); + if (isset($_SESSION['time']) && ((time() - $_SESSION['time']) < 3*60) && isset($_SESSION['sqdata']) && is_array($_SESSION['sqdata'])) { + //only if the latest data was less than 3 minutes ago + $session_data = $_SESSION['sqdata']; + } + $table=''; + foreach($users as $key=>$v){ + $ausers++; + $table.=''. + ''; + $user_avg = $user_curr = $con_color = 0; + foreach ($v as $con){ + if(substr($con["uri"],0,7)=="http://" || substr($con["uri"],0,6)=="ftp://"){ + if(strlen($con["uri"])>SQSTAT_SHOWLEN) $uritext=htmlspecialchars(substr($con["uri"],0,SQSTAT_SHOWLEN)).' ....'; + else $uritext=htmlspecialchars($con["uri"]).''; + $uri=''.$uritext; + } + else $uri=htmlspecialchars($con["uri"]); + $acon++; + //speed stuff + $con_id = $con['connection']; + $is_time = time(); + $curr_speed=0; + $avg_speed=0; + if (isset($session_data[$con_id]) && $con_data = $session_data[$con_id] ) { + // if we have info about current connection, we do analyze its data + // current speed + $was_time = $con_data['time']; + $was_size = $con_data['size']; + if ($was_time && $was_size) { + $delta = $is_time - $was_time; + if ($delta == 0) { + $delta = 1; + } + if ($con['bytes'] >= $was_size) { + $curr_speed = ($con['bytes'] - $was_size) / 1024 / $delta; + } + } else { + $curr_speed = $con['bytes'] / 1024; + } + + //avg speed + $avg_speed = $con['bytes'] / 1024; + if ($con['seconds'] > 0) { + $avg_speed /= $con['seconds']; + } + } + + $new_data[$con_id]['time'] = $is_time; + $new_data[$con_id]['size'] = $con['bytes']; + + //sum speeds + $total_avg += $avg_speed; + $user_avg += $avg_speed; + $total_curr += $curr_speed; + $user_curr += $curr_speed; + + if($use_js) $js='onMouseout="hideddrivetip()" onMouseover="ddrivetip(\''.$this->implode_with_keys($con,'
').'\')"'; + else $js=''; + $table.='
'. + ''; + if($this->use_sessions){ + $table .= ''. + ''; + } + $table .= ''. + ''. + ''; + } + if($this->use_sessions){ + $table.=sprintf("", + $user_curr, $user_avg); + } + + } + $_SESSION['time'] = time(); + if(isset($new_data)) $_SESSION['sqdata'] = $new_data; + $stat_row=''; + if($this->use_sessions){ + $stat_row.=sprintf("", + $ausers, $acon, $total_curr, $total_avg); + } + else { + $stat_row.=sprintf("", + $ausers, $acon); + } + if($ausers==0){ + $text.=''; + } + else { + $text.=$stat_row.$table.$stat_row; + } + $text .= '
'.$group_by_name.'URICurr. SpeedAvg. SpeedSizeTime
'.(is_int($key)?long2ip($key):$key).' 
'.$uri.''.( (round($curr_speed, 2) > 0) ? sprintf("%01.2f KB/s", $curr_speed) : '' ).''.( (round($avg_speed, 2) > 0) ? sprintf("%01.2f KB/s", $avg_speed) : '' ). ''.$this->filesize_format($con["bytes"]).''.$this->duration($con["seconds"],"short").'
%01.2f KB/s%01.2f KB/s
Total:%d users and %d connections @ %01.2f/%01.2f KB/s (CURR/AVG)
Total:%d users and %d connections
No active connections
'. + '

© Alex Samorukov, 2006

'; + return $this->formatXHTML($text,$refresh,$use_js); + } + + function parseRequest($data, $group_by = 'host', $resolveip = false) { $parsed = array(); + if ($this->use_sessions) { + session_name('SQDATA'); + session_start(); + } + + # resort data array + $users = array(); + switch ($group_by) { + case "username": + $group_by_name = "User"; + $group_by_key = "username"; + break; + case "host": + default: + $group_by_name = "Host"; + $group_by_key = "peer"; + break; + } + + # resolve IP & group + foreach ($data["con"] as $key => $v) { # skip myself + if (substr($v["uri"], 0, 13) == "cache_object:") continue; + + $ip = substr($v["peer"], 0, strpos($v["peer"], ":")); + $v["peer"] = $ip; + + # name from hosts + if (isset($this->hosts[$ip])) { + $ip = $this->hosts[$ip]; + } + else + # i use ip2long() to make ip sorting work correctly + if ($resolveip) { + $hostname = gethostbyaddr($ip); + if ($hostname == $ip) + $ip = ip2long($ip); # resolve failed. use (ip2long) key + else $ip = $hostname; + } + else { + $ip = ip2long(substr($v["peer"], 0, strpos($v["peer"], ":"))); + } + $v['con_id'] = $key; + $v["username"] = isset($v["username"]) ? $v["username"] : "N/A"; + + # users [key => conn_array] + $users[$v[$group_by_key]][] = $v; + } + ksort($users); + + unset($session_data); + if (isset($_SESSION['time']) && ((time() - $_SESSION['time']) < 3*60) && + isset($_SESSION['sqdata']) && is_array($_SESSION['sqdata'])) { + # only if the latest data was less than 3 minutes ago + $session_data = $_SESSION['sqdata']; + } + + # users count & con cont + $ausers = $acon = 0; + $total_avg = $total_curr = 0; + foreach ($users as $key => $v) { $ausers++; + + $user_avg = $user_curr = $con_color = 0; + foreach ($v as $con_key => $con){ $cres = array(); + $acon++; + + $uritext = $con["uri"]; + if (substr($con["uri"], 0, 7) == "http://" || substr($con["uri"], 0, 6) == "ftp://") { + if (strlen($uritext) > SQSTAT_SHOWLEN) + $uritext = htmlspecialchars(substr($uritext, 0, SQSTAT_SHOWLEN)) . ' ....'; + } + else $uritext = htmlspecialchars($uritext); + $cres['uritext'] = $uritext; + $cres['uri'] = $con["uri"]; + + # speed stuff + $con_id = $con['connection']; + $is_time = time(); + $curr_speed = $avg_speed = 0; + if (isset($session_data[$con_id]) && $con_data = $session_data[$con_id] ) { + # if we have info about current connection, we do analyze its data + # current speed + $was_time = $con_data['time']; + $was_size = $con_data['size']; + if ($was_time && $was_size) { + $delta = $is_time - $was_time; + if ($delta == 0) { + $delta = 1; + } + if ($con['bytes'] >= $was_size) { + $curr_speed = ($con['bytes'] - $was_size) / 1024 / $delta; + } + } else { + $curr_speed = $con['bytes'] / 1024; + } + + # avg speed + $avg_speed = $con['bytes'] / 1024; + if ($con['seconds'] > 0) { + $avg_speed /= $con['seconds']; + } + } + $cres['cur_speed'] = $curr_speed; + $cres['avg_speed'] = $avg_speed; + $cres['seconds'] = $con["seconds"]; + $cres['bytes'] = $con["bytes"]; + + # groupped parsed[key => conn_key] + $parsed['users'][$key]['con'][$con_key] = $cres; + + # for sessions + $new_data[$con_id]['time'] = $is_time; + $new_data[$con_id]['size'] = $con['bytes']; + + # sum speeds + $total_avg += $avg_speed; + $user_avg += $avg_speed; + $total_curr += $curr_speed; + $user_curr += $curr_speed; + } + + # total per user + $parsed['users'][$key]['user_curr'] = $user_curr; + $parsed['users'][$key]['user_avg'] = $user_avg; + } + + # total info + $parsed['ausers'] = $ausers; + $parsed['acon'] = $acon; + $parsed['total_avg'] = $total_avg; + $parsed['total_curr'] = $total_curr; + + # update session info + $_SESSION['time'] = time(); + if (isset($new_data)) $_SESSION['sqdata'] = $new_data; + + return $parsed; + } + + function errorMsg($errno, $errstr) + { $this->errno = $errno; + $this->errstr = $errstr; + } + + function load_hosts() + { + # loading hosts file + $hosts_array = array(); + + if (!empty($this->hosts_file)) { + if (is_file($this->hosts_file)) { + $handle = @fopen($this->hosts_file, "r"); + if ($handle) { + while (!feof($handle)) { + $buffer = fgets($handle, 4096); + unset($matches); + if (preg_match('/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})[ \t]+(.+)$/i', $buffer, $matches)) { + $hosts_array[$matches[1]]=$matches[2]; + } + } + fclose($handle); + } + $this->hosts = $hosts_array; + } + else { + #error + $this->errorMsg(4, "Hosts file not found. Cant read '{$this->hosts_file}'."); + return $this->errno; + } + } + + return 0; + } + + function query_exec() + { + $data = ""; + + $this->server_version = '(unknown)'; + if ($this->connect($this->squidhost, $this->squidport)) { + $data = $this->makeQuery($this->cachemgr_passwd); + if ($this->errno == 0) { + $this->server_version = $data['server_version']; + $data = $this->parseRequest($data, 'host', true); + } + } + + return $data; + } - - - - - - - - Downloads · dvserg/pfsense-packages · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - -
-
-
-
- - - - - - -

- public - - - / - pfsense-packages - - forked from bsdperimeter/pfsense-packages - -

-
- - - - - - - - - - - - - - - - - - - -
- - - - - - -

- - Download as zip - - - Download as tar.gz - -

- - -
- -

Download Packages

- -
    -
  1. - - - 1 download - -

    - zhabascript.js - — SQStat mon > to Lightsquid folder -

    -

    4KB · Uploaded

    -
  2. -
  3. - - - 0 downloads - -

    - sqstat.php - — SQStat mon > to Lightsquid folder -

    -

    12KB · Uploaded

    -
  4. -
  5. - - - 1 download - -

    - sqstat.css - — SQStat mon > to Lightsquid folder -

    -

    1KB · Uploaded

    -
  6. -
  7. - - - 0 downloads - -

    - sqstat.class.php - — SQStat mon > to Lightsquid folder -

    -

    20KB · Uploaded

    -
  8. -
- -
- - -
-
-
- - -
- - - - - - - - -
-

Markdown Cheat Sheet

- -
- -
-
-

Format Text

-

Headers

-
-# This is an <h1> tag
-## This is an <h2> tag
-###### This is an <h6> tag
-

Text styles

-
-*This text will be italic*
-_This will also be italic_
-**This text will be bold**
-__This will also be bold__
-
-*You **can** combine them*
-
-
-
-

Lists

-

Unordered

-
-* Item 1
-* Item 2
-  * Item 2a
-  * Item 2b
-

Ordered

-
-1. Item 1
-2. Item 2
-3. Item 3
-   * Item 3a
-   * Item 3b
-
-
-

Miscellaneous

-

Images

-
-![GitHub Logo](/images/logo.png)
-Format: ![Alt Text](url)
-
-

Links

-
-http://github.com - automatic!
-[GitHub](http://github.com)
-

Blockquotes

-
-As Kanye West said:
-
-> We're living the future so
-> the present is our past.
-
-
-
-
- -

Code Examples in Markdown

-
-

Syntax highlighting with GFM

-
-```javascript
-function fancyAlert(arg) {
-  if(arg) {
-    $.facebox({div:'#foo'})
-  }
 }
-```
-
-
-

Or, indent your code 4 spaces

-
-Here is a Python code example
-without syntax highlighting:
-
-    def foo:
-      if not bar:
-        return true
-
-
-

Inline code for comments

-
-I think you should use an
-`<addr>` element here instead.
-
-
- -
- - - -
-

Something went wrong with that request. Please try again. Dismiss

-
- -
-

Looking for the GitHub logo?

- -
- - - - - - - - +?> \ No newline at end of file -- cgit v1.2.3