Skip to content

Commit eaae26d

Browse files
committed
feat: design change
1 parent 40aa5f7 commit eaae26d

34 files changed

Lines changed: 3981 additions & 1641 deletions

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
--parameter-overrides \
5454
Environment=${{ env.ENVIRONMENT }} \
5555
FromEmailAddress=${{ secrets.FROM_EMAIL_ADDRESS }} \
56-
GeminiApiKey=${{ secrets.GEMINI_API_KEY }} \
56+
GroqApiKey=${{ secrets.GROQ_API_KEY }} \
5757
--stack-name ${{ env.STACK_NAME }} \
5858
--region ${{ env.AWS_REGION }} \
5959
--s3-bucket ${{ env.SAM_BUCKET }} \

VIEW_LOGS.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# Lambda 함수 로그 확인 가이드
2+
3+
Lambda 함수의 실행 로그를 확인하는 방법을 설명합니다.
4+
5+
## 📋 CloudWatch Logs로 로그 확인
6+
7+
### 1. AWS 콘솔에서 확인
8+
9+
1. AWS 콘솔에 로그인
10+
2. **CloudWatch** 서비스로 이동
11+
3. 왼쪽 메뉴에서 **로그 > 로그 그룹** 선택
12+
4. `/aws/lambda/fate-calculator-dev` (또는 해당 함수 이름) 로그 그룹 선택
13+
5. 최신 로그 스트림 선택
14+
6. 로그 확인
15+
16+
### 2. AWS CLI로 로그 확인
17+
18+
```bash
19+
# 최신 로그 확인
20+
aws logs tail /aws/lambda/fate-calculator-dev --follow --region ap-northeast-1
21+
22+
# 특정 시간대의 로그 확인
23+
aws logs tail /aws/lambda/fate-calculator-dev \
24+
--since 1h \
25+
--region ap-northeast-1
26+
27+
# 오류만 필터링하여 확인
28+
aws logs tail /aws/lambda/fate-calculator-dev \
29+
--filter-pattern "ERROR" \
30+
--region ap-northeast-1
31+
32+
# JSON 형식으로 출력
33+
aws logs tail /aws/lambda/fate-calculator-dev \
34+
--format short \
35+
--region ap-northeast-1 | jq
36+
```
37+
38+
### 3. 특정 로그 그룹 찾기
39+
40+
Lambda 함수 이름에 따라 로그 그룹 이름이 달라질 수 있습니다:
41+
42+
```bash
43+
# 모든 Lambda 로그 그룹 찾기
44+
aws logs describe-log-groups \
45+
--log-group-name-prefix "/aws/lambda/fate" \
46+
--region ap-northeast-1 \
47+
--query 'logGroups[*].logGroupName' \
48+
--output table
49+
```
50+
51+
일반적인 로그 그룹 이름:
52+
- `/aws/lambda/fate-stack-dev-FateCalculatorFunction-XXXXX`
53+
- `/aws/lambda/fate-calculator-dev`
54+
55+
### 4. SAM CLI로 로그 확인 (로컬 테스트용)
56+
57+
```bash
58+
# SAM 로컬 실행 시 로그 확인
59+
sam local invoke FateCalculatorFunction --event event.json --log-file log.txt
60+
61+
# 또는 실시간 로그
62+
sam local start-api 2>&1 | tee api.log
63+
```
64+
65+
## 🔍 로그에서 확인할 사항
66+
67+
### 정상 실행 시 로그
68+
69+
```
70+
Lambda 함수 실행 시작
71+
요청 파라미터: { ... }
72+
운세 계산 시작 - 카테고리: saju
73+
calculateFateWithGemini 호출: { category: 'saju', language: 'ko' }
74+
GEMINI_API_KEY 확인 완료
75+
Gemini API 호출 시작
76+
프롬프트 길이: 1234
77+
Gemini API 응답 받음, 상태 코드: 200
78+
Gemini API 응답 받음, 길이: 5678
79+
JSON 파싱 성공: [ 'fortune', 'description', 'year', ... ]
80+
결과 구조 생성 완료: [ 'category', 'fortune', 'description' ]
81+
운세 계산 완료: { ... }
82+
DynamoDB 저장 시작
83+
DynamoDB 저장 완료 - ID: xxxxx
84+
```
85+
86+
### 오류 발생 시 확인 사항
87+
88+
1. **"GEMINI_API_KEY가 설정되지 않았습니다"**
89+
- Lambda 함수 환경 변수 확인
90+
- CloudFormation 템플릿의 `GeminiApiKey` 파라미터 확인
91+
92+
2. **"Gemini API 오류: 400" 또는 "401"**
93+
- API 키가 유효한지 확인
94+
- API 키 사용량/할당량 확인
95+
96+
3. **"JSON 파싱 실패"**
97+
- Gemini API 응답 형식 확인
98+
- 응답 내용 로그 확인
99+
100+
4. **"DynamoDB 저장 실패"**
101+
- DynamoDB 테이블 존재 확인
102+
- IAM 권한 확인
103+
104+
## 🛠️ 로그 레벨 조정
105+
106+
현재 코드에는 `console.log`를 사용하여 로그를 남기고 있습니다.
107+
108+
프로덕션에서는 불필요한 로그를 줄이기 위해:
109+
110+
1. 중요한 오류만 로그 남기기
111+
2. 환경 변수로 로그 레벨 제어
112+
3. CloudWatch Logs Insights 사용
113+
114+
## 📊 CloudWatch Logs Insights 사용
115+
116+
복잡한 로그 분석이 필요한 경우:
117+
118+
```bash
119+
# CloudWatch Logs Insights 쿼리 예시
120+
aws logs start-query \
121+
--log-group-name /aws/lambda/fate-calculator-dev \
122+
--start-time $(date -u -d '1 hour ago' +%s) \
123+
--end-time $(date -u +%s) \
124+
--query-string 'fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc' \
125+
--region ap-northeast-1
126+
```
127+
128+
또는 AWS 콘솔에서:
129+
1. CloudWatch > 로그 > 인사이트
130+
2. 로그 그룹 선택
131+
3. 쿼리 작성 및 실행
132+
133+
## ⚡ 빠른 문제 해결 명령어
134+
135+
```bash
136+
# 최근 1시간의 모든 로그 확인
137+
aws logs tail /aws/lambda/fate-calculator-dev --since 1h --region ap-northeast-1
138+
139+
# 최근 오류만 확인
140+
aws logs tail /aws/lambda/fate-calculator-dev \
141+
--since 1h \
142+
--filter-pattern "ERROR" \
143+
--region ap-northeast-1
144+
145+
# Lambda 함수 이름 확인 (CloudFormation에서)
146+
aws cloudformation describe-stack-resources \
147+
--stack-name fate-stack-dev \
148+
--logical-resource-id FateCalculatorFunction \
149+
--region ap-northeast-1 \
150+
--query 'StackResources[0].PhysicalResourceId' \
151+
--output text
152+
```
153+
154+
## 📝 참고
155+
156+
- CloudWatch Logs는 24시간 후부터 보관 기간에 따라 비용이 발생할 수 있습니다
157+
- Lambda 함수 실행 시간이 3초를 넘으면 타임아웃 오류가 발생할 수 있습니다
158+
- 로그는 최대 15분 후에 나타날 수 있습니다 (CloudWatch 지연)

