Added multiple backend support, better monitor config & more improvements
This commit is contained in:
parent
f4fbe1413f
commit
5e9e0d0297
|
@ -1,16 +1,55 @@
|
|||
<?php
|
||||
|
||||
$config = [
|
||||
"uptime_kuma_url" => "http://uptime-kuma.local:3001",
|
||||
"pages" => [
|
||||
"public",
|
||||
"second"
|
||||
],
|
||||
"monitor_options" => [
|
||||
4 => ["rich" => true]
|
||||
],
|
||||
"enable_twig_cache" => true,
|
||||
"default_language" => "en",
|
||||
"timezone" => "Etc/UTC"
|
||||
];
|
||||
|
||||
/**
|
||||
* Uptime Kuma backends
|
||||
* - URL addresses of backends
|
||||
*/
|
||||
"backends" => [
|
||||
"http://uptime-kuma1.local:3001", // KUMA_ID = 0
|
||||
"http://uptime-kuma2.local:3001" // KUMA_ID = 1
|
||||
],
|
||||
|
||||
/**
|
||||
* Status pages
|
||||
* - all available pages and their backends
|
||||
* - when passing an array, other backends are used as failovers
|
||||
*/
|
||||
"pages" => [
|
||||
"public" => 0, // first defined page is visible on the home page
|
||||
"second" => [0, 1] // other pages are displayed on their own subpages based on their slug (eg. /second)
|
||||
],
|
||||
|
||||
/**
|
||||
* Monitor options
|
||||
* - the key must be in one of formats below (MON_ID = monitor ID, KUMA_ID = backend ID, PAGE = page)
|
||||
* - MON_ID
|
||||
* - KUMA_ID:MON_ID
|
||||
* - PAGE/MON_ID
|
||||
* - PAGE/KUMA_ID:MON_ID
|
||||
* - available options are listed below
|
||||
* - heartbeats: boolean
|
||||
*/
|
||||
"monitor_options" => [
|
||||
"4" => ["heartbeats" => true],
|
||||
"second/1" => ["heartbeats" => true],
|
||||
"public/0:2" => ["heartbeats" => true]
|
||||
],
|
||||
|
||||
/**
|
||||
* Enable twig caching for better performance
|
||||
*/
|
||||
"enable_twig_cache" => true,
|
||||
|
||||
/**
|
||||
* Default language code
|
||||
*/
|
||||
"default_language" => "en",
|
||||
|
||||
/**
|
||||
* Timezone of displayed date
|
||||
*/
|
||||
"timezone" => "Etc/UTC"
|
||||
|
||||
];
|
||||
|
|
23
controller/Config.php
Normal file
23
controller/Config.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php namespace UptimeStatus;
|
||||
|
||||
use Exception;
|
||||
|
||||
class Config {
|
||||
|
||||
private static array $config;
|
||||
|
||||
public static function set(array $config): void {
|
||||
self::$config = $config;
|
||||
}
|
||||
|
||||
public static function get(string $key, mixed $default = null): mixed {
|
||||
if (array_key_exists($key, self::$config)) {
|
||||
return self::$config[$key];
|
||||
}
|
||||
if ($default !== null) {
|
||||
return $default;
|
||||
}
|
||||
throw new Exception("Missing config key '$key'!");
|
||||
}
|
||||
|
||||
}
|
|
@ -10,14 +10,14 @@ class Filters {
|
|||
return 2;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static function statusicon() {
|
||||
return new \Twig\TwigFilter('statusicon', function (int $status, string $suffix = "svg") {
|
||||
$icons = ["error", "success", "warning", "maintenance"];
|
||||
return "/icon/{$icons[$status]}.$suffix";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static function statuscolor() {
|
||||
return new \Twig\TwigFilter('statuscolor', function (int $status) {
|
||||
return ["#F87171", "#10B981", "#FFBB6D", "#9575cd"][$status];
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
|
||||
class Router {
|
||||
|
||||
private Status $status;
|
||||
|
||||
public function __construct($config) {
|
||||
$this->status = new Status($config);
|
||||
}
|
||||
|
||||
public function get_path(): string {
|
||||
$url = $_SERVER["REQUEST_URI"];
|
||||
$parsed_url = parse_url($url);
|
||||
|
@ -21,14 +15,15 @@ class Router {
|
|||
return $path;
|
||||
}
|
||||
|
||||
public function get_page($path) {
|
||||
$pages = $this->status->cfg("pages");
|
||||
foreach ($pages as $page) {
|
||||
public function get_page($path): string {
|
||||
$pages = Config::get("pages");
|
||||
$slugs = array_keys($pages);
|
||||
foreach ($slugs as $page) {
|
||||
if ($path == $page) {
|
||||
return $page;
|
||||
}
|
||||
}
|
||||
return $pages[0];
|
||||
return $slugs[0];
|
||||
}
|
||||
|
||||
public function render() {
|
||||
|
@ -36,10 +31,20 @@ class Router {
|
|||
$path = $this->get_path();
|
||||
$slug = $this->get_page($path);
|
||||
|
||||
$page = $this->status->get_page($slug);
|
||||
if (!$page) die("Failed to load data!");
|
||||
|
||||
$this->status->display($page);
|
||||
$backend_ids = Config::get("pages")[$slug];
|
||||
|
||||
if (!is_array($backend_ids)) $backend_ids = [$backend_ids];
|
||||
|
||||
$status = null;
|
||||
foreach ($backend_ids as $bid) {
|
||||
$status = new Status($bid, $slug);
|
||||
$page = $status->get_page();
|
||||
if ($page) {
|
||||
$status->display();
|
||||
return;
|
||||
}
|
||||
}
|
||||
echo "Failed to load data!";
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,29 +4,29 @@ use UptimeStatus\Model\Page;
|
|||
|
||||
class Status {
|
||||
|
||||
private array $config;
|
||||
readonly int $backend_id;
|
||||
|
||||
public function __construct(array $config) {
|
||||
$this->config = $config;
|
||||
readonly string $slug;
|
||||
|
||||
public ?Page $page = null;
|
||||
|
||||
public function __construct(int $backend_id, string $slug) {
|
||||
$this->backend_id = $backend_id;
|
||||
$this->slug = $slug;
|
||||
}
|
||||
|
||||
public function cfg($name) {
|
||||
if(array_key_exists($name, $this->config)) {
|
||||
return $this->config[$name];
|
||||
}
|
||||
return null;
|
||||
public function get_page(): ?Page {
|
||||
$this->page = Page::get($this, $this->backend_id, $this->slug);
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
public function get_page(string $page): ?Page {
|
||||
return Page::get($this, $page);
|
||||
}
|
||||
public function display(): void {
|
||||
|
||||
public function display(Page $page) {
|
||||
|
||||
$data = $page->export();
|
||||
if ($this->page == null) return;
|
||||
$data = $this->page->export();
|
||||
|
||||
$twig_config = [];
|
||||
if ($this->cfg("enable_twig_cache")) $twig_config["cache"] = "../cache/twig/";
|
||||
if (Config::get("enable_twig_cache")) $twig_config["cache"] = "../cache/twig/";
|
||||
|
||||
$loader = new \Twig\Loader\FilesystemLoader("../view/");
|
||||
$twig = new \Twig\Environment($loader, $twig_config);
|
||||
|
@ -35,12 +35,12 @@ class Status {
|
|||
$twig->addFilter(Filters::statusicon());
|
||||
$twig->addFilter(Filters::statuscolor());
|
||||
|
||||
$locale = new Locale($this->cfg("default_language"));
|
||||
$locale = new Locale(Config::get("default_language"));
|
||||
$twig->addFilter($locale->t());
|
||||
|
||||
$ext = $twig->getExtension(\Twig\Extension\CoreExtension::class);
|
||||
$ext->setDateFormat($locale->get("dateformat"));
|
||||
$ext->setTimezone($this->cfg("timezone"));
|
||||
$ext->setTimezone(Config::get("timezone"));
|
||||
|
||||
echo $twig->render('index.twig', $data);
|
||||
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
"status.2": "Problém",
|
||||
"status.3": "Údržba",
|
||||
"heartbeat.ping": "Odezva: {{ping}}ms",
|
||||
"dateformat": "j. m. Y G:i",
|
||||
"dateformat": "j. n. Y G:i",
|
||||
"footer.poweredby": "Poháněno projektem <b><a href=\"{{link}}\" target=\"_blank\">Uptime Status</a></b>"
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<?php namespace UptimeStatus\Model;
|
||||
|
||||
use UptimeStatus\Config;
|
||||
use UptimeStatus\Status;
|
||||
|
||||
class Monitor {
|
||||
|
@ -25,8 +26,10 @@ class Monitor {
|
|||
public static function convert(Status $s, array $oldMonitor, array $heartbeat): Monitor {
|
||||
|
||||
$id = $oldMonitor["id"];
|
||||
$opts = $s->cfg("monitor_options") ?? [];
|
||||
$opt = $opts[$id] ?? [];
|
||||
$opts = Config::get("monitor_options", []);
|
||||
$bid = $s->backend_id;
|
||||
$page = $s->slug;
|
||||
$opt = $opts["$page/$bid:$id"] ?? $opts["$page/$id"] ?? $opts["$bid:$id"] ?? $opts[$id] ?? [];
|
||||
|
||||
$heartbeats = [];
|
||||
foreach ($heartbeat["heartbeatList"][$id] as $beat) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php namespace UptimeStatus\Model;
|
||||
|
||||
use UptimeStatus\Config;
|
||||
use UptimeStatus\Status;
|
||||
|
||||
class Page {
|
||||
|
@ -32,12 +33,12 @@ class Page {
|
|||
];
|
||||
}
|
||||
|
||||
public static function get(Status $s, string $page): ?Page {
|
||||
public static function get(Status $s, int $backend_id, string $page): ?Page {
|
||||
|
||||
$url = $s->cfg("uptime_kuma_url");
|
||||
$backend = Config::get("backends")[$backend_id];
|
||||
$urls = [
|
||||
$url . "/api/status-page/" . $page,
|
||||
$url . "/api/status-page/heartbeat/" . $page
|
||||
$backend . "/api/status-page/" . $page,
|
||||
$backend . "/api/status-page/heartbeat/" . $page
|
||||
];
|
||||
|
||||
[$oldPage, $heartbeat] = Page::download($urls);
|
||||
|
@ -60,6 +61,7 @@ class Page {
|
|||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_multi_add_handle($mh, $ch);
|
||||
array_push($chs, $ch);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
<?php
|
||||
|
||||
use UptimeStatus\Config;
|
||||
use UptimeStatus\Router;
|
||||
|
||||
require("../vendor/autoload.php");
|
||||
require("../config.inc.php");
|
||||
|
||||
$router = new UptimeStatus\Router($config);
|
||||
|
||||
Config::set($config);
|
||||
$router = new Router();
|
||||
$router->render();
|
|
@ -30,6 +30,7 @@ html, body {
|
|||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
:is(header, section, footer) > .inner {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{{ "monitor.uptime" | t({pct: (monitor.uptime * 100) | number_format(1, '.')}) | raw }}
|
||||
</div>
|
||||
</div>
|
||||
{% if monitor.opt.rich %}
|
||||
{% if monitor.opt.heartbeats %}
|
||||
{{ include("./heartbeats.twig") }}
|
||||
{% endif %}
|
||||
</div>
|
Loading…
Reference in a new issue