aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2026-10-17 20:17:52 +0200
committerDaniel Schadt <kingdread@gmx.de>2026-10-17 20:17:52 +0200
commitaa7b1996f50b0861af51913faca48385f01f90aa (patch)
treeb7835facad79f5e5aa15abe6ecfea7acb17efea7
parente11c0bea5f23387be85e03e478928a5bc054c462 (diff)
downloadfietsboek-aa7b1996f50b0861af51913faca48385f01f90aa.tar.gz
fietsboek-aa7b1996f50b0861af51913faca48385f01f90aa.tar.bz2
fietsboek-aa7b1996f50b0861af51913faca48385f01f90aa.zip
also show fietscron logs in admin viewlogs-in-ui
-rw-r--r--fietsboek/scripts/fietscron.py5
-rw-r--r--fietsboek/templates/admin_logs.jinja2102
-rw-r--r--fietsboek/views/admin.py12
3 files changed, 85 insertions, 34 deletions
diff --git a/fietsboek/scripts/fietscron.py b/fietsboek/scripts/fietscron.py
index c9bb9dd..57ba820 100644
--- a/fietsboek/scripts/fietscron.py
+++ b/fietsboek/scripts/fietscron.py
@@ -1,6 +1,7 @@
"""Script to do maintenance actions for fietsboek."""
import datetime
+import json
import logging
import logging.config
@@ -13,7 +14,7 @@ from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session
from .. import config as mod_config
-from .. import hittekaart, models, osm, trackmap
+from .. import hittekaart, log, models, osm, trackmap
from ..config import Config
from ..data import DataManager
from ..models import get_engine
@@ -41,6 +42,7 @@ def cli(config):
* Finds names for climbs not yet named
"""
logging.config.fileConfig(config)
+ log.install()
settings = pyramid.paster.get_appsettings(config)
config = mod_config.parse(settings)
@@ -67,6 +69,7 @@ def cli(config):
run_hittekaart(engine, data_manager, redis, config)
redis.set("last-cronjob", datetime.datetime.now(datetime.UTC).timestamp())
+ redis.set("last-cronjob:log", json.dumps([line.as_dict() for line in log.HANDLER.buffer]))
def remove_old_uploads(engine: Engine):
diff --git a/fietsboek/templates/admin_logs.jinja2 b/fietsboek/templates/admin_logs.jinja2
index ac3f956..fad0cab 100644
--- a/fietsboek/templates/admin_logs.jinja2
+++ b/fietsboek/templates/admin_logs.jinja2
@@ -1,46 +1,86 @@
{% set admin_index = 2 %}
{% extends "admin.jinja2" %}
{% block admin_content %}
-<div>
- Filter:
- <select class="form-select my-2" id="logLevelSelect">
- <option value="10">Debug</option>
- <option value="20" selected>Info</option>
- <option value="30">Warning</option>
- <option value="40">Error</option>
- <option value="50">Critical</option>
- </select>
-</div>
-<div class="logview" style="overflow: scroll; white-space: nowrap;">
- <table>
- {% for entry in entries %}
- <tr class="logline logline-{{entry.level_name | lower}}" data-level="{{ entry.level }}">
- <td>{{ entry.time }}</td>
- <td>{{ entry.level_name }}</td>
- <td>{{ entry.name }}:{{ entry.lineno }}</td>
- <td>{{ entry.thread }}</td>
- <td>{{ entry.message }}</td>
- </tr>
- {% endfor %}
- </table>
+<ul class="nav nav-tabs" id="myTab" role="tablist">
+ <li class="nav-item" role="presentation">
+ <button class="nav-link active" id="fietsboek-tab" data-bs-toggle="tab" data-bs-target="#fietsboek-logs-tab" type="button" role="tab" aria-controls="fietsboek-logs-tab" aria-selected="true">Fietsboek</button>
+ </li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link" id="fietscron-tab" data-bs-toggle="tab" data-bs-target="#fietscron-logs-tab" type="button" role="tab" aria-controls="fietscron-logs-tab" aria-selected="false"><code>fietscron</code></button>
+ </li>
+</ul>
+<div class="tab-content" id="logTab">
+ <div class="tab-pane fade show active" id="fietsboek-logs-tab" role="tabpanel" aria-labelledby="fietsboek-tab" tabindex="0">
+ <div>
+ Filter:
+ <select class="form-select my-2 loglevelselect" data-logview-id="#fietsboek-logs-tab">
+ <option value="10">Debug</option>
+ <option value="20" selected>Info</option>
+ <option value="30">Warning</option>
+ <option value="40">Error</option>
+ <option value="50">Critical</option>
+ </select>
+ </div>
+ <div class="logview" style="overflow: scroll; white-space: nowrap;">
+ <table>
+ {% for entry in entries %}
+ <tr class="logline logline-{{entry.level_name | lower}}" data-level="{{ entry.level }}">
+ <td>{{ entry.time }}</td>
+ <td>{{ entry.level_name }}</td>
+ <td>{{ entry.name }}:{{ entry.lineno }}</td>
+ <td>{{ entry.thread }}</td>
+ <td>{{ entry.message }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+ </div>
+ <div class="tab-pane fade" id="fietscron-logs-tab" role="tabpanel" aria-labelledby="fietscron-tab" tabindex="0">
+ <div>
+ Filter:
+ <select class="form-select my-2 loglevelselect" data-logview-id="#fietscron-logs-tab">
+ <option value="10">Debug</option>
+ <option value="20" selected>Info</option>
+ <option value="30">Warning</option>
+ <option value="40">Error</option>
+ <option value="50">Critical</option>
+ </select>
+ </div>
+ <div class="logview" style="overflow: scroll; white-space: nowrap;">
+ <table>
+ {% for entry in entries_fietscron %}
+ <tr class="logline logline-{{entry.level_name | lower}}" data-level="{{ entry.level }}">
+ <td>{{ entry.time }}</td>
+ <td>{{ entry.level_name }}</td>
+ <td>{{ entry.name }}:{{ entry.lineno }}</td>
+ <td>{{ entry.thread }}</td>
+ <td>{{ entry.message }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+ </div>
</div>
{% endblock %}
{% block latescripts %}
<script type="text/javascript">
function filterLogEntries() {
- let wantedLevel = parseInt(document.querySelector("#logLevelSelect").value);
- document.querySelectorAll(".logline").forEach((line) => {
- let lineLevel = parseInt(line.getAttribute("data-level"));
- if (lineLevel >= wantedLevel) {
- line.style.display = "";
- } else {
- line.style.display = "none";
- }
+ document.querySelectorAll(".loglevelselect").forEach((filter) => {
+ let wantedLevel = parseInt(filter.value);
+ let controlled = filter.getAttribute("data-logview-id");
+ document.querySelectorAll(`${controlled} .logline`).forEach((line) => {
+ let lineLevel = parseInt(line.getAttribute("data-level"));
+ if (lineLevel >= wantedLevel) {
+ line.style.display = "";
+ } else {
+ line.style.display = "none";
+ }
+ });
});
}
- document.querySelector("#logLevelSelect").addEventListener("change", (e) => filterLogEntries());
+ document.querySelectorAll(".loglevelselect").forEach((l) => l.addEventListener("change", (e) => filterLogEntries()));
filterLogEntries();
</script>
{% endblock %}
diff --git a/fietsboek/views/admin.py b/fietsboek/views/admin.py
index 3385d3e..0f741a3 100644
--- a/fietsboek/views/admin.py
+++ b/fietsboek/views/admin.py
@@ -1,6 +1,7 @@
"""Admin views."""
import datetime
+import json
import platform
import stat
from dataclasses import dataclass
@@ -153,12 +154,19 @@ def admin(request: Request):
renderer="fietsboek:templates/admin_logs.jinja2",
permission="admin",
)
-def admin_logs(_request: Request):
+def admin_logs(request: Request):
"""Renders the admin logs overview.
:param request: The pyramid request.
"""
- return {"entries": log.HANDLER.buffer}
+ entries_fc_json = request.redis.get("last-cronjob:log")
+ entries_fc = []
+ if entries_fc_json is not None:
+ entries_fc = json.loads(entries_fc_json)
+ return {
+ "entries": log.HANDLER.buffer,
+ "entries_fietscron": entries_fc,
+ }
@view_config(