모니터링과 로깅 시스템 구축
애플리케이션 모니터링과 로깅은 시스템의 건강 상태를 파악하고, 문제를 신속하게 진단하며, 성능을 최적화하는 데 필수적입니다.
NestJS 애플리케이션에서 효과적인 모니터링과 로깅 시스템을 구축하면 운영 효율성이 크게 향상됩니다.
모니터링과 로깅의 이점
- 실시간 성능 모니터링
- 문제 조기 발견 및 신속한 대응
- 트렌드 분석을 통한 용량 계획
- 보안 위협 탐지
- 사용자 경험 개선
Prometheus와 Grafana 기반 메트릭
- 의존성 설치
npm install @nestjs/terminus prom-client
- HealthController 구현
import { Controller, Get } from '@nestjs/common';
import { HealthCheck, HealthCheckService, HttpHealthIndicator } from '@nestjs/terminus';
@Controller('health')
export class HealthController {
constructor(
private health: HealthCheckService,
private http: HttpHealthIndicator,
) {}
@Get()
@HealthCheck()
check() {
return this.health.check([
() => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
]);
}
}
- Prometheus 메트릭 엔드포인트 설정
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { PrometheusModule } from '@nestjs/terminus';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(PrometheusModule.createMiddleware());
await app.listen(3000);
}
bootstrap();
- Grafana 대시보드 설정 : Prometheus 데이터 소스 추가 및 대시보드 생성
ELK 스택을 이용한 로그 중앙화 및 분석
- winston 로거 설정
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
@Module({
imports: [
WinstonModule.forRoot({
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'combined.log' }),
],
}),
],
})
export class AppModule {}
- Logstash 설정 (logstash.conf)
input {
file {
path => "/path/to/combined.log"
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
}
}
- Kibana에서 인덱스 패턴 생성 및 대시보드 구성
분산 추적 시스템 통합
Jaeger를 NestJS 마이크로서비스에 통합
- 의존성 설치
npm install @nestjs/opentelemetry @opentelemetry/instrumentation-http @opentelemetry/exporter-jaeger
- 추적 모듈 설정
import { Module } from '@nestjs/common';
import { OpenTelemetryModule } from '@nestjs/opentelemetry';
@Module({
imports: [
OpenTelemetryModule.forRoot({
serviceName: 'my-service',
exporter: {
type: 'jaeger',
options: {
endpoint: 'http://localhost:14268/api/traces',
},
},
}),
],
})
export class AppModule {}
클라우드 제공업체의 모니터링 서비스 적용
AWS CloudWatch 활용
- 의존성 설치
npm install aws-sdk
- CloudWatch 로거 구현
import { CloudWatchLogs } from 'aws-sdk';
const cloudWatchLogs = new CloudWatchLogs();
async function logToCloudWatch(message: string, logGroupName: string, logStreamName: string) {
await cloudWatchLogs.putLogEvents({
logGroupName,
logStreamName,
logEvents: [{ message, timestamp: Date.now() }],
}).promise();
}
APM 도구 통합
New Relic APM 통합
- 의존성 설치
npm install newrelic
- 진입점 파일 (main.ts) 수정
import 'newrelic';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
APM을 통해 얻을 수 있는 인사이트
- 트랜잭션 성능 분석
- 에러 추적 및 근본 원인 분석
- 데이터베이스 쿼리 성능
- 외부 서비스 의존성 모니터링
알림 시스템 구축
Slack을 이용한 알림 시스템
- Slack 웹훅 URL 설정
- 알림 서비스 구현
import { Injectable } from '@nestjs/common';
import axios from 'axios';
@Injectable()
export class AlertService {
private slackWebhookUrl = 'YOUR_SLACK_WEBHOOK_URL';
async sendAlert(message: string) {
await axios.post(this.slackWebhookUrl, { text: message });
}
}
- 중요 이벤트에서 알림 트리거
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
constructor(private alertService: AlertService) {}
async catch(exception: unknown, host: ArgumentsHost) {
await this.alertService.sendAlert(`Error occurred: ${exception}`);
// 추가적인 예외 처리 로직
}
}
로그 레벨 관리 및 동적 설정
- 환경 변수를 통한 로그 레벨 설정
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
WinstonModule.forRoot({
level: process.env.LOG_LEVEL || 'info',
// 기타 설정
})
- API를 통한 동적 로그 레벨 변경
@Controller('logs')
export class LogController {
constructor(private logger: Logger) {}
@Post('level')
setLogLevel(@Body() body: { level: string }) {
this.logger.setLogLevel(body.level);
return { message: `Log level set to ${body.level}` };
}
}
Best Practices 및 주의사항
- 민감한 정보 로깅 주의 : 개인정보, 비밀번호 등 마스킹 처리
- 로그 보존 정책 수립 : 법적 요구사항 및 스토리지 비용 고려
- 구조화된 로깅 : JSON 형식 사용으로 분석 용이성 증대
- 상관관계 ID 사용 : 분산 시스템에서 요청 추적 용이
- 적절한 로그 레벨 사용 : INFO, WARN, ERROR 등 상황에 맞는 레벨 선택
- 정기적인 모니터링 대시보드 리뷰 : 트렌드 분석 및 이상 징후 조기 발견
- 알림 임계값 최적화 : 과도한 알림으로 인한 피로도 방지
- 성능 영향 최소화 : 로깅 작업이 애플리케이션 성능에 미치는 영향 고려
- 로그 롤링 및 압축 : 디스크 공간 관리 및 검색 성능 최적화
- 모니터링 및 로깅 시스템 자체의 모니터링 : 메타 모니터링 구현
효과적인 모니터링과 로깅 시스템을 구축하는 것은 애플리케이션의 안정성, 성능, 그리고 운영 효율성을 크게 향상시킵니다.
Prometheus와 Grafana를 활용한 메트릭 수집 및 시각화는 실시간 성능 모니터링을 가능하게 하며, 시스템의 병목 현상이나 이상 동작을 신속하게 감지할 수 있게 해줍니다.
ELK 스택을 통한 로그 중앙화 및 분석은 분산된 시스템에서 발생하는 로그를 효과적으로 관리하고 분석할 수 있게 합니다.
이를 통해 문제의 근본 원인을 빠르게 파악하고, 트렌드를 분석하여 선제적인 대응이 가능해집니다.
분산 추적 시스템의 통합은 마이크로서비스 아키텍처에서 특히 중요합니다.
Jaeger와 같은 도구를 사용하면 서비스 간 요청 흐름을 시각화하고, 성능 병목 지점을 식별할 수 있습니다.