208 lines
7.8 KiB
HTML
208 lines
7.8 KiB
HTML
|
|
{% extends "base.html" %}
|
||
|
|
{% block content %}
|
||
|
|
|
||
|
|
<div class="container-fluid py-4">
|
||
|
|
|
||
|
|
<!-- HEADER -->
|
||
|
|
<div class="card shadow-sm border-0 mb-4">
|
||
|
|
<div class="card-body">
|
||
|
|
<div class="d-flex flex-column flex-lg-row justify-content-between align-items-lg-center">
|
||
|
|
<div class="mb-3 mb-lg-0">
|
||
|
|
<h3 class="fw-bold text-primary mb-1"> <i class="bi bi-clock-history me-2"></i> Activity Logs </h3>
|
||
|
|
<small class="text-muted"> View application logs, search records and download log files. </small>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="d-flex flex-wrap gap-2">
|
||
|
|
<a id="downloadLogBtn" href="{{ url_for('activity.download_log') }}?file={{ file_name }}" class="btn btn-success">
|
||
|
|
<i class="bi bi-download me-1"></i>
|
||
|
|
Download Log
|
||
|
|
</a>
|
||
|
|
<a href="{{ url_for('activity.activity') }}" class="btn btn-outline-primary">
|
||
|
|
<i class="bi bi-arrow-clockwise me-1"></i>
|
||
|
|
Refresh
|
||
|
|
</a>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- FILTERS -->
|
||
|
|
<div class="card shadow-sm mb-4">
|
||
|
|
|
||
|
|
<div class="card-header bg-primary text-white">
|
||
|
|
<h5 class="mb-0">
|
||
|
|
<i class="bi bi-funnel-fill me-2"></i> Filters
|
||
|
|
</h5>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card-body">
|
||
|
|
|
||
|
|
<form method="GET">
|
||
|
|
<div class="row g-3">
|
||
|
|
<!-- Log File select -->
|
||
|
|
<div class="col-xl-2 col-lg-4 col-md-6">
|
||
|
|
<label class="form-label fw-bold">Log File</label>
|
||
|
|
<select class="form-select" name="file">
|
||
|
|
<option value="app.log" {% if file_name=="app.log" %}selected{% endif %}> Application </option>
|
||
|
|
|
||
|
|
<option value="debug.log" {% if file_name=="debug.log" %}selected{% endif %}> Debug </option>
|
||
|
|
|
||
|
|
<option value="error.log" {% if file_name=="error.log" %}selected{% endif %}> Error </option>
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
<!-- User search -->
|
||
|
|
<div class="col-xl-2 col-lg-4 col-md-6">
|
||
|
|
<label class="form-label fw-bold">User</label>
|
||
|
|
<input type="text" class="form-control" name="user" value="{{ user }}" placeholder="Username">
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Level -->
|
||
|
|
<div class="col-xl-2 col-lg-4 col-md-6">
|
||
|
|
<label class="form-label fw-bold">Level</label>
|
||
|
|
<select class="form-select" name="level">
|
||
|
|
<option value="">All</option>
|
||
|
|
|
||
|
|
<option value="INFO"
|
||
|
|
{% if level=="INFO" %}selected{% endif %}>
|
||
|
|
INFO
|
||
|
|
</option>
|
||
|
|
|
||
|
|
<option value="WARNING"
|
||
|
|
{% if level=="WARNING" %}selected{% endif %}>
|
||
|
|
WARNING
|
||
|
|
</option>
|
||
|
|
|
||
|
|
<option value="ERROR"
|
||
|
|
{% if level=="ERROR" %}selected{% endif %}>
|
||
|
|
ERROR
|
||
|
|
</option>
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- From Date -->
|
||
|
|
<div class="col-xl-2 col-lg-4 col-md-6">
|
||
|
|
<label class="form-label fw-bold">From Date</label>
|
||
|
|
<input type="date" class="form-control" name="from_date" value="{{ from_date }}">
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- To Date -->
|
||
|
|
<div class="col-xl-2 col-lg-4 col-md-6">
|
||
|
|
<label class="form-label fw-bold">To Date</label>
|
||
|
|
<input type="date" class="form-control" name="to_date" value="{{ to_date }}">
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Search button -->
|
||
|
|
<div class="col-xl-2 col-lg-12">
|
||
|
|
<label class="form-label fw-bold">Search</label>
|
||
|
|
<input type="text" class="form-control" name="search" value="{{ search }}" placeholder="Search">
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<hr>
|
||
|
|
|
||
|
|
<!-- Search and Reset button -->
|
||
|
|
<div class="d-flex gap-2">
|
||
|
|
|
||
|
|
<button class="btn btn-primary">
|
||
|
|
<i class="bi bi-search"></i> Search
|
||
|
|
</button>
|
||
|
|
|
||
|
|
<button type="reset" class="btn btn-secondary">
|
||
|
|
<i class="bi bi-arrow-clockwise"></i> Reset
|
||
|
|
</button>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- LOG TABLE -->
|
||
|
|
<div class="card shadow-sm">
|
||
|
|
<!-- Log Entries -->
|
||
|
|
<div class="card-header bg-dark text-white">
|
||
|
|
<div class="d-flex justify-content-between align-items-center">
|
||
|
|
<h5 class="mb-0">
|
||
|
|
<i class="bi bi-list-ul me-2"></i>
|
||
|
|
Log Entries
|
||
|
|
</h5>
|
||
|
|
|
||
|
|
<span class="badge bg-light text-dark">
|
||
|
|
{{ logs|length }} Records
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Show table Entries -->
|
||
|
|
<div class="card-body p-0">
|
||
|
|
<div class="table-responsive" style="max-height:600px; overflow-y:auto; font-size:12px;">
|
||
|
|
<table class="table table-striped table-hover table-bordered align-middle mb-0 small">
|
||
|
|
|
||
|
|
<thead class="table-dark sticky-top">
|
||
|
|
<tr>
|
||
|
|
<th>Sr No</th>
|
||
|
|
<th>Date & Time</th>
|
||
|
|
<th>User</th>
|
||
|
|
<th>Level</th>
|
||
|
|
<th>Module</th>
|
||
|
|
<th>Activity</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
|
||
|
|
<tbody>
|
||
|
|
|
||
|
|
{% for log in logs %}
|
||
|
|
<tr>
|
||
|
|
<td>{{ loop.index }}</td>
|
||
|
|
<td>{{ log.date }}</td>
|
||
|
|
<td>{{ log.user }}</td>
|
||
|
|
<td>
|
||
|
|
{% if log.level=="INFO" %}
|
||
|
|
<span class="badge bg-success">INFO</span>
|
||
|
|
{% elif log.level=="WARNING" %}
|
||
|
|
<span class="badge bg-warning text-dark">WARNING</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge bg-danger">ERROR</span>
|
||
|
|
{% endif %}
|
||
|
|
</td>
|
||
|
|
|
||
|
|
<td>{{ log.module }}</td>
|
||
|
|
<td>{{ log.message }}</td>
|
||
|
|
</tr>
|
||
|
|
{% endfor %}
|
||
|
|
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
|
||
|
|
<script>
|
||
|
|
document.addEventListener("DOMContentLoaded", function () {
|
||
|
|
|
||
|
|
const fileSelect = document.querySelector('select[name="file"]');
|
||
|
|
const downloadBtn = document.getElementById("downloadLogBtn");
|
||
|
|
|
||
|
|
function updateDownloadLink() {
|
||
|
|
|
||
|
|
downloadBtn.href =
|
||
|
|
"{{ url_for('activity.download_log') }}?file=" +
|
||
|
|
encodeURIComponent(fileSelect.value);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
updateDownloadLink();
|
||
|
|
|
||
|
|
fileSelect.addEventListener("change", updateDownloadLink);
|
||
|
|
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
{% endblock %}
|