Skip to content

Commit

Permalink
[Server] 로거 기능 확대 (#176)
Browse files Browse the repository at this point in the history
* feat: no auth 버그 -> password 주석 해제

* feat: 로그에 한국 시간대 추가

* feat: 로그파일이 dist 내부에 존재해 한 단계 위로 옮겨줌.

* feat: 응답로그는 interceptor에서 처리하도록 로직 수정

* feat: 로그 인터셉터 app.module.ts 프로바이더에 추가
  • Loading branch information
pminsung12 authored Dec 4, 2023
1 parent 7ae37bb commit d047b41
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
6 changes: 3 additions & 3 deletions server/redis/redis.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class RedisModule {
const client = createClient({
url: process.env.REDIS_URL, // Redis 서버의 URL
// username: process.env.REDIS_USERNAME, // Redis 사용자 이름
// password: process.env.REDIS_PASSWORD, // Redis 비밀번호
password: process.env.REDIS_PASSWORD, // Redis 비밀번호
}) as RedisClientType;
await client.connect(); // 클라이언트 연결
return client; // 연결된 클라이언트 반환
Expand All @@ -36,7 +36,7 @@ export class RedisModule {
const client = createClient({
url: process.env.REDIS_URL,
// username: process.env.REDIS_USERNAME,
// password: process.env.REDIS_PASSWORD,
password: process.env.REDIS_PASSWORD,
}) as RedisClientType;
await client.connect();
return client;
Expand All @@ -52,7 +52,7 @@ export class RedisModule {
const client = createClient({
url: process.env.REDIS_URL,
// username: process.env.REDIS_USERNAME,
// password: process.env.REDIS_PASSWORD,
password: process.env.REDIS_PASSWORD,
}) as RedisClientType;
await client.connect();
return client;
Expand Down
10 changes: 9 additions & 1 deletion server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { SharedChecklistsModule } from './shared-checklists/shared-checklists.mo
import { UserModel } from './users/entities/user.entity';
import { UsersModule } from './users/users.module';
import { winstonConfig } from './utils/winston.config';
import { LoggingInterceptor } from './common/interceptor/log.interceptor';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
imports: [
Expand Down Expand Up @@ -60,7 +62,13 @@ import { winstonConfig } from './utils/winston.config';
CategoriesModule,
],
controllers: [AppController],
providers: [AppService],
providers: [
AppService,
{
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
},
],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
Expand Down
42 changes: 42 additions & 0 deletions server/src/common/interceptor/log.interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
CallHandler,
ExecutionContext,
Injectable,
NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { WinstonModule } from 'nest-winston';
import { winstonConfig } from '../../utils/winston.config';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
private readonly logger = WinstonModule.createLogger(winstonConfig);

intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const ctx = context.switchToHttp();
const request = ctx.getRequest();
const response = ctx.getResponse();
const startTime = request['startTime'];
const reqBody = request['reqBody'];

return next.handle().pipe(
tap((data) => {
const endTime = Date.now();
const duration = endTime - startTime;
const { method, originalUrl, ip } = request;
const { statusCode } = response;
const startTimeString = new Date(startTime).toLocaleString('ko-KR', {
timeZone: 'Asia/Seoul',
});

this.logger.log({
level: 'info',
message: `${startTimeString} - ${method} ${originalUrl} - Status: ${statusCode} - IP: ${ip} - Duration: ${duration}ms - Request Body: ${JSON.stringify(
reqBody,
)} - Response Body: ${JSON.stringify(data)}`,
});
}),
);
}
}
15 changes: 3 additions & 12 deletions server/src/common/middlewares/logger.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,9 @@ export class LoggerMiddleware implements NestMiddleware {
private readonly logger = WinstonModule.createLogger(winstonConfig);

use(req: Request, res: Response, next: NextFunction) {
const startTime = Date.now(); // 요청 시작 시간 기록
const { ip, method, originalUrl } = req;
const userAgent = req.get('user-agent');

res.on('finish', () => {
const duration = Date.now() - startTime; // 요청 처리 시간 계산
const { statusCode } = res;
this.logger.log({
level: 'info',
message: `${method} ${originalUrl} ${statusCode} ${ip} ${userAgent} - ${duration}ms`,
});
});
const startTime = Date.now(); // 요청 시작 시간을 현재 시간으로 설정
req['startTime'] = startTime; // startTime을 req 객체에 저장
req['reqBody'] = req.body; // 요청 본문을 req 객체에 저장

next();
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/utils/winston.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as winstonDaily from 'winston-daily-rotate-file';
import * as winston from 'winston';

const env = process.env.NODE_ENV;
const logDir = __dirname + '/../../logs'; // log 파일을 관리할 폴더
const logDir = __dirname + '/../../../logs'; // log 파일을 관리할 폴더

const dailyOptions = (level: string) => {
return {
Expand Down

0 comments on commit d047b41

Please sign in to comment.