diff --git a/html/launcher.php b/html/launcher.php index 8008684..0825574 100755 --- a/html/launcher.php +++ b/html/launcher.php @@ -423,9 +423,50 @@ if ($type == "set_RTC_withBrowser") { if ($type == "clear_loopLogs") { - $command = 'truncate -s 0 /var/www/nebuleair_pro_4g/logs/loop.log'; - $output = shell_exec($command); - echo $output; + $response = array(); + + try { + $logPath = '/var/www/nebuleair_pro_4g/logs/master.log'; + + // Check if file exists and is writable + if (!file_exists($logPath)) { + throw new Exception("Log file does not exist"); + } + + if (!is_writable($logPath)) { + throw new Exception("Log file is not writable"); + } + + // Execute the command + $command = 'truncate -s 0 ' . escapeshellarg($logPath); + $output = shell_exec($command . ' 2>&1'); + + // Check if there was any error output + if (!empty($output)) { + throw new Exception("Command error: " . $output); + } + + // Success response + $response = array( + 'status' => 'success', + 'message' => 'Logs cleared successfully', + 'timestamp' => date('Y-m-d H:i:s') + ); + } catch (Exception $e) { + // Error response + $response = array( + 'status' => 'error', + 'message' => $e->getMessage(), + 'timestamp' => date('Y-m-d H:i:s') + ); + } + + // Set content type to JSON + header('Content-Type: application/json'); + + // Return the JSON response + echo json_encode($response); + exit; } if ($type == "database_size") { diff --git a/html/logs.html b/html/logs.html index d3d97ed..d2c7aef 100755 --- a/html/logs.html +++ b/html/logs.html @@ -56,7 +56,10 @@
- Master logs + Master logs + + +
@@ -69,6 +72,7 @@
Boot logs +
@@ -112,64 +116,16 @@ //Getting Master logs console.log("Getting master logs"); + displayLogFile('../logs/master.log', loop_card_content); + + console.log("Getting app/boot logs"); + displayLogFile('../logs/app.log', boot_card_content); - fetch('../logs/master.log') - .then((response) => { - console.log("OK"); - - if (!response.ok) { - throw new Error('Failed to fetch the log file.'); - } - return response.text(); - }) - .then((data) => { - const lines = data.split('\n'); - - // Format log content - const formattedLog = lines - .map((line) => line.trim()) // Remove extra whitespace - .filter((line) => line) // Remove empty lines - .join('
'); // Join formatted lines with line breaks - - loop_card_content.innerHTML = `
${formattedLog}
`; - loop_card_content.scrollTop = loop_card_content.scrollHeight; // Scroll to the bottom - - }) - .catch((error) => { - console.error(error); - loop_card_content.textContent = 'Error loading log file.'; - }); - - console.log("Getting app/boot logs"); - - //Getting App logs - fetch('../logs/app.log') - .then((response) => { - console.log("OK"); - - if (!response.ok) { - throw new Error('Failed to fetch the log file.'); - } - return response.text(); - }) - .then((data) => { - const lines = data.split('\n'); - - // Format log content - const formattedLog = lines - .map((line) => line.trim()) // Remove extra whitespace - .filter((line) => line) // Remove empty lines - .join('
'); // Join formatted lines with line breaks - - boot_card_content.innerHTML = `
${formattedLog}
`; - boot_card_content.scrollTop = loop_card_content.scrollHeight; // Scroll to the bottom - - }) - .catch((error) => { - console.error(error); - boot_card_content.textContent = 'Error loading log file.'; - }); - + // Setup master log with refresh button + setupLogRefreshButton('refresh-master-log', '../logs/master.log', 'card_loop_content', 3000); + + // Setup boot log with refresh button + setupLogRefreshButton('refresh-boot-log', '../logs/app.log', 'card_boot_content', 300); }); @@ -220,6 +176,75 @@ window.onload = function() { }//end onload +function displayLogFile(logFilePath, containerElement, scrollToBottom = true, maxLines = 0) { + // Show loading indicator + containerElement.innerHTML = '
Loading log file...
'; + + return fetch(logFilePath) + .then((response) => { + if (!response.ok) { + throw new Error(`Failed to fetch the log file: ${response.status} ${response.statusText}`); + } + return response.text(); + }) + .then((data) => { + // Split the log into lines + let lines = data.split('\n'); + + // Apply max lines limit if specified + if (maxLines > 0 && lines.length > maxLines) { + lines = lines.slice(-maxLines); // Get only the last N lines + } + + // Format log content + const formattedLog = lines + .map((line) => line.trim()) // Remove extra whitespace + .filter((line) => line) // Remove empty lines + .join('
'); // Join formatted lines with line breaks + + // Display the formatted log + containerElement.innerHTML = `
${formattedLog}
`; + + // Scroll to bottom if requested + if (scrollToBottom) { + containerElement.scrollTop = containerElement.scrollHeight; + } + + return formattedLog; // Return the formatted log in case the caller needs it + }) + .catch((error) => { + console.error(`Error loading log file ${logFilePath}:`, error); + containerElement.innerHTML = `
Error loading log file: ${error.message}
`; + throw error; // Re-throw the error for the caller to handle if needed + }); +} + +/** + * Set up a refresh button for a log file + * @param {string} buttonId - ID of the button element + * @param {string} logFilePath - Path to the log file + * @param {string} containerId - ID of the container to display the log in + * @param {number} maxLines - Maximum number of lines to display (0 for all) + */ + function setupLogRefreshButton(buttonId, logFilePath, containerId, maxLines = 0) { + console.log("Refreshing logs"); + + const button = document.getElementById(buttonId); + const container = document.getElementById(containerId); + + if (!button || !container) { + console.error('Button or container element not found'); + return; + } + + // Initial load + displayLogFile(logFilePath, container, true, maxLines); + + // Set up button click handler + button.addEventListener('click', () => { + displayLogFile(logFilePath, container, true, maxLines); + }); +} function clear_loopLogs(){ console.log("Clearing loop logs");