feat: Enhance logs view with support for displaying all entries and improved pagination

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Ross
2026-04-29 22:37:13 +01:00
co-authored by Copilot
parent 7479b44f53
commit 2478de6b98
2 changed files with 34 additions and 30 deletions
+10 -2
View File
@@ -243,10 +243,12 @@ def logs_view(request):
Scope: superusers only. Scope: superusers only.
Functionality: reads log.txt, displays entries with optional text search filter. Functionality: reads log.txt, displays entries with optional text search filter.
Supports ?all=1 to show all entries without pagination limit.
""" """
log_file_path = os.path.join(settings.BASE_DIR, "log.txt") log_file_path = os.path.join(settings.BASE_DIR, "log.txt")
entries = [] entries = []
search_query = request.GET.get("q", "").strip() search_query = request.GET.get("q", "").strip()
show_all = request.GET.get("all") == "1"
if os.path.exists(log_file_path): if os.path.exists(log_file_path):
try: try:
@@ -267,14 +269,20 @@ def logs_view(request):
else: else:
entries = [f"Log file not found at {log_file_path}"] entries = [f"Log file not found at {log_file_path}"]
total = len(entries)
limit = None if show_all else 500
displayed_entries = entries[:limit] if limit else entries
return render( return render(
request, request,
"logs_viewer.html", "logs_viewer.html",
{ {
"entries": entries[:500], "entries": displayed_entries,
"total_entries": len(entries), "total_entries": total,
"search_query": search_query, "search_query": search_query,
"log_file_path": log_file_path, "log_file_path": log_file_path,
"show_all": show_all,
"limit": limit,
}, },
) )
+23 -27
View File
@@ -11,7 +11,11 @@
</div> </div>
<div class="text-end"> <div class="text-end">
<span class="badge bg-secondary rounded-pill px-3 py-2"> <span class="badge bg-secondary rounded-pill px-3 py-2">
{% if show_all %}
Viewing all {{ total_entries }} entries
{% else %}
Showing {{ entries|length }}/{{ total_entries }} entries Showing {{ entries|length }}/{{ total_entries }} entries
{% endif %}
</span> </span>
</div> </div>
</div> </div>
@@ -19,7 +23,7 @@
<div class="card border-0 shadow-sm mb-4"> <div class="card border-0 shadow-sm mb-4">
<div class="card-body"> <div class="card-body">
<form method="get" class="row g-2"> <form method="get" class="row g-2">
<div class="col-12 col-md-8"> <div class="col-12 col-md-6">
<input type="search" <input type="search"
name="q" name="q"
class="form-control" class="form-control"
@@ -32,44 +36,36 @@
<a href="{% url 'logs_view' %}" class="btn btn-outline-secondary ms-1">Clear</a> <a href="{% url 'logs_view' %}" class="btn btn-outline-secondary ms-1">Clear</a>
{% endif %} {% endif %}
</div> </div>
<div class="col-12 col-md-auto">
{% if show_all %}
<a href="{% url 'logs_view' %}?q={{ search_query }}" class="btn btn-outline-secondary">Show recent only</a>
{% else %}
<a href="{% url 'logs_view' %}?q={{ search_query }}&all=1" class="btn btn-outline-info">View all logs</a>
{% endif %}
</div>
</form> </form>
</div> </div>
</div> </div>
{% if entries %} {% if entries %}
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-0"> <div class="card-body p-0" style="max-height: 75vh; overflow-y: auto;">
<div style="max-height: 70vh; overflow-y: auto;"> <pre style="margin: 0; padding: 1rem; font-size: 0.85rem; line-height: 1.5;">{% for entry in entries %}
<table class="table table-sm table-striped mb-0" style="font-family: monospace; font-size: 0.875rem;">
<tbody>
{% for entry in entries %}
<tr>
<td class="text-muted align-top" style="width: 30px; white-space: nowrap;">
{{ forloop.counter }}
</td>
<td style="word-break: break-all; white-space: pre-wrap;">
{% if 'ERROR' in entry %}
<span class="badge bg-danger me-1">ERROR</span>
{% elif 'WARNING' in entry or 'WARN' in entry %}
<span class="badge bg-warning me-1">WARN</span>
{% elif 'DEBUG' in entry %}
<span class="badge bg-secondary me-1">DEBUG</span>
{% elif 'INFO' in entry %}
<span class="badge bg-info me-1">INFO</span>
{% endif %}
{{ entry }} {{ entry }}
</td> {% endfor %}</pre>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div> </div>
</div> </div>
<div class="alert alert-secondary mt-3 small"> <div class="alert alert-secondary mt-3 small">
<i class="bi bi-info-circle"></i> <i class="bi bi-info-circle"></i>
Showing most recent entries first. Filtered display limited to 500 entries. {% if show_all %}
Displaying all {{ total_entries }} log entries (newest first).
{% else %}
Displaying most recent 500 entries (newest first).
{% if total_entries > 500 %}
<a href="{% url 'logs_view' %}?q={{ search_query }}&all=1" class="alert-link">View all {{ total_entries }} entries</a>.
{% endif %}
{% endif %}
{% if search_query %} {% if search_query %}
Search found {{ entries|length }} matching entr{{ entries|length|pluralize:"y,ies" }}. Search found {{ entries|length }} matching entr{{ entries|length|pluralize:"y,ies" }}.
{% endif %} {% endif %}