From e57adbe042c4eff55024c72844eb9af763056ae0 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Sun, 30 Mar 2025 20:36:49 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=94=92=20refactor(config):=20Mask=20N?= =?UTF-8?q?extDNS=20server=20address=20in=20config=20output?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- podkop/files/usr/bin/podkop | 1 + 1 file changed, 1 insertion(+) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index e733920..0a17d76 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -1918,6 +1918,7 @@ show_config() { -e 's/\(ss:\/\/[^@]*@\)/ss:\/\/MASKED@/g' \ -e 's/\(pbk=[^&]*\)/pbk=MASKED/g' \ -e 's/\(sid=[^&]*\)/sid=MASKED/g' \ + -e 's/\(option dns_server '\''[^'\'']*\.dns\.nextdns\.io'\''\)/option dns_server '\''MASKED.dns.nextdns.io'\''/g' \ > "$tmp_config" cat "$tmp_config" From e816da51333fab95e6e2b9420bcad38bfc4fb273 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 3 Apr 2025 13:36:22 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20feat(podkop):=20add=20error=20l?= =?UTF-8?q?ogging=20and=20notification=20system?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/view/podkop/podkop.js | 123 ++++++++++++++++++ podkop/files/usr/bin/podkop | 19 ++- 2 files changed, 139 insertions(+), 3 deletions(-) diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js index 83e2b82..149b543 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js @@ -12,6 +12,8 @@ const STATUS_COLORS = { WARNING: '#ff9800' }; +const ERROR_POLL_INTERVAL = 5000; // 5 seconds + async function safeExec(command, args = [], timeout = 7000) { try { const controller = new AbortController(); @@ -850,6 +852,121 @@ function checkDNSAvailability() { }); } +async function getPodkopErrors() { + try { + const result = await safeExec('/usr/bin/podkop', ['check_logs']); + if (!result || !result.stdout) return []; + + const logs = result.stdout.split('\n'); + const errors = logs.filter(log => + // log.includes('saved for future filters') || + log.includes('[critical]') + ); + + console.log('Found errors:', errors); + return errors; + } catch (error) { + console.error('Error getting podkop logs:', error); + return []; + } +} + +function createErrorModal(errors) { + return [ + E('div', { + 'class': 'panel-body', + style: 'max-height: 70vh; overflow-y: auto; margin: 1em 0; padding: 1.5em; ' + + 'font-family: monospace; white-space: pre-wrap; word-wrap: break-word; ' + + 'line-height: 1.5; font-size: 14px; background-color: #1e1e1e; color: #e0e0e0;' + }, [ + E('pre', { style: 'margin: 0; white-space: pre-wrap;' }, errors) + ]), + E('div', { + 'class': 'right', + style: 'margin-top: 1em;' + }, [ + E('button', { + 'class': 'btn', + 'click': ev => copyToClipboard(errors, ev.target) + }, _('Copy')), + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Close')) + ]) + ]; +} + +let errorPollTimer = null; +let lastErrorsSet = new Set(); +let isInitialCheck = true; + +function showErrorNotification(error, isMultiple = false) { + const notificationContent = E('div', { 'class': 'alert-message error' }, [ + E('pre', { 'class': 'error-log' }, error) + ]); + + const notification = ui.addNotification(null, notificationContent); +} + +function startErrorPolling() { + if (errorPollTimer) { + clearInterval(errorPollTimer); + } + + async function checkErrors() { + const result = await safeExec('/usr/bin/podkop', ['check_logs']); + if (!result || !result.stdout) return; + + // Get all logs since last "Starting podkop" + const logs = result.stdout; + + // Extract all error messages + const errorLines = logs.split('\n').filter(line => + line.includes('error') || + line.includes('Error') || + line.includes('ERROR') + ); + + if (errorLines.length > 0) { + // Create a set of current errors + const currentErrors = new Set(errorLines); + + if (isInitialCheck) { + // При первой проверке показываем все ошибки в одном уведомлении + if (errorLines.length > 0) { + showErrorNotification(errorLines.join('\n'), true); + } + isInitialCheck = false; + } else { + // Find new errors that weren't shown before + const newErrors = [...currentErrors].filter(error => !lastErrorsSet.has(error)); + + // Show each new error as a separate notification + newErrors.forEach(error => { + showErrorNotification(error, false); + }); + } + + // Update the set of shown errors + lastErrorsSet = currentErrors; + } + } + + // Initial check + checkErrors(); + + // Set up polling + errorPollTimer = setInterval(checkErrors, ERROR_POLL_INTERVAL); +} + +function stopErrorPolling() { + if (errorPollTimer) { + clearInterval(errorPollTimer); + errorPollTimer = null; + } +} + return view.extend({ async render() { document.head.insertAdjacentHTML('beforeend', ` @@ -1348,8 +1465,10 @@ return view.extend({ const diagnosticsContainer = document.getElementById('diagnostics-status'); if (document.hidden) { stopDiagnosticsUpdates(); + stopErrorPolling(); } else if (diagnosticsContainer && diagnosticsContainer.hasAttribute('data-loading')) { startDiagnosticsUpdates(); + startErrorPolling(); } }); @@ -1360,6 +1479,7 @@ return view.extend({ if (!this.hasAttribute('data-loading')) { this.setAttribute('data-loading', 'true'); startDiagnosticsUpdates(); + startErrorPolling(); } }); } @@ -1375,9 +1495,11 @@ return view.extend({ if (container && !container.hasAttribute('data-loading')) { container.setAttribute('data-loading', 'true'); startDiagnosticsUpdates(); + startErrorPolling(); } } else { stopDiagnosticsUpdates(); + stopErrorPolling(); } } }); @@ -1388,6 +1510,7 @@ return view.extend({ if (container && !container.hasAttribute('data-loading')) { container.setAttribute('data-loading', 'true'); startDiagnosticsUpdates(); + startErrorPolling(); } } } diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 0a17d76..e33707b 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -45,6 +45,7 @@ nolog() { } start() { + log "Starting podkop" migration config_foreach process_validate_service @@ -1857,12 +1858,24 @@ check_fakeip() { check_logs() { nolog "Showing podkop logs from system journal..." - if command -v logread >/dev/null 2>&1; then - logread -e podkop | tail -n 50 - else + if ! command -v logread >/dev/null 2>&1; then nolog "Error: logread command not found" return 1 fi + + # Get all logs first + local all_logs=$(logread) + + # Find the last occurrence of "Starting podkop" + local start_line=$(echo "$all_logs" | grep -n "podkop.*Starting podkop" | tail -n 1 | cut -d: -f1) + + if [ -z "$start_line" ]; then + nolog "No 'Starting podkop' message found in logs" + return 1 + fi + + # Output all logs from the last start + echo "$all_logs" | tail -n +"$start_line" } show_sing_box_config() { From 389def90562bc5d52fa2b3827e2fde5f14d15f9c Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 3 Apr 2025 13:40:41 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(podkop):=20re?= =?UTF-8?q?move=20unused=20createErrorModal=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/view/podkop/podkop.js | 38 +------------------ 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js index 149b543..91493b1 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js @@ -871,32 +871,6 @@ async function getPodkopErrors() { } } -function createErrorModal(errors) { - return [ - E('div', { - 'class': 'panel-body', - style: 'max-height: 70vh; overflow-y: auto; margin: 1em 0; padding: 1.5em; ' + - 'font-family: monospace; white-space: pre-wrap; word-wrap: break-word; ' + - 'line-height: 1.5; font-size: 14px; background-color: #1e1e1e; color: #e0e0e0;' - }, [ - E('pre', { style: 'margin: 0; white-space: pre-wrap;' }, errors) - ]), - E('div', { - 'class': 'right', - style: 'margin-top: 1em;' - }, [ - E('button', { - 'class': 'btn', - 'click': ev => copyToClipboard(errors, ev.target) - }, _('Copy')), - E('button', { - 'class': 'btn', - 'click': ui.hideModal - }, _('Close')) - ]) - ]; -} - let errorPollTimer = null; let lastErrorsSet = new Set(); let isInitialCheck = true; @@ -906,7 +880,7 @@ function showErrorNotification(error, isMultiple = false) { E('pre', { 'class': 'error-log' }, error) ]); - const notification = ui.addNotification(null, notificationContent); + ui.addNotification(null, notificationContent); } function startErrorPolling() { @@ -918,10 +892,8 @@ function startErrorPolling() { const result = await safeExec('/usr/bin/podkop', ['check_logs']); if (!result || !result.stdout) return; - // Get all logs since last "Starting podkop" const logs = result.stdout; - // Extract all error messages const errorLines = logs.split('\n').filter(line => line.includes('error') || line.includes('Error') || @@ -929,34 +901,26 @@ function startErrorPolling() { ); if (errorLines.length > 0) { - // Create a set of current errors const currentErrors = new Set(errorLines); if (isInitialCheck) { - // При первой проверке показываем все ошибки в одном уведомлении if (errorLines.length > 0) { showErrorNotification(errorLines.join('\n'), true); } isInitialCheck = false; } else { - // Find new errors that weren't shown before const newErrors = [...currentErrors].filter(error => !lastErrorsSet.has(error)); - // Show each new error as a separate notification newErrors.forEach(error => { showErrorNotification(error, false); }); } - - // Update the set of shown errors lastErrorsSet = currentErrors; } } - // Initial check checkErrors(); - // Set up polling errorPollTimer = setInterval(checkErrors, ERROR_POLL_INTERVAL); } From 5f780955eb97d6d6d013f903fe64be03e41fcc29 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 3 Apr 2025 13:42:55 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=92=84=20style(podkop):=20update=20er?= =?UTF-8?q?ror=20log=20filtering=20criteria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../htdocs/luci-static/resources/view/podkop/podkop.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js index 91493b1..f7df280 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js @@ -895,9 +895,8 @@ function startErrorPolling() { const logs = result.stdout; const errorLines = logs.split('\n').filter(line => - line.includes('error') || - line.includes('Error') || - line.includes('ERROR') + // line.includes('saved for future filters') || + line.includes('[critical]') ); if (errorLines.length > 0) {