Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- winston
- nestjs
- javascript
- bean
- GraphQL
- Linux
- 코딩테스트
- css
- puppeteer
- 알고리즘
- JWT
- MySQL
- 프로그래머스
- REST API
- OOP
- Interceptor
- Deep Dive
- Kubernetes
- LifeCycle
- node.js
- Spring
- 인접행렬
- dfs
- TIL
- 인접리스트
- typescript
- java
- 자료구조
- 탐욕법
- html
Archives
- Today
- Total
처음부터 차근차근
[NestJS] Winston Logger Interceptor 구현 본문
728x90
이번에는 Winston을 통한 NestJS Logger Interceptor를 구현해보겠습니다.
저번에 Winston을 NestJS App에 초기 설정을 하였는데, 이 부분을 먼저 읽고 오시면 도움이 됩니다.
[NestJS] Winston Logger 초기 설정 및 Logger 사용
이번 시간에는 NestJS에 Logger를 적용해보겠습니다. GraphQL 과제에서 Logging 기능을 추가해야 되기 때문에, 공부할 겸 적용시켰습니다. Log?? 컴퓨팅에서 로그파일은 운영체제나 다른 소프트웨어가 실
hangju95.tistory.com
사용 의도
- 접속한 사람의 IP와 자주 사용하는 정보를 기록하기 위해
- brutal force 공격을 통해 접속을 많이 하는 경우 Ban 처리도 가능할 것으로 기능 구현 예정(Throttler 모듈을 통해 rate limit도 가능)
Logger Interceptor 구현
GraphQL로 Interceptor로 구현할 때는, ExecutionContext를 Gql 전용 ExecutionContext로 전환해야 하며, Guard나 Interceptor를 사용할 때는 필수적으로 적용해야 합니다.
// NestJS 공식 문서 예시
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const ctx = GqlExecutionContext.create(context);
return true;
}
}
현재 과제는 GraphQL로 구현하고 있기 때문에, gqlContext로 interceptor를 구현하였습니다.
저번 시간에 Logger를 적용하였기 때문에 이번 시간에는 Logger를 한번 불러오겠습니다.
Logger의 내용으로는 Path와 fieldName 그리고 IP와 ResponseTime을 작성하였습니다.
// src/common/interceptor/logger.interceptor.ts
import {
CallHandler,
ExecutionContext,
Injectable,
LoggerService,
NestInterceptor,
} from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
constructor(private readonly logger: LoggerService) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
// Response까지 timed 계산하기 위한 시간
const now = Date.now();
// gqlContext로 전환
const gqlContext = GqlExecutionContext.create(context);
// Ip 접근용 Context 변환
const ip = gqlContext.getContext().req.ip;
// path와 fieldName을 얻기 위한 info
const info = gqlContext.getInfo();
// tap을 통해 Response가 끝나는 경우 응답 처리 진행
return next.handle().pipe(
tap(() => {
// Response time 계산
const responseTime = Date.now() - now;
// info level로 logger 진행
this.logger.log({
// context는 path와 fieldName으로
context: `${info.path.typename}: ${info.fieldName}`,
// message는 IP 주소와 Response time으로 진행
message: `IP: ${ip} - ${responseTime}ms`,
});
}),
);
}
}
다만, 에러가 발생할 경우는 Logger를 적용시키지 않았습니다.
그것은 다음 시간 Custom Exception을 통해 구현할 예정입니다.
참고
'FrameWork > NestJS' 카테고리의 다른 글
[NestJS] Custom Exception 구현 (2) | 2023.12.03 |
---|---|
[NestJS] Winston Logger 초기 설정 및 Logger 사용 (0) | 2023.12.01 |
[NestJS] GraphQL Mutation (1) | 2023.11.30 |
[NestJS] GraphQL Resolvers (0) | 2023.11.29 |
[NestJS] NestJS에서 GraphQL 초기 설정 (1) | 2023.11.29 |