Compare commits

...

3 Commits

Author SHA1 Message Date
085ade75bf backmerge 2026-02-13 12:25:21 -06:00
dae0882e0f min checks bug 2026-02-13 11:29:15 -06:00
d0f50141c7 update status intervals 2026-02-13 11:25:02 -06:00
4 changed files with 44 additions and 17 deletions

View File

@@ -33,8 +33,12 @@ SERVICES = [
}
]
# Check interval: 30 mins
CHECK_INTERVAL = 1800
# Check interval: 1 min
CHECK_INTERVAL = 60
# Retention: 90 days (quarter year)
RETENTION_DAYS = 90
CLEANUP_INTERVAL = 86400 # 24 hours
DATABASE_URL = os.environ.get('DATABASE_URL')
@@ -273,14 +277,13 @@ class ServiceMonitor:
if total_count == 0:
return None
# Minimum-data thresholds
# Only show uptime for a window if we have data older than it
if hours:
expected_checks = (hours * 3600) / CHECK_INTERVAL
minimum_checks = max(3, expected_checks * 0.5)
if total_count < minimum_checks:
return None
else:
if total_count < 3:
cur.execute(
'SELECT EXISTS(SELECT 1 FROM service_checks WHERE service_id = %s AND timestamp <= %s)',
(service_id, cutoff),
)
if not cur.fetchone()[0]:
return None
return round((online_count / total_count) * 100, 2)
@@ -341,20 +344,44 @@ class ServiceMonitor:
finally:
conn.close()
def _purge_old_records(self):
"""Delete check records older than RETENTION_DAYS."""
conn = self._get_conn()
if conn is None:
return
try:
cutoff = datetime.now() - timedelta(days=RETENTION_DAYS)
with conn, conn.cursor() as cur:
cur.execute(
'DELETE FROM service_checks WHERE timestamp < %s',
(cutoff,),
)
deleted = cur.rowcount
if deleted:
print(f"Purged {deleted} records older than {RETENTION_DAYS} days")
finally:
conn.close()
def start_monitoring(self):
"""Start background monitoring thread"""
def monitor_loop():
# Initial check
self.check_all_services()
self._purge_old_records()
checks_since_cleanup = 0
checks_per_cleanup = CLEANUP_INTERVAL // CHECK_INTERVAL
# Periodic checks
while True:
time.sleep(CHECK_INTERVAL)
self.check_all_services()
checks_since_cleanup += 1
if checks_since_cleanup >= checks_per_cleanup:
self._purge_old_records()
checks_since_cleanup = 0
thread = Thread(target=monitor_loop, daemon=True)
thread.start()
print(f"Service monitoring started (checks every {CHECK_INTERVAL/3600} hours)")
print(f"Service monitoring started (checks every {CHECK_INTERVAL} seconds)")
# Global monitor instance
monitor = ServiceMonitor()

View File

@@ -244,8 +244,8 @@ function initStatusPage() {
clearInterval(statusIntervalId);
}
fetchStatus();
// Auto-refresh every 5 minutes to get latest data
statusIntervalId = setInterval(fetchStatus, 300000);
// Auto-refresh every 1 minute to get latest data
statusIntervalId = setInterval(fetchStatus, 60000);
}
// Clean up interval when navigating away via SPA

View File

@@ -53,7 +53,7 @@
<link rel="canonical" href="{{ request.url_root | trim('/') }}{{ var['canonical'] }}" />
<script defer src="{{ url_for('static', filename='js/checkbox.js') }}"></script>
<script defer src="{{ url_for('static', filename='js/responsive.js') }}"></script>
<script src="{{ url_for('static', filename='js/chessbed.js') }}"></script>
{# <script src="{{ url_for('static', filename='js/chessbed.js') }}"></script> #}
<script defer src="{{ url_for('static', filename='js/idler.js') }}"></script>
<script defer src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
<title>{{ var['title'] }}</title>

View File

@@ -91,8 +91,8 @@
<div class="info-box">
<h4>About This Monitor</h4>
<ul>
<li><strong>Check Frequency:</strong> Services are checked automatically every 30 minutes from the server</li>
<li><strong>Page Refresh:</strong> This page auto-refreshes every 5 minutes to show latest data</li>
<li><strong>Check Frequency:</strong> Services are checked automatically every minute from the server</li>
<li><strong>Page Refresh:</strong> This page auto-refreshes every minute to show latest data</li>
</ul>
</div>
</div>