aws/cloudformation/template.yaml

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ Parameters:
2020
Description: '답장 받을 이메일 주소 (선택사항). 비워두면 FromEmailAddress 사용'
2121
AllowedPattern: '^$|^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
2222

23-
GeminiApiKey:
23+
GroqApiKey:
2424
Type: String
2525
Default: ''
26-
Description: 'Google Gemini API 키 (Gemini API 사용 시 필수)'
26+
Description: 'Groq API 키 (Groq API 사용 시 필수)'
2727
NoEcho: true
2828

2929
Conditions:
@@ -33,15 +33,27 @@ Conditions:
3333
- !Not [!Equals [!Ref ReplyToEmailAddress, '']]
3434

3535
Resources:
36+
# Lambda 함수: 회원가입 자동 확인 (이메일 인증 없이 바로 사용 가능)
37+
# UserPool보다 먼저 정의해야 함 (참조 순서 문제)
38+
AutoConfirmUserFunction:
39+
Type: AWS::Serverless::Function
40+
Properties:
41+
FunctionName: !Sub 'auto-confirm-user-${Environment}'
42+
CodeUri: ../lambda/auto-confirm-user
43+
Handler: index.handler
44+
Runtime: nodejs18.x
45+
# Pre Sign-up Trigger에서는 autoConfirmUser만 설정하면 되므로 추가 권한 불필요
46+
3647
# Cognito User Pool
3748
UserPool:
3849
Type: AWS::Cognito::UserPool
50+
DependsOn: AutoConfirmUserFunction
3951
Properties:
4052
UserPoolName: !Sub 'fate-user-pool-${Environment}'
41-
AutoVerifiedAttributes:
42-
- email
53+
# 이메일 인증 없이 바로 사용 가능하도록 설정
4354
UsernameAttributes:
4455
- email
56+
AutoVerifiedAttributes: []
4557
Schema:
4658
- Name: email
4759
Required: true
@@ -54,25 +66,33 @@ Resources:
5466
Required: false
5567
Mutable: true
5668
UserAttributeUpdateSettings:
57-
AttributesRequireVerificationBeforeUpdate:
58-
- email
69+
AttributesRequireVerificationBeforeUpdate: []
5970
Policies:
6071
PasswordPolicy:
6172
MinimumLength: 8
6273
RequireUppercase: true
6374
RequireLowercase: true
6475
RequireNumbers: true
6576
RequireSymbols: false
66-
EmailConfiguration: !If
67-
- UseSES
68-
- EmailSendingAccount: DEVELOPER
69-
SourceArn: !Sub 'arn:aws:ses:${AWS::Region}:${AWS::AccountId}:identity/${FromEmailAddress}'
70-
From: !Ref FromEmailAddress
71-
ReplyToEmailAddress: !If
72-
- HasReplyTo
73-
- !Ref ReplyToEmailAddress
74-
- !Ref FromEmailAddress
75-
- !Ref 'AWS::NoValue'
77+
# 이메일 인증 없이 바로 사용 가능하도록 설정
78+
# Lambda Trigger를 통한 자동 계정 활성화
79+
LambdaConfig:
80+
PreSignUp: !GetAtt AutoConfirmUserFunction.Arn
81+
# VerificationMessageTemplate 제거 - 이메일 인증이 필요하지 않음
82+
# AdminCreateUserConfig 제거 - 기본 설정 사용
83+
84+
# Lambda Permission: Cognito User Pool이 Lambda 함수를 호출할 수 있도록 권한 부여
85+
# UserPool 생성 후에 설정해야 함 (순환 참조 방지)
86+
AutoConfirmUserFunctionPermission:
87+
Type: AWS::Lambda::Permission
88+
DependsOn:
89+
- UserPool
90+
- AutoConfirmUserFunction
91+
Properties:
92+
FunctionName: !Ref AutoConfirmUserFunction
93+
Principal: cognito-idp.amazonaws.com
94+
Action: lambda:InvokeFunction
95+
SourceArn: !GetAtt UserPool.Arn
7696

