Skip to content

전역 가용량 경고 로그를 알림 룰 규약에 맞춤 - #943

Open
m-a-king wants to merge 2 commits into
devfrom
fix/capacity-alert-log-format
Open

전역 가용량 경고 로그를 알림 룰 규약에 맞춤#943
m-a-king wants to merge 2 commits into
devfrom
fix/capacity-alert-log-format

Conversation

@m-a-king

@m-a-king m-a-king commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Situation

  • 아이템 등록 전역 가용량 상한과 계정 한도 통합 #935 로 전역 가용량 상한이 들어가면서 상한의 66% 도달 시 경고 로그를 남기게 했다. 그 로그를 Grafana Loki 알림 룰이 집어 Discord 로 보내는 것이 아이템 파싱 시간당 가용량 상한 (전역 load shedding) #927 의 마지막 조각이다.

  • 룰을 걸려고 기존 알림을 열어 보니, 이 repo 에는 이미 확립된 규약이 있었다. 파싱 실패 알림은 로그를 이렇게 남긴다.

    item.parse.result item=512 result=failed reason=timeout latency=8200ms
    

    고정 이벤트 키로 시작하고 나머지는 전부 키=값 이다. 룰은 |= "item.parse.result" | logfmt | __error__="" 로 집는다.

  • 아이템 등록 전역 가용량 상한과 계정 한도 통합 #935 가 남긴 로그는 그 규약이 아니었다. 한국어 산문에 값이 뒤따르는 형태라, 룰이 매칭할 앵커가 사람이 읽는 문구밖에 없었다.

    아이템 등록 전역 가용량 경고선 도달 — used=1980 threshold=1980 limit=3000 window=PT1H
    

Task

  • 알림을 걸기 전에 로그 형식을 규약에 맞춘다. 산문을 검색어로 삼는 룰을 만들면 문구를 다듬는 순간 매칭이 깨지는데, 알림이 안 울리는 것은 정상 상태와 구분되지 않아 아무도 알아채지 못한다. 죽은 알림을 안고 가게 된다.
  • 형식이 나중에 다시 흐트러지지 않도록 기계가 지키게 만든다.

Action

로그 형식 교체

로그 아이템 등록 전역 가용량 경고선 도달 — used=1980 ... item.quota.capacity.alert used=1980 threshold=1980 limit=3000 windowSeconds=3600
룰의 검색어 "전역 가용량 경고선 도달" (한국어 문구) item.quota.capacity.alert (고정 키)
문구를 고치면 알림이 조용히 죽는다 안 죽는다
Discord 메시지 "뭔가 울렸다" 까지 사용량·경고선·상한이 본문에 실린다

값이 logfmt 여야 라벨로 추출된다. 기존 파싱 실패 알림이 {{ $labels.item }}·{{ $labels.reason }} 를 문구에 넣는 것과 같은 구조다. 산문 앞머리가 붙으면 | logfmt__error__ 를 세워 룰의 __error__="" 필터에 걸러진다.

windowDuration.toString()(PT1H) 대신 초로 남긴다. logfmt 값이 숫자여야 알림에서 비교·표시가 된다.

형식을 기계가 지키게 한다

  • 이벤트 키를 상수(ItemQuotaGuard.CAPACITY_ALERT_EVENT)로 뺐다. 이 문자열은 Grafana 룰과의 계약이라 바꾸면 룰도 함께 바꿔야 하고, 안 바꾸면 알림이 죽는다.
  • 렌더된 로그 한 줄을 받아 정규식으로 형식을 고정하는 통합 테스트를 더했다. Loki 가 보는 것은 템플릿이 아니라 렌더 결과이므로 결과를 검사한다. 경고선 직전까지 카운터를 채우고 등록 1건을 태워 실제 경로에서 나온 줄을 잡는다.

사람이 읽을 문구는 어디로 가나

이 줄은 기계가 읽는 줄이므로 한국어를 뺐다. 사람이 읽을 설명은 알림 룰의 summary 가 한국어로 담는다. 기존 파싱 실패 알림도 같은 구조다.

[prod] 파싱 실패 - item 512, 사유 timeout

Result

  • negative control 로 확인했다. windowSecondsDuration 표기로 되돌리니 이 테스트만 실패하고, 실패 메시지에 window=PT1H 가 그대로 찍혔다. 산문 복귀·logfmt 이탈도 같은 정규식에 걸린다.

  • 이 PR 이 머지되면 Loki 알림 룰을 걸 수 있다. 룰은 기존 파싱 실패 알림과 같은 모양이 된다.

    sum by (environment) (count_over_time(
      {service="piki-core", environment=~"dev|prod"}
      |= "item.quota.capacity.alert" | logfmt | __error__="" [10m]))
    

    라우팅은 기존 정책 트리를 그대로 탄다. root 는 discord-prod, environment=devdiscord-dev 로 갈린다.

  • 알림 룰 자체는 Grafana 에만 있고 repo 에 체크인되어 있지 않다. 그래서 이벤트 키가 룰과 맞는지는 기계가 못 잡는다 - 이 PR 의 테스트는 "로그가 규약 형식을 유지하는가" 까지만 지킨다. 키를 바꾸려면 룰도 함께 손대야 한다.


