Skip to content

[COMMON]: 인프라 모니터링 워크플로우 대폭 개선 - #167

Merged
geunu97 merged 9 commits into
mainfrom
staging
Aug 31, 2026
Merged

[COMMON]: 인프라 모니터링 워크플로우 대폭 개선#167
geunu97 merged 9 commits into
mainfrom
staging

Conversation

@geunu97

@geunu97 geunu97 commented Aug 31, 2026

Copy link
Copy Markdown
Member

📋 요약

monitor-infra.yml(매일 09:00 KST 자동 실행되는 인프라 상태 Discord 리포트)에 CPU/메모리/Postgres 체크, 사내 업그레이드 가이드 기반 조언, CloudWatch/Cost Explorer 실시간 연동을 추가하고 레이아웃을 재설계했습니다.

cron 스케줄은 default 브랜치(main) 기준으로 실행되므로, 이 PR이 머지돼야 실제 매일 자동 리포트에 반영됩니다.

✨ 주요 변경사항

  • [COMMON] CPU(load 기반 근사)·메모리·Postgres(연결 수, pg_stat_statements 여부) 체크 추가, 디스크 경고 임계치를 사내 문서 기준(80%)으로 통일
  • [COMMON] 인스턴스 타입·ID를 IMDS로 조회해 리포트에 표시
  • [COMMON] "업그레이드 가이드" 필드 추가 — 사내 5단계 사다리(EC2 단일 → 인스턴스 확장 → RDS → ALB+ASG → Redis) 기준으로, 디스크/CPU/메모리는 임계치 초과 시 조건부 경고, 이후 단계는 사업 판단 필요로 고정 안내
  • [COMMON] CloudWatch(EC2 CPU 3시간 평균/최대, SSH 무관 교차검증)·Cost Explorer(이번 달 누적 비용) 실시간 연동
  • [COMMON] Discord 임베드를 인라인 배지 그리드 레이아웃으로 재설계, 소제목 기반으로 가독성 개선
  • [COMMON] staging/production EC2에 pg_stat_statements 확장 설치·활성화 (인프라 작업, 이 PR과 별개로 이미 적용됨)

🧪 테스트 계획

  • 로컬에서 정상/경고/단계혼재 등 여러 케이스로 payload JSON을 직접 생성해 검증
  • workflow_dispatch로 실제 GitHub Actions 환경에서 반복 실행, Discord 발송 성공(HTTP 204) 확인
  • CloudWatch 리전 불일치, pg_stat_statements DB 미지정 등 실행 중 발견한 버그 모두 수정 확인
  • 머지 후 다음 날 09:00 KST 정기 실행에서 최종 확인

📎 참고 사항

  • CloudWatch Agent가 설치되어 있지 않아 메모리·디스크는 CloudWatch로 못 보고 CPU만 가능합니다(SSH 기반 체크가 여전히 주 소스).
  • CloudWatch/Cost Explorer 조회는 기존 AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_REGION 시크릿을 재사용했고, 실제 권한이 있는 것까지 확인했습니다.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm

geunu97 and others added 9 commits August 31, 2026 22:18
사내 "Backend 업그레이드/모니터링" 문서(Notion)의 임계치(CPU 80%, 메모리 80~90%,
디스크 80%)를 반영합니다. 지금까지 디스크만 임계치가 있고 메모리·CPU는 숫자만
보여줄 뿐 경고 로직이 없었습니다.

- CPU: 1분 load average / vCPU 수로 근사(스냅샷, "지속" 여부는 판단 못 함 — 참고용)
- 메모리: 사용률 % 계산해서 80/90% 임계치 적용 (기존엔 숫자만 표시)
- 디스크: 경고 기준을 75% → 80%로 통일 (사내 문서 기준과 일치)
- Postgres: 서비스 active 여부, 연결 수, pg_stat_statements 설치 여부 추가
  (Redis 도입 판단 근거인 "느린 쿼리/반복 조회" 를 실제로 확인하려면 이 확장이
  필요한데 현재 staging/production 둘 다 미설치 상태 — 리포트에 노출해 인지시킴)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm
기존엔 지표만 보여주고 "그래서 뭘 해야 하는지"가 없었음. 사내 "Backend 업그레이드/모니터링"
문서(Notion)의 5단계 사다리를 반영해, 임계치로 실제 판단 가능한 것만 조건부 경고로 노출한다.

- 인스턴스 타입(t4g.small 등)을 EC2 필드 제목에 표시 (IMDSv2)
- AWS 사용 현황 필드 추가 (EC2/Route53/CloudFront+S3/Let's Encrypt — 정적 정보,
  실시간 API 조회 아님)
- 업그레이드 가이드 필드 추가:
  - 디스크 80%↑ → EBS 볼륨 증설 검토 (조건부, 실측 가능)
  - CPU/메모리 80%↑ → t4g.medium 전환 검토, 2단계 (조건부, 실측 가능)
  - RDS/ALB+ASG/Redis(3~5단계)는 사업 판단이 필요해 지표 하나로 자동 감지 불가 —
    고정 안내문으로만 노출. Redis는 pg_stat_statements 없으면 판단 근거 없음도 같이 알림

