2024-04-03 22:08:54 -05:00
<? php
$CONFIG = array (); $services = array ();
include (( $_SERVER [ 'DOCUMENT_ROOT' ] ?: getcwd ()) . '/data/config.php' );
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
$SQL = new PDO ( $CONFIG [ 'db_host' ], $CONFIG [ 'db_username' ], $CONFIG [ 'db_password' ]);
if ( $SQL -> errorCode () && $SQL -> errorCode () !== '00000' ) {
die ( $SQL -> errorCode ());
}
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
$SQL -> query ( 'CREATE TABLE IF NOT EXISTS service_status(service TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, ping INTEGER, status INTEGER, PRIMARY KEY(service, timestamp))' );
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
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 );
2026-07-02 13:13:43 -05:00
if ( $fp = @ fsockopen ( $data [ 'hostname' ], $port , $errno , $errstr , 15 )) {
2024-04-03 22:08:54 -05:00
$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 );
}
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
// Check for PID (status)
if ( isset ( $data [ 'pidfile' ])) {
if ( ! posix_getpgid ( file_get_contents ( $data [ 'pidfile' ])))
$status = - 1 ;
}
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
// 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 ;
}
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
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 ();
}
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
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' ]);
2026-07-02 13:13:43 -05:00
if ( $stmt = $SQL -> prepare ( 'DELETE FROM service_status WHERE service = :service AND timestamp NOT IN ( SELECT timestamp FROM service_status WHERE service = :service ORDER BY timestamp DESC LIMIT :limit )' )) {
$stmt -> bindParam ( 'service' , $id );
$stmt -> bindParam ( 'limit' , $CONFIG [ 'max_slices' ]);
$stmt -> execute ();
$stmt -> closeCursor ();
}
2024-04-03 22:08:54 -05:00
}
?>
<!DOCTYPE html>
<html>
<head>
<title><?=$CONFIG['page_name'];?></title>
2026-07-02 13:13:43 -05:00
<meta property='og:site_name' content='<?=$CONFIG['site_name'];?>' />
<meta property='og:image' content='favicon.png' />
<meta property='og:title' content='<?=$CONFIG['page_name'];?>' />
<meta property='og:description' content='<?=$CONFIG['site_description'];?>' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='icon' href='favicon.png' type='image/png' sizes='64x64' />
<link rel='icon' href='favicon.ico' type='image/x-icon' sizes='64x64' />
<link rel='stylesheet' href='style.css' />
2024-04-03 22:08:54 -05:00
</head>
<body>
<center class='page'>
2026-07-02 13:13:43 -05:00
<div class='banner'><img src='banner.png' width="640" /><br /><h3>Status Page</h3><a><?=$CONFIG['site_message'];?></a></div>
<?php foreach ($services as $id=>$service): ?>
<table class='status' id='<?=$id;?>'>
<tr class='title'>
<td colspan='<?=count($service['status']);?>'>
<?php if (!empty($service['message'])): ?>
<details>
<summary><b><?php if (!empty($service['icon'])): ?><img src='<?=$service['icon'];?>' height='16' /> <?php endif ?><?=$service['name'];?></b></summary>
<?=$service['message'];?>
</details>
<?php else: ?>
<b><?php if (!empty($service['icon'])): ?><img src='<?=$service['icon'];?>' height='16' /> <?php endif ?><?=$service['name'];?></b>
<?php endif ?>
</td
</tr>
<tr>
<?php foreach ($service['status'] as $slice): ?>
<?php
2024-04-03 22:08:54 -05:00
$cell_status; $bgclrstyle = '';
$_time = date($CONFIG['timestamp_format'], strtotime($slice['timestamp']));
$_ping = $slice['ping'].'ms';
2026-07-02 13:13:43 -05:00
2024-04-03 22:08:54 -05:00
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(
2026-07-02 13:13:43 -05:00
"#%02x%02x%02x",
2024-04-03 22:08:54 -05:00
$slice['ping']!=-1?max(0, min(255, round($slice['ping'])*2)):0,
max(0, min(255, 128+(round($slice['ping'])/2))),
0
);
}
2026-07-02 13:13:43 -05:00
?>
<td class='<?=$cell_status;?>' bgcolor='<?=$bgclrstyle;?>' value='<?=$_ping."\n".strtoupper($cell_status).' - '.$_time;?>'></td>
<?php endforeach ?>
</tr>
</table>
<?php endforeach ?>
<hr />
2024-04-03 22:08:54 -05:00
</center>
</body>
</html>