7797
# Cognito User Pool Client
7898
UserPoolClient:
@@ -176,6 +196,7 @@ Resources:
176196
AllowMethods: "'GET,POST,OPTIONS'"
177197
AllowHeaders: "'Content-Type,Authorization'"
178198
AllowOrigin: "'*'"
199+
# 참고: 504 오류 시 CORS 헤더는 Lambda 함수의 응답에서 처리됩니다.
179200

180201
# Lambda 함수: 사주 계산
181202
FateCalculatorFunction:
@@ -185,10 +206,12 @@ Resources:
185206
CodeUri: ../lambda/fate-calculator
186207
Handler: index.handler
187208
Runtime: nodejs18.x
209+
Timeout: 29
210+
MemorySize: 1024
188211
Environment:
189212
Variables:
190213
FATE_TABLE_NAME: !Ref FateTable
191-
GEMINI_API_KEY: !Ref GeminiApiKey
214+
GROQ_API_KEY: !Ref GroqApiKey
192215
Policies:
193216
- DynamoDBCrudPolicy:
194217
TableName: !Ref FateTable
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
exports.handler = async (event) => {
2+
console.log('Auto confirm user event:', JSON.stringify(event, null, 2));
3+
4+
// Pre Sign-up Trigger: 회원가입 전에 계정을 자동으로 확인
5+
if (event.triggerSource === 'PreSignUp_SignUp' || event.triggerSource === 'PreSignUp_AdminCreateUser') {
6+
// 이메일 인증 없이 바로 사용 가능하도록 설정
7+
event.response = {
8+
...event.response,
9+
autoConfirmUser: true,
10+
autoVerifyEmail: true,
11+
autoVerifyPhone: false
12+
};
13+
14+
console.log('Auto confirming user:', event.userName);
15+
console.log('Event response:', JSON.stringify(event.response, null, 2));
16+
return event;
17+
}
18+
19+
// Post Confirmation Trigger: 이미 확인된 상태이므로 그대로 반환
20+
if (event.triggerSource === 'PostConfirmation_ConfirmSignUp') {
21+
console.log('User already confirmed:', event.userName);
22+
return event;
23+
}
24+
25+
console.log('Unhandled trigger source:', event.triggerSource);
26+
return event;
27+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "auto-confirm-user",
3+
"version": "1.0.0",
4+
"description": "Lambda function to auto-confirm Cognito users",
5+
"main": "index.js",
6+
"dependencies": {
7+
"aws-sdk": "^2.1691.0"
8+
}
9+
}

0 commit comments

Comments
 (0)