From 1d4960913147e0258fe90f41d3304f933a08f638 Mon Sep 17 00:00:00 2001 From: 7015725 Date: Sat, 23 May 2026 02:42:46 +0800 Subject: [PATCH] fix: stabilize ToolHub logging --- ToolHub.js | 21 ++++++-- ToolHub.js.sha256 | 2 +- code/th_01_base.js | 110 ++++---------------------------------- code/th_05_persistence.js | 3 -- code/th_11_action.js | 35 ++++++------ code/th_16_entry.js | 11 ---- manifest.json | 18 +++---- manifest.sig | 2 +- 8 files changed, 57 insertions(+), 145 deletions(-) diff --git a/ToolHub.js b/ToolHub.js index 35f705c..b37a6c5 100644 --- a/ToolHub.js +++ b/ToolHub.js @@ -33,16 +33,31 @@ function getTrustedShaPath(relPath) { return getCodeDirPath() + ".trusted_sha_" function getTrustedVersionPath() { return getCodeDirPath() + ".trusted_manifest_version"; } function writeLog(msg) { + var writer = null; try { var f = new java.io.File(getLogPath()); var dir = f.getParentFile(); if (dir && !dir.exists()) dir.mkdirs(); + try { + var maxBytes = 512 * 1024; + if (f.exists() && f.length() > maxBytes) { + var bak = new java.io.File(String(f.getAbsolutePath()) + ".bak"); + try { if (bak.exists()) bak.delete(); } catch (eBak0) {} + var moved = false; + try { moved = f.renameTo(bak); } catch (eMv) { moved = false; } + if (!moved) { + try { f.delete(); } catch (eDel) {} + } + } + } catch (eTrim) {} var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); var ts = sdf.format(new java.util.Date()); - var writer = new java.io.FileWriter(f, true); + writer = new java.io.FileWriter(f, true); writer.write("[" + ts + "] " + String(msg) + "\n"); - writer.close(); - } catch (e) {} + } catch (e) { + } finally { + try { if (writer) writer.close(); } catch (eClose) {} + } } function runShell(cmdArr) { diff --git a/ToolHub.js.sha256 b/ToolHub.js.sha256 index cd7a79b..2b0fc56 100644 --- a/ToolHub.js.sha256 +++ b/ToolHub.js.sha256 @@ -1 +1 @@ -a154dbf74570e6cd8ca14ad212c9213824b9c82d94722e0959e9e51cce577447 ToolHub.js +01d93690bdfc402ad59d6f51db45e3e057a3ebcbbf146a5667ecc5486e2d3ed6 ToolHub.js diff --git a/code/th_01_base.js b/code/th_01_base.js index 50bd182..6960f02 100644 --- a/code/th_01_base.js +++ b/code/th_01_base.js @@ -1188,8 +1188,15 @@ function applyRule(rule, kv) { } // =======================【日志:文件写入器(尽力落盘 + 自动清理旧日志)】======================= -// =======================【日志:文件写入器(全局统一目录 + 分级)】======================= -// 优化后的日志系统(带缓冲,减少文件 IO) +function sanitizeLogMessage(msg) { + try { + var s = String(msg == null ? "" : msg); + s = s.replace(/(authorization\s*[:=]\s*bearer\s+)[^\s,;]+/ig, "$1[REDACTED]"); + s = s.replace(/((access_)?token|api[_-]?key|password|passwd|secret)(\s*[=:]\s*)[^\s,;]+/ig, "$1$3[REDACTED]"); + return s; + } catch (e) { return String(msg == null ? "" : msg); } +} + function ToolHubLogger(procInfo) { this.proc = procInfo || {}; this.dir = PATH_LOG_DIR; @@ -1199,17 +1206,10 @@ function ToolHubLogger(procInfo) { this.debug = false; this.initOk = false; this.lastInitErr = ""; - - // 新增:日志缓冲 - this._buffer = []; - this._bufferSize = 20; // 每 20 条写一次磁盘 - this._flushTimer = null; - this._initOnce(); } ToolHubLogger.prototype._now = function() { return new Date().getTime(); }; - ToolHubLogger.prototype._initOnce = function() { try { if (FileIO.ensureDir(this.dir)) { @@ -1224,110 +1224,22 @@ ToolHubLogger.prototype._initOnce = function() { this.lastInitErr = String(e); } }; - ToolHubLogger.prototype.updateConfig = function(cfg) { if (!cfg) return; if (typeof cfg.LOG_KEEP_DAYS === "number") this.keepDays = cfg.LOG_KEEP_DAYS; if (typeof cfg.LOG_ENABLE !== "undefined") this.enable = !!cfg.LOG_ENABLE; if (typeof cfg.LOG_DEBUG !== "undefined") this.debug = !!cfg.LOG_DEBUG; }; - -ToolHubLogger.prototype._line = function(level, msg) { - var ts = this._now(); - var d = new Date(ts); - function pad2(x) { return (x < 10 ? "0" : "") + x; } - var t = d.getFullYear() + "-" + pad2(d.getMonth() + 1) + "-" + pad2(d.getDate()) + - " " + pad2(d.getHours()) + ":" + pad2(d.getMinutes()) + ":" + pad2(d.getSeconds()); - return t + " [" + level + "] " + msg + "\n"; -}; - -ToolHubLogger.prototype._scheduleFlush = function() { - if (this._flushTimer) try { this._flushTimer.cancel(); } catch(e) {} - var self = this; - this._flushTimer = new java.util.Timer(); - this._flushTimer.schedule(new java.util.TimerTask({ - run: function() { self._flushBuffer(); } - }), 3000); // 3秒后强制刷新 -}; - -ToolHubLogger.prototype._flushBuffer = function() { - if (this._buffer.length === 0) return; - var content = this._buffer.join(''); - this._buffer = []; - var path = this.dir + "/" + this.prefix + "_" + this._ymd() + ".log"; - FileIO.appendText(path, content); -}; - ToolHubLogger.prototype._ymd = function() { var d = new Date(); return "" + d.getFullYear() + ((d.getMonth() < 9 ? "0" : "") + (d.getMonth() + 1)) + ((d.getDate() < 10 ? "0" : "") + d.getDate()); }; - -ToolHubLogger.prototype._write = function(level, msg) { - if (!this.enable) return false; - this._buffer.push(this._line(level, msg)); - - // 缓冲满或错误级别立即写入 - if (this._buffer.length >= this._bufferSize || level === 'F' || level === 'E') { - this._flushBuffer(); - } else { - this._scheduleFlush(); // 延迟写入 - } - return true; -}; - -ToolHubLogger.prototype.d = function(msg) { if (this.debug) this._write("D", msg); }; -ToolHubLogger.prototype.i = function(msg) { this._write("I", msg); }; -ToolHubLogger.prototype.w = function(msg) { this._write("W", msg); }; -ToolHubLogger.prototype.e = function(msg) { this._write("E", msg); }; -ToolHubLogger.prototype.fatal = function(msg) { this._write("F", msg); this._flushBuffer(); }; - -ToolHubLogger.prototype.cleanupOldFiles = function() { - try { - if (!this.initOk) return false; - var dirF = new java.io.File(this.dir); - var files = dirF.listFiles(); - if (!files) return false; - var now = this._now(); - var cutoff = now - this.keepDays * 24 * 60 * 60 * 1000; - for (var i = 0; i < files.length; i++) { - var f = files[i]; - if (f && f.isFile() && f.getName().indexOf(this.prefix) === 0 && f.lastModified() < cutoff) { - f["delete"](); - } - } - return true; - } catch (e) { return false; }; -}; - ToolHubLogger.prototype._filePathForToday = function() { - var name = this.prefix + "_" + this._ymd(this._now()) + ".log"; + var name = this.prefix + "_" + this._ymd() + ".log"; return this.dir + "/" + name; }; -ToolHubLogger.prototype._initOnce = function() { - try { - // # 尝试创建目录 - if (FileIO.ensureDir(this.dir)) { - this.initOk = true; - // # 清理旧日志 - this.cleanupOldFiles(); - } else { - this.initOk = false; - this.lastInitErr = "Mkdirs failed: " + this.dir; - } - } catch (e) { - this.initOk = false; - this.lastInitErr = String(e); - } -}; -ToolHubLogger.prototype.updateConfig = function(cfg) { - if (!cfg) return; - if (typeof cfg.LOG_KEEP_DAYS === "number") this.keepDays = cfg.LOG_KEEP_DAYS; - if (typeof cfg.LOG_ENABLE !== "undefined") this.enable = !!cfg.LOG_ENABLE; - if (typeof cfg.LOG_DEBUG !== "undefined") this.debug = !!cfg.LOG_DEBUG; -}; ToolHubLogger.prototype._line = function(level, msg) { var ts = this._now(); var d = new Date(ts); @@ -1339,7 +1251,7 @@ ToolHubLogger.prototype._line = function(level, msg) { proc = " uid=" + String(this.proc.uid) + " pid=" + String(this.proc.pid) + " tid=" + String(this.proc.tid) + " th=" + String(this.proc.threadName) + " proc=" + String(this.proc.processName); } catch (e0) {} - return t + " [" + String(level) + "] " + String(msg) + proc + "\n"; + return t + " [" + String(level) + "] " + sanitizeLogMessage(msg) + proc + "\n"; }; ToolHubLogger.prototype._writeRaw = function(level, msg) { if (!this.initOk) return false; diff --git a/code/th_05_persistence.js b/code/th_05_persistence.js index 3b4c1f5..ffbab56 100644 --- a/code/th_05_persistence.js +++ b/code/th_05_persistence.js @@ -288,7 +288,6 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) { try { if (this.L) { this.L.enable = !!this.config.LOG_ENABLE; - this.L.cfg.LOG_ENABLE = !!this.config.LOG_ENABLE; this.L.i("apply LOG_ENABLE=" + String(this.config.LOG_ENABLE)); } } catch(eLE) { safeLog(null, 'e', "catch " + String(eLE)); } @@ -298,7 +297,6 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) { try { if (this.L) { this.L.debug = !!this.config.LOG_DEBUG; - this.L.cfg.LOG_DEBUG = !!this.config.LOG_DEBUG; this.L.i("apply LOG_DEBUG=" + String(this.config.LOG_DEBUG)); } } catch(eLD) { safeLog(null, 'e', "catch " + String(eLD)); } @@ -310,7 +308,6 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) { this.config.LOG_KEEP_DAYS = n; if (this.L) { this.L.keepDays = n; - this.L.cfg.LOG_KEEP_DAYS = n; this.L.i("apply LOG_KEEP_DAYS=" + String(n)); this.L.cleanupOldFiles(); } diff --git a/code/th_11_action.js b/code/th_11_action.js index 7d5eb4b..aa43279 100644 --- a/code/th_11_action.js +++ b/code/th_11_action.js @@ -21,24 +21,23 @@ FloatBallAppWM.prototype.execButtonAction = function(btn, idx) { } if (t === "open_viewer") { - var logPath = (this.L && this.L._filePathForToday) ? this.L._filePathForToday() : ""; - if (!logPath) logPath = PATH_LOG_DIR + "/ShortX_ToolHub_" + (new java.text.SimpleDateFormat("yyyyMMdd").format(new java.util.Date())) + ".log"; - - var content = FileIO.readText(logPath); - if (!content) content = "(日志文件不存在或为空: " + logPath + ")"; - - if (content.length > 30000) { - content = "[...前略...]\n" + content.substring(content.length - 30000); + function tailLogText(path, maxLen) { + var txt = FileIO.readText(path); + if (!txt) return "(日志文件不存在或为空: " + path + ")"; + txt = String(txt); + if (txt.length > maxLen) txt = "[...前略...]\n" + txt.substring(txt.length - maxLen); + try { + var lines = txt.split("\n"); + if (lines.length > 1) txt = lines.reverse().join("\n"); + } catch(eRev) { safeLog(null, 'e', "catch " + String(eRev)); } + return txt; } - - // 简单的按行倒序,方便查看最新日志 - try { - var lines = content.split("\n"); - if (lines.length > 1) { - content = lines.reverse().join("\n"); - } - } catch(eRev) { safeLog(null, 'e', "catch " + String(eRev)); } - + var runLogPath = (this.L && this.L._filePathForToday) ? this.L._filePathForToday() : ""; + if (!runLogPath) runLogPath = PATH_LOG_DIR + "/ShortX_ToolHub_" + (new java.text.SimpleDateFormat("yyyyMMdd").format(new java.util.Date())) + ".log"; + var initLogPath = PATH_LOG_DIR + "/init.log"; + var content = "【启动/更新日志】\n" + tailLogText(initLogPath, 15000) + + "\n\n【运行日志】\n" + tailLogText(runLogPath, 15000); + if (content.length > 32000) content = content.substring(0, 32000) + "\n[...后略...]"; this.showViewerPanel("今日日志 (倒序)", content); return; } @@ -132,7 +131,7 @@ return; if (r && r.ok) return; this.toast("shell 广播桥发送失败"); - safeLog(this.L, 'e', "shell all failed cmd_b64=" + cmdB64 + " ret=" + JSON.stringify(r || {})); + safeLog(this.L, 'e', "shell all failed cmd_b64_len=" + String(cmdB64 ? cmdB64.length : 0) + " ret=" + JSON.stringify(r || {})); return; } diff --git a/code/th_16_entry.js b/code/th_16_entry.js index 931550b..5507b27 100644 --- a/code/th_16_entry.js +++ b/code/th_16_entry.js @@ -128,17 +128,6 @@ FloatBallAppWM.prototype.close = function() { safeLog(this.L, 'i', "close done"); - // # 清理日志定时器 - try { - if (this.L) { - try { this.L._flushBuffer(); } catch (eFlushLog0) { safeLog(this.L, 'e', "logger flush fail: " + String(eFlushLog0)); } - if (this.L._flushTimer) { - this.L._flushTimer.cancel(); - this.L._flushTimer = null; - } - } - } catch (eLog) {} - // # 清空缓存 try { this._iconLru = null; diff --git a/manifest.json b/manifest.json index e7661fb..38fc1ad 100644 --- a/manifest.json +++ b/manifest.json @@ -2,8 +2,8 @@ "alg": "SHA256withRSA", "files": { "th_01_base.js": { - "sha256": "c77eb730b0a54bfe784ff9fee4f88e3276826dc73ae98a2ef964bf5041632d38", - "size": 57562 + "sha256": "e465a92b21f6819079255719bfe41c28a42ff3716f1d29b399897bc299ef92ec", + "size": 54633 }, "th_02_core.js": { "sha256": "7bfd21df21c137595c3e2a8724b3eb3f0cce82ef0dd18b732de08e9be30b2ba3", @@ -18,8 +18,8 @@ "size": 42568 }, "th_05_persistence.js": { - "sha256": "fac67158d57ce23c92dbc4103d1732946b6ea0fde9f55a04edede9a1f201a7da", - "size": 14921 + "sha256": "7fd2a62275bd26fcd940202057480fca7a8a800eaeb1fcb9d52003e255d1ef60", + "size": 14763 }, "th_06_icon_parser.js": { "sha256": "25b95a5df634a7ee359f3ab798e4d3154a71c24016f7b4bf8a658096644b2484", @@ -42,8 +42,8 @@ "size": 1094 }, "th_11_action.js": { - "sha256": "a0142d26621f3d076bd1b749f2885af2c0806c9f206e362a3b3680a5d2312b31", - "size": 13545 + "sha256": "1ba348415e891093bcf49619d950e9653e1c7323c3d35f74f6f71bec14b7c9e6", + "size": 13838 }, "th_12_rebuild.js": { "sha256": "7b820e813d2dd8866778fefe8bfeb6aca227bb1a32a89d318de830178f19824f", @@ -74,11 +74,11 @@ "size": 122822 }, "th_16_entry.js": { - "sha256": "6c59d9891cd010647f84c3db93f1cf95c7bbfb758470ea21044bf72eb8ff73d1", - "size": 12799 + "sha256": "652aa70214a9419923785e528a067d3828094fde48fc9c8c57cfda1e08206e25", + "size": 12479 } }, "keyId": "toolhub-targets-2026-rsa3072", "schema": 2, - "version": 20260522181206 + "version": 20260522184240 } diff --git a/manifest.sig b/manifest.sig index 87e8f8c..1526fce 100644 --- a/manifest.sig +++ b/manifest.sig @@ -1 +1 @@ -Oj/koe1KG25KEOTq/5jJfYFRBPL3ue9kSuhhKc7h0DGGpKJPwt0P1lmLCwJAKpIbwaQiuJo806UKW6r1qtHdjptDU0XreC8URd27lLWg1YgT61mVTKZK7qW8XSV71AebS51sHP+AmqAP9aiIdDRF1atUr0IX4+lxZAcN5t14aDLPwAqd0Kq5YJUUAjGACPbA9JuwjEwyXxlZ2NoyM2KZyDE983VlbJTEYUpvQYGZKKCSpPsowdNdz5OQMouDKigyLbCKQNva3+JtFfX4ZTzz4NMVJesBw82Q2MhlosCoAnrubhwj15MAYEMEP6TpajxjZVGVvFqCLJGh6d4lTq3i1RWPBGq7jTgIZPhlhUXSypt+v8TvWgv5UdmmDE+tSvPdNE+j8oLsah3toquYgiUcWnNaN2qdU9taa3cLb9JBOY1+mgs/M21yjYUC7A4WYpX7N4FPOqGLRUF0tPABBY1L6hY/gJ9YKPvvM4LC6e0C0cZThuBCJu/obk40Dl7iTcpS +n1MKKVJT2cLNduThC64RZLZvdODhjyP+6PheBexWKVf7kRZdPCFfq9hB0jxIq+F/Mb3XyhHvHaRcXwG/Za6bQnIAeYF1I/7dmMXlcR/vEplDIS4P6B8dV+r5XM3QtidZmF4cF6+2vwkKUkA9Azy8z2Grpp/3K8nbPC0gQQFFpxF6hTWqCPprUDszQBELRttMCtu4hQcsA/IPCJZEFq50hi7NiLMOFk9/QMTzDLb1T3xK8BhGXGIOkIZhQIJXhERycklQ5vyW70+iazevGGm/tNkZlhH4ozo6QO4MVKbWmu+45qP8wVozpX0XSXbcRDUJq6zUkWlDFUEZlm1SCLf0tXLD1Rq8zbnIUsaO8/i4scA9tqOpsXrLCiXGxGgLDLYiyfQvQHDdD7IKjJgOCrIu/OF+bOn8Dey+9/QERpsmGofnVQc5Yo003m4T534XMcO7b0VRbK1yIzLNHL96uikJsHncypSqnOGi2nuaZLEix07ABRbHfA6JXrOIbiqhbrd+