DSP Project first push, date: 29/01/2026
This commit is contained in:
119
admin/app_log.php
Normal file
119
admin/app_log.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once __DIR__ . '/../config.php';
|
||||
require_once __DIR__ . '/../includes/auth.php';
|
||||
|
||||
redirect_if_not_role('DAC Staff', '../index.php');
|
||||
|
||||
$logPath = realpath(__DIR__ . '/../logs/app.log');
|
||||
$canReadLog = $logPath && is_readable($logPath);
|
||||
$lineLimit = filter_input(INPUT_GET, 'lines', FILTER_VALIDATE_INT);
|
||||
$lineLimit = $lineLimit ?: 200;
|
||||
$lineLimit = max(50, min(2000, $lineLimit));
|
||||
$logEntries = [];
|
||||
$logMeta = [
|
||||
'size' => null,
|
||||
'modified' => null,
|
||||
];
|
||||
|
||||
if ($canReadLog) {
|
||||
$logMeta['size'] = filesize($logPath);
|
||||
$logMeta['modified'] = filemtime($logPath);
|
||||
|
||||
if (isset($_GET['download'])) {
|
||||
header('Content-Type: text/plain');
|
||||
header('Content-Disposition: attachment; filename="app.log"');
|
||||
header('Content-Length: ' . $logMeta['size']);
|
||||
readfile($logPath);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$logEntries = tail_file($logPath, $lineLimit);
|
||||
} catch (RuntimeException $e) {
|
||||
$canReadLog = false;
|
||||
$logError = $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
$logError = 'The application log file is missing or unreadable.';
|
||||
}
|
||||
|
||||
function tail_file(string $path, int $lines): array
|
||||
{
|
||||
$file = new SplFileObject($path, 'r');
|
||||
$file->seek(PHP_INT_MAX);
|
||||
$lastLine = $file->key();
|
||||
$startLine = max($lastLine - $lines + 1, 0);
|
||||
$file->seek($startLine);
|
||||
|
||||
$buffer = [];
|
||||
while (!$file->eof()) {
|
||||
$buffer[] = rtrim($file->current(), "\r\n");
|
||||
$file->next();
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
$lastUpdated = $logMeta['modified'] ? date('Y-m-d H:i:s', $logMeta['modified']) . ' UTC' : 'Unknown';
|
||||
$logSizeHuman = $logMeta['size'] !== null ? number_format($logMeta['size'] / 1024, 1) . ' KB' : 'Unknown';
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<?php include_once __DIR__ . '/../includes/header_admin.php'; ?>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<?php include_once __DIR__ . '/../includes/nav_admin.php'; ?>
|
||||
<div class="main-content">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h1 class="h4 mb-1">Application Log</h1>
|
||||
<p class="text-muted mb-0">Streaming the latest <?php echo htmlspecialchars($lineLimit); ?> lines from <code>logs/app.log</code>.</p>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<small class="text-muted d-block">Last updated: <?php echo htmlspecialchars($lastUpdated); ?></small>
|
||||
<small class="text-muted">Size: <?php echo htmlspecialchars($logSizeHuman); ?></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body d-flex flex-wrap gap-2 align-items-center">
|
||||
<form class="d-flex align-items-center gap-2" method="get">
|
||||
<label for="lines" class="form-label mb-0">Lines to display</label>
|
||||
<select class="form-select form-select-sm w-auto" id="lines" name="lines" onchange="this.form.submit()">
|
||||
<?php foreach ([100, 200, 500, 1000, 2000] as $option): ?>
|
||||
<option value="<?php echo $option; ?>" <?php echo ($lineLimit === $option) ? 'selected' : ''; ?>>
|
||||
<?php echo $option; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</form>
|
||||
<?php if ($canReadLog): ?>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="?lines=<?php echo $lineLimit; ?>">
|
||||
<i class="fas fa-sync-alt me-1"></i> Refresh
|
||||
</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="?download=1">
|
||||
<i class="fas fa-download me-1"></i> Download
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!$canReadLog): ?>
|
||||
<div class="alert alert-danger rounded shadow-sm">
|
||||
<strong>Cannot read log file.</strong>
|
||||
<div><?php echo htmlspecialchars($logError ?? 'Unknown error.'); ?></div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<pre class="bg-dark text-light p-3 rounded small" style="max-height: 60vh; overflow:auto;"><?php echo htmlspecialchars(implode("\n", $logEntries)); ?></pre>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php include_once __DIR__ . '/../includes/footer_admin.php'; ?>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user