5 class Polling extends \Rsi\Fred\Security\Check{
20 return $this->path . str_replace([
'.',
':'],
'-',$addr ?: $this->
component(
'security')->remoteAddr) .
$this->ext;
24 $exists = is_file($filename = $this->
filename());
25 $f = fopen($filename,$exists ?
'a' :
'w');
26 if(!$exists) fwrite($f,$this->
component(
'security')->remoteAddr .
"\n");
27 fwrite($f,time() .
"\n");
29 if(!$exists) chmod($filename,0666);
33 return is_file($this->pollerFilename) && in_array($this->
component(
'security')->remoteAddr,file($this->pollerFilename,FILE_IGNORE_NEW_LINES));
36 public function check($expected =
false){
37 if($expected)
return true;
41 ($url = $_SERVER[
'REQUEST_URI'] ?? null) &&
42 ($this->session->lastTime < $this->_fred->startTime - $this->timeDelta)
43 )
foreach($this->filters as $name => $filter)
if(preg_match($filter,$url)){
45 $this->session->lastTime = time();
48 if((($result = $this->session->lastResult) === null) || ($this->session->lastCheck < $this->_fred->startTime - $this->checkTtl)){
49 $this->session->lastResult = $result = !$this->
isPoller();
50 $this->session->lastCheck = $this->_fred->startTime;
54 if($this->_fred->debug)
throw $e;
61 if(count($times) > $this->countThreshold){
62 $total = $count = $prev = 0;
64 foreach($times as $time){
65 if($prev && ($time > $prev + $this->timeDelta)){
66 if(!$polls) $polls[] = $prev;
68 $total += $time - $prev;
73 if($count > $this->countThreshold){
74 $average = $total / $count;
76 foreach($polls as $time){
77 if($prev) $total += pow($time - $prev - $average,2);
80 if($result = ($deviation = 100 * sqrt($total / $count) / $average) < $this->deviationPerc)
81 $this->
component(
'log')->add($this->logPrio,
"IP address $addr is polling: count = $count, average = " . number_format($average) .
", deviation% = " . number_format($deviation,2),__FILE__,__LINE__);
92 foreach((
new \GlobIterator($this->path .
'*' . $this->ext)) as $filename => $file){
93 $lines = file($filename,FILE_IGNORE_NEW_LINES);
94 \Rsi\File::unlink($filename);
95 $addr = array_shift($lines);
96 if($this->
analyseTimes($addr,$lines)) $pollers[] = $addr;
98 file_put_contents($this->pollerFilename,implode(
"\n",$pollers));
102 return \Rsi\File::unlink($this->
filename($addr));
106 if(!$this->_path) $this->_path = $this->
component(
'security')->path;
111 return $this->_pollerFilename ?: $this->path .
'pollers.csv';
analyseTimes($addr, $times)
$deviationPerc
Consider a deviation within this percentage of the average a poller.
$logPrio
Log prio for the warning message.
$checkTtl
Re-use polling info for this amount of time (seconds).
$timeDelta
Consider everything between this amount of seconds as a single request.
$countThreshold
Minimum number of requests.
$_pollerFilename
File with IP addresses of pollers (extension must differ from times files or other.
$ext
Extension for times file.
analyse()
Analyse the times files, and compile a list of pollers.
component($name)
Get a component (local or default).