Skip to main content Link Menu Expand (external link) Document Search Copy Copied

PLG(Promtail, Loki, Grafana) 기반으로 로그와 API 처리량을 같이 볼 수 있도록 대시보드를 구성해봄.

처음에는 그냥 로그만 쌓을려고했는데 좀 더 나아가서 API qps 가 튀는 시점, Redis Stream lag 이 쌓이는 시점, 슬로우 쿼리가 발생하는 시점을 같이 봐야 병목이 어디서 시작됐는지 세부 모니터링을 구성함. 따로 Datadog 이나 Sentry, 와탭을 붙이면 관리와 유지보수가 훨씬 편하겠지만 먼저 돈 안드는 grafana 로 해봄.

그래서 이번에는 로그 검색, consumer group lag, API latency, query percentile 을 한 화면에서 볼 수 있도록 정리. 장애가 났을 때 “어디서 느려졌는지” 를 빠르게 좁히기 위한 목적.

Monitoring

Coordinator monitoring

alt text

샤드별 lag 및 할당된 consumer-id, pending 된 엔트리 개수, 길이, 크기 모니터링.

여기서 중요한 건 단순히 Stream 길이만 보는게 아니라 consumer group 기준 lag 을 보는 것. Stream length 는 계속 쌓이는 전체 이벤트 수에 가깝고, 실제로 문제가 되는 건 “컨슈머가 처리하지 못하고 밀린 양”이다. 그래서 shard 별로 lag 이 튀는지 보고, 특정 consumer-id 에만 pending 이 몰리는지도 같이 확인한다.

만약 특정 shard 만 lag 이 계속 증가한다면 shard key 분포가 한쪽으로 몰렸거나, 해당 consumer 가 느려졌거나, downstream API/DB 쪽에서 병목이 발생했을 가능성이 높음.

https://redis.io/docs/latest/commands/xinfo-groups/#consumer-group-lag

Promtail Loki Grafana 로그 대시보드

alt text

Promtail 로 애플리케이션 로그를 수집하고 Loki 에 적재한 뒤 Grafana 에서 조회하도록 구성.

로그는 단순 grep 용도로만 쓰면 나중에 장애 분석할 때 너무 힘듦. API path, status, trace id, error message 같은 필드를 라벨이나 json field 로 잘 뽑아두면 특정 시간대에 qps 가 튀었을 때 바로 관련 로그로 넘어갈 수 있다.

alt text

  • jsonTreeNode 형태로 해야 백슬래쉬 안붙음
  • 문자열로 json 을 한번 더 감싸버리면 Grafana 에서 보기 힘들고, 검색 조건도 애매함.
  • 가능하면 로그를 구조화해서 남기고, message 에 모든걸 몰아넣지 않는게 좋다.

슬로우 쿼리 모니터링

슬로쿼리 모니터링으로 4초가 넘어가는 API 개선필요! validate 도 1초 넘어가서 체크.

처음에는 평균 응답시간만 보면 된다고 생각할 수 있는데, 실제로는 평균보다 p99 를 보는게 더 중요했음. 평균은 괜찮아보여도 일부 요청이 4초 이상 튀면 사용자는 이미 느리다고 느낄 수 있다. 특히 validate 처럼 자주 호출되는 API 가 1초를 넘어가기 시작하면 전체 qps 가 높아졌을 때 병목이 바로 드러난다.

slow query

p99, p90, p50 쿼리 체크.

p50 은 일반적인 요청이 어느정도인지 확인하기 좋고, p90/p99 는 tail latency 를 확인하기 좋다. 여기서 p99 만 튄다면 특정 케이스의 쿼리 조건이나 외부 의존성이 문제일 가능성이 높고, p50 부터 같이 올라간다면 전체 처리 경로 자체가 무거워졌다고 볼 수 있음.

p50, p90, p99

Maven Central publishing

maven central 0.2.0

모니터링 관련 모듈은 재사용할 수 있게 분리해서 maven central 에 배포해봄.

프로젝트마다 같은 metric/logging 코드를 복붙하면 나중에 수정할 때 너무 귀찮아짐. 그래서 공통으로 필요한 부분은 라이브러리로 분리하고, 버전만 올려서 각 서비스에서 가져다 쓰는 방식으로 정리.

그리고 redis RDB 시 메모리 예약 필요

  1. BGSAVE 실행되면 포크된 자식프로세스가 기존 메모리를 디스크에 쓰기 시작
  2. 프로세스 도중에 페이지 수정할려고하면 부모가 해당 값을 새 페이지로 복사한 뒤 수정함.

여기서 전체 페이지 수정이 들어오면 부모가 50% 를 복사해서 수정해야하니까 일단 절반을 예약으로 남겨두라고함. 하지만 실제로 50% 는 어디까지나 이론이고 실제론 운영지표와 함께 봐야하는데, INFO persistence 내 COW(Copy on Write) 를 보고 적절하게 퍼센트 설정해주면 된다.