Browse Source

Nc fix/throttler logging (#9154)

* fix: avoid spamming throttler logs

* fix: key & remaining ttl

---------

Co-authored-by: mertmit <mertmit99@gmail.com>
pull/9151/head
Raju Udava 4 months ago committed by GitHub
parent
commit
7f7eda318b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 57
      packages/nocodb/src/filters/global-exception/global-exception.filter.ts

57
packages/nocodb/src/filters/global-exception/global-exception.filter.ts

@ -1,9 +1,12 @@
import { Catch, Logger, NotFoundException, Optional } from '@nestjs/common'; import { Catch, Logger, NotFoundException, Optional } from '@nestjs/common';
import { InjectSentry, SentryService } from '@ntegral/nestjs-sentry'; import { InjectSentry, SentryService } from '@ntegral/nestjs-sentry';
import { ThrottlerException } from '@nestjs/throttler'; import { ThrottlerException } from '@nestjs/throttler';
import hash from 'object-hash';
import { NcErrorType } from 'nocodb-sdk'; import { NcErrorType } from 'nocodb-sdk';
import type { ArgumentsHost, ExceptionFilter } from '@nestjs/common'; import type { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
import NocoCache from '~/cache/NocoCache';
import { CacheGetType } from '~/utils/globals';
import { import {
AjvError, AjvError,
BadRequest, BadRequest,
@ -70,12 +73,60 @@ export class GlobalExceptionFilter implements ExceptionFilter {
this.logError(exception, request); this.logError(exception, request);
if (exception instanceof ThrottlerException) { if (exception instanceof ThrottlerException) {
const key = hash({
ip: request.ip,
baseId: (request as any).ncBaseId,
workspaceId: (request as any).ncWorkspaceId,
path: request.path,
});
const cacheKey = `throttler:${key}`;
NocoCache.get(cacheKey, CacheGetType.TYPE_OBJECT)
.then((data) => {
if (!data) {
this.logger.warn(
`ThrottlerException: ${exception.message}, Path: ${
request.path
}, Workspace ID: ${(request as any).ncWorkspaceId}, Base ID: ${
(request as any).ncBaseId
}`,
);
NocoCache.setExpiring(
cacheKey,
{ value: true, count: 1, timestamp: Date.now() },
300,
).catch((err) => {
this.logger.error(err);
});
} else {
data.count += 1;
const ttlInSeconds = Math.floor(
(data.timestamp + 300000 - Date.now()) / 1000,
);
NocoCache.setExpiring(cacheKey, data, ttlInSeconds).catch((err) => {
this.logger.error(err);
});
// log every 50th request in last 5 minutes after first
if (data.count % 50 === 0) {
this.logger.warn( this.logger.warn(
`${exception.message}, Path : ${request.path}, Workspace ID : ${ `ThrottlerException: ${exception.message}, Path: ${
(request as any).ncWorkspaceId request.path
}, Project ID : ${(request as any).ncBaseId}`, }, Workspace ID: ${(request as any).ncWorkspaceId}, Base ID: ${
(request as any).ncBaseId
}, Requests in last 5 minutes: ${data.count}`,
); );
} }
}
})
.catch((err) => {
this.logger.error(err);
});
}
// if sso error then redirect to ui with error in query parameter // if sso error then redirect to ui with error in query parameter
if ( if (

Loading…
Cancel
Save