로컬에서 실제 EC2 값(t4g.small, 디스크 74/25%, 메모리 25%)과 임계치 초과 케이스 둘 다
페이로드 JSON을 직접 생성해 검증 완료.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm
기존엔 환경별로 텍스트 뭉치 2개 필드에 모든 정보를 욱여넣어 가독성이 떨어졌음.
Discord 인라인 필드를 활용한 그리드 레이아웃으로 재구성:

- 환경별 CPU/메모리/디스크, Postgres/PM2/nginx를 3열 인라인 배지로 나열 (짧은 상태만)
- 상세 수치(가동시간·메모리 용량·디스크 용량·재시작 횟수 등)는 별도 "상세" 필드로 분리
- 상단 description에 한 줄 요약("N개 항목 비정상/주의/모든 항목 정상") + 워크플로우 로그 링크
- 타이틀을 🔴/🟠/🟢 신호등 색상으로 단순화
- 섹션 구분선(▬▬▬) 추가, footer에 실행 주기 표시
- 필드 24개로 Discord 임베드 한도(25개) 이내 확인

로컬에서 정상/경고 두 케이스 모두 payload JSON을 만들어 필드 개수·빈 필드 여부·
설명/footer 렌더링을 검증 완료.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm
sudo -u postgres psql를 -d 없이 실행하면 postgres 기본 DB로 접속되는데, 확장은
picake_staging_db/picake_production_db에 만들어서 리포트에 항상 "미설치"로 잘못 표시됨.
-d picake_staging_db / -d picake_production_db 지정으로 수정.

이 김에 staging/production 모두 실제로 pg_stat_statements를 설치·활성화 완료:
- postgresql16-contrib 패키지 설치 (pg_stat_statements.so가 base 패키지에 없어서
  최초 재시도 때 staging에서 짧은 다운타임 발생 — production은 순서를 바꿔 패키지
  먼저 설치 후 재시작해서 무중단으로 진행)
- shared_preload_libraries 설정 + Postgres 재시작 + CREATE EXTENSION
- 양쪽 다 health check로 정상 복구 확인

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm
기존 "AWS 사용 현황" 필드가 고정 텍스트였던 걸 실제 API 조회값으로 교체.

- 인스턴스 ID를 IMDS로 조회(EC2 gather 단계에 추가)
- 새 단계 "Gather AWS CloudWatch & Cost Explorer metrics": 기존 AWS_ACCESS_KEY_ID/
  SECRET/REGION 시크릿 재사용
  - CloudWatch: EC2 CPUUtilization 3시간 평균/최대 (SSH와 무관한 교차검증용 —
    SSH 자체가 막혀도 이 지표는 살아있음). CloudWatch Agent는 미설치라 메모리·
    디스크는 여기서 못 봄, CPU만 가능
  - Cost Explorer: 이번 달 누적 비용(us-east-1 고정 엔드포인트, 하루 지연 가능)
- 기존 IAM 키에 CloudWatch/Cost Explorer 권한이 있는지 로컬에서 확인할 방법이
  없어서(GitHub Secret 값을 알 수 없음), 권한이 없거나 데이터가 없을 때는
  에러로 전체 리포트를 깨뜨리지 않고 "조회 불가" 문구로 정상 표시되도록 방어적으로
  구현 — 실제 권한 여부는 이번 실행으로 확인

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm
리전 미지정이 원인이었고(ap-northeast-2 명시로 해결), 실제 값 확인:
staging CPU 평균 0.35%/최대 3.1%, production 평균 0.37%/최대 2.67%.
Cost Explorer도 정상 동작(이번 달 누적 $27.00).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm
여러 라운드로 자체 검토하며 실제 발견한 문제들을 수정:

- (버그) 업그레이드 가이드의 "현재 단계"에 t4g.small이 하드코딩되어 있어서,
  실제로 인스턴스를 업그레이드해도 텍스트가 갱신 안 되는 문제 → 실제 조회값 사용
- (버그) "현재 단계"가 staging 인스턴스 타입만 참조해서, production만 먼저
  업그레이드된 경우(현실적으로 흔한 시나리오) 잘못된 단계를 표시 → 환경별로 분리 표시
- (버그) 같은 이유로 "AWS 사용 현황"의 EC2 타입 표기도 staging 타입만 반영 →
  두 환경이 다르면 각각, 같으면 "타입 × 2"로 표시
- (개선) CPU/메모리 부하 경고 문구가 항상 "t4g.medium 전환 검토"였는데, 이미
  2단계(medium)인데도 부하가 높은 경우 이 조언이 틀림 → 단계별로 다른 조언
  (1단계면 medium 전환, 2단계 이상이면 구조 확장 검토)
- (가독성) "업그레이드 가이드"·"AWS 사용 현황" 필드를 소제목(**bold**)과 빈 줄로
  구획을 나눠 한 문단에 다 욱여넣던 걸 스캔하기 쉽게 재구성
- (가독성) 파일 상단 설명 주석이 CloudWatch/Cost Explorer/업그레이드 가이드 추가를
  반영 안 하고 있어서 최신화

로컬에서 정상/경고/단계혼재(staging·production 인스턴스 타입이 다른 경우)/이미
2단계인 경우까지 각 케이스별로 payload JSON을 직접 생성해 검증 완료.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BBrpN6Agny3skLGBXgofpm
@geunu97 geunu97 self-assigned this Aug 31, 2026
@geunu97
geunu97 merged commit 2ec7ad4 into main Aug 31, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant