mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
feat: exception logger (#4059)
This commit is contained in:
@@ -3,7 +3,7 @@ import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
import { ConfigModule } from './config';
|
||||
import { MetricsModule } from './metrics';
|
||||
import { BusinessModules } from './modules';
|
||||
import { BusinessModules, Providers } from './modules';
|
||||
import { PrismaModule } from './prisma';
|
||||
import { StorageModule } from './storage';
|
||||
import { RateLimiterModule } from './throttler';
|
||||
@@ -17,6 +17,7 @@ import { RateLimiterModule } from './throttler';
|
||||
RateLimiterModule,
|
||||
...BusinessModules,
|
||||
],
|
||||
providers: Providers,
|
||||
controllers: [AppController],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
@@ -7,7 +7,6 @@ import { Plugin } from '@nestjs/apollo';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { Response } from 'express';
|
||||
|
||||
import { OPERATION_NAME, REQUEST_ID } from '../constants';
|
||||
import { Metrics } from '../metrics/metrics';
|
||||
import { ReqContext } from '../types';
|
||||
|
||||
@@ -22,19 +21,10 @@ export class GQLLoggerPlugin implements ApolloServerPlugin {
|
||||
): Promise<GraphQLRequestListener<GraphQLRequestContext<ReqContext>>> {
|
||||
const res = reqContext.contextValue.req.res as Response;
|
||||
const operation = reqContext.request.operationName;
|
||||
const headers = reqContext.request.http?.headers;
|
||||
const requestId = headers
|
||||
? headers.get(`${REQUEST_ID}`)
|
||||
: 'Unknown Request ID';
|
||||
const operationName = headers
|
||||
? headers.get(`${OPERATION_NAME}`)
|
||||
: 'Unknown Operation Name';
|
||||
|
||||
this.metrics.gqlRequest(1, { operation });
|
||||
const timer = this.metrics.gqlTimer({ operation });
|
||||
|
||||
const requestInfo = `${REQUEST_ID}: ${requestId}, ${OPERATION_NAME}: ${operationName}`;
|
||||
|
||||
return Promise.resolve({
|
||||
willSendResponse: () => {
|
||||
const costInMilliseconds = timer() * 1000;
|
||||
@@ -42,7 +32,6 @@ export class GQLLoggerPlugin implements ApolloServerPlugin {
|
||||
'Server-Timing',
|
||||
`gql;dur=${costInMilliseconds};desc="GraphQL"`
|
||||
);
|
||||
this.logger.log(requestInfo);
|
||||
return Promise.resolve();
|
||||
},
|
||||
didEncounterErrors: () => {
|
||||
@@ -52,7 +41,6 @@ export class GQLLoggerPlugin implements ApolloServerPlugin {
|
||||
'Server-Timing',
|
||||
`gql;dur=${costInMilliseconds};desc="GraphQL ${operation}"`
|
||||
);
|
||||
this.logger.error(`${requestInfo}, query: ${reqContext.request.query}`);
|
||||
return Promise.resolve();
|
||||
},
|
||||
});
|
||||
|
||||
38
apps/server/src/middleware/exception-logger.ts
Normal file
38
apps/server/src/middleware/exception-logger.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
ArgumentsHost,
|
||||
Catch,
|
||||
ExceptionFilter,
|
||||
HttpException,
|
||||
Logger,
|
||||
} from '@nestjs/common';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
import { REQUEST_ID } from '../constants';
|
||||
|
||||
@Catch(HttpException)
|
||||
export class ExceptionLogger implements ExceptionFilter {
|
||||
private logger = new Logger('ExceptionLogger');
|
||||
|
||||
catch(exception: Error, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const request = ctx.getRequest<Request>();
|
||||
const requestId = request?.header(REQUEST_ID);
|
||||
this.logger.error(
|
||||
new Error(
|
||||
`${requestId ? `requestId-${requestId}:` : ''}${exception.message}`,
|
||||
{ cause: exception }
|
||||
),
|
||||
exception.stack
|
||||
);
|
||||
|
||||
const response = ctx.getResponse<Response>();
|
||||
if (exception instanceof HttpException) {
|
||||
response.json(exception.getResponse());
|
||||
} else {
|
||||
response.status(500).json({
|
||||
message: exception.message,
|
||||
statusCode: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import { DynamicModule, Type } from '@nestjs/common';
|
||||
import { DynamicModule, Provider, Type } from '@nestjs/common';
|
||||
import { APP_FILTER } from '@nestjs/core';
|
||||
|
||||
import { GqlModule } from '../graphql.module';
|
||||
import { ExceptionLogger } from '../middleware/exception-logger';
|
||||
import { AuthModule } from './auth';
|
||||
import { DocModule } from './doc';
|
||||
import { SyncModule } from './sync';
|
||||
@@ -8,6 +10,7 @@ import { UsersModule } from './users';
|
||||
import { WorkspaceModule } from './workspaces';
|
||||
|
||||
const { SERVER_FLAVOR } = process.env;
|
||||
const { NODE_ENV } = process.env;
|
||||
|
||||
const BusinessModules: (Type | DynamicModule)[] = [];
|
||||
|
||||
@@ -37,4 +40,13 @@ switch (SERVER_FLAVOR) {
|
||||
break;
|
||||
}
|
||||
|
||||
export { BusinessModules };
|
||||
const Providers: Provider[] = [];
|
||||
|
||||
if (NODE_ENV !== 'test') {
|
||||
Providers.push({
|
||||
provide: APP_FILTER,
|
||||
useClass: ExceptionLogger,
|
||||
});
|
||||
}
|
||||
|
||||
export { BusinessModules, Providers };
|
||||
|
||||
Reference in New Issue
Block a user