Vercel部署Serverless应用时Winston创建./logs目录报错求助
解决SvelteKit部署Vercel Serverless时Winston日志目录错误问题
问题重现
部署SvelteKit应用到Vercel Serverless环境时出现以下错误:
Error: ENOENT: no such file or directory, mkdir './logs' at Object.mkdirSync (node:fs:1391:3) at File._createLogDirIfNotExist (/var/task/vercel/path0/node_modules/winston/lib/winston/transports/file.js:761:10) at new File (/var/task/vercel/path0/node_modules/winston/lib/winston/transports/file.js:94:28) at file:///var/task/vercel/path0/.svelte-kit/output/server/chunks/db.js:14:5 at ModuleJob.run (node:internal/modules/esm/module_job:195:25) at async ModuleLoader.import (node:internal/modules/esm/loader:337:24) at async Server.init (file:///var/task/vercel/path0/.svelte-kit/output/server/index.js:2875:24) at async file:///var/task/vercel/path0/.svelte-kit/vercel-tmp/index.js:10:1 { errno: -2, syscall: 'mkdir', code: 'ENOENT', path: './logs' } Node.js process exited with exit status: 1. The logs above can help with debugging the issue. INIT_REPORT Init Duration: 845.59 ms Phase: invoke Status: error Error Type: Runtime.ExitError
已尝试上传./logs目录、将日志文件移至根目录,均未解决。Winston为第三方依赖引入,不想全局禁用日志功能。
问题根源
Vercel Serverless运行环境的当前工作目录是只读的,仅/tmp目录具备临时写入权限。Winston默认尝试在当前目录创建./logs文件夹,但没有写入权限,导致报错。上传./logs目录无效,因为部署后的目录依然是只读状态,无法写入日志文件。
解决方案
1. 修改Winston日志路径到/tmp目录
找到Winston初始化File传输器的代码(根据错误提示在db.js第14行),将日志路径改为Vercel允许的/tmp目录:
// 原代码示例(核心是修改filename路径) const fileTransport = new File({ filename: './logs/app.log' }); // 修改后 const fileTransport = new File({ filename: '/tmp/logs/app.log' });
/tmp目录是Vercel Serverless环境默认存在的可写目录,Winston会自动创建/tmp/logs子目录(如果不存在),无需手动上传。
2. 全局重写Winston配置(找不到第三方依赖配置时)
如果Winston是由第三方依赖自动引入的,无法直接修改其配置,可以在SvelteKit的服务器入口文件(如src/hooks.server.js)中重写Winston的传输器,替换为指向/tmp的File传输器或Console传输器:
import winston from 'winston'; // 清除原有传输器,添加新的可写传输器 winston.clear(); winston.add(new winston.transports.File({ filename: '/tmp/logs/app.log' })); // 或者直接使用Console传输器(无需写入文件,Vercel会捕获控制台输出) // winston.add(new winston.transports.Console());
3. 改用Vercel原生日志系统
Vercel Serverless会自动捕获所有console.log/console.error等输出,并整合到Vercel控制台的函数日志中。可以直接将Winston的传输器替换为Console,完全避免文件写入操作:
const consoleTransport = new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ) }); winston.add(consoleTransport);
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

