我试图在我的REST API中使用Loopback 4跟踪每个HTTP请求,以便使用log4js在控制器中记录它们,就像这样。
[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
这个... 大问题 这里是 [request-id:UUID]
部分,因为Node.js有时会混淆日志,我无法识别其中哪些属于同一个请求。我已经找到了一些针对Express应用的解决方案,但我无法找到一种方法让它与Loopback 4和log4js一起工作。
解决方法可能涉及到Sequence处理程序的使用,但我还没弄明白怎么做。注入Request对象的一些提示。https:/github.comstronglooploopback-nextissues1881#issuecomment-431384142。
我们使用winston logger做的,它是作为一个日志服务注入到我们的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`,
);
}
}
}
你可以在这里使用任何记录器作为提供者。你可以在log4js上创建一个封装提供者,然后像上面那样做。希望这对你有帮助。如果你也想看提供者的代码,请告诉我。我也会分享的。