18 public $graphColors = [[200,0,0],[0,200,0],[0,0,200],[200,200,0],[0,200,200],[200,0,200],[100,0,0],[0,100,0],[0,0,100],[100,100,0],[0,100,100],[100,0,100]];
28 protected function save($data){
31 protected function send($messages){
33 foreach($messages as $name => $message)
34 $table .=
'<tr><td>' . htmlspecialchars($name) .
'</td><td>' . htmlspecialchars($message) .
"</td></tr>\n";
36 return $this->_log->component(
'mail')->send(
38 $this->to ?: ini_get(
'sendmail_from'),
39 str_replace(
'*',$host = \
Rsi\Http::host(),$this->subject),
40 strtr($this->
template,[
41 '[time]' => date(
'Y-m-d H:i:s'),
43 '[ip]' => $_SERVER[
'SERVER_ADDR'] ?? gethostbyname($host),
44 '[messages]' => $table
53 $messages = $data = [];
54 foreach($this->checks as $name => $check){
55 $data[$name] = $check->check($message);
56 if($message) $messages[$name] = $message;
59 if($messages) $this->
send($messages);
66 public function data($since =
null){
76 public function graph($width = 640,$height = 480,$since =
null){
77 $image = imagecreate($width,$height);
78 imagecolorallocate($image,255,255,255);
79 if(count($data = $this->
data($since)) > 1){
80 $color_border = imagecolorallocate($image,0,0,0);
81 $color_grid = imagecolorallocate($image,200,200,200);
83 $value_min = $value_max = 0;
84 $font_width = imagefontwidth($this->graphFont);
85 $font_height = imagefontheight($this->graphFont);
87 foreach($data as $record)
foreach($record as $name => $value) $names[$name] = max($names[$name] ?? 0,$value);
88 $value_max = max($names);
89 $graph_height = $height - 2 * $font_height;
90 $interval_min = 2 * $font_height * ($value_max - $value_min) / $graph_height;
92 $value_interval = 0.001;
93 while($value_interval < $interval_min) $value_interval *= $this->graphIntervalFactors[$index++ % count($this->graphIntervalFactors)];
94 $value_max = ceil($value_max / $value_interval) * $value_interval;
96 $value_chars = max(5,strlen($value_max) + ($decimals = ($i = strpos($value_interval,
'.')) ? strlen($value_interval) - $i : 0));
97 $graph_width = $width - $font_width * $value_chars;
98 if(($graph_width > 50) && ($graph_height > 50)){
100 while(($value += $value_interval) < $value_max){
101 $y = round(($value_max - $value) / ($value_max - $value_min) * $graph_height);
102 imageline($image,$width - $graph_width,$y,$width,$y,$color_grid);
103 $value_str = number_format($value,max(0,$decimals - 1));
104 imagestring($image,$this->graphFont,$width - $graph_width - strlen($value_str) * $font_width,$y - $font_height / 2,$value_str,$color_border);
106 $times = array_keys($data);
107 $time_min = floor(min($times) / 86400) * 86400;
108 $time_max = ceil(max($times) / 86400) * 86400;
109 $time_interval = ceil(11 * $font_width * ($time_max - $time_min) / $graph_width / 86400) * 86400;
112 $x = $width - round(($time_max - $time) / ($time_max - $time_min) * $graph_width);
113 imageline($image,$x,0,$x,$graph_height,$color_grid);
114 if(!(($time - $time_min) % $time_interval)) imagestring($image,$this->graphFont,$x - 5 * $font_width,$graph_height,date(
'Y-m-d',$time),$color_border);
116 while(($time += 86400) < $time_max);
117 $legend_size = $font_height;
120 (strlen(implode(array_keys($names))) + count(array_filter($names)) * (strlen($this->graphSecondaryFactor) + 1)) * $font_width -
121 count($names) * $legend_size * 2 - $legend_size
124 foreach($names as $name => $secondary){
125 $color = imagecolorallocate($image,...$this->graphColors[$index++ % count($this->graphColors)]);
126 $y = $height - $legend_size;
127 imagefilledrectangle($image,$legend_x ,$y + 2,$legend_x + $legend_size - 4,$height - 2,$color);
128 imagerectangle($image,$legend_x,$y + 2,$legend_x + $legend_size - 4,$height - 2,$color_border);
129 imagestring($image,$this->graphFont,$legend_x += $legend_size,$y,$name,$color_border);
130 $legend_x += strlen($name) * $font_width;
132 imagestring($image,$this->graphFont,$legend_x,$y,$str =
'x' . $this->graphSecondaryFactor,$color_grid);
133 $legend_x += strlen($str) * $font_width;
135 $legend_x += $legend_size;
136 $prev_x = $prev_y =
null;
137 foreach($data as $time => $record)
if(array_key_exists($name,$record)){
138 $x = $width - round(($time_max - $time) / ($time_max - $time_min) * $graph_width);
139 $y = round(($value_max - $record[$name] * ($secondary ? $this->graphSecondaryFactor : 1)) / ($value_max - $value_min) * $graph_height);
140 if($prev_x !==
null) imageline($image,$prev_x,$prev_y,$x,$y,$color);
144 else $prev_x = $prev_y =
null;
146 imageline($image,$width - $graph_width,0,$width - $graph_width,$graph_height,$color_border);
147 imageline($image,$width - $graph_width,$graph_height,$width,$graph_height,$color_border);
154 if($this->_checks ===
null){
156 foreach($this->
config(
'checks',[]) as $name => $config){
157 $class_name = \Rsi\Record::get($config,
'className',__CLASS__ .
'\\Check\\' . ucfirst($name));
158 $this->_checks[$name] =
new $class_name($this->_fred,$config);