是否有可能在全球范围内获取next.js请求对象?

时间:2019-05-21 06:40:04

标签: next.js fastify

我正在将 <li >{{std['sizeofGroups_' + item]}}</li>fastify一起使用,并且需要包括跟踪(到目前为止,next.js是问题)。我现在正在做的是创建一个requestId onRequest钩子并生成一个fastify值并将其设置在请求对象中(也可以作为请求标头)。我想要的是访问此请求对象的原因有两个:

  1. 在记录器对象中(在本例中为requestId,我想在所有自定义服务器端日志中都包含pino)。
  2. 在需要对其他服务进行的所有请求中,都必须在标头中包含requestId

也许我错过了一些琐碎的事情,而我却没有做到最好。

某些片段

这是我生成reqId的方式

requestId

皮诺实例

const fastify = fastifyFactory({
  logger, // logger configuration (Pino instance with custom configuration, see below)
  genReqId: () => {
    return Math.random()
      .toString(36)
      .slice(-6);
  }
});

这是一个插件,用于获取生成的reqId并将其设置为请求对象内的查询属性

const pino = require('pino');
const logger = pino({
  messageKey: 'message',
  prettyPrint: true,
  changeLevelName: 'severity',
  useLevelLabels: true,
  base: {
    serviceContext: {
      service: 'web'
    }
  },
  level:'info'
});
module.exports = {
  logger
};

使用const tracing = function tracing(fastify, opt, next) { fastify.addHook('onRequest', (req, res, nextRequest) => { const { id } = req; const logger = fastify.log.child({ reqId: id }); req.query.reqId = id; fastify.log = logger; //overrides the current fastify logger to include the reqId in all custom logs nextRequest(); }); next(); }; tracing[Symbol.for('skip-override')] = true; module.exports = tracing; 时没有问题,因为在每个请求中如何覆盖记录器,它将包括fastify.log.info(...)作为子日志。问题是我想创建一个通用的记录器以在任何地方使用,并且固定记录器在React组件中不可用(例如,在reqId处写日志)。另一个重要的想法是,我需要将此getInitialProps包含在我发送给其他服务的所有请求中(例如:在获取数据时),这就是为什么我试图将此值存储在请求对象中但需要获取它的原因。 / p>

1 个答案:

答案 0 :(得分:0)

从以下项目构建开始:

npx create-next-app --example custom-server-fastify custom-server-fastify-app

并通过以下方式更改server.js

const Next = require('next')
const Fastify = require('fastify')

// your pino config
const fastify = Fastify({
  logger: {
    level: 'info',
    prettyPrint: true,
    changeLevelName: 'severity',
    useLevelLabels: true,
    base: {
      serviceContext: {
        service: 'web'
      }
    }
  },
  genReqId: () => { return Math.random().toString(36).slice(-6) }
})

// your plugin
const aPlugin = function yourPlugin (fastify, opts, next) {
  fastify.addHook('onRequest', (request, reply, next) => {
    request.log.info('hello')
    const { id } = request
    request.query.reqId = id
    next()
  })
  next()
}
aPlugin[Symbol.for('skip-override')] = true
fastify.register(aPlugin)

[.... other generated code]
const port = parseInt(process.env.PORT, 10) || 3000

[.... other generated code]
      fastify.get('/*', (req, reply) => {
        console.log('-------->', req.id, req.query.reqId) // both your id is ok
        return app.handleRequest(req.req, reply.res).then(() => {
          reply.sent = true
        })
[.... other generated code]
      })

然后:

npm run dev
# another console
curl http://localhost:3000/

它将打印出:

[1558441374784] INFO : Server listening at http://127.0.0.1:3000
    serviceContext: {
      "service": "web"
    }
> Ready on http://localhost:3000
[1558441405416] INFO : incoming request
    serviceContext: {
      "service": "web"
    }
    reqId: "2i810l"
    req: {
      "method": "GET",
      "url": "/",
      "hostname": "localhost:3000",
      "remoteAddress": "127.0.0.1",
      "remotePort": 57863
    }
req id ----> 2i810l
--------> 2i810l 2i810l
[ event ] build page: /
[ wait ]  compiling ...
[1558441406171] INFO : request completed
    serviceContext: {
      "service": "web"
    }
    reqId: "2i810l"
    res: {
      "statusCode": 200
    }
    responseTime: 753.012099981308

所以我认为误解在于请求对象是Fastify请求,而不是可以用request.req访问的Node.js“低级”请求对象。

此外,运行fastify.log = logger;是危险的,因为这意味着每个请求都将覆盖并创建一个新的记录器,并为fastify实例更改记录器,这是不安全的,并且如图所示,这是不必要的。

如果您想要更多的子记录器(每个示例的每个路由前缀),我建议您探索/使用onRegister hook


编辑:

现在使用自定义钩子打印:

[1558443540483] INFO : hello
    serviceContext: {
      "service": "web"
    }
    reqId: "zjuhw2"