aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2025-03-26 19:39:55 +0100
committerDaniel Schadt <kingdread@gmx.de>2025-03-26 19:39:55 +0100
commitfcf75892a49fe35c36cad10c6597c6192f0d04b8 (patch)
tree697e149a6aa5180d0f5781ce4b63ad05cf78a6c2
parent577ef97bbfa01d0e9a233cd11c9bb7bd96f4c9b2 (diff)
downloadfietsboek-fcf75892a49fe35c36cad10c6597c6192f0d04b8.tar.gz
fietsboek-fcf75892a49fe35c36cad10c6597c6192f0d04b8.tar.bz2
fietsboek-fcf75892a49fe35c36cad10c6597c6192f0d04b8.zip
add system stats to admin page
-rw-r--r--fietsboek/scripts/fietscron.py4
-rw-r--r--fietsboek/templates/admin_overview.jinja227
-rw-r--r--fietsboek/views/admin.py38
3 files changed, 67 insertions, 2 deletions
diff --git a/fietsboek/scripts/fietscron.py b/fietsboek/scripts/fietscron.py
index 7687e12..923885f 100644
--- a/fietsboek/scripts/fietscron.py
+++ b/fietsboek/scripts/fietscron.py
@@ -53,10 +53,12 @@ def cli(config):
remove_old_tokens(engine)
rebuild_cache(engine, data_manager)
+ redis = mod_redis.from_url(config.redis_url)
if config.hittekaart_autogenerate:
- redis = mod_redis.from_url(config.redis_url)
run_hittekaart(engine, data_manager, redis, config)
+ redis.set("last-cronjob", datetime.datetime.now(datetime.UTC).timestamp())
+
def remove_old_uploads(engine: Engine):
"""Removes old uploads from the database."""
diff --git a/fietsboek/templates/admin_overview.jinja2 b/fietsboek/templates/admin_overview.jinja2
index 0e1bac8..dedd57e 100644
--- a/fietsboek/templates/admin_overview.jinja2
+++ b/fietsboek/templates/admin_overview.jinja2
@@ -14,12 +14,37 @@
</p>
<p class="admin-stat">
- &hellip; {{ (total_size / 1024 / 1024) | round(2) }} MiB bytes of data
+ &hellip; {{ (total_size / 1024 / 1024) | round(2) }} MiB of data
</p>
<div style="position: relative; height: 500px; margin: auto; width: 75%;">
<canvas id="graph-size-breakdown"></canvas>
</div>
+
+<h2>System information</h2>
+
+<table class="table">
+ <tr>
+ <td>Fietsboek version</td>
+ <td>{{ versions["fietsboek"] }}</td>
+ </tr>
+ <tr>
+ <td>Python version</td>
+ <td>{{ versions["python"] }}</td>
+ </tr>
+ <tr>
+ <td>Kernel version</td>
+ <td>{{ versions["linux"] }}</td>
+ </tr>
+ <tr>
+ <td>Distribution</td>
+ <td>{{ versions["distro"] }}</td>
+ </tr>
+ <tr class="{% if cron_good %}table-success{% else %}table-warning{% endif %}">
+ <td>Last cronjob {% if not cron_good %}<i class="bi bi-exclamation-triangle-fill"></i>{% endif %}</td>
+ <td>{{ last_cronjob }}</td>
+ </tr>
+</table>
{% endblock %}
{% block latescripts %}
diff --git a/fietsboek/views/admin.py b/fietsboek/views/admin.py
index 78eec12..ca002c8 100644
--- a/fietsboek/views/admin.py
+++ b/fietsboek/views/admin.py
@@ -1,6 +1,9 @@
"""Admin views."""
+import datetime
+import platform
import stat
+import subprocess
from dataclasses import dataclass
from pathlib import Path
@@ -13,6 +16,9 @@ from sqlalchemy import func, select
from .. import models, util
+GOOD_CRON_THRESHOLD = datetime.timedelta(hours=1)
+
+
def _safe_size(path: Path) -> int:
try:
res = path.stat()
@@ -51,6 +57,14 @@ def _get_size_breakdown(data_manager):
return breakdown
+def _get_fietsboek_version():
+ modules = subprocess.check_output(["pip", "list"]).split(b"\n")
+ for module in modules:
+ if module.startswith(b"fietsboek "):
+ return module.split()[1].decode("ascii")
+ return ""
+
+
@view_config(
route_name="admin",
renderer="fietsboek:templates/admin_overview.jinja2",
@@ -70,11 +84,35 @@ def admin(request: Request):
size_total = request.data_manager.size()
size_breakdown = _get_size_breakdown(request.data_manager)
+ try:
+ distro = platform.freedesktop_os_release()["PRETTY_NAME"]
+ except OSError:
+ distro = None
+
+ try:
+ last_cronjob_timestamp = float(request.redis.get("last-cronjob"))
+ except (TypeError, ValueError):
+ last_cronjob = None
+ cron_good = False
+ else:
+ last_cronjob = datetime.datetime.fromtimestamp(last_cronjob_timestamp, datetime.UTC)
+ cron_good = (datetime.datetime.now(datetime.UTC) - last_cronjob) < GOOD_CRON_THRESHOLD
+
+ versions = {
+ "fietsboek": _get_fietsboek_version(),
+ "python": platform.python_version(),
+ "linux": platform.platform(),
+ "distro": distro,
+ }
+
return {
"user_count": user_count,
"track_count": track_count,
"total_size": size_total,
"size_breakdown": size_breakdown,
+ "versions": versions,
+ "last_cronjob": last_cronjob,
+ "cron_good": cron_good,
}