From 3d50432ff438e250d8b1d44497668e43fee29265 Mon Sep 17 00:00:00 2001 From: Wirlaburla Date: Wed, 3 Apr 2024 22:08:54 -0500 Subject: [PATCH] Initial commit --- banner.png | Bin 0 -> 7192 bytes data/config.php.example | 61 ++++++++++++++++++ data/update.php | 136 ++++++++++++++++++++++++++++++++++++++++ style.css | 28 +++++++++ 4 files changed, 225 insertions(+) create mode 100644 banner.png create mode 100755 data/config.php.example create mode 100755 data/update.php create mode 100755 style.css diff --git a/banner.png b/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..733c4d6a548f85ad02ddbaed553cef72ba705995 GIT binary patch literal 7192 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 IrYubRKTSzn1^@s6 literal 0 HcmV?d00001 diff --git a/data/config.php.example b/data/config.php.example new file mode 100755 index 0000000..8a21eaa --- /dev/null +++ b/data/config.php.example @@ -0,0 +1,61 @@ +array( + ## This will be the name of the service as displayed on the status page. + #'name'=>'Web Server', + + ## This will be the message displayed under the collapsable title. + #'message'=>'To be, or not to be.', + + ## The pid file of the service to check. If 'process' is also defined, + ## this will override its check. Make sure the runner has permissions + ## to read the file. + #'pidfile'=>'/run/nginx.pid', + + ## Icon to display alongside the service name. Path is relative to page. + ## You can also leave this blank for no icon. + #'icon'=>'http.png', + + ## Name of the process to query. This will search using pgrep. + #'process'=>'nginx', + + ## Hostname of the server to ping. This and 'ports' may be omitted if + ## you do not want to ping it. + #'hostname'=>'shakespear.lit', + + ## Array of ports to ping. If more than one port, the displayed ping will be averaged. Requires 'hostname' to function properly. + #'ports'=>array(80,443) + #) +); +?> \ No newline at end of file diff --git a/data/update.php b/data/update.php new file mode 100755 index 0000000..5e3dae4 --- /dev/null +++ b/data/update.php @@ -0,0 +1,136 @@ +errorCode() && $SQL->errorCode() !== '00000') { + die($SQL->errorCode()); + } + + $SQL->query('CREATE TABLE IF NOT EXISTS service_status(service TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, ping INTEGER, status INTEGER, PRIMARY KEY(service, timestamp))'); + + foreach($CONFIG['services'] as $id=>$data) { + $services[$id] = array( + 'name'=>$data['name'], + 'message'=>$data['message'] + ); + if (isset($data['icon'])) $services[$id]['icon'] = $data['icon']; + $timestamp = date('Y-m-d H:i:s'); + // Ping is in ms. Status is 0 if okay, +1 for each unreachable, and -1 if offline completely. + $ping = -1; $status = 0; + // Check for ports (with ping) + if (isset($data['ports'])) { + $pings = array(); $i = 0; + foreach ($data['ports'] as $port) { + $starttime = microtime(true); + if ($fp = fsockopen($data['hostname'],$port,$errno,$errstr,15)) { + $stoptime = microtime(true); + $newping = ($stoptime - $starttime) * 1000; + $pings[$i++] = $newping; + } else $status++; + } + if ($i == 1) + $ping = round($pings[0], 2); + else if ($i > 0 && ($ping_sum = array_sum($pings)) > 0) + $ping = round($ping_sum / $i, 2); + } + + // Check for PID (status) + if (isset($data['pidfile'])) { + if (!posix_getpgid(file_get_contents($data['pidfile']))) + $status = -1; + } + + // Check for process (status) + if (isset($data['process']) && !isset($data['pidfile'])) { + $otp; $rtn; + exec('pgrep -fl "'.$data['process'].'"', $otp, $rtn); + if ($rtn!=0) $status = -1; + } + + if ($stmt = $SQL->prepare('INSERT INTO service_status(service, timestamp, ping, status) VALUES (?, ?, ?, ?)')) { + $stmt->bindParam(1, $id); + $stmt->bindParam(2, $timestamp); + $stmt->bindParam(3, $ping); + $stmt->bindParam(4, $status); + $stmt->execute(); + $stmt->closeCursor(); + } + + if ($stmt = $SQL->prepare('SELECT timestamp,ping,status FROM service_status WHERE service = ? ORDER BY timestamp DESC LIMIT ?')) { + $stmt->bindParam(1, $id); + $stmt->bindParam(2, $CONFIG['max_slices']); + if ($stmt->execute()) { + $services[$id]['status'] = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + array_push($services[$id]['status'], $row); + } + } + $stmt->closeCursor(); + } + $services[$id]['status'] = array_reverse($services[$id]['status']); + } +?> + + + + <?=$CONFIG['page_name'];?> + '> + + '> + '> + + + + + + + +
+ + '; + echo ''; + if (!empty($service['message'])) { + echo '
'; + if (!empty($service['icon'])) + echo ' '; + echo $service['name'].''.$service['message'].'
'; + } else { + if (!empty($service['icon'])) + echo ' '; + echo ''.$service['name'].''; + } + echo ''; + echo ''; + foreach ($service['status'] as $slice) { + $cell_status; $bgclrstyle = ''; + $_time = date($CONFIG['timestamp_format'], strtotime($slice['timestamp'])); + $_ping = $slice['ping'].'ms'; + + if ($slice['status'] > 0 || ($slice['status'] == -1 && $slice['ping'] > 0)) { + $cell_status = 'partial'; + $bgclrstyle = sprintf("#%02x%02x%02x", 255, 128, 0); + } else if ($slice['status'] == -1) { + $cell_status = 'offline'; + $bgclrstyle = sprintf("#%02x%02x%02x", 255, 0, 0); + } else { + $cell_status = 'ok'; + $bgclrstyle = sprintf( + "#%02x%02x%02x", + $slice['ping']!=-1?max(0, min(255, round($slice['ping'])*2)):0, + max(0, min(255, 128+(round($slice['ping'])/2))), + 0 + ); + } + + echo ''; + } + echo ''."\n"; + } + ?> +
+
+ + \ No newline at end of file diff --git a/style.css b/style.css new file mode 100755 index 0000000..de5b449 --- /dev/null +++ b/style.css @@ -0,0 +1,28 @@ +body { + background: #d3d3d3; +} + +body > center > * { + max-width: 800px; +} +details { + text-align: left; +} +details > summary { + cursor: pointer; +} + +table { width: 100%; } +table.status { margin: 8px 0; } +table.status tr:not(.title) td { height: 16px; } +table.status tr:not(.title) td:hover:after { + content: attr(value); + position: absolute; + background-color: rgba(0,0,0,0.75); + border-radius: 8px; + color: white; + padding: 2px 4px; + margin: -58px -8px; + white-space: pre; + pointer-events: none; +} \ No newline at end of file