Winston 3.x版本是否缺失Logstash集成支持?
我之前也碰到过一模一样的情况,Winston 3.x重构了整个transport架构,原来的winston-logstash包是针对Winston 2.x开发的,所以会提示它是legacy transport。官方文档里提到的logstash format只是负责把日志格式转换成Logstash能识别的结构,但并没有帮你把日志发送到Logstash服务——这部分需要你搭配合适的transport来实现,不用降级到2.x版本,下面给你两个可行方案:
方案一:使用适配Winston 3.x的第三方Logstash Transport
有第三方包专门适配了Winston 3.x的Logstash传输,比如winston-transport-logstash(注意和旧的winston-logstash区分开)。先安装它:
npm install winston-transport-logstash
然后修改代码,同时配置格式和传输:
const winston = require('winston'); const { LogstashTransport } = require('winston-transport-logstash'); const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.logstash() ), transports: [ new winston.transports.Console(), new LogstashTransport({ host: '127.0.0.1', port: 5000, node_name: 'my node name' }) ] }); logger.info('ciao mondo');
这个包会帮你把格式化后的日志通过TCP发送到Logstash,只要你的Logstash配置了对应的TCP输入(比如在logstash.conf里设置input { tcp { port => 5000 codec => json } }),就能收到日志了。
方案二:自定义简单传输逻辑(无需第三方包)
如果不想引入额外依赖,你可以自己编写一个简单的TCP客户端,把经过logstash format处理后的日志发送到Logstash:
const winston = require('winston'); const net = require('net'); // 创建Logstash TCP客户端 const logstashClient = new net.Socket(); logstashClient.connect(5000, '127.0.0.1', () => { console.log('Connected to Logstash'); }); // 自定义transport class LogstashTCPTransport extends winston.Transport { constructor(opts) { super(opts); this.host = opts.host; this.port = opts.port; } log(info, callback) { setImmediate(() => { this.emit('logged', info); }); // 把格式化后的日志转为字符串发送 logstashClient.write(JSON.stringify(info) + '\n'); callback(); } } const logger = winston.createLogger({ level: 'info', format: winston.format.logstash(), transports: [ new winston.transports.Console(), new LogstashTCPTransport({ host: '127.0.0.1', port: 5000 }) ] }); logger.info('ciao mondo');
这个方法需要你自己处理连接异常、重连等逻辑,适合对依赖有严格控制的场景。
另外要注意,Logstash端必须配置对应的输入来接收日志,比如TCP输入的配置示例:
input { tcp { port => 5000 codec => json } } output { elasticsearch { hosts => ["localhost:9200"] index => "winston-logs-%{+YYYY.MM.dd}" } }
这样配置后,Winston 3.x的日志就能正常发送到ELK栈了,不用放弃新版本的特性。
内容的提问来源于stack exchange,提问作者Carmine Ingaldi

