You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何监控Express与Socket.io服务器的HTTP/WSS请求网络字节出入量

Got it, let's break this down for you. Since you're running Express with Socket.io wrapped around an http.Server, we can split the solution into two clear parts: tracking HTTP request/response bytes, and monitoring WebSocket (WSS) traffic for Socket.io connections. Plus, we'll cover key considerations for your Nginx production setup.


1. Tracking HTTP Request/Response Bytes

We can add an Express middleware to capture incoming and outgoing bytes for every HTTP request. This middleware hooks into the request's data stream and overrides the response's write method to count bytes, then logs/stores the stats once the response finishes.

// Place this middleware BEFORE any body-parsing middleware (like express.json())
app.use((req, res, next) => {
  // Track incoming request bytes
  let incomingBytes = 0;
  req.on('data', (chunk) => {
    incomingBytes += chunk.length;
  });

  // Track outgoing response bytes
  let outgoingBytes = 0;
  const originalWrite = res.write;
  res.write = function(chunk, encoding, callback) {
    if (chunk) {
      // Calculate byte length correctly for buffers or strings
      outgoingBytes += Buffer.isBuffer(chunk) ? chunk.length : Buffer.byteLength(chunk, encoding);
    }
    // Call the original write method to maintain functionality
    return originalWrite.call(this, chunk, encoding, callback);
  };

  // Log stats when the response is fully sent
  res.on('finish', () => {
    console.log(`[HTTP] ${req.method} ${req.path} | In: ${incomingBytes} bytes | Out: ${outgoingBytes} bytes`);
    // Replace console.log with your monitoring logic (e.g., send to Prometheus, Datadog, or a database)
  });

  next();
});

Critical Note: If you use body-parsing middleware like express.json() or express.urlencoded(), ensure this byte-tracking middleware runs before them. Body parsers consume the request's data event, so our middleware won't capture incoming bytes if it's placed after.


2. Monitoring Socket.io (WSS) Connection Bytes

Socket.io uses Engine.IO under the hood, which provides built-in byte tracking for each connection. The socket.client object (an Engine.IO Client instance) exposes bytesReceived and bytesSent properties that track total bytes for the lifetime of the WebSocket connection.

io.on('connection', (socket) => {
  const engineClient = socket.client;
  const socketId = socket.id;

  console.log(`[Socket] Connected: ${socketId}`);

  // Option 1: Log total bytes when the socket disconnects
  socket.on('disconnect', () => {
    const totalIncoming = engineClient.bytesReceived;
    const totalOutgoing = engineClient.bytesSent;
    console.log(`[Socket] Disconnected: ${socketId} | Total In: ${totalIncoming} bytes | Total Out: ${totalOutgoing} bytes`);
    // Store these stats in your monitoring system as needed
  });

  // Option 2: Periodically log real-time stats (e.g., every 15 seconds)
  const statsInterval = setInterval(() => {
    console.log(`[Socket] ${socketId} | Current In: ${engineClient.bytesReceived} bytes | Current Out: ${engineClient.bytesSent} bytes`);
  }, 15000);

  // Clean up the interval when the socket disconnects
  socket.on('disconnect', () => clearInterval(statsInterval));
});

This tracks all WebSocket traffic, including Socket.io's internal protocol frames and your custom messages.


3. Nginx Production Environment Notes

Since you're using Nginx as a reverse proxy, keep these points in mind:

Client-to-Nginx Byte Tracking

If you want to track bytes directly between the client and Nginx (not just Nginx to your Node.js server), configure Nginx to log these values in its access logs. Add a custom log format that includes:

  • $request_length: Total bytes sent by the client (request headers + body)
  • $bytes_sent: Total bytes sent by Nginx to the client (response headers + body)

Example Nginx config snippet:

log_format app_traffic '$remote_addr - $remote_user [$time_local] "$request" '
                       '$status $bytes_sent "$http_referer" '
                       '"$http_user_agent" "$request_length"';

access_log /var/log/nginx/your-app-traffic.log app_traffic;

You can then use tools like Loki+Grafana or the ELK Stack to analyze these logs and aggregate traffic stats.

Nginx-to-Node.js Byte Tracking

The Node.js code above will track bytes between Nginx and your server, but note that these values may differ from client-to-Nginx stats. Nginx may compress responses, add headers, or handle WebSocket frame translation, so the byte counts won't match exactly.


Full Integrated Code

Here's your original code with all the tracking logic added:

const express = require('express')
const app = express()
const http = require('http').Server(app)
const io = require('socket.io')(http)

// HTTP Byte Tracking Middleware (place before body parsers)
app.use((req, res, next) => {
  let incomingBytes = 0;
  req.on('data', (chunk) => {
    incomingBytes += chunk.length;
  });

  let outgoingBytes = 0;
  const originalWrite = res.write;
  res.write = function(chunk, encoding, callback) {
    if (chunk) {
      outgoingBytes += Buffer.isBuffer(chunk) ? chunk.length : Buffer.byteLength(chunk, encoding);
    }
    return originalWrite.call(this, chunk, encoding, callback);
  };

  res.on('finish', () => {
    console.log(`[HTTP] ${req.method} ${req.path} | In: ${incomingBytes} bytes | Out: ${outgoingBytes} bytes`);
  });

  next();
});

// Add your body-parsing middleware here (if needed)
// app.use(express.json());
// app.use(express.urlencoded({ extended: true }));

app.get('/', (req, res) => {
  res.render('index')
})

// Socket.io Byte Tracking
io.on('connection', (socket) => {
  const engineClient = socket.client;
  const socketId = socket.id;

  console.log(`[Socket] Connected: ${socketId}`);

  socket.on('disconnect', () => {
    const totalIn = engineClient.bytesReceived;
    const totalOut = engineClient.bytesSent;
    console.log(`[Socket] Disconnected: ${socketId} | Total In: ${totalIn} bytes | Total Out: ${totalOut} bytes`);
  });

  const statsInterval = setInterval(() => {
    console.log(`[Socket] ${socketId} | Current In: ${engineClient.bytesReceived} bytes | Current Out: ${engineClient.bytesSent} bytes`);
  }, 15000);

  socket.on('disconnect', () => clearInterval(statsInterval));
})

http.listen(8080, () => console.log(`Server is running at 0.0.0.0:8080`))

内容的提问来源于stack exchange,提问作者Amala Amala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:22:44