diff --git a/app/Controllers/StatusController.php b/app/Controllers/StatusController.php index 47d91e4..636cf7f 100644 --- a/app/Controllers/StatusController.php +++ b/app/Controllers/StatusController.php @@ -31,9 +31,15 @@ class StatusController extends Controller { $endpoints = array_keys(config('status.check')); $events = DB::table('status_events') + ->where('event_date', '>', Carbon::now()->subWeek(1)->format('Y-m-d')) ->get(); $incidents = []; + for ($i = 0; $i < 7; $i++) { + $date = Carbon::now()->subDay($i); + $incidents[$date->format('M j, Y')] = []; + } + foreach ($events as $row) { $date = Carbon::createFromFormat('Y-m-d H:i:s', $row->event_date); $incidents[$date->format('M j, Y')][] = [ @@ -60,7 +66,7 @@ class StatusController extends Controller } [$address, $port, $protocol] = explode('/', $endpoints[$name]); - $status = new Status($address, $port, $protocol); + $status = new Status($address, $port, $protocol, true, ($_GET['history'] ?? '1') !== '0'); if ($status->state === null) { $status->check(); diff --git a/app/Net.php b/app/Net.php index fe647a1..75b2305 100644 --- a/app/Net.php +++ b/app/Net.php @@ -220,9 +220,18 @@ class Net CURLOPT_CONNECTTIMEOUT => 2, CURLOPT_TIMEOUT => 4, CURLOPT_USERAGENT => 'Sakura/1.0 (+https://sakura.flash.moe)', + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_SSL_VERIFYPEER => false, // for CF flexible SSL ]); switch (strtolower($method)) { + case 'head': + curl_setopt_array($curl, [ + CURLOPT_HEADER => true, + CURLOPT_NOBODY => true, + ]); + break; + case 'post': curl_setopt_array($curl, [ CURLOPT_POST => is_array($params) ? count($params) : 1, diff --git a/app/Status.php b/app/Status.php index b903a28..7893aae 100644 --- a/app/Status.php +++ b/app/Status.php @@ -24,24 +24,25 @@ class Status public const ERROR = 1; public const FAIL = 0; - public function __construct(string $address, int $port, string $protocol = '', bool $populate = true) + public function __construct(string $address, int $port, string $protocol = '', bool $populate = true, bool $history = true) { $this->address = $address; $this->port = $port; $this->protocol = $protocol; if ($populate) { - $this->populate(); + $this->populate($history); } } - public function populate(): void + public function populate(bool $history = true): void { $this->history = DB::table('status_history') ->where('history_name', $this->address) ->where('history_port', $this->port) ->where('history_protocol', $this->protocol) ->orderBy('history_date', 'desc') + ->limit($history ? 10 : 1) ->get(); $this->state = isset($this->history[0]) ? intval($this->history[0]->history_state) : null; @@ -50,7 +51,14 @@ class Status public function check(): int { $this->state = static::FAIL; - $sock = checkdnsrr($this->address) ? fsockopen($this->address, $this->port, $errno, $errstr, 1) : false; + + $sock = Net::detectIPVersion( + $this->address[0] === '[' && $this->address[strlen($this->address) - 1] === ']' + ? substr($this->address, 1, -1) + : $this->address + ) !== 0 || dns_get_record($this->address, DNS_A | DNS_A6 | DNS_MX) + ? fsockopen($this->address, $this->port, $errno, $errstr, 1) + : false; if ($sock !== false) { fclose($sock); @@ -64,7 +72,7 @@ class Status ); if ($header !== false && strtolower(substr($header, 0, 4)) == 'http') { - list($protocol, $response, $text) = explode(' ', $header, 3); + [$protocol, $response, $text] = explode(' ', $header, 3); if ($response >= 400 && $response < 500) { $this->state = static::ERROR; diff --git a/config/config.example.ini b/config/config.example.ini index 9afccfe..5aabcda 100644 --- a/config/config.example.ini +++ b/config/config.example.ini @@ -211,6 +211,10 @@ repo['Sakura'] = https://github.com/flashwave/sakura ; Status settings [status] +; Format: +; check['display name'] = "address/port/protocol" +; protocol only really matters if you're pinging to http or https +; in which case it should be set to the respective value check['flash.moe http'] = "flash.moe/80/http" check['flash.moe https'] = "flash.moe/443/https" diff --git a/resources/assets/less/yuuno/bem/status.less b/resources/assets/less/yuuno/bem/status.less new file mode 100644 index 0000000..083c99b --- /dev/null +++ b/resources/assets/less/yuuno/bem/status.less @@ -0,0 +1,11 @@ +.status { + &__services { + vertical-align: middle; + text-align: center; + } + + &__service { + padding: 10px 20px; + display: inline-block; + } +} diff --git a/resources/assets/less/yuuno/main.less b/resources/assets/less/yuuno/main.less index 4af1864..0fe5196 100644 --- a/resources/assets/less/yuuno/main.less +++ b/resources/assets/less/yuuno/main.less @@ -29,6 +29,7 @@ @import "bem/profile"; @import "bem/settings"; @import "bem/sidepanel-table"; +@import "bem/status"; @import "bem/topic"; @import "bem/uploader"; @import "bem/user"; diff --git a/resources/views/aitemu/status/index.twig b/resources/views/aitemu/status/index.twig new file mode 100644 index 0000000..5443154 --- /dev/null +++ b/resources/views/aitemu/status/index.twig @@ -0,0 +1,59 @@ +{% extends 'master.twig' %} + +{% set title = 'Status' %} +{% set banner = '/images/status-banner.png' %} +{% set banner_large = true %} + +{% block banner_content %} + +{% endblock %} + +{% block content %} +
+
+ {% for name in endpoints %} +
+
+
{{ name }}
+
+ {% endfor %} +
+
graph goes here
+
+
+ {% for date, events in incidents %} +
+
{{ date }}
+
+ {% if events|length > 0 %} + {% for event in events %} + {% set state = event.state|lower %} +
+
+
{{ event.time }} UTC
+
{{ event.state }}
+
+
+ {{ event.comment }} +
+
+ {% endfor %} + {% else %} +
+
+ No incidents occurred. +
+
+ {% endif %} +
+
+ {% endfor %} +
+{% endblock %} diff --git a/resources/views/yuuno/status/index.twig b/resources/views/yuuno/status/index.twig index 1d95df4..4a93bb9 100644 --- a/resources/views/yuuno/status/index.twig +++ b/resources/views/yuuno/status/index.twig @@ -1,59 +1,79 @@ -{% extends '@aitemu/master.twig' %} +{% extends 'master.twig' %} {% set title = 'Status' %} -{% set banner = '/images/status-banner.png' %} -{% set banner_large = true %} -{% block banner_content %} - +{% block js %} + {% endblock %} {% block content %} -
+
+
Status
{% for name in endpoints %} -
-
-
{{ name }}
+
+

{{ name }}

+

loading...

{% endfor %}
-
graph goes here
-
-
+
Incidents
{% for date, events in incidents %} -
-
{{ date }}
-
- {% if events|length > 0 %} - {% for event in events %} - {% set state = event.state|lower %} -
-
-
{{ event.time }} UTC
-
{{ event.state }}
-
-
- {{ event.comment }} -
-
- {% endfor %} - {% else %} -
-
- No incidents occurred. -
-
- {% endif %} -
-
+
{{ date }}
+ {% if events|length > 0 %} + + {% for event in events %} + {% set state = event.state|lower %} + + + + + + {% endfor %} +
{{ event.time }} UTC{{ event.state }}{{ event.comment }}
+ {% else %} + No incidents occurred. + {% endif %} {% endfor %}
{% endblock %}