如何配置Winston日志,使其打印Bot实例的内部状态?
问题需求
拥有一组Bot类实例,希望每个Bot调用logger.info('指定文本')时,能将该Bot的内部状态(如mode、name)作为日志内容的一部分输出,期望输出格式为:21-09 22:00 info[wet] 🤖 Game: foo
现有代码问题
当前代码中,Bot.talk()方法仅传递文本给logger.info(),Winston日志处理器无法获取Bot实例的状态信息,导致printf模板中的bot参数为undefined,无法生成目标格式日志。
解决方案
1. 修改Bot类的talk方法,传递Bot状态元数据
在调用logger.info时,将当前Bot的状态作为第二个参数(元数据)传入,让Winston能捕获到Bot的上下文信息:
talk(text){ // 传递当前Bot实例作为元数据,后续可直接读取状态 logger.info(text, { bot: this }); }
2. 修正Winston的日志格式化逻辑
调整printf模板,正确读取元数据中的bot字段,同时添加容错处理(避免非Bot调用日志报错):
logger = winston.createLogger({ format: format.combine( format.timestamp({format: 'MM-DD HH:mm'}), format.printf(({timestamp, level, message, bot, ...rest})=>{ // 容错处理:无bot元数据时使用默认值 const botMode = bot?.mode || 'unknown'; const botName = bot?.name || 'unnamed'; return `${timestamp} ${level}[${botMode}] 🤖 ${botName}: ${message}`; }), ), transports: [ new winston.transports.Console({ level: "silly" }) ], });
注:原代码中的
format.label未被使用,可直接移除;原transports中的consoleFormat未定义,若不需要额外控制台格式可省略。
完整可运行代码
const winston = require('winston'); const { format } = winston; // 配置Winston日志 const logger = winston.createLogger({ format: format.combine( format.timestamp({format: 'MM-DD HH:mm'}), format.printf(({timestamp, level, message, bot, ...rest})=>{ const botMode = bot?.mode || 'unknown'; const botName = bot?.name || 'unnamed'; return `${timestamp} ${level}[${botMode}] 🤖 ${botName}: ${message}`; }), ), transports: [ new winston.transports.Console({ level: "silly" }) ], }); // 修改后的Bot类 class Bot{ constructor(name){ this.mode = 'wet'; this.name = name; } wetMode(){ this.mode = 'wet'} dryMode(){ this.mode = 'dry' } talk(text){ logger.info(text, { bot: this }); } } // 测试 const bot1 = new Bot('Game'); bot1.talk('foo'); // 输出示例:09-21 22:00 info[wet] 🤖 Game: foo bot1.dryMode(); bot1.talk('bar'); // 输出示例:09-21 22:00 info[dry] 🤖 Game: bar
内容的提问来源于stack exchange,提问作者pery mimon
相关产品推荐
相关产品推荐

