본문으로 건너뛰기

MetricsLoggerService

개요

MetricsLoggerService는 CoreLoggingModule에서 제공하는 메트릭 수집 전용 서비스입니다. 이 서비스는 애플리케이션 전반의 메트릭을 수집하고, Prometheus 형식으로 변환하여 모니터링 시스템과의 통합을 지원합니다.

주요 기능

  1. 메트릭 수집 및 기록
  2. Prometheus 형식 지원
  3. 태그 기반 메트릭 분류
  4. 다양한 메트릭 타입 지원 (gauge, counter, histogram)

사용 방법

1. 서비스 주입

@Injectable()
class SampleService {
constructor(private readonly metrics: MetricsLoggerService) {}
}

2. 메트릭 기록

// 기본 메트릭 기록
this.metrics.record({
name: 'metric.name', // 메트릭 이름
value: 123, // 메트릭 값
tags: { // 메트릭 태그 (레이블)
module: 'ModuleName',
operation: 'OperationName'
}
});

메트릭 타입

interface MetricTypes {
// 단순 값 측정 (게이지)
gauge: {
value: number;
help: string;
};

// 누적 값 측정 (카운터)
counter: {
value: number;
help: string;
labelNames?: string[];
};

// 값 분포 측정 (히스토그램)
histogram: {
value: number;
help: string;
buckets?: number[];
labelNames?: string[];
};
}

태그 (레이블) 규칙

1. 필수 태그

  • module: 메트릭을 생성하는 모듈 이름 (필수)

2. 공통 태그

  • operation: 작업 종류
  • status: 작업 결과 상태
  • errorType: 에러 타입 (에러 발생 시)

3. 커스텀 태그

  • 각 모듈의 특성에 맞는 추가 태그 정의 가능
  • 태그 이름은 camelCase 사용
  • 값은 가능한 한 열거형으로 정의

네이밍 규칙

1. 메트릭 이름 형식

const metricNameFormat = '{domain}.{category}.{measurement}';

// 예시
const metricNames = {
REQUEST_DURATION: 'http.request.duration',
ERROR_COUNT: 'app.errors.total',
MEMORY_USAGE: 'system.memory.usage'
};

2. 네이밍 컨벤션

  • 소문자와 점(.) 사용
  • 마지막 부분은 측정 단위나 특성을 나타냄
    • count, total: 누적 개수
    • duration: 시간 측정
    • usage: 사용량
    • rate: 비율
    • status: 상태

Prometheus 통합

1. 메트릭 정의

const metricConfig = {
'http.request.duration': {
type: 'histogram',
help: 'Duration of HTTP requests',
buckets: [10, 50, 100, 200, 500, 1000]
}
};

2. 출력 형식

# HELP http_request_duration Duration of HTTP requests
# TYPE http_request_duration histogram
http_request_duration_bucket{le="10",module="HttpModule"} 100
http_request_duration_bucket{le="50",module="HttpModule"} 150
http_request_duration_sum{module="HttpModule"} 15000
http_request_duration_count{module="HttpModule"} 200

모범 사례

1. 메트릭 설계

  • 의미 있는 메트릭만 수집
  • 적절한 메트릭 타입 선택
  • 일관된 네이밍 규칙 적용
  • 필요한 태그만 사용 (과도한 카디널리티 주의)

2. 성능 고려사항

  • 고성능 작업에서는 배치 처리 사용
  • 메모리 사용량 모니터링
  • 태그 수 제한
  • 주기적인 메트릭 정리

3. 운영 관리

  • 메트릭 문서화
  • 알림 규칙 설정
  • 대시보드 구성
  • 정기적인 메트릭 검토

예시 코드

1. HTTP 요청 모니터링

@Injectable()
export class HttpMetricsInterceptor {
constructor(private readonly metrics: MetricsLoggerService) {}

intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const startTime = Date.now();

return next.handle().pipe(
tap({
next: () => this.recordMetrics('success', startTime),
error: (error) => this.recordMetrics('error', startTime, error)
})
);
}

private recordMetrics(
status: 'success' | 'error',
startTime: number,
error?: Error
): void {
const duration = Date.now() - startTime;

this.metrics.record({
name: 'http.request.duration',
value: duration,
tags: {
module: 'HttpModule',
status,
errorType: error?.name
}
});
}
}

2. 데이터베이스 쿼리 모니터링

@Injectable()
export class DatabaseMetrics {
constructor(private readonly metrics: MetricsLoggerService) {}

async recordQueryMetrics(
operation: string,
startTime: number,
success: boolean
): Promise<void> {
const duration = Date.now() - startTime;

this.metrics.record({
name: 'db.query.duration',
value: duration,
tags: {
module: 'DatabaseModule',
operation,
status: success ? 'success' : 'error'
}
});
}
}

문제 해결

1. 메트릭이 기록되지 않는 경우

  • MetricsLoggerService가 올바르게 주입되었는지 확인
  • 메트릭 이름과 태그가 올바른지 확인
  • 로깅 레벨 설정 확인

2. 성능 문제

  • 배치 처리 사용 검토
  • 불필요한 태그 제거
  • 메트릭 수집 주기 조정
  • 메모리 사용량 모니터링

3. Prometheus 통합 문제

  • 메트릭 형식 확인
  • 레이블 이름 규칙 준수 여부 확인
  • 메트릭 타입 설정 확인