4.9 KiB
4.9 KiB
tags
| tags | ||||||
|---|---|---|---|---|---|---|
|
9시 네이버 이메일 분석 미전송과 실패 은닉 이슈
상위 원칙
- Infra Project Identity
- Core Infrastructure Principles
- Operational Guardrails
- 공통 작성 원칙: 0_VALUE Writing Principles
관련 문서
- Infra Journey
- 9시 네이버 이메일 분석 미전송 실패 은닉 리서치
- 24서버 실서비스 운영전환 리서치
- 51123 구 IP 하드코딩 실행 경로와 런타임 SSOT 불일치 리서치
문제 정의
- 2026-03-09 09:00 KST에 로빙의 NAVER WORKS(네이버웍스) 이메일 분석 브리핑이 전송되지 않았다.
- 그러나 스케줄러 로그에는 작업이
completed successfully로 남아 있어, 실제 실패가 성공처럼 보였다. - 이번 이슈의 본질은 "스케줄 미실행"이 아니라
rb8001 -> skill-email호출 실패가메일 없음으로 은닉되는 실행 경로 문제다.
확인된 사실
1. 9시 스케줄 자체는 정상 실행됐다
rb8001로그에는2026-03-09 09:00:00에naverworks_daily가 실행된 기록이 있다.- 같은 로그에
Running job: NAVER WORKS Daily Briefing와Starting NaverWorks briefing process for info@company-x.partners가 남아 있다. - 따라서 이번 사건은 스케줄 등록 누락이나 프로세스 다운으로 보이지 않는다.
2. 실제 실패 지점은 skill-email /messages 호출 타임아웃이다
rb8001로그에는2026-03-09 09:00:30시점httpx.ReadTimeout예외가 남아 있다.- 실패가 발생한 호출은
http://localhost:8501/messages이며, 파라미터는provider=naverworks,searchDateType=read,startSearchDate=2026-03-06T09:00:00+09:00,endSearchDate=2026-03-09T09:00:00+09:00,limit=100이다. - 따라서 오늘 미전송의 직접 원인은 메일 조회 단계의 읽기 타임아웃이다.
3. 실패 후 작업은 성공처럼 기록됐다
rb8001/app/services/skills/naverworks_briefing.py는_fetch_recent_emails()에서 예외나 비정상 응답을return []로 처리한다.- 같은 파일
process_briefing()는 빈 리스트를No emails in the last 24 hours로 처리하고 그대로 종료한다. - 그 결과 스케줄러 로그에는
NAVER WORKS Daily Briefing completed successfully가 남는다.
4. 같은 요청은 현재 시점에는 정상 응답한다
- 같은 파라미터로
http://127.0.0.1:8501/messages를 다시 호출했을 때HTTP 200, 총 응답시간 약0.61초로 정상 응답했다. - 따라서 현재는 상시 장애 상태가 아니라, 09:00 시점의 단발성 타임아웃 또는 외부 의존성 지연이 있었던 것으로 좁혀진다.
5. 당시 NAVER WORKS 토큰은 만료 상태였다
main_db.naverworks_token조회 결과, 해당 계정 토큰의expires_at는 당시2026-03-05로 남아 있었다.- 이후 수동 토큰 갱신 호출은
HTTP 200, 약0.23초에 성공했고, 현재expires_at는2026-03-09 13:59:37로 갱신됐다. - 즉 9시 시점에는 토큰 만료 상태가 실제로 존재했다.
왜 문제인가
- 실패가 성공처럼 기록되면 운영자는 "메일이 없었다"고 오인하고 실제 장애를 놓치게 된다.
- 상위 SSOT의
Truth First,광범위 예외 폴백 금지,근본 원인 직접 수정 우선원칙과 충돌한다. - 특히 외부 의존성 지연, 토큰 만료, 내부 서비스 타임아웃이 다시 발생해도 같은 방식으로 재발할 수 있다.
직접 원인
rb8001의 NAVER WORKS 브리핑 로직이skill-email조회 실패를 원인별 실패로 올리지 않고 빈 메일 목록으로 삼킨다.
근본 원인
- 브리핑 로직이
메일이 실제로 0건인 경우와메일 조회 자체가 실패한 경우를 같은 값[]로 표현하는 구조다.
우회가 아닌 해결 기준
timeout,토큰 갱신 실패,비200 응답,응답 구조 이상을메일 0건과 분리한다.- 스케줄러 실행 결과는 실패면 실패로 기록되도록 올린다.
- 로그에는
No emails가 아니라 실제 실패 원인과 단계가 남아야 한다.
완료 판단 기준
rb80019시 브리핑에서skill-email조회 실패 시 스케줄러가 실패로 기록된다.- 실제 메일 0건일 때만
No emails로그가 남는다. - 토큰 만료, 외부 API 지연, 내부 타임아웃이 발생해도 각각의 원인이 로그에서 구분된다.