我需要在NestJS中保存日志的建议

我需要在NestJS中保存日志的建议,nestjs,typeorm,Nestjs,Typeorm,我需要关于如何正确或最有效地在数据库中保存用户日志的建议 async create(createUserDto: CreateUserDto): Promise<User> { try { const user = new User(); user.email = createUserDto.email; user.role = createUserDto.role; user.firstName = createUserDto.firstName; user.l

我需要关于如何正确或最有效地在数据库中保存用户日志的建议

async create(createUserDto: CreateUserDto): Promise<User> {
try {
  const user = new User();
  user.email = createUserDto.email;
  user.role = createUserDto.role;
  user.firstName = createUserDto.firstName;
  user.lastName = createUserDto.lastName;

  const rs = await this.usersRepository.save(user);

  const audit = new AuditLog();
  audit.userId = rs.id;
  audit.eventType = CREATE_CUSTOMER_SUCESS;
  audit.rqMessage = createUserDto;
  audit.rsMessage = rs;

  //Audit Service which save the logs.
  await this.auditService.create(audit); 

  return rs;
} catch (err) {
  // Error
} 
因此,我希望每次用户执行CRUD时都记录日志。我想拯救世界

  • 用户ID
  • 事件或操作,如果他删除或更新了
  • api的Json响应
  • 以及api的请求-响应
我所拥有的是,在用户服务层,我调用另一个服务名称auditService,它将日志插入数据库中

async create(createUserDto: CreateUserDto): Promise<User> {
try {
  const user = new User();
  user.email = createUserDto.email;
  user.role = createUserDto.role;
  user.firstName = createUserDto.firstName;
  user.lastName = createUserDto.lastName;

  const rs = await this.usersRepository.save(user);

  const audit = new AuditLog();
  audit.userId = rs.id;
  audit.eventType = CREATE_CUSTOMER_SUCESS;
  audit.rqMessage = createUserDto;
  audit.rsMessage = rs;

  //Audit Service which save the logs.
  await this.auditService.create(audit); 

  return rs;
} catch (err) {
  // Error
} 
异步创建(createUserDto:createUserDto):承诺{ 试一试{ const user=新用户(); user.email=createUserDto.email; user.role=createUserDto.role; user.firstName=createUserDto.firstName; user.lastName=createUserDto.lastName; const rs=wait this.usersRepository.save(用户); const audit=new AuditLog(); audit.userId=rs.id; audit.eventType=CREATE\u CUSTOMER\u success; audit.rqMessage=createUserDto; audit.rsMessage=rs; //保存日志的审核服务。 等待这个.auditService.create(审计); 返回rs; }捕捉(错误){ //错误 }
好的,这是可行的。但我知道还有比这更有效的方法。谢谢。

要完全访问请求和响应,最好的方法是设置记录器侦听器或中间件

例如,如果您将日志保存到MongoDB,下面是一个示例:

    @Injectable()
export class LoggingInterceptor implements NestInterceptor {
    constructor(@InjectModel('Log') private logModel: Model<LogDocument>) {}

    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const req = context?.switchToHttp()?.getRequest<Request>();
        const { statusCode } = context?.switchToHttp()?.getResponse<Response>();
        const { originalUrl, method, params, query, body, headers, user } = req;
        const requestTime = new Date();

        const request: RequestInterface = {
            originalUrl,
            method,
            params,
            query,
            body,
            headers,
        };

        return next.handle().pipe(
            tap((data) => {
                const response = { statusCode, data };
                this.insertMongo(originalUrl, request, response, requestTime);
            }),
        );
    }

    private async insertMongo(
        endpoint: string,
        request: RequestInterface,
        response: ResponseInterface,
        requestTime: Date,
    ): Promise<LogDocument> {
        const logInfo: CreateLogDto = {
            endpoint,
            request,
            response,
            requestTime,
        };
        const createdLog = new this.logModel(logInfo);
        return createdLog.save();
    }
}

我没有时间写一个完整的答案,所以我只建议一个您可以探索的可能解决方案。审计是一个贯穿各领域的问题,可以在这里使用typescript decorator来实现。因此,您可以使用
@Audit(CREATE\u CUSTOMER\u SUCCESS)来装饰您的方法
装饰程序可以包装您的方法,以捕获输入、输出和异常,并根据您的需要记录它们。然后,您的方法可以专注于域功能。它可以工作,但我遇到了一个问题,当我没有更改api路由时,它不会保存,因为操作员点击。可观察对象没有返回订阅