Skip to content

Commit

Permalink
setting: Swagger 및 Winston 모듈 세팅 (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
RookieAND authored Apr 23, 2024
1 parent a12c90a commit 3e7ce23
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 45 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ jobs:
run: pnpm lint

- name: Run Prettier
run: pnpm prettier
run: pnpm run format
16 changes: 13 additions & 3 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { Module } from '@nestjs/common';
import {
Logger,
type MiddlewareConsumer,
Module,
NestModule,
} from '@nestjs/common';

import { LoggerMiddleware } from '#/middlewares/logger.middleware';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
controllers: [AppController],
providers: [AppService],
providers: [AppService, Logger],
})
export class AppModule {}
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
}
58 changes: 19 additions & 39 deletions src/configs/logger.config.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,23 @@
import { LoggerService } from '@nestjs/common';

import { utilities } from 'nest-winston';
import * as winston from 'winston';

const { combine, timestamp } = winston.format;

export class WinstonLoggerService implements LoggerService {
private logger: winston.Logger;

constructor(service: string) {
this.logger = winston.createLogger({
transports: [
new winston.transports.Console({
level: 'debug',
format: combine(
import { WinstonModule, utilities } from 'nest-winston';
import { format, transports } from 'winston';

const isProduction = process.env.NODE_ENV === 'production';
const { combine, timestamp, simple, ms } = format;

export const winstonLogger = WinstonModule.createLogger({
transports: [
new transports.Console({
level: isProduction ? 'http' : 'debug',
format: isProduction
? simple()
: combine(
timestamp({ format: 'isoDateTime' }),
utilities.format.nestLike(service, {
prettyPrint: true,
ms(),
utilities.format.nestLike('dev-malssami', {
colors: true,
prettyPrint: true,
}),
),
}),
],
});
}

log(message: string) {
this.logger.log({ level: 'info', message });
}

error(message: string, errorStackTrace: string) {
this.logger.error(message, errorStackTrace);
}

warn(message: string) {
this.logger.warning(message);
}

info(message: string) {
this.logger.info(message);
}
}
}),
],
});
2 changes: 1 addition & 1 deletion src/configs/swagger.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { INestApplication } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

export function setupSwagger(app: INestApplication): void {
export function setupSwaggerModule(app: INestApplication): void {
const config = new DocumentBuilder()
.setTitle('Devminjeong-eum')
.setDescription('데브말ㅆㆍ미 | 개발 용어 발음 사전')
Expand Down
13 changes: 12 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';

import { winstonLogger } from '#/configs/logger.config';
import { setupSwaggerModule } from '#/configs/swagger.config';
import { setupExceptionFilter } from '#/middlewares/http-exception.filter';
import { AppModule } from './app.module';

async function bootstrap() {
const app = await NestFactory.create(AppModule);
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
bufferLogs: true,
logger: winstonLogger,
});

setupSwaggerModule(app);
setupExceptionFilter(app);

await app.listen(8080);
}
bootstrap();
45 changes: 45 additions & 0 deletions src/middlewares/http-exception.filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
type ArgumentsHost,
type ExceptionFilter,
type HttpException,
HttpStatus,
INestApplication,
Logger,
} from '@nestjs/common';

import type { Request, Response } from 'express';

export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const statusCode = exception.getStatus();

const errorResponse = {
statusCode,
timestamp: new Date().toISOString(),
path: request.url,
method: request.method,
};

switch (statusCode) {
case HttpStatus.INTERNAL_SERVER_ERROR: {
Logger.error(
'SERVER Error',
JSON.stringify(errorResponse),
exception.stack,
);
}
default: {
Logger.warn('HTTP Error', JSON.stringify(errorResponse));
}
}

response.status(statusCode).json(errorResponse);
}
}

export const setupExceptionFilter = (app: INestApplication) => {
app.useGlobalFilters(new HttpExceptionFilter());
};
31 changes: 31 additions & 0 deletions src/middlewares/logger.middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
Inject,
Injectable,
Logger,
LoggerService,
NestMiddleware,
} from '@nestjs/common';

import type { NextFunction, Request, Response } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
constructor(@Inject(Logger) private readonly logger: LoggerService) {}

use(request: Request, response: Response, next: NextFunction) {
const { method, url, query, body } = request;
const { statusCode } = response;

this.logger.log(
JSON.stringify({
statusCode,
method,
url,
query,
body,
}),
);

next();
}
}

0 comments on commit 3e7ce23

Please # to comment.