Refactor code structure for improved readability and maintainability
This commit is contained in:
608
log/logging.php
Normal file
608
log/logging.php
Normal file
@@ -0,0 +1,608 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>System Logging</title>
|
||||
<style>
|
||||
:root {
|
||||
--primary-green: #22c55e;
|
||||
--white: #ffffff;
|
||||
--gray-50: #f9fafb;
|
||||
--gray-100: #f3f4f6;
|
||||
--gray-200: #e5e7eb;
|
||||
--gray-300: #d1d5db;
|
||||
--gray-500: #6b7280;
|
||||
--gray-600: #4b5563;
|
||||
--gray-700: #374151;
|
||||
--gray-900: #111827;
|
||||
--space-xs: 0.25rem;
|
||||
--space-sm: 0.5rem;
|
||||
--space-md: 0.75rem;
|
||||
--space-lg: 1rem;
|
||||
--space-xl: 1.5rem;
|
||||
--radius-md: 0.375rem;
|
||||
--radius-lg: 0.5rem;
|
||||
--font-size-sm: 0.875rem;
|
||||
--font-size-base: 1rem;
|
||||
--font-size-lg: 1.125rem;
|
||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||
background: var(--gray-50);
|
||||
color: var(--gray-900);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
padding: var(--space-xl);
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--white);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-md);
|
||||
border: 1px solid var(--gray-200);
|
||||
}
|
||||
|
||||
.card__header {
|
||||
padding: var(--space-xl);
|
||||
}
|
||||
|
||||
.card__title {
|
||||
font-size: 1.875rem;
|
||||
font-weight: 700;
|
||||
color: var(--gray-900);
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
|
||||
.card__subtitle {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--gray-500);
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 1px solid var(--gray-300);
|
||||
background: var(--white);
|
||||
color: var(--gray-700);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: var(--gray-50);
|
||||
border-color: var(--gray-400);
|
||||
}
|
||||
|
||||
.btn--secondary {
|
||||
background: var(--gray-100);
|
||||
}
|
||||
|
||||
.btn--sm {
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// POST HANDLER - Delete all logs
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
$delete_message = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_all_logs'])) {
|
||||
$logs_dir = __DIR__ . '/';
|
||||
$deleted_count = 0;
|
||||
|
||||
if (is_dir($logs_dir)) {
|
||||
$files = scandir($logs_dir);
|
||||
foreach ($files as $file) {
|
||||
if (preg_match('/\.txt$/', $file)) {
|
||||
if (unlink($logs_dir . $file)) {
|
||||
$deleted_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$delete_message = "Successfully deleted $deleted_count log file(s).";
|
||||
// Redirect to clear POST data
|
||||
header("Location: " . strtok($_SERVER["REQUEST_URI"], '?') . "?deleted=$deleted_count");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Show delete confirmation message
|
||||
if (isset($_GET['deleted'])) {
|
||||
$delete_message = "Successfully deleted " . intval($_GET['deleted']) . " log file(s).";
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// GET HANDLER
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
// Get selected log file from query parameter
|
||||
$selected_log = $_GET['log'] ?? '';
|
||||
|
||||
// Scan logs directory for all log files
|
||||
// Use __DIR__ to get current directory of this script
|
||||
$logs_dir = __DIR__ . '/';
|
||||
$log_files = [];
|
||||
|
||||
if (is_dir($logs_dir)) {
|
||||
$files = scandir($logs_dir);
|
||||
foreach ($files as $file) {
|
||||
if (preg_match('/\.txt$/', $file) && is_file($logs_dir . $file)) {
|
||||
// Extract date from filename (last 2 digits before .txt)
|
||||
$date = '00'; // Default date
|
||||
if (preg_match('/_(\d{2})\.txt$/', $file, $matches)) {
|
||||
$date = $matches[1];
|
||||
}
|
||||
|
||||
$log_files[] = [
|
||||
'filename' => $file,
|
||||
'date' => $date,
|
||||
'path' => $logs_dir . $file,
|
||||
'size' => filesize($logs_dir . $file)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by date descending, then by filename
|
||||
usort($log_files, function($a, $b) {
|
||||
if ($a['date'] === $b['date']) {
|
||||
return strcmp($b['filename'], $a['filename']);
|
||||
}
|
||||
return $b['date'] <=> $a['date'];
|
||||
});
|
||||
|
||||
// Load selected log content
|
||||
$contents = '';
|
||||
if ($selected_log && file_exists($logs_dir . $selected_log)) {
|
||||
$contents = file_get_contents($logs_dir . $selected_log);
|
||||
} elseif (!empty($log_files)) {
|
||||
// Default to most recent log
|
||||
$contents = file_get_contents($log_files[0]['path']);
|
||||
$selected_log = $log_files[0]['filename'];
|
||||
} else {
|
||||
$contents = 'No application log files found.';
|
||||
}
|
||||
|
||||
$filelocation_webserver = '/var/www/vhosts/morvalwatches.com/logs/'.$_SERVER['HTTP_HOST'].'/access_ssl_log';
|
||||
|
||||
if (file_exists($filelocation_webserver)){
|
||||
$contents_webserver = file_get_contents($filelocation_webserver);
|
||||
} else {$contents_webserver = 'No webserver log file found.';}
|
||||
?>
|
||||
|
||||
<!-- Main Content Area --><?php
|
||||
// Display delete message if exists
|
||||
if ($delete_message) {
|
||||
echo '<div style="
|
||||
position: fixed;
|
||||
top: var(--space-lg);
|
||||
right: var(--space-lg);
|
||||
background: var(--primary-green);
|
||||
color: var(--white);
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-md);
|
||||
z-index: 1000;
|
||||
font-weight: 500;
|
||||
" id="delete-notification">
|
||||
✓ ' . htmlspecialchars($delete_message) . '
|
||||
</div>';
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="content-area">
|
||||
<div class="w-full">
|
||||
<!-- Tab Navigation -->
|
||||
<div style="
|
||||
background: var(--white);
|
||||
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
||||
border: 1px solid var(--gray-200);
|
||||
border-bottom: none;
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
box-shadow: var(--shadow-sm);
|
||||
">
|
||||
<div style="
|
||||
display: flex;
|
||||
gap: 0;
|
||||
padding: var(--space-sm);
|
||||
background: var(--gray-50);
|
||||
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
||||
">
|
||||
<button
|
||||
class="tab-button active"
|
||||
onclick="switchTab(\'app\', this)"
|
||||
style="
|
||||
flex: 1;
|
||||
padding: var(--space-md) var(--space-xl);
|
||||
border: none;
|
||||
background: var(--primary-green);
|
||||
color: var(--white);
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
font-size: var(--font-size-base);
|
||||
transition: all 0.2s ease;
|
||||
margin-right: var(--space-sm);
|
||||
box-shadow: var(--shadow-sm);
|
||||
"
|
||||
onmouseover="if(!this.classList.contains(\'active\')) { this.style.background=\'var(--gray-200)\'; this.style.color=\'var(--gray-700)\'; }"
|
||||
onmouseout="if(!this.classList.contains(\'active\')) { this.style.background=\'var(--gray-100)\'; this.style.color=\'var(--gray-600)\'; }"
|
||||
>
|
||||
Application Log
|
||||
</button>
|
||||
<button
|
||||
class="tab-button"
|
||||
onclick="switchTab(\'webserver\', this)"
|
||||
style="
|
||||
flex: 1;
|
||||
padding: var(--space-md) var(--space-xl);
|
||||
border: none;
|
||||
background: var(--gray-100);
|
||||
color: var(--gray-600);
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
font-size: var(--font-size-base);
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: var(--shadow-sm);
|
||||
"
|
||||
onmouseover="if(!this.classList.contains(\'active\')) { this.style.background=\'var(--gray-200)\'; this.style.color=\'var(--gray-700)\'; }"
|
||||
onmouseout="if(!this.classList.contains(\'active\')) { this.style.background=\'var(--gray-100)\'; this.style.color=\'var(--gray-600)\'; }"
|
||||
>
|
||||
Webserver Log
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab Content Container -->
|
||||
<div style="
|
||||
background: var(--white);
|
||||
border: 1px solid var(--gray-200);
|
||||
border-radius: 0 0 var(--radius-lg) var(--radius-lg);
|
||||
padding: var(--space-xl);
|
||||
box-shadow: var(--shadow-md);
|
||||
min-height: 70vh;
|
||||
">
|
||||
<!-- Application Log Tab -->
|
||||
<div id="tab-app" class="tab-content active" style="display: block;">
|
||||
<div style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: var(--space-lg);
|
||||
padding-bottom: var(--space-md);
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
">
|
||||
<div style="flex: 1;">
|
||||
<h3 style="
|
||||
margin: 0;
|
||||
color: var(--gray-900);
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: 600;
|
||||
">Application Log</h3>
|
||||
<div style="
|
||||
margin-top: var(--space-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
">
|
||||
<label style="
|
||||
color: var(--gray-600);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: 500;
|
||||
">Select Log File:</label>
|
||||
<select
|
||||
id="log-file-selector"
|
||||
onchange="loadLogFile(this.value)"
|
||||
style="
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
border: 1px solid var(--gray-300);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-sm);
|
||||
background: var(--white);
|
||||
color: var(--gray-700);
|
||||
cursor: pointer;
|
||||
min-width: 250px;
|
||||
"
|
||||
>';
|
||||
|
||||
foreach ($log_files as $log) {
|
||||
$selected = ($log['filename'] === $selected_log) ? 'selected' : '';
|
||||
$size_kb = round($log['size'] / 1024, 2);
|
||||
echo '<option value="'.htmlspecialchars($log['filename']).'" '.$selected.'>'.htmlspecialchars($log['filename']).' ('.$size_kb.' KB)</option>';
|
||||
}
|
||||
|
||||
echo '</select>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: var(--space-sm);">
|
||||
<button
|
||||
onclick="refreshLog(\'app\')"
|
||||
class="btn btn--secondary btn--sm"
|
||||
style="
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: var(--font-size-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
"
|
||||
>
|
||||
🔄 Refresh
|
||||
</button>
|
||||
<button
|
||||
onclick="clearLogContent(\'app-log\')"
|
||||
class="btn btn--secondary btn--sm"
|
||||
style="
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: var(--font-size-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
"
|
||||
>
|
||||
🗑️ Clear View
|
||||
</button>
|
||||
<form method="POST" onsubmit="return confirmDeleteAll()" style="margin: 0; display: inline;">
|
||||
<button
|
||||
type="submit"
|
||||
name="delete_all_logs"
|
||||
class="btn btn--sm"
|
||||
style="
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: var(--font-size-sm);
|
||||
background: #ef4444;
|
||||
color: var(--white);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
"
|
||||
onmouseover="this.style.background=\'#dc2626\'"
|
||||
onmouseout="this.style.background=\'#ef4444\'"
|
||||
>
|
||||
🗑️ Delete All Logs
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<textarea
|
||||
id="app-log"
|
||||
readonly
|
||||
style="
|
||||
width: 100%;
|
||||
min-height: 60vh;
|
||||
padding: var(--space-lg);
|
||||
border: 1px solid var(--gray-300);
|
||||
border-radius: var(--radius-md);
|
||||
font-family: \'Courier New\', monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
background: var(--gray-900);
|
||||
color: var(--gray-100);
|
||||
resize: vertical;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
"
|
||||
placeholder="No log content available..."
|
||||
>'.htmlspecialchars($contents).'</textarea>
|
||||
</div>
|
||||
|
||||
<!-- Webserver Log Tab -->
|
||||
<div id="tab-webserver" class="tab-content" style="display: none;">
|
||||
<div style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: var(--space-lg);
|
||||
padding-bottom: var(--space-md);
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
">
|
||||
<div>
|
||||
<h3 style="
|
||||
margin: 0;
|
||||
color: var(--gray-900);
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: 600;
|
||||
">Webserver Access Log</h3>
|
||||
<p style="
|
||||
margin: var(--space-xs) 0 0;
|
||||
color: var(--gray-500);
|
||||
font-size: var(--font-size-sm);
|
||||
">File: '.$filelocation_webserver.'</p>
|
||||
</div>
|
||||
<div style="display: flex; gap: var(--space-sm);">
|
||||
<button
|
||||
onclick="refreshLog(\'webserver\')"
|
||||
class="btn btn--secondary btn--sm"
|
||||
style="
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: var(--font-size-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
"
|
||||
>
|
||||
🔄 Refresh
|
||||
</button>
|
||||
<button
|
||||
onclick="clearLogContent(\'webserver-log\')"
|
||||
class="btn btn--secondary btn--sm"
|
||||
style="
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: var(--font-size-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
"
|
||||
>
|
||||
🗑️ Clear View
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<textarea
|
||||
id="webserver-log"
|
||||
readonly
|
||||
style="
|
||||
width: 100%;
|
||||
min-height: 60vh;
|
||||
padding: var(--space-lg);
|
||||
border: 1px solid var(--gray-300);
|
||||
border-radius: var(--radius-md);
|
||||
font-family: \'Courier New\', monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
background: var(--gray-900);
|
||||
color: var(--gray-100);
|
||||
resize: vertical;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
"
|
||||
placeholder="No log content available..."
|
||||
>'.htmlspecialchars($contents_webserver).'</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
'; ?>
|
||||
|
||||
<script>
|
||||
// Confirm delete all logs
|
||||
function confirmDeleteAll() {
|
||||
return confirm('⚠️ WARNING: This will permanently delete ALL log files in the logs directory.\n\nAre you absolutely sure you want to continue?');
|
||||
}
|
||||
|
||||
// Auto-hide delete notification
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const notification = document.getElementById('delete-notification');
|
||||
if (notification) {
|
||||
setTimeout(() => {
|
||||
notification.style.opacity = '0';
|
||||
notification.style.transition = 'opacity 0.5s ease';
|
||||
setTimeout(() => notification.remove(), 500);
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
|
||||
// Tab switching functionality
|
||||
function switchTab(tabName, clickedButton) {
|
||||
// Hide all tab contents
|
||||
const tabContents = document.querySelectorAll('.tab-content');
|
||||
tabContents.forEach(content => {
|
||||
content.style.display = 'none';
|
||||
});
|
||||
|
||||
// Remove active class and reset styles for all tab buttons
|
||||
const tabButtons = document.querySelectorAll('.tab-button');
|
||||
tabButtons.forEach(button => {
|
||||
button.classList.remove('active');
|
||||
button.style.background = 'var(--gray-100)';
|
||||
button.style.color = 'var(--gray-600)';
|
||||
});
|
||||
|
||||
// Show the selected tab content
|
||||
const selectedTab = document.getElementById('tab-' + tabName);
|
||||
if (selectedTab) {
|
||||
selectedTab.style.display = 'block';
|
||||
}
|
||||
|
||||
// Add active class and style to clicked button
|
||||
clickedButton.classList.add('active');
|
||||
clickedButton.style.background = 'var(--primary-green)';
|
||||
clickedButton.style.color = 'var(--white)';
|
||||
}
|
||||
|
||||
// Load selected log file
|
||||
function loadLogFile(filename) {
|
||||
if (filename) {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set('log', filename);
|
||||
window.location.href = url.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh log functionality
|
||||
function refreshLog(logType) {
|
||||
const button = event.target.closest('button');
|
||||
const originalText = button.innerHTML;
|
||||
|
||||
// Show loading state
|
||||
button.innerHTML = '⏳ Refreshing...';
|
||||
button.disabled = true;
|
||||
|
||||
// Simulate refresh (reload the page to get fresh content)
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// Clear log content from view
|
||||
function clearLogContent(textareaId) {
|
||||
const textarea = document.getElementById(textareaId);
|
||||
if (textarea) {
|
||||
if (confirm('Clear the log content from view? (This won\'t delete the actual log file)')) {
|
||||
textarea.value = '';
|
||||
|
||||
// Show notification
|
||||
showNotification('Log view cleared', 'info');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show notification function
|
||||
|
||||
|
||||
// Add CSS animations
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@keyframes slideInRight {
|
||||
from { opacity: 0; transform: translateX(100%); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes slideOutRight {
|
||||
from { opacity: 1; transform: translateX(0); }
|
||||
to { opacity: 0; transform: translateX(100%); }
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// Auto-scroll to bottom of logs when page loads
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const activeTextarea = document.querySelector('.tab-content.active textarea');
|
||||
if (activeTextarea && activeTextarea.value.trim()) {
|
||||
activeTextarea.scrollTop = activeTextarea.scrollHeight;
|
||||
}
|
||||
});
|
||||
|
||||
// Handle checkbox values (existing functionality)
|
||||
document.querySelectorAll("input[type='checkbox']").forEach(checkbox => {
|
||||
checkbox.onclick = () => checkbox.value = checkbox.checked ? 'true' : 'false';
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user