Merge pull request #342 from lly835/fix/logger-context-memory-leak
fix: 为 Logger.requestContext 添加 TTL 清理机制防止内存泄漏
This commit is contained in:
commit
328bdcee43
1 changed files with 38 additions and 1 deletions
|
|
@ -22,6 +22,8 @@ class Logger {
|
||||||
this.logStream = null;
|
this.logStream = null;
|
||||||
this.currentRequestId = null; // 当前请求ID
|
this.currentRequestId = null; // 当前请求ID
|
||||||
this.requestContext = new Map(); // 存储请求上下文
|
this.requestContext = new Map(); // 存储请求上下文
|
||||||
|
this.contextTTL = 5 * 60 * 1000; // 请求上下文 TTL:5 分钟
|
||||||
|
this._contextCleanupTimer = null;
|
||||||
this.levels = {
|
this.levels = {
|
||||||
debug: 0,
|
debug: 0,
|
||||||
info: 1,
|
info: 1,
|
||||||
|
|
@ -87,7 +89,8 @@ class Logger {
|
||||||
requestId = randomUUID().substring(0, 8);
|
requestId = randomUUID().substring(0, 8);
|
||||||
}
|
}
|
||||||
this.currentRequestId = requestId;
|
this.currentRequestId = requestId;
|
||||||
this.requestContext.set(requestId, context);
|
this.requestContext.set(requestId, { ...context, _createdAt: Date.now() });
|
||||||
|
this._ensureContextCleanup();
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,6 +123,36 @@ class Logger {
|
||||||
this.currentRequestId = null;
|
this.currentRequestId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动定期清理过期请求上下文的定时器(防止内存泄漏)
|
||||||
|
* 每 60 秒扫描一次,清除超过 contextTTL 的条目
|
||||||
|
*/
|
||||||
|
_ensureContextCleanup() {
|
||||||
|
if (this._contextCleanupTimer) return;
|
||||||
|
this._contextCleanupTimer = setInterval(() => {
|
||||||
|
const now = Date.now();
|
||||||
|
let cleaned = 0;
|
||||||
|
for (const [id, ctx] of this.requestContext) {
|
||||||
|
if (now - (ctx._createdAt || 0) > this.contextTTL) {
|
||||||
|
this.requestContext.delete(id);
|
||||||
|
cleaned++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cleaned > 0) {
|
||||||
|
this.log('warn', [`[Logger] Cleaned ${cleaned} stale request context(s) (TTL: ${this.contextTTL}ms)`]);
|
||||||
|
}
|
||||||
|
// 当 Map 为空时停止定时器
|
||||||
|
if (this.requestContext.size === 0) {
|
||||||
|
clearInterval(this._contextCleanupTimer);
|
||||||
|
this._contextCleanupTimer = null;
|
||||||
|
}
|
||||||
|
}, 60_000);
|
||||||
|
// 不阻止进程退出
|
||||||
|
if (this._contextCleanupTimer.unref) {
|
||||||
|
this._contextCleanupTimer.unref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化日志消息
|
* 格式化日志消息
|
||||||
* @param {string} level - 日志级别
|
* @param {string} level - 日志级别
|
||||||
|
|
@ -310,6 +343,10 @@ class Logger {
|
||||||
* 关闭日志流
|
* 关闭日志流
|
||||||
*/
|
*/
|
||||||
close() {
|
close() {
|
||||||
|
if (this._contextCleanupTimer) {
|
||||||
|
clearInterval(this._contextCleanupTimer);
|
||||||
|
this._contextCleanupTimer = null;
|
||||||
|
}
|
||||||
if (this.logStream && !this.logStream.destroyed) {
|
if (this.logStream && !this.logStream.destroyed) {
|
||||||
this.logStream.end();
|
this.logStream.end();
|
||||||
this.logStream = null;
|
this.logStream = null;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue