Azure App Service下winston-daily-rotate-file日志轮转随机报错求助
问题根因
这个EIO: i/o error, close错误由两个核心原因共同触发:
- Azure App Service 默认的
/home持久化目录是SMB网络共享存储,日志轮转执行旧文件关闭操作时,网络波动、存储层瞬时限流、多实例文件锁竞争都会触发I/O异常 - 你当前的日志配置没有对DailyRotateFile传输器监听
error事件,抛出的异常没有被捕获,最终成为未处理异常导致进程退出
可行解决步骤
1. 优先添加异常监听,避免进程直接崩溃
给DailyRotateFile实例绑定error事件处理逻辑,捕获轮转过程中的所有非致命异常,不会直接终止服务:
const rotateTransport = new winston.transports.DailyRotateFile({ dirname: logDir, filename: '%DATE%-KBK.log', datePattern: 'YYYY-MM-DD', zippedArchive: true }) // 新增异常监听 rotateTransport.on('error', (err) => { // 可以自行把错误输出到控制台或者其他稳定的上报通道,不要打回文件传输器避免循环 console.error('日志轮转异常:', err) }) const logger = winston.createLogger({ format: winston.format.combine( winston.format.splat(), winston.format.timestamp(), winston.format.printf(info => { return `${tsFormat()} | ${info.level} | ${ info.message }`; }) ), transports: [ new winston.transports.Console(), rotateTransport ] });
2. 适配Azure App Service的存储特性
- 若不需要持久化保留本地日志(已经配置了Azure Monitor、应用洞察等日志收集服务),直接把日志目录
logDir改为本地临时目录D:\local\Temp(Windows实例)或/tmp(Linux实例),本地磁盘没有SMB网络存储的I/O异常问题 - 若开了多实例横向扩展,必须在日志文件名中添加实例唯一标识,避免多个实例同时操作同一个日志文件触发锁冲突:
filename: `%DATE%-KBK-${process.env.WEBSITE_INSTANCE_ID || 'single'}.log`,
3. 调整轮转配置规避已知问题
- 关闭软链接创建:Azure SMB共享存储默认不允许创建符号链接,新增配置
createSymlink: false - 如非必须可以暂时关闭归档压缩:
zippedArchive: false,压缩过程的额外文件操作会提升锁冲突概率 - 升级底层依赖:手动安装最新稳定版的
file-stream-rotator,该库旧版本存在文件关闭异常未正确捕获的已知问题,执行命令npm install file-stream-rotator@latest即可
内容的提问来源于stack exchange,提问作者pkuller
相关产品推荐
相关产品推荐

