added healthcheck api and updated docker-compose to use it
This commit is contained in:
+20
-2
@@ -2,9 +2,10 @@ import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
from flask import Flask, jsonify, render_template
|
||||
import os, sys, time
|
||||
from datetime import datetime
|
||||
import os, sys
|
||||
|
||||
from src.anayzer import (
|
||||
from src.analyzer import (
|
||||
calculate_totals,
|
||||
get_last_n_days,
|
||||
get_stats,
|
||||
@@ -45,6 +46,23 @@ def api_dashboard():
|
||||
def api_sessions():
|
||||
return jsonify(sessions_cache.get())
|
||||
|
||||
@app.route("/api/health")
|
||||
def api_health():
|
||||
is_alive = daemon.is_alive()
|
||||
last_fetch = calendar.get_last_fetch_date()
|
||||
if last_fetch:
|
||||
min_since_last_fetch = round((datetime.now(tz=config.TIME_ZONE) - last_fetch).total_seconds() / 60)
|
||||
is_up_to_date = min_since_last_fetch < 4 * config.REFETCH_MINUTES # four fetches failed -> bad health
|
||||
else:
|
||||
is_up_to_date = False
|
||||
|
||||
healthy = is_alive and is_up_to_date
|
||||
return jsonify({
|
||||
"status": "ok" if healthy else "degraded",
|
||||
"daemon_alive": is_alive,
|
||||
"last_fetch_success": str(last_fetch) if last_fetch else None
|
||||
}), 200 if healthy else 503
|
||||
|
||||
# data
|
||||
initial_fetch(calendar, sessions_cache)
|
||||
daemon.run(calendar, sessions_cache)
|
||||
|
||||
@@ -7,3 +7,9 @@ services:
|
||||
ports:
|
||||
- "5000:5000"
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:5000/api/health"]
|
||||
interval: 2m
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
@@ -23,7 +23,7 @@ def calculate_totals(sessions) -> dict:
|
||||
def get_last_n_days(n: int, sessions) -> list[dict]:
|
||||
days = []
|
||||
|
||||
today = datetime.now().date()
|
||||
today = datetime.now(tz=config.TIME_ZONE).date()
|
||||
for i in range(n):
|
||||
day = today - timedelta(days=i)
|
||||
days.append(
|
||||
@@ -52,7 +52,7 @@ def get_total_month(sessions) -> int:
|
||||
for session in sessions:
|
||||
year_month = str(session["date"])[:7]
|
||||
|
||||
if year_month == datetime.now(config.TIME_ZONE).strftime("%Y-%m"):
|
||||
if year_month == datetime.now(tz=config.TIME_ZONE).strftime("%Y-%m"):
|
||||
total_min += session["minutes"]
|
||||
return total_min
|
||||
|
||||
@@ -23,7 +23,8 @@ REFETCH_MINUTES = os.environ.get("REFETCH_INTERVAL_MINUTES", "5")
|
||||
if not REFETCH_MINUTES.isdigit():
|
||||
logger.error("Invalid refetch interval")
|
||||
sys.exit(1)
|
||||
REFETCH_SECONDS = int(REFETCH_MINUTES) * 60
|
||||
REFETCH_MINUTES = int(REFETCH_MINUTES)
|
||||
REFETCH_SECONDS = REFETCH_MINUTES * 60
|
||||
|
||||
# get the date of the start of the semester were currently in
|
||||
# or return None if no semesters were specified
|
||||
@@ -33,7 +34,7 @@ def get_current_semester_start() -> date:
|
||||
return None
|
||||
|
||||
# first check if one the dates was previously this year
|
||||
today = datetime.now().date()
|
||||
today = datetime.now(tz=TIME_ZONE).date()
|
||||
found_start = None
|
||||
try:
|
||||
dates = [datetime.strptime(str(today.year)+"-"+date_str, "%Y-%m-%d").date() for date_str in SEMESTER_STARTS]
|
||||
|
||||
@@ -33,3 +33,6 @@ class BGFetchJob:
|
||||
logger.info("Starting fetch job daemon")
|
||||
self.thread = threading.Thread(target=background_fetch_job, args=(calendar, sessions_cache), daemon=True)
|
||||
self.thread.start()
|
||||
|
||||
def is_alive(self):
|
||||
return self.thread.is_alive()
|
||||
|
||||
@@ -24,6 +24,10 @@ class Calendar:
|
||||
password=config.CALDAV_PASS,
|
||||
)
|
||||
self._calendar = self._client.calendar(url=config.CALDAV_URL)
|
||||
self._last_succ_fetch: datetime = None
|
||||
|
||||
def get_last_fetch_date(self):
|
||||
return self._last_succ_fetch
|
||||
|
||||
def fetch_events(self):
|
||||
return self._calendar.events()
|
||||
@@ -45,6 +49,7 @@ class Calendar:
|
||||
})
|
||||
|
||||
logger.info(f"Fetched {len(event_list)} sessions from calDAV server")
|
||||
self._last_succ_fetch = datetime.now(tz=config.TIME_ZONE)
|
||||
return event_list
|
||||
|
||||
# grab only the sessions that fall into the current semester
|
||||
|
||||
Reference in New Issue
Block a user