如何使用Winston结合Socket.io将日志发送至前端?
实现Winston日志通过Socket.io推送至前端
Winston 2.0及以上版本移除了WebHook Transport,你可以通过以下两种方案实现日志向前端的Socket.io推送:
方案一:自定义Winston Transport(推荐)
直接编写自定义传输器,在日志触发时通过Socket.io实时推送到前端,这是最直接高效的方式。
后端实现步骤
- 安装依赖:
npm install winston socket.io express
- 代码示例:
const express = require('express'); const http = require('http'); const { Server } = require('socket.io'); const winston = require('winston'); const app = express(); const server = http.createServer(app); // 初始化Socket.io,配置跨域(替换为你的前端地址) const io = new Server(server, { cors: { origin: "http://localhost:5173", methods: ["GET", "POST"] } }); // 自定义Socket.io传输器 class SocketIOTransport extends winston.Transport { constructor(opts) { super(opts); this.io = opts.io; // 可自定义命名空间和房间,按需调整 this.namespace = opts.namespace || '/logs'; this.room = opts.room || 'all'; } log(info, callback) { setImmediate(() => this.emit('logged', info)); // 将日志推送到前端 this.io.of(this.namespace).to(this.room).emit('new-log', { level: info.level, message: info.message, timestamp: info.timestamp, ...info.meta }); callback(); } } // 注册自定义传输器 winston.transports.SocketIO = SocketIOTransport; // 配置Winston Logger const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ new winston.transports.Console(), // 使用自定义的Socket.io传输器 new SocketIOTransport({ io: io }) ] }); // 测试推送 logger.info('测试Socket.io日志推送'); server.listen(3000, () => { console.log('服务器运行在3000端口'); });
前端实现
import { io } from "socket.io-client"; // 连接到后端的日志命名空间 const socket = io('http://localhost:3000/logs'); // 监听新日志事件 socket.on('new-log', (log) => { // 将日志渲染到页面(示例) const logItem = document.createElement('div'); logItem.className = `log-${log.level}`; logItem.textContent = `${log.timestamp} [${log.level.toUpperCase()}]: ${log.message}`; document.getElementById('logs-container').appendChild(logItem); });
方案二:使用Winston HTTP Transport转发
通过Winston的HTTP Transport将日志发送到后端接口,再由接口通过Socket.io推送给前端。
后端代码示例
const express = require('express'); const http = require('http'); const { Server } = require('socket.io'); const winston = require('winston'); const { HttpTransport } = require('winston/lib/winston/transports'); const app = express(); app.use(express.json()); // 解析JSON请求体 const server = http.createServer(app); const io = new Server(server, { cors: { origin: "http://localhost:5173", methods: ["GET", "POST"] } }); // 接收Winston HTTP Transport发送的日志 app.post('/logs/webhook', (req, res) => { const log = req.body; // 推送给前端 io.emit('new-log', log); res.status(200).send('日志已接收'); }); // 配置Winston HTTP Transport const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ new winston.transports.Console(), new HttpTransport({ host: 'localhost', port: 3000, path: '/logs/webhook', method: 'POST', headers: { 'Content-Type': 'application/json' } }) ] }); // 测试推送 logger.info('测试HTTP Transport转Socket.io推送'); server.listen(3000, () => { console.log('服务器运行在3000端口'); });
前端代码与方案一完全一致,只需监听new-log事件即可。
内容的提问来源于stack exchange,提问作者marcox
相关产品推荐
相关产品推荐

