최근 node.js 기반의 백엔드 서비스를 설계 + 제작 + 운영을 위한 템플릿을 작성한적이 있다
https://loy124.tistory.com/381?category=747622
위의 방식을 그대로 따라가되 nest.js에 맞게 변경시켜보았다.
소스코드 주소
https://github.com/loy124/nestjs-backend-system
pm2로 node.js 프로세스 관리하기 - https://loy124.tistory.com/379
winston.js로 node.js 로그 관리하기 - https://loy124.tistory.com/380
위 내용을 기반으로 작성되었습니다.
프로젝트를 구상할 때 먼저 흐름도를 작성해서 어떠한 흐름으로 관리를 할지 고려해보았다.
클라이언트에 특정 IP(or 도메인)에 접근 -> 해당 nginx 80포트에 도착 -> 80포트에 도착한 nginx는 proxy를 통해 container backend(3000번 포트)에 보낸다 -> 해당 포트는 node단의 pm2에 의해 클러스터링 되어 특정 nest의 dist/main.js에 도착한다.
실행법
//docker 및 docker-compose 가 설치되어 있다는 가정하에
docker-compose up -d --build
위 명령어만 실행하면 기본 구축은 완료된다.
backend container 접근 + pm2 모니터링
docker exec -it backend sh
pm2 monit
이번엔 docker를 자동으로 재시작하기위해 shell을 작성해 두었다.
import os
import sys
import subprocess
os.system("docker exec -it backend npm run build")
os.system("docker exec -it backend pm2 reload all")
정말 간단한 쉘이지만 늘 일일히 치기는 번거로운 점이 있어 쉘을 추가하였다.
위 내용대로
docker exec -it 를 통해 nest를 한번 빌드하고
reload를 통해 새로 빌드된 코드를 적용시키는 방식을 추가하였다.
nestjs에서 loggin을 적용한 부분
일단 폴더구조는 다음과같다.
logger.ts에는 기존 express에서 작성했던 winston및 daily-roate-file을 그대로 옮겨두었다.
logger.ts
import winston from 'winston';
import 'winston-daily-rotate-file';
const { combine, timestamp, printf } = winston.format;
const customFormat = printf((info) => {
return ` ${info.timestamp} ${info.level}: ${info.message}`;
});
export const logger = winston.createLogger({
format: combine(
timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
customFormat,
),
transports: [
new winston.transports.DailyRotateFile({
level: 'info',
datePattern: 'YYYY-MM-DD',
dirname: './logs',
filename: `server_%DATE%.log`,
maxSize: '20m',
maxFiles: '7d',
zippedArchive: true,
}),
new winston.transports.DailyRotateFile({
level: 'error',
datePattern: 'YYYY-MM-DD',
dirname: './logs',
filename: `server_%DATE%.error.log`,
maxSize: '20m',
maxFiles: '7d',
zippedArchive: true,
}),
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple(),
),
}),
);
}
export const stream = {
write: (message) => {
logger.info(message);
},
};
이제 옮겨둔 ts파일을
AppLogginService.ts 에 적용시켜주었다.
import { LoggerService } from "@nestjs/common";
import { logger } from "./logger";
export class AppLoggingService implements LoggerService{
log(message: string, context: string){
logger.info(message, {
from: context
})
}
warn(message: string, context: string){
logger.warn(message, context);
}
error(message: string, trace: string, context: string){
logger.error(message, {stack:trace, context});
}
debug(message: string, context: string){
logger.debug(message, context);
}
verbose(message: string, context: string){
logger.verbose(message, context);
}
}
기본적으로 이런 Service까지 작성되었다면
app.module.ts에서 해당 로깅을 전역적으로 사용할 수 있게 하였다.
App.module.ts
import { Logger, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [ConfigModule.forRoot(),
],
controllers: [AppController],
providers: [AppService, Logger],
})
export class AppModule {}
사실 기존에 고안했던 프로젝트를 단순히 nest에 맞게 옮긴거라 제작기간은 정말 짧았으나
최근에 nestjs에 엄청난 요소들을 경험하고 이를 통해 프로젝트를 진행할예정이라 발빠르게 작성해보았다.
'프로젝트 > 미니 프로젝트' 카테고리의 다른 글
원격 로그 수집 시스템 구성하기 (elastic stack) (0) | 2022.11.17 |
---|---|
데이터 백업 시스템 구성하기 (0) | 2022.10.26 |
express + react 를 활용한 OAuth 소셜 회원가입및 로그인 진행하기 (3) express 셋팅 및 Oauth 회원가입및 로그인 설정하기 (5) | 2021.08.16 |
express + react 를 활용한 OAuth 소셜 회원가입및 로그인 진행하기 (2) Google, Kakao 소셜 회원가입 셋팅하기 (0) | 2021.08.16 |
express + react 를 활용한 OAuth 소셜 회원가입및 로그인 진행하기 (1) - 백엔드 Sequelize 연동하기 (0) | 2021.08.16 |