Now that I'm adding more logging, I wanted to add a log viewer so people don't have to ssh to their servers to inspect logs. Also added tests around logging and the viewer. Reviewed-on: https://gitea.subcultureofone.org/greg/tkr/pulls/41 Co-authored-by: Greg Sarjeant <greg@subcultureofone.org> Co-committed-by: Greg Sarjeant <greg@subcultureofone.org>
90 lines
4.7 KiB
PHP
90 lines
4.7 KiB
PHP
<?php /** @var ConfigModel $config */ ?>
|
|
<?php /** @var array $logEntries */ ?>
|
|
<?php /** @var array $availableRoutes */ ?>
|
|
<?php /** @var array $availableLevels */ ?>
|
|
<?php /** @var string $currentLevelFilter */ ?>
|
|
<?php /** @var string $currentRouteFilter */ ?>
|
|
<h1>System Logs</h1>
|
|
<main>
|
|
<!-- Filters -->
|
|
<div class="log-filters">
|
|
<form method="get" action="<?= Util::buildRelativeUrl($config->basePath, 'admin/logs') ?>">
|
|
<fieldset>
|
|
<legend>Filter Logs</legend>
|
|
<div class="fieldset-items">
|
|
<label for="level-filter">Level:</label>
|
|
<select id="level-filter" name="level">
|
|
<option value="">All Levels</option>
|
|
<?php foreach ($availableLevels as $level): ?>
|
|
<option value="<?= Util::escape_html($level) ?>"
|
|
<?= $currentLevelFilter === $level ? 'selected' : '' ?>>
|
|
<?= Util::escape_html($level) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
|
|
<label for="route-filter">Route:</label>
|
|
<select id="route-filter" name="route">
|
|
<option value="">All Routes</option>
|
|
<?php foreach ($availableRoutes as $route): ?>
|
|
<option value="<?= Util::escape_html($route) ?>"
|
|
<?= $currentRouteFilter === $route ? 'selected' : '' ?>>
|
|
<?= Util::escape_html($route) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
|
|
<div></div><button type="submit">Filter</button>
|
|
<div></div><a href="<?= Util::buildRelativeUrl($config->basePath, 'admin/logs') ?>">Clear</a>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Log entries table -->
|
|
<div class="log-entries">
|
|
<?php if (empty($logEntries)): ?>
|
|
<p>No log entries found matching the current filters.</p>
|
|
<?php else: ?>
|
|
<table class="log-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>Level</th>
|
|
<th>IP</th>
|
|
<th>Route</th>
|
|
<th>Message</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($logEntries as $entry): ?>
|
|
<tr class="log-entry log-<?= strtolower($entry['level']) ?>">
|
|
<td class="log-timestamp log-monospace">
|
|
<time datetime="<?= Util::escape_html($entry['timestamp']) ?>">
|
|
<?= Util::escape_html($entry['timestamp']) ?>
|
|
</time>
|
|
</td>
|
|
<td class="log-level">
|
|
<span class="log-level-badge"><?= Util::escape_html($entry['level']) ?></span>
|
|
</td>
|
|
<td class="log-ip log-monospace"><?= Util::escape_html($entry['ip']) ?></td>
|
|
<td class="log-route log-monospace">
|
|
<?php if ($entry['route']): ?>
|
|
<?= Util::escape_html($entry['route']) ?>
|
|
<?php else: ?>
|
|
<span class="log-no-route">-</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="log-message log-monospace"><?= Util::escape_html($entry['message']) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="log-info">
|
|
<p>Showing <?= count($logEntries) ?> recent log entries.
|
|
Log files are automatically rotated when they reach 1000 lines.</p>
|
|
</div>
|
|
</main>
|