node.js - एक्सप्रेस लॉगिंग प्रतिक्रिया शरीर




express (4)

आप express-winston उपयोग कर सकते हैं और इसका उपयोग कर कॉन्फ़िगर कर सकते हैं:

expressWinston.requestWhitelist.push('body');
expressWinston.responseWhitelist.push('body');

कॉफ़ीस्क्रिप्ट में उदाहरण:

expressWinston.requestWhitelist.push('body')
expressWinston.responseWhitelist.push('body')
app.use(expressWinston.logger({
      transports: [
        new winston.transports.Console({
          json: true,
          colorize: true
        })
      ],
      meta: true, // optional: control whether you want to log the meta data about the request (default to true)
      msg: "HTTP {{req.method}} {{req.url}}", // optional: customize the default logging message. E.g. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}"
      expressFormat: true, // Use the default Express/morgan request formatting, with the same colors. Enabling this will override any msg and colorStatus if true. Will only output colors on transports with colorize set to true
      colorStatus: true, // Color the status code, using the Express/morgan color palette (default green, 3XX cyan, 4XX yellow, 5XX red). Will not be recognized if expressFormat is true
      ignoreRoute: function (req, res) { return false; } // optional: allows to skip some log messages based on request and/or response
    }));

शीर्षक सुंदर आत्म व्याख्यात्मक होना चाहिए।

डिबगिंग उद्देश्यों के लिए, मैं सेवा के हर अनुरोध के लिए प्रतिक्रिया कोड और शरीर को मुद्रित करना चाहता हूं। प्रतिक्रिया कोड को प्रिंट करना काफी आसान है, लेकिन प्रतिक्रिया शरीर को प्रिंट करना मुश्किल है, क्योंकि ऐसा लगता है कि प्रतिक्रिया निकाय संपत्ति के रूप में आसानी से उपलब्ध नहीं है।

निम्नलिखित काम नहीं करता है:

var express = require('express');
var app = express();

// define custom logging format
express.logger.format('detailed', function (token, req, res) {                                    
    return req.method + ': ' + req.path + ' -> ' + res.statusCode + ': ' + res.body + '\n';
});  

// register logging middleware and use custom logging format
app.use(express.logger('detailed'));

// setup routes
app.get(..... omitted ...);

// start server
app.listen(8080);

निस्संदेह, मैं उस ग्राहक पर प्रतिक्रियाओं को आसानी से प्रिंट कर सकता हूं जिन्होंने अनुरोध उत्सर्जित किया था, लेकिन मैं भी सर्वर पक्ष में करना पसंद करूंगा।

पीएस: अगर यह मदद करता है, तो मेरे सभी प्रतिक्रियाएं जेसन हैं, लेकिन उम्मीद है कि एक ऐसा समाधान है जो सामान्य प्रतिक्रियाओं के साथ काम करता है।


उपर्युक्त स्वीकृत कोड में ES6 के साथ समस्याएं हैं। नीचे दिए गए कोड का प्रयोग करें

function logReqRes(req, res, next) {
  const oldWrite = res.write;
  const oldEnd = res.end;

  const chunks = [];

  res.write = (...restArgs) => {
    chunks.push(new Buffer(restArgs[0]));
    oldWrite.apply(res, restArgs);
  };

  res.end = (...restArgs) => {
    if (restArgs[0]) {
      chunks.push(new Buffer(restArgs[0]));
    }
    const body = Buffer.concat(chunks).toString('utf8');

    console.log({
      time: new Date().toUTCString(),
      fromIP: req.headers['x-forwarded-for'] || 
      req.connection.remoteAddress,
      method: req.method,
      originalUri: req.originalUrl,
      uri: req.url,
      requestData: req.body,
      responseData: body,
      referer: req.headers.referer || '',
      ua: req.headers['user-agent']
    });

    // console.log(body);
    oldEnd.apply(res, restArgs);
  };

  next();
}

module.exports = logReqRes;

मैंने पाया कि इस समस्या का सबसे आसान समाधान प्रतिक्रिया भेजते समय पुनर्विक्रय ऑब्जेक्ट में body प्रॉपर्टी जोड़ना था, जिसे बाद में लॉगर द्वारा एक्सेस किया जा सकता था। मैं इसे अपने नामस्थान में जोड़ता हूं जो कि टकराव नामकरण से बचने के लिए मैं req और res वस्तुओं पर रखता हूं। जैसे

res[MY_NAMESPACE].body = ...

मेरे पास एक उपयोगिता विधि है जो मेरे मानकीकृत एपीआई / जेएसओएन प्रतिक्रिया के सभी प्रतिक्रियाओं को स्वरूपित करती है, इसलिए इस लाइनर को जोड़ने से प्रतिक्रिया शरीर को उजागर किया जाता है जब लॉगिंग चालू हो जाती है।


सुनिश्चित नहीं है कि यह सबसे आसान समाधान है, लेकिन आप प्रतिक्रिया में लिखे गए डेटा को अवरुद्ध करने के लिए एक मिडलवेयर लिख सकते हैं। सुनिश्चित करें कि आप app.compress() अक्षम करते हैं।

function logResponseBody(req, res, next) {
  var oldWrite = res.write,
      oldEnd = res.end;

  var chunks = [];

  res.write = function (chunk) {
    chunks.push(chunk);

    oldWrite.apply(res, arguments);
  };

  res.end = function (chunk) {
    if (chunk)
      chunks.push(chunk);

    var body = Buffer.concat(chunks).toString('utf8');
    console.log(req.path, body);

    oldEnd.apply(res, arguments);
  };

  next();
}

app.use(logResponseBody);