107 lines
5.4 KiB
HTML
107 lines
5.4 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Logs des watchdogs — GMAO Collège{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h2 class="h5 mb-0"><i class="bi bi-journal-text"></i> Logs des watchdogs</h2>
|
|
<div class="d-flex gap-2">
|
|
<a href="{{ url_for('logs.api_recent', limit=100) }}" class="btn btn-sm btn-outline-secondary" target="_blank"><i class="bi bi-download"></i> API JSON</a>
|
|
{% if current_user.is_admin() %}
|
|
<form method="POST" action="{{ url_for('logs.apply_retention') }}" class="d-flex"><input type="hidden" name="csrf_token" value="{{ csrf_token() }}"><input type="number" min="1" max="3650" name="days" value="{{ retention_days }}" class="form-control form-control-sm" style="width:85px" title="Jours de conservation"><button class="btn btn-sm btn-outline-primary">Purger</button></form>
|
|
<form method="POST" action="{{ url_for('logs.clear_watchdog_logs') }}" onsubmit="return confirm('Vider définitivement tous les journaux des watchdogs ?');">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<button type="submit" class="btn btn-sm btn-outline-danger">
|
|
<i class="bi bi-trash3"></i> Vider les logs
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card border-0 shadow-sm mb-3">
|
|
<div class="card-body py-2">
|
|
<form method="GET" class="row g-2 align-items-end">
|
|
<div class="col-md-3">
|
|
<select name="watchdog" class="form-select form-select-sm">
|
|
<option value="" {% if not filters.watchdog %}selected{% endif %}>Tous les watchdogs</option>
|
|
{% for w in watchdogs %}
|
|
<option value="{{ w }}" {% if filters.watchdog == w %}selected{% endif %}>{{ w }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<select name="level" class="form-select form-select-sm">
|
|
<option value="" {% if not filters.level %}selected{% endif %}>Tous les niveaux</option>
|
|
<option value="info" {% if filters.level == 'info' %}selected{% endif %}>Info</option>
|
|
<option value="warning" {% if filters.level == 'warning' %}selected{% endif %}>Warning</option>
|
|
<option value="error" {% if filters.level == 'error' %}selected{% endif %}>Error</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button type="submit" class="btn btn-sm btn-outline-primary w-100"><i class="bi bi-funnel"></i> Filtrer</button>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<a href="{{ url_for('logs.index') }}" class="btn btn-sm btn-outline-secondary w-100"><i class="bi bi-x-circle"></i> Reset</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-striped table-hover">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Watchdog</th>
|
|
<th>Niveau</th>
|
|
<th>Message</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for log in pagination.items %}
|
|
<tr>
|
|
<td class="text-nowrap small">{{ log.created_at.strftime('%d/%m/%Y %H:%M:%S') if log.created_at else '-' }}</td>
|
|
<td><span class="badge bg-secondary">{{ log.watchdog_name }}</span></td>
|
|
<td>
|
|
{% if log.level == 'error' %}
|
|
<span class="badge bg-danger">Error</span>
|
|
{% elif log.level == 'warning' %}
|
|
<span class="badge bg-warning text-dark">Warning</span>
|
|
{% else %}
|
|
<span class="badge bg-info text-dark">Info</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="font-monospace small"><pre class="mb-0">{{ log.message }}</pre></td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="4" class="text-center text-muted py-4">Aucun log</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{% if pagination.pages > 1 %}
|
|
<nav aria-label="Pagination logs">
|
|
<ul class="pagination pagination-sm justify-content-center">
|
|
<li class="page-item {% if not pagination.has_prev %}disabled{% endif %}">
|
|
<a class="page-link" href="{{ url_for('logs.index', page=pagination.prev_num, **filters) if pagination.has_prev else '#' }}">«</a>
|
|
</li>
|
|
{% for p in pagination.iter_pages(left_edge=1, right_edge=1, left_current=2, right_current=2) %}
|
|
{% if p %}
|
|
<li class="page-item {% if p == pagination.page %}active{% endif %}">
|
|
<a class="page-link" href="{{ url_for('logs.index', page=p, **filters) }}">{{ p }}</a>
|
|
</li>
|
|
{% else %}
|
|
<li class="page-item disabled"><span class="page-link">…</span></li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
<li class="page-item {% if not pagination.has_next %}disabled{% endif %}">
|
|
<a class="page-link" href="{{ url_for('logs.index', page=pagination.next_num, **filters) if pagination.has_next else '#' }}">»</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
<p class="text-center text-muted small">Page {{ pagination.page }} / {{ pagination.pages }}</p>
|
|
{% endif %}
|
|
{% endblock %}
|