Hapi.js中如何将console.log()输出写入日志文件?
实现console.log写入Hapi.js的good-file日志文件
要让console.log()的内容也写入通过good-file配置的日志文件,核心思路是重写全局的console方法,让它在调用时同时触发Hapi的server.log()(这样就能被good的监听机制捕获),具体步骤如下:
1. 重写全局console方法(推荐方案)
在Hapi服务启动完成后,获取server实例,然后重写console.log、console.error等方法,将其输出转发到server.log():
// 假设这是你的Hapi启动文件 const Hapi = require('@hapi/hapi'); const Good = require('@hapi/good'); const init = async () => { const server = Hapi.server({ port: 3000, host: 'localhost' }); // 注册good插件(你的现有配置) await server.register({ plugin: Good, options: { reporters: { myFileReporter: [ { module: 'good-squeeze', name: 'Squeeze', args: [{ request: '*', error: '*', response: '*', log: '*' }] }, { module: 'good-squeeze', name: 'SafeJson' }, { module: 'good-file', args: ['./logs/log'] } ] } } }); await server.start(); // 保存原始console方法(可选,保留控制台输出) const originalLog = console.log; const originalError = console.error; // 重写console.log console.log = (...args) => { // 处理复杂参数(如对象),避免输出[object Object] const logContent = args.map(item => typeof item === 'object' ? JSON.stringify(item, null, 2) : item ).join(' '); // 触发server.log,标签设为['console']方便区分来源 server.log(['console'], logContent); // 保留原始控制台输出(如果不需要可以删除这行) originalLog.apply(console, args); }; // 同理重写console.error console.error = (...args) => { const logContent = args.map(item => typeof item === 'object' ? JSON.stringify(item, null, 2) : item ).join(' '); server.log(['console', 'error'], logContent); originalError.apply(console, args); }; console.log(`Server running on ${server.info.uri}`); // 这行日志会同时写入文件和控制台 }; process.on('unhandledRejection', (err) => { console.error(err); process.exit(1); }); init();
2. 适配无server实例的场景
如果有些模块在server启动前就需要调用console.log,可以先缓存这些日志,等server初始化完成后再批量写入:
// 创建一个全局日志缓存模块(logger.js) let serverInstance = null; const pendingLogs = []; exports.setServer = (server) => { serverInstance = server; // 写入启动前缓存的日志 pendingLogs.forEach(({ tags, content }) => { server.log(tags, content); }); pendingLogs.length = 0; }; const logHandler = (tags, args) => { const content = args.map(item => typeof item === 'object' ? JSON.stringify(item, null, 2) : item ).join(' '); if (serverInstance) { serverInstance.log(tags, content); } else { pendingLogs.push({ tags, content }); } // 保留原始输出 console._originalLog.apply(console, args); }; // 保存原始方法并覆盖 console._originalLog = console.log; console.log = (...args) => logHandler(['console'], args); console._originalError = console.error; console.error = (...args) => logHandler(['console', 'error'], args);
然后在启动文件中导入并初始化:
const { setServer } = require('./logger.js'); // ... server初始化代码 ... await server.start(); setServer(server); // 传入server实例,触发缓存日志写入
3. 验证配置有效性
确保你的good插件配置中,Squeeze的log选项设置为*(如你现有配置所示),这样所有通过server.log()触发的日志(包括我们转发的console输出)都会被捕获并写入文件。
这样修改后,无论在哪个模块中调用console.log或console.error,内容都会同时输出到控制台和指定的日志文件中,完美解决无法获取request/server对象的场景。
内容的提问来源于stack exchange,提问作者Anil Kumar R
相关产品推荐
相关产品推荐

