简体   繁体   English

在 Node.js/Express 中记录所有请求

[英]Logging all requests in Node.js/Express

In my small node.js application, using express, I wanted to log all the incoming requests, so I ended up with this:在我的小型 node.js 应用程序中,我想使用 express 记录所有传入的请求,所以我最终得到了这个:

var bodyParser = require('body-parser');

module.exports = function(app) {
   app.set("port", 50001);
   app.set("json spaces", 2);
   app.use(bodyParser.json());
   app.use(function (error, req, res, next) {
      app.logger.info("received from "+req.get("X-Forwarded-For")+" : "+req.method+" "+req.originalUrl+" (Authorization: "+req.get("Authorization")+")");
      //does not work if json is malformed
      //app.logger.info("content :"+JSON.stringify(req.body));
      if (error /*instanceof SyntaxError*/) {
         res.status(400);
         app.logger.error(error);
         res.json({ error:{msg: error.message}});
      } else {
         next();
      }
   });
   app.use(app.auth.initialize());
};

Unfortunately, I only get the logs via the app.logger.info line when there's an error (in my case a malformed JSON string in the body).不幸的是,当出现错误时,我只能通过app.logger.info行获取日志(在我的情况下,正文中的 JSON 字符串格式错误)。 What am I missing here?我在这里想念什么?

Expressjs adapts its functionality based on what type of callback you give it (this is not common in JS libraries so it is not surprising that people get confused by it). Expressjs 根据您提供的回调类型调整其功能(这在 JS 库中并不常见,因此人们对此感到困惑也就不足为奇了)。

If you do this where your callback has four arguments:如果你这样做,你的回调有四个参数:

app.use(function(error, req, res, next) {...});

then Express assumes this is an error-only middleware handler and will only be called when there are errors.然后 Express 假定这是一个仅错误的中间件处理程序,并且只会在出现错误时调用。 In the express doc , see the section labeled Error-handling middleware .express 文档中,请参阅标记为Error-handling middleware的部分。 Note this specific part of that page:请注意该页面的这一特定部分:

Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature (err, req, res, next)):以与其他中间件函数相同的方式定义错误处理中间件函数,除了使用四个参数而不是三个参数,特别是使用签名(err、req、res、next)):

And, here's a whole section of the documentation devoted to error handling middleware .而且,这里有一整节专门介绍错误处理中间件的文档。

If you use just three arguments:如果您只使用三个参数:

app.use(function(req, res, next) {...});

then, it is a normal middleware that is called when there are not errors.然后,它是一个正常的中间件,在没有错误时调用。 I'm not sure if they provide a single way to get both.我不确定他们是否提供了一种方式来获得两者。 But, certainly as a workaround, you could put your logging code into a function and then call that function from two separate middleware handlers, one for errors and one for non-errors.但是,当然作为一种解决方法,您可以将日志记录代码放入一个函数中,然后从两个单独的中间件处理程序调用该函数,一个处理错误,一个处理非错误。

Use morgan https://github.com/expressjs/morgan使用摩根https://github.com/expressjs/morgan

Install morgan安装摩根

$ npm install morgan

Include morgan in the index.js or app.js or server.js file (The file that pointed by the script tag in the package.json)在 index.js 或 app.js 或 server.js 文件中包含摩根(package.json 中的 script 标签所指向的文件)

var morgan = require('morgan')

Then add below before all the app call.然后在所有应用程序调用之前添加以下内容。

app.use(morgan('combined'))

Complete example完整示例

var express = require('express')
var morgan = require('morgan')

var app = express()

app.use(morgan('combined'))

app.get('/', function (req, res) {
  res.send('hello, world!')
})

A sample output line looks like this:示例输出行如下所示:

::1 - - [31/May/2021:09:03:14 +0000] "GET / HTTP/1.1" 200 2078 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"

DEBUG='*' or DEBUG='express:router' environment variable DEBUG='*'DEBUG='express:router'环境变量

It does not show a lot of information about the request, but it does show the path and method, which might be enough for basic applications, and is convenient as it does not require any extra setup.它没有显示很多关于请求的信息,但它显示了路径和方法,这对于基本应用程序来说可能已经足够了,并且因为不需要任何额外设置而方便。

DEBUG='*' enables all logs and is slightly easier to type: DEBUG='*'启用所有日志,并且更容易输入:

DEBUG='*' ./app.js

or the more specific DEBUG='express:router' is what you will generally want in a complex application with a lot of middleware, otherwise the DEBUG='*' could produce mountains of output:或者更具体的DEBUG='express:router'是您在具有大量中间件的复杂应用程序中通常需要的,否则DEBUG='*'可能会产生大量输出:

DEBUG='express:router' ./app.js

Eg with the hello world:例如,你好世界:

#!/usr/bin/env node

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

Then as I play on the browser with different URLs I can see logs such as:然后,当我使用不同的 URL 在浏览器上玩游戏时,我可以看到如下日志:

  express:router dispatching GET / +3m
  express:router query  : / +0ms
  express:router expressInit  : / +0ms
  express:router dispatching GET /asdf +10s
  express:router query  : /asdf +0ms
  express:router expressInit  : /asdf +0ms
  finalhandler default 404 +3m
  express:router dispatching GET /asdf?qwer=zxcv +17s
  express:router query  : /asdf?qwer=zxcv +0ms
  express:router expressInit  : /asdf?qwer=zxcv +0ms
  finalhandler default 404 +17s

Documentation at: https://expressjs.com/en/guide/debugging.html文档位于: https : //expressjs.com/en/guide/debugging.html

Tested on express 4.17.1.在 express 4.17.1 上测试。

npm install body-parser npm 安装正文解析器

and use this snippet,并使用这个片段,

const express = require('express')
const morganBody = require("morgan-body")
const bodyParser = require("body-parser")

const app = express()
const port = 8888

// must parse body before morganBody as body will be logged
app.use(bodyParser.json());

// hook morganBody to express app
morganBody(app, {logAllReqHeader:true, maxBodyLength:5000});

app.get('/', (req, res) => {
  res.send('Hello World!')

})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

You can just use grackle_tracking npm library to easily log all your traffic out to the console or log it to your database - also tracks uncaugt/caught errors - you can toggle it on/off easily for different environments as well since it's just您可以使用 grackle_tracking npm 库轻松将所有流量记录到控制台或将其记录到数据库 - 还跟踪未捕获/捕获的错误 - 您也可以针对不同的环境轻松打开/关闭它,因为它只是

grackle_tracking.configure({...configuration...});
app.use(grackle_tracking.track);

so you can comment out both or just the bottom line for environments/users you don't want to track https://www.getgrackle.com/libraries#grackle_tracking_overview因此,您可以注释掉两个或只注释掉您不想跟踪的环境/用户的底线https://www.getgrackle.com/libraries#grackle_tracking_overview

You could use try/catch你可以使用 try/catch

try {
   var jsonBody = JSON.stringify(req.body);
   app.logger.info("content :" + jsonBody);
} catch (err) { 
    app.logger.error("content error, error type: invalid json, error msg:" + err);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM