- 루트 디렉토리의 트러블슈팅 문서들을 troubleshooting 폴더로 이동 - rb8001 일일 요약 크론잡 실패 분석 문서에 OAuth 토큰 검증 결과 추가 - 토큰 만료 상태 상세 확인 (모든 토큰 24시간 이상 만료) - auth-server 정상 작동 확인 - 자동 갱신 실패 원인 분석 섹션 추가
9.0 KiB
9.0 KiB
rb8001 일일 요약 크론잡 실패 분석
작성일: 2025-08-24
작성자: 서버 관리자 with Claude
영향 서버: 51123(Gateway) → 51124(rb8001, skill-email)
1. 문제 개요
1.1 증상
- 발생 시간: 매일 오전 9시 (KST)
- 영향: 사용자들에게 불완전한 모닝 브리핑 전송 (이메일 요약 누락)
- 대상 사용자:
- 전희재 (U091UNVE41M)
- 김종태 (U0925SXQFDK)
- HanYong Hwang (U092F7FQ55L)
1.2 에러 메시지
Gmail token not ready for user U091UNVE41M: reauth_required
500 Internal Server Error from skill-email service
2. 시스템 아키텍처
2.1 크론잡 구성 (51123 서버)
# Gateway 컨테이너 내부 크론탭
0 9 * * * curl -X POST http://192.168.219.52:8001/api/cron/daily-summary \
-H "Content-Type: application/json" \
2>/dev/null || true # briefing
2.2 네트워크 플로우
[51123 Gateway 크론]
↓ POST 요청
[51124 rb8001:8001]
↓ 데이터 수집 (병렬)
├→ skill-news:8505 (뉴스 검색) ✅
├→ skill-email:8501 (이메일 조회) ❌ 500 에러
└→ rb10508_micro (LLM 요약) ✅
↓
[Slack API → 사용자 DM]
2.3 인증 체계
- 엔드포인트:
/api/cron/daily-summary - 인증 토큰: Bearer cron-secret-2024
- 실행 주체: Gateway 컨테이너 (51123)
3. 근본 원인 분석
3.1 skill-email 서비스 실패 (51124 서버)
데이터베이스 연결 문제
# skill-email 환경 설정
TOKEN_PROVIDER=database
DATABASE_URL=postgresql://robeings:robeings@localhost:5433/auth_db
문제점:
- auth_db 부재: 51123 서버에 auth_db 데이터베이스 없음 (main_db만 존재)
- SSH 터널 설정: 5433 포트가 51123으로 포워딩되나 DB 자체가 없음
- 토큰 조회 실패: DBCredentialsProvider가 연결 실패로 토큰 조회 불가
에러 체인
1. rb8001 → skill-email API 호출 (/messages?user_id=U091UNVE41M)
2. skill-email → PostgreSQL 연결 시도 (auth_db)
3. PostgreSQL → "database 'auth_db' does not exist" 에러
4. skill-email → "reauth_required" 폴백 응답
5. rb8001 → 500 Internal Server Error 수신
3.2 추가 이슈
datetime import 누락
# rb8001/main.py 에러
NameError: name 'datetime' is not defined
슬랙 워크스페이스 불일치
- 현재 등록: T035VFRKCN6 (GoodGang Labs)
- 필요한 것: T0925SXPS4D (미등록)
4. 실행 프로세스 상세
4.1 정상 동작 시나리오
- 09:00:00 - Gateway 크론 트리거
- 09:00:01 - rb8001
/api/cron/daily-summary호출 - 09:00:02 - 병렬 데이터 수집 시작
- 뉴스: AI 키워드로 최신 뉴스 5개
- 이메일: 사용자별 최근 이메일 5개
- 09:00:05 - LLM 요약 생성
- 09:00:07 - Slack DM 전송
4.2 현재 실패 시나리오
- 09:00:00 - Gateway 크론 트리거 ✅
- 09:00:01 - rb8001 엔드포인트 호출 ✅
- 09:00:02 - 데이터 수집 시작
- 뉴스: 성공 ✅
- 이메일: 실패 ❌ (500 에러)
- 09:00:03 - 부분적 요약 생성 (뉴스만)
- 09:00:04 - 불완전한 DM 전송
5. 해결 방안
5.1 즉시 조치 (임시)
# skill-email 환경 변경 (database → file 모드)
cd /home/admin/ivada_project/skill_email
vi .env
# TOKEN_PROVIDER=file 로 변경
# 서비스 재시작
docker compose down && docker compose up -d --build
5.2 근본 해결
옵션 1: auth_db → main_db 마이그레이션
# skill-email .env 수정
DATABASE_URL=postgresql://robeings:robeings@localhost:5433/main_db
# gmail_tokens 테이블이 main_db에 이미 존재하므로 정상 작동 예상
옵션 2: 51123 서버 직접 연결
# SSH 터널 대신 직접 연결
DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db
옵션 3: rb8001 내장 이메일 기능 사용
- rb8001에 이미 통합된 email_integration.py 활용
- skill-email 의존성 제거
5.3 코드 수정 필요
# rb8001/main.py 상단에 추가
import datetime
# 또는
from datetime import datetime
6. 검증 방법
6.1 수동 테스트
# skill-email 직접 테스트
curl -X GET http://localhost:8501/messages?user_id=U091UNVE41M \
-H "Authorization: Bearer test-token"
# rb8001 크론 엔드포인트 테스트
curl -X POST http://localhost:8001/api/cron/daily-summary \
-H "Authorization: Bearer cron-secret-2024"
6.2 로그 확인
# skill-email 로그
docker logs skill-email --tail 50
# rb8001 로그
docker logs rb8001 --tail 50
# Gateway 로그 (크론 실행 확인)
docker exec robeing-gateway tail -f /var/log/cron.log
7. 모니터링 포인트
7.1 일일 체크리스트
- 오전 9시 크론 실행 여부
- skill-email 500 에러 발생 여부
- Slack DM 정상 수신 여부
- 이메일 요약 포함 여부
7.2 알람 설정 권장
# 크론 실패 시 알람
0 9 * * * curl ... || echo "Cron failed" | mail -s "Alert" admin@example.com
8. 교훈 및 개선사항
8.1 아키텍처 개선
- 환경 일관성: 모든 서비스가 동일한 DB 사용 (main_db)
- 의존성 최소화: 단일 서비스 장애가 전체 기능 마비 방지
- 폴백 메커니즘: 이메일 실패 시에도 기본 브리핑 전송
8.2 운영 개선
- 헬스체크 강화: 각 마이크로서비스 상태 모니터링
- 에러 핸들링: graceful degradation 구현
- 로그 중앙화: 분산 서비스 로그 통합 관리
8.3 문서화
- 시스템 다이어그램: 서비스 간 의존성 명확화
- 환경변수 문서: 각 서비스별 필수 설정 문서화
- 트러블슈팅 가이드: 일반적인 문제 해결 방법 정리
9. 관련 파일
51123 서버
/home/admin/robeing-gateway/entrypoint.sh- 크론 시작/home/admin/robeing-gateway/Dockerfile- 크론 설치
51124 서버
/home/admin/ivada_project/rb8001/main.py- 크론 엔드포인트/home/admin/ivada_project/rb8001/app/cron/daily_summary.py- 요약 로직/home/admin/ivada_project/skill_email/.env- DB 설정/home/admin/ivada_project/skill_email/services/gmail_service.py- Gmail 서비스
10. 현재 상태 (2025-08-25 00:20 업데이트)
확인 사항
- Gateway 크론: 정상 작동 ✅
- rb8001 서비스: 정상 작동 ✅
- skill-news: 정상 작동 ✅
- skill-email: DB 연결 성공, 토큰 데이터 없음 ⚠️
- auth_db → main_db 마이그레이션: 완료 ✅
- main_db gmail_tokens: 테이블 존재, 토큰 데이터 NULL ❌
조치 사항 (2025-08-25 00:12)
- skill-email .env 수정:
- 변경 전:
postgresql://robeings:robeings@192.168.219.45:5432/main_db - 변경 후:
postgresql://robeings:robeings@localhost:5433/main_db
- 변경 전:
- 서비스 재시작: docker compose 재빌드 완료
남은 문제
- Gmail OAuth 토큰 부재: 모든 사용자의 token_data가 NULL
- b6ea2ee0 (전희재/U091UNVE41M): token_data = NULL
- 1e16e9d5 (김종태/U0925SXQFDK): token_data = NULL
- 69ae4ea9 (HanYong Hwang/U092F7FQ55L): token_data = NULL
- 해결 필요: 사용자들이 프론트엔드에서 Gmail 재인증 필요
긴급도
- 높음: 매일 오전 9시 사용자 영향
- 현재 상태: DB 연결 문제는 해결, OAuth 토큰 재발급 필요
11. OAuth 토큰 상태 검증 (2025-08-25 00:30)
DB 검증 결과
-- 토큰 데이터 확인
SELECT username,
token_data IS NOT NULL as has_token_data,
access_token IS NOT NULL as has_access,
refresh_token IS NOT NULL as has_refresh,
expiry
FROM gmail_tokens;
결과:
| username | has_token_data | has_access | has_refresh | expiry |
|---|---|---|---|---|
| 0914eagle | false | true | true | 2025-08-23 16:04:15 |
| cdctfm | false | true | true | 2025-08-23 08:52:13 |
| happybell80 | false | true | true | 2025-08-23 08:52:11 |
토큰 만료 상태
-- 만료 시간 검증
SELECT username,
CASE WHEN expiry < NOW() THEN '만료됨' ELSE '유효함' END as status,
AGE(NOW(), expiry) as expired_since
FROM gmail_tokens;
결과:
- 0914eagle: 만료됨 (1일 8시간 전)
- cdctfm: 만료됨 (1일 15시간 전)
- happybell80: 만료됨 (1일 15시간 전)
auth-server 상태
- 컨테이너: 정상 작동 중 (32시간 운영)
- 헬스체크:
/health엔드포인트 정상 응답 - 상태: healthy
분석 결과
- token_data 필드: 모두 NULL (JSONB 필드 미사용)
- access_token/refresh_token: 별도 컬럼에 존재
- 만료 상태: 모든 토큰 24시간 이상 만료
- 자동 갱신 실패: refresh_token 있으나 자동 갱신 미작동
결론
- 문서의 "OAuth 토큰 재발급 필요" 진단 정확함
- refresh_token이 존재하나 자동 갱신 메커니즘 작동 안함
- 사용자가 프론트엔드에서 수동으로 Gmail 재인증 필요
문서 끝