연관 이슈

Summary by CodeRabbit

  • 개선 사항

    • 용량 경고 로그가 고정 이벤트 키와 표준화된 logfmt 형식으로 기록됩니다.
    • 경고 윈도우 정보가 읽기 쉬운 초 단위 숫자로 제공됩니다.
    • 모니터링 및 알림 시스템에서 용량 초과 경고를 더욱 일관되게 식별할 수 있습니다.
  • 테스트

    • 위시 등록 시 용량 경고 로그가 정확히 한 번 기록되는지 검증을 추가했습니다.

- #927 로 넣은 경고 로그가 한국어 산문("아이템 등록 전역 가용량 경고선 도달 — used=...")이라, Loki 알림 룰이 그 문구 자체를 검색어로 삼아야 했다. 문구를 다듬는 순간 매칭이 깨지는데 알림이 안 울리는 것은 정상 상태와 구분되지 않아 아무도 알아채지 못한다. 죽은 알림을 안고 가는 셈이라 룰을 걸기 전에 형식부터 고쳤다
- 이 repo 에 이미 돌고 있는 파싱 실패 알림의 규약을 따른다: 고정 이벤트 키(`item.parse.result`)로 시작하고 나머지는 logfmt(`키=값`). Grafana 룰이 `|= "<키>" | logfmt | __error__=""` 로 집는 구조다. 키를 확인하지 않고 사람이 읽기 좋은 문구로 쓴 것이 원래 실수였다
- 값이 logfmt 여야 라벨로 추출돼 Discord 문구에 실린다. 지금 형태로는 "뭔가 울렸다" 까지만 알 수 있고, 바꾼 뒤에는 사용량·경고선·상한이 알림 본문에 들어간다
- window 는 Duration.toString(PT1H)이 아니라 초로 남긴다. logfmt 값이 숫자여야 알림에서 비교·표시가 된다
- 이벤트 키를 상수(`ItemQuotaGuard.CAPACITY_ALERT_EVENT`)로 빼 테스트가 같은 값을 참조하게 했다. 이 문자열은 Grafana 룰과의 계약이라 바꾸면 룰도 함께 바꿔야 한다
- 렌더된 로그 한 줄을 받아 형식을 정규식으로 고정하는 통합 테스트를 더했다. Loki 가 보는 것이 렌더 결과이므로 템플릿이 아니라 결과를 검사한다. 산문 복귀·logfmt 이탈·Duration 표기 회귀가 전부 여기서 걸린다
- 검증: window 를 Duration 표기로 되돌려 보니 그 테스트만 실패하고 메시지에 `window=PT1H` 가 그대로 찍혔다
@m-a-king m-a-king added the fix 외부 가시적 결함 수정 label Aug 14, 2026
@m-a-king m-a-king self-assigned this Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3cb6e679-e2fd-411b-97a5-b5319a648e90

📥 Commits

Reviewing files that changed from the base of the PR and between 6e8389d and 573216c.

📒 Files selected for processing (2)
  • src/main/kotlin/com/depromeet/piki/common/ratelimit/ItemQuotaGuard.kt
  • src/test/kotlin/com/depromeet/piki/common/ratelimit/ItemQuotaIntegrationTest.kt

Walkthrough

전역 용량 경고 로그를 item.quota.capacity.alert 이벤트 키와 숫자형 logfmt 필드로 변경했습니다. 통합 테스트는 경고 조건의 위시 등록 성공과 WARN 로그 형식을 검증합니다.

Changes

전역 용량 경고 로그

Layer / File(s) Summary
경고 로그 형식 변경
src/main/kotlin/com/depromeet/piki/common/ratelimit/ItemQuotaGuard.kt
CAPACITY_ALERT_EVENT 상수를 추가했습니다. WARN 로그에 used, threshold, limit, windowSeconds 필드를 기록하도록 변경했습니다.
경고 로그 통합 검증
src/test/kotlin/com/depromeet/piki/common/ratelimit/ItemQuotaIntegrationTest.kt
전역 Redis 가용량이 경고선에 도달할 때 위시 등록 성공과 WARN 로그 한 건을 검증합니다. 고정 이벤트 키와 숫자형 logfmt 필드를 정규식으로 확인하고, 테스트 후 appender와 Redis 카운터를 정리합니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 57321

This localized change standardizes the capacity warning log format and adds coverage for the rendered output; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/capacity-alert-log-format

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix 외부 가시적 결함 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant