<?php
/**
* App Diagnostic Log Viewer & Exporter
*/
$logFile = 'logs/app_diagnostic.txt';
// --- CSV EXPORT LOGIC ---
if (isset($_GET['export']) && $_GET['export'] === 'csv') {
if (!file_exists($logFile)) die("No log file found.");
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="App_Logs_'.date('Ymd_His').'.csv"');
$output = fopen('php://output', 'w');
fputcsv($output, ['Timestamp', 'User ID', 'Version', 'Message/Label', 'Raw Data']);
$entries = file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($entries as $line) {
preg_match('/\[(.*?)\] User: (.*?) \| Ver: (.*?) \| Msg: (.*?) \| Raw: (.*)/', $line, $matches);
if (count($matches) >= 6) {
fputcsv($output, [$matches[1], $matches[2], $matches[3], $matches[4], $matches[5]]);
}
}
fclose($output);
exit;
}
// --- VIEW LOGIC ---
if (!file_exists($logFile)) {
die("No diagnostic logs found yet.");
}
$logEntries = array_reverse(file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>App Diagnostic Center</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background-color: #f8f9fa; font-size: 0.85rem; }
.raw-data { max-height: 80px; overflow-y: auto; background: #f1f1f1; padding: 5px; font-family: monospace; font-size: 0.75rem; word-break: break-all; }
.sticky-top-header { position: sticky; top: 0; background: #212529; color: white; z-index: 1000; }
</style>
</head>
<body>
<div class="container-fluid py-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h2 class="h4">Remote Diagnostic Logs</h2>
<div class="btn-group">
<button onclick="window.location.reload();" class="btn btn-outline-primary btn-sm">Refresh</button>
<a href="?export=csv" class="btn btn-outline-success btn-sm">Download CSV</a>
</div>
</div>
<div class="table-responsive shadow-sm border rounded bg-white">
<table class="table table-sm table-hover mb-0">
<thead class="sticky-top-header">
<tr>
<th width="15%">Time (AEST)</th>
<th width="10%">User</th>
<th width="5%">Ver</th>
<th width="20%">Label</th>
<th width="50%">Response Content</th>
</tr>
</thead>
<tbody>
<?php foreach ($logEntries as $line):
preg_match('/\[(.*?)\] User: (.*?) \| Ver: (.*?) \| Msg: (.*?) \| Raw: (.*)/', $line, $matches);
if (count($matches) < 6) continue;
$isError = (stripos($matches[4], 'Crash') !== false || stripos($matches[4], 'Failure') !== false);
?>
<tr class="<?php echo $isError ? 'table-danger' : ''; ?>">
<td class="text-nowrap"><?php echo $matches[1]; ?></td>
<td><span class="badge bg-light text-dark border"><?php echo htmlspecialchars($matches[2]); ?></span></td>
<td><?php echo htmlspecialchars($matches[3]); ?></td>
<td><span class="badge <?php echo $isError ? 'bg-danger' : 'bg-primary'; ?>"><?php echo htmlspecialchars($matches[4]); ?></span></td>
<td><div class="raw-data"><?php echo htmlspecialchars($matches[5]); ?></div></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</body>
</html>