Как отследить идентификатор запроса в Loopback 4? - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь отследить каждый HTTP-запрос в моем REST API, используя Loopback 4, чтобы регистрировать их в контроллерах с помощью log4 js, вот так:

[2020-05-05T19:21:52.191] [INFO] [request-id:47e9a486-1243-1c07-3ac0-0acc9cce2c0e] user.controller.ts - starting request validation
[2020-05-05T19:21:52.191] [INFO] [request-id:1dc81e45-093a-8009-42d2-e545c3a10c9d] user.controller.ts - starting request validation
[2020-05-05T19:21:53.126] [INFO] [request-id:47e9a486-1243-1c07-3ac0-0acc9cce2c0e] user.controller.ts - request validation success
[2020-05-05T19:21:53.145] [ERROR] [request-id:1dc81e45-093a-8009-42d2-e545c3a10c9d] user.controller.ts - request validation failed

The main проблема здесь часть [request-id:UUID], поскольку Node.js иногда смешивает журналы, и я не могу определить, какие из них принадлежат одному запросу. Я нашел несколько решений для приложений Express, но не смог найти способ заставить их работать с Loopback 4 и log4 js:

Решение может включать использование обработчика последовательности, но я пока не мог понять, как это сделать. Намек на внедрение объекта запроса: https://github.com/strongloop/loopback-next/issues/1881#issuecomment -431384142

1 Ответ

1 голос
/ 07 мая 2020

Мы сделали это с помощью Winston logger, который был внедрен как Logger Service в наш sequence.ts. Вот код для sequence.ts.

export class MySequence implements SequenceHandler {
  constructor(
    @inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
    @inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
    @inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
    @inject(SequenceActions.SEND) public send: Send,
    @inject(SequenceActions.REJECT) public reject: Reject,
    @inject(LOGGER.LOGGER_INJECT) public logger: ILogger,
    @inject(HelmetSecurityBindings.HELMET_SECURITY_ACTION)
    protected helmetAction: HelmetAction,
    @inject(RateLimitSecurityBindings.RATELIMIT_SECURITY_ACTION)
    protected rateLimitAction: RateLimitAction,
    @inject(AlivioBindings.i18n)
    protected i18n: i18nAPI,
  ) {}

  async handle(context: RequestContext) {
    const requestTime = Date.now();
    try {
      const {request, response} = context;
      this.logger.info(
        `Request ${request.method} ${
          request.url
        } started at ${requestTime.toString()}.
        Request Details
        Referer = ${request.headers.referer}
        User-Agent = ${request.headers['user-agent']}
        Remote Address = ${request.connection.remoteAddress}
        Remote Address (Proxy) = ${request.headers['x-forwarded-for']}`,
      );
      const route = this.findRoute(request);
      const args = await this.parseParams(request, route);

      await this.rateLimitAction(request, response);
      await this.helmetAction(request, response);

      request.body = args[args.length - 1];
      const result = await this.invoke(route, args);
      this.send(response, result);
    } catch (err) {
      this.logger.error(
        `Request ${context.request.method} ${
          context.request.url
        } errored out. Error :: ${JSON.stringify(err)} ${err}`,
      );

      this.reject(context, error);
    } finally {
      this.logger.info(
        `Request ${context.request.method} ${
          context.request.url
        } Completed in ${Date.now() - requestTime}ms`,
      );
    }
  }
}

Здесь вы можете использовать любой регистратор в качестве провайдера. Вы можете создать поставщика оболочки для log4 js, а затем сделать это, как указано выше. Надеюсь это поможет. Дайте мне знать, если вы тоже хотите увидеть код провайдера. Я тоже поделюсь этим.

...