diff --git a/Dockerfile b/Dockerfile index a3b3ae6..9b6975d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,8 +31,8 @@ RUN pnpm i # 复制项目文件 COPY . . -# 创建数据目录并设置权限 -RUN mkdir -p /app/data && \ +# 创建数据目录和日志目录并设置权限 +RUN mkdir -p /app/data /app/logs && \ chown -R node:node /app # 切换到非root用户 diff --git a/src/services/logger.js b/src/services/logger.js index 649194e..c6f4468 100644 --- a/src/services/logger.js +++ b/src/services/logger.js @@ -28,10 +28,16 @@ class Logger { } ensureLogsDirectory() { - if (!fs.existsSync(this.logsDir)) { - fs.mkdirSync(this.logsDir, { recursive: true }); - // 使用原始console,避免循环调用 - this.originalConsole.log(`创建日志目录: ${this.logsDir}`); + try { + if (!fs.existsSync(this.logsDir)) { + fs.mkdirSync(this.logsDir, { recursive: true }); + // 使用原始console,避免循环调用 + this.originalConsole.log(`创建日志目录: ${this.logsDir}`); + } + } catch (error) { + // 如果创建目录失败(比如权限问题),警告但不阻止应用启动 + this.originalConsole.warn(`无法创建日志目录 ${this.logsDir}:`, error.message); + this.originalConsole.warn('日志将仅输出到控制台,不会保存到文件'); } } @@ -48,9 +54,15 @@ class Logger { this.currentDate = today; this.currentLogFile = this.getLogFileName(); - // 确保文件存在 + // 确保文件存在 - 使用try-catch处理权限问题 if (!fs.existsSync(this.currentLogFile)) { - fs.writeFileSync(this.currentLogFile, ''); + try { + // 尝试创建空文件,如果失败则会在下次写入时自动创建 + fs.writeFileSync(this.currentLogFile, '', { flag: 'a' }); + } catch (error) { + // 如果创建文件失败(比如权限问题),不抛出错误,会在后续写入时处理 + this.originalConsole.warn(`无法创建日志文件 ${this.currentLogFile}:`, error.message); + } } } } @@ -71,8 +83,15 @@ class Logger { const timestamp = this.formatTimestamp(); const logLine = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`; - // 写入文件 - fs.appendFileSync(this.currentLogFile, logLine, 'utf8'); + // 写入文件 - 使用flag: 'a'确保文件不存在时自动创建 + try { + fs.appendFileSync(this.currentLogFile, logLine, { encoding: 'utf8', flag: 'a' }); + } catch (error) { + // 如果写入失败(比如权限问题),输出到原始console + this.originalConsole.error('写入日志文件失败:', error.message); + this.originalConsole[level](message); + return; // 不继续处理 + } // 添加到缓冲区用于实时推送 const logEntry = { @@ -102,9 +121,12 @@ class Logger { } } catch (error) { - // 如果文件写入失败,至少输出到原始console - this.originalConsole.error('写入日志文件失败:', error); - this.originalConsole[level](message); + // 如果文件写入失败(已经在上面处理了),这里只是防止其他错误 + // 如果上面的appendFileSync已经捕获了错误,这里不会执行 + // 这里主要是处理其他可能的错误 + if (error.code !== 'EACCES' && !error.message.includes('permission')) { + this.originalConsole.error('日志处理失败:', error); + } } }