티스토리 뷰
서버 배포와 함께 모니터링을 세팅하면서 다음과 같은 의문이 들었다.
Spring Actuator가 기본으로 제공하는 메트릭으로는 파악하기 어려운 부분을 모니터링할 수 없을까?
특히나, 외부와 상호작용하거나 통신하는 부분을 모니터링하고 싶었다. 이러한 부분들에 대한 커스텀 메트릭을 만들기로 결정하였다.
다음과 같은 부분을 타겟으로 success, failure 횟수와 소요 시간을 메트릭화 하고자 한다.
- OpenAPI
- Internal API (core <-> alarm)
- Redis Pub/Sub
모니터링을 위한 메트릭 추가를 횡단 관심사로 보았고, 각 메서드마다 이름을 주어 간편히 사용할 수 있도록 어노테이션과 AOP 기반으로 적용해보았다.
어노테이션, AOP 코드 예시
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OpenApiMonitored {
String name() default "";
}
- 위 어노테이션을 원하는 메서드에 적용하면 메트릭을 수집할 수 있게 구현했다.
- String name() 으로 지표에 이름을 동적으로 넣어주도록 하였다.
@Aspect
@Component
public class OpenApiMetricAdvice {
private final MeterRegistry meterRegistry;
private final ConcurrentHashMap<String, Counter> successCounters = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Counter> failureCounters = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Timer> timers = new ConcurrentHashMap<>();
public OpenApiMetricAdvice(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@Around("@annotation(org.example.metric.OpenApiMonitored)")
public Object monitorExecution(ProceedingJoinPoint joinPoint) throws Throwable {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
OpenApiMonitored annotation = method.getAnnotation(OpenApiMonitored.class);
String name = annotation.name();
Counter successCounter = successCounters.computeIfAbsent(
name, key -> meterRegistry.counter("api.open.success." + name, "method", key)
);
Counter failureCounter = failureCounters.computeIfAbsent(
name, key -> meterRegistry.counter("api.open.failure." + name, "method", key)
);
Timer timer = timers.computeIfAbsent(
name,
key -> Timer.builder("api.open.time." + name).tags("method", key).register(meterRegistry)
);
return MetricUtils.executeWithMetrics(timer, joinPoint, successCounter, failureCounter);
}
}
- 공통적으로 try - catch 문이 많아졌기에 MetricUtils 라는 유틸 클래스를 만들어 이를 처리하도록 코드를 개선했다.
- 그 결과, 원하는 부분마다의 메트릭이 수집됨을 확인했다.
- 위 코드의 api.open.success + name 부분을 아래와 같이 확인할 수 있었다.
- 이제 Pub/Sub 의 유실이나 OpenAPI의 응답 속도 등을 바로 확인할 수 있게 되었다.
- 성능 개선 작업 시 API Latency, 운영 시 API Status Code 분포 등을 확인하며 활용 중이다. 또한 서비스가 운영 중이므로 하드웨어 자원의 사용률, 스레드 block 여부 등등을 더 살펴보려고 한다.
PromQL을 통한 커스텀 메트릭 시각화
- 여러 레퍼런스를 참고하며 원하는 지표에 대한 PromQL을 작성해봤다.
커스텀 메트릭 시각화 예시
추가 알람 설정 작업
'프로젝트 탐구 > Showpot' 카테고리의 다른 글
조회수 카운팅 동시성 이슈 해결과 비동기 처리 (0) | 2024.12.04 |
---|---|
운영 서버 배포 사전 성능 테스트 (0) | 2024.12.04 |