Reputation: 69
I need suggestion about how to properly or most efficient way to save user logs in database.
So I want to log every time the user do CRUD. I want to save the
what I have, in user service layer I call another service name auditService which insert the logs in database.
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
}
Well, this works. but I know there is more efficient way than this. Thank you.
Upvotes: 1
Views: 3991
Reputation: 162
To have full access over request and Response, the best way is by setting a Logger Interceptor or Middleware.
For example, if you are keeping the log to MongoDB, here is an example:
@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();
}
}
It will handle the Request, Response, Context, and Timestamp of every request intercepted.
To use it in a module, you just have to add an APP_INTERCEPTOR provider to it. In the case of the example logger, it should look like this:
providers: [
{ provide: APP_INTERCEPTOR, useClass: LoggingInterceptor },
],
Upvotes: 1