E-mail 진행사항
This commit is contained in:
parent
b2f8ae637f
commit
f30b2104f9
426
postgresql_ssh_tunnel_guide.md
Normal file
426
postgresql_ssh_tunnel_guide.md
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
# PostgreSQL SSH 터널 및 데이터베이스 접속 가이드
|
||||||
|
|
||||||
|
## 📋 목차
|
||||||
|
1. [SSH 터널 설정](#ssh-터널-설정)
|
||||||
|
2. [PostgreSQL 접속](#postgresql-접속)
|
||||||
|
3. [Python으로 DB 조회](#python으로-db-조회)
|
||||||
|
4. [주요 테이블 구조](#주요-테이블-구조)
|
||||||
|
5. [자주 사용하는 쿼리](#자주-사용하는-쿼리)
|
||||||
|
6. [문제 해결](#문제-해결)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSH 터널 설정
|
||||||
|
|
||||||
|
### 1. 현재 SSH 터널 확인
|
||||||
|
```bash
|
||||||
|
# 실행 중인 SSH 터널 확인
|
||||||
|
ps aux | grep "ssh.*5433" | grep -v grep
|
||||||
|
|
||||||
|
# 특정 포트 사용 확인
|
||||||
|
netstat -tlnp | grep 5433
|
||||||
|
lsof -i :5433
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. SSH 터널 생성
|
||||||
|
```bash
|
||||||
|
# 기본 SSH 터널 생성 (백그라운드 실행)
|
||||||
|
ssh -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51123
|
||||||
|
|
||||||
|
# StrictHostKeyChecking 비활성화 (테스트용)
|
||||||
|
ssh -o StrictHostKeyChecking=no -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51123
|
||||||
|
|
||||||
|
# 옵션 설명:
|
||||||
|
# -f : 백그라운드 실행
|
||||||
|
# -N : 원격 명령 실행하지 않음 (포트 포워딩만)
|
||||||
|
# -L : 로컬 포트 포워딩 (로컬포트:원격호스트:원격포트)
|
||||||
|
# -p : SSH 포트 지정
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. SSH 터널 종료
|
||||||
|
```bash
|
||||||
|
# 프로세스 ID 찾기
|
||||||
|
ps aux | grep "ssh.*5433"
|
||||||
|
|
||||||
|
# 프로세스 종료
|
||||||
|
sudo kill [PID]
|
||||||
|
|
||||||
|
# 또는 한 번에
|
||||||
|
sudo pkill -f "ssh.*5433"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PostgreSQL 접속
|
||||||
|
|
||||||
|
### 1. 연결 정보
|
||||||
|
```
|
||||||
|
Host: localhost (SSH 터널 사용시)
|
||||||
|
Port: 5433 (터널 로컬 포트)
|
||||||
|
Database: auth_db
|
||||||
|
Username: robeings
|
||||||
|
Password: robeings
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. psql 명령어로 접속
|
||||||
|
```bash
|
||||||
|
# psql 설치 (Ubuntu/Debian)
|
||||||
|
sudo apt-get install postgresql-client
|
||||||
|
|
||||||
|
# DB 접속
|
||||||
|
psql postgresql://robeings:robeings@localhost:5433/auth_db
|
||||||
|
|
||||||
|
# 또는
|
||||||
|
psql -h localhost -p 5433 -U robeings -d auth_db
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. psql 기본 명령어
|
||||||
|
```sql
|
||||||
|
-- 테이블 목록 보기
|
||||||
|
\dt
|
||||||
|
|
||||||
|
-- 특정 테이블 구조 보기
|
||||||
|
\d gmail_tokens
|
||||||
|
\d users
|
||||||
|
|
||||||
|
-- 데이터베이스 목록
|
||||||
|
\l
|
||||||
|
|
||||||
|
-- 현재 데이터베이스 정보
|
||||||
|
\conninfo
|
||||||
|
|
||||||
|
-- 종료
|
||||||
|
\q
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Python으로 DB 조회
|
||||||
|
|
||||||
|
### 1. 필요한 패키지 설치
|
||||||
|
```bash
|
||||||
|
pip install psycopg2-binary
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 기본 연결 및 조회
|
||||||
|
```python
|
||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
|
||||||
|
# DB 연결
|
||||||
|
conn = psycopg2.connect('postgresql://robeings:robeings@localhost:5433/auth_db')
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
# 쿼리 실행
|
||||||
|
cur.execute("SELECT * FROM users LIMIT 5")
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
print(row)
|
||||||
|
|
||||||
|
# 연결 종료
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 안전한 쿼리 실행 (파라미터 바인딩)
|
||||||
|
```python
|
||||||
|
# SQL Injection 방지를 위해 항상 파라미터 바인딩 사용
|
||||||
|
user_id = 'b6ea2ee0-a15a-5cf4-93a9-a9ca20d4c4a0'
|
||||||
|
cur.execute(
|
||||||
|
"SELECT * FROM users WHERE id = %s",
|
||||||
|
(user_id,) # 튜플로 전달
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 주요 테이블 구조
|
||||||
|
|
||||||
|
### 1. users 테이블
|
||||||
|
```sql
|
||||||
|
CREATE TABLE users (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
email VARCHAR UNIQUE,
|
||||||
|
name VARCHAR,
|
||||||
|
picture VARCHAR,
|
||||||
|
oauth_provider VARCHAR,
|
||||||
|
oauth_id VARCHAR,
|
||||||
|
is_active BOOLEAN,
|
||||||
|
created_at TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP,
|
||||||
|
last_login_at TIMESTAMP,
|
||||||
|
username VARCHAR
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. gmail_tokens 테이블
|
||||||
|
```sql
|
||||||
|
CREATE TABLE gmail_tokens (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id UUID REFERENCES users(id),
|
||||||
|
is_equipped BOOLEAN,
|
||||||
|
token_data JSONB, -- access_token, refresh_token 저장
|
||||||
|
oauth_config JSONB, -- OAuth 설정 정보
|
||||||
|
scopes JSONB, -- Gmail API 권한 목록
|
||||||
|
metadata JSONB,
|
||||||
|
expiry TIMESTAMP,
|
||||||
|
created_at TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP,
|
||||||
|
robeing_id VARCHAR, -- 로빙 ID (rb8001 등)
|
||||||
|
equipped_to VARCHAR
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 자주 사용하는 쿼리
|
||||||
|
|
||||||
|
### 1. Gmail 토큰 확인
|
||||||
|
```python
|
||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
|
||||||
|
conn = psycopg2.connect('postgresql://robeings:robeings@localhost:5433/auth_db')
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
# Gmail 토큰 상태 확인
|
||||||
|
query = """
|
||||||
|
SELECT
|
||||||
|
u.username,
|
||||||
|
u.email,
|
||||||
|
g.user_id,
|
||||||
|
g.is_equipped,
|
||||||
|
g.robeing_id,
|
||||||
|
g.token_data,
|
||||||
|
g.scopes
|
||||||
|
FROM gmail_tokens g
|
||||||
|
JOIN users u ON g.user_id = u.id
|
||||||
|
ORDER BY g.created_at DESC
|
||||||
|
"""
|
||||||
|
|
||||||
|
cur.execute(query)
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
print(f"\nUser: {row[0]} ({row[1]})")
|
||||||
|
print(f" UUID: {row[2]}")
|
||||||
|
print(f" Equipped: {row[3]}")
|
||||||
|
print(f" Robeing: {row[4]}")
|
||||||
|
|
||||||
|
token_data = row[5] if row[5] else {}
|
||||||
|
if token_data and 'access_token' in token_data:
|
||||||
|
access_token = token_data.get('access_token', '')
|
||||||
|
if access_token.startswith('ya29'):
|
||||||
|
print(f" Token: 실제 OAuth 토큰 있음")
|
||||||
|
else:
|
||||||
|
print(f" Token: 테스트 토큰")
|
||||||
|
|
||||||
|
scopes = row[6] if row[6] else []
|
||||||
|
if scopes:
|
||||||
|
print(f" Scopes: {len(scopes)}개")
|
||||||
|
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Slack User ID를 UUID로 변환
|
||||||
|
```python
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
def slack_id_to_uuid(slack_user_id):
|
||||||
|
"""Slack User ID를 일관된 UUID로 변환"""
|
||||||
|
namespace = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
|
||||||
|
return str(uuid.uuid5(namespace, slack_user_id))
|
||||||
|
|
||||||
|
# 예시
|
||||||
|
slack_id = 'U091UNVE41M'
|
||||||
|
user_uuid = slack_id_to_uuid(slack_id)
|
||||||
|
print(f"Slack ID: {slack_id}")
|
||||||
|
print(f"UUID: {user_uuid}")
|
||||||
|
# 출력: b6ea2ee0-a15a-5cf4-93a9-a9ca20d4c4a0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 사용자별 Gmail 토큰 추가/업데이트
|
||||||
|
```python
|
||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
def add_gmail_token(slack_user_id, email, access_token, refresh_token):
|
||||||
|
"""Gmail 토큰 추가 또는 업데이트"""
|
||||||
|
|
||||||
|
# Slack ID를 UUID로 변환
|
||||||
|
namespace = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
|
||||||
|
user_uuid = str(uuid.uuid5(namespace, slack_user_id))
|
||||||
|
|
||||||
|
conn = psycopg2.connect('postgresql://robeings:robeings@localhost:5433/auth_db')
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 1. users 테이블에 사용자 추가 (없으면)
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO users (id, email, username, created_at)
|
||||||
|
VALUES (%s, %s, %s, NOW())
|
||||||
|
ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email
|
||||||
|
""", (user_uuid, email, slack_user_id))
|
||||||
|
|
||||||
|
# 2. gmail_tokens 추가 또는 업데이트
|
||||||
|
token_data = {
|
||||||
|
"access_token": access_token,
|
||||||
|
"refresh_token": refresh_token,
|
||||||
|
"token_type": "Bearer"
|
||||||
|
}
|
||||||
|
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO gmail_tokens (user_id, token_data, is_equipped, robeing_id, created_at)
|
||||||
|
VALUES (%s, %s::jsonb, true, 'rb8001', NOW())
|
||||||
|
ON CONFLICT (user_id) DO UPDATE
|
||||||
|
SET token_data = EXCLUDED.token_data,
|
||||||
|
updated_at = NOW()
|
||||||
|
""", (user_uuid, json.dumps(token_data)))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
print(f"✅ Gmail 토큰 저장 완료: {email}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
conn.rollback()
|
||||||
|
print(f"❌ 오류 발생: {e}")
|
||||||
|
finally:
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 문제 해결
|
||||||
|
|
||||||
|
### 1. SSH 터널이 연결되지 않을 때
|
||||||
|
```bash
|
||||||
|
# 기존 터널 프로세스 종료
|
||||||
|
sudo pkill -f "ssh.*5433"
|
||||||
|
|
||||||
|
# 포트 사용 확인
|
||||||
|
lsof -i :5433
|
||||||
|
|
||||||
|
# 다시 연결
|
||||||
|
ssh -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51123
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. psycopg2 설치 오류
|
||||||
|
```bash
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt-get install libpq-dev python3-dev
|
||||||
|
pip install psycopg2
|
||||||
|
|
||||||
|
# 또는 바이너리 버전 사용
|
||||||
|
pip install psycopg2-binary
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. UUID 타입 오류
|
||||||
|
```python
|
||||||
|
# UUID 문자열을 PostgreSQL UUID 타입으로 변환
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
# 방법 1: 직접 캐스팅
|
||||||
|
cur.execute(
|
||||||
|
"SELECT * FROM users WHERE id = %s::uuid",
|
||||||
|
('b6ea2ee0-a15a-5cf4-93a9-a9ca20d4c4a0',)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 방법 2: uuid 객체 사용
|
||||||
|
user_uuid = uuid.UUID('b6ea2ee0-a15a-5cf4-93a9-a9ca20d4c4a0')
|
||||||
|
cur.execute(
|
||||||
|
"SELECT * FROM users WHERE id = %s",
|
||||||
|
(str(user_uuid),)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. JSONB 필드 처리
|
||||||
|
```python
|
||||||
|
import json
|
||||||
|
|
||||||
|
# JSONB 데이터 삽입
|
||||||
|
data = {"key": "value", "nested": {"field": "data"}}
|
||||||
|
cur.execute(
|
||||||
|
"INSERT INTO table_name (jsonb_column) VALUES (%s::jsonb)",
|
||||||
|
(json.dumps(data),)
|
||||||
|
)
|
||||||
|
|
||||||
|
# JSONB 데이터 조회
|
||||||
|
cur.execute("SELECT jsonb_column FROM table_name")
|
||||||
|
row = cur.fetchone()
|
||||||
|
json_data = row[0] # 자동으로 Python dict로 변환됨
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 환경 변수 설정
|
||||||
|
|
||||||
|
`.env` 파일에 추가:
|
||||||
|
```bash
|
||||||
|
# PostgreSQL Connection (SSH tunnel)
|
||||||
|
POSTGRES_CONNECTION_STRING=postgresql://robeings:robeings@localhost:5433/auth_db
|
||||||
|
|
||||||
|
# SSH Tunnel Config
|
||||||
|
SSH_HOST=124.55.18.179
|
||||||
|
SSH_PORT=51123
|
||||||
|
SSH_USER=admin
|
||||||
|
LOCAL_PORT=5433
|
||||||
|
REMOTE_PORT=5432
|
||||||
|
```
|
||||||
|
|
||||||
|
Python에서 사용:
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
conn_string = os.getenv('POSTGRES_CONNECTION_STRING')
|
||||||
|
conn = psycopg2.connect(conn_string)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 자동화 스크립트
|
||||||
|
|
||||||
|
### SSH 터널 자동 재연결 스크립트
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /home/heejae/scripts/ssh_tunnel_monitor.sh
|
||||||
|
|
||||||
|
LOCAL_PORT=5433
|
||||||
|
SSH_CMD="ssh -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51123"
|
||||||
|
|
||||||
|
# 터널이 살아있는지 확인
|
||||||
|
if ! nc -z localhost $LOCAL_PORT 2>/dev/null; then
|
||||||
|
echo "SSH tunnel is down. Restarting..."
|
||||||
|
|
||||||
|
# 기존 프로세스 종료
|
||||||
|
pkill -f "ssh.*$LOCAL_PORT"
|
||||||
|
|
||||||
|
# 새 터널 생성
|
||||||
|
$SSH_CMD
|
||||||
|
|
||||||
|
echo "SSH tunnel restarted"
|
||||||
|
else
|
||||||
|
echo "SSH tunnel is running"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
crontab에 추가 (5분마다 체크):
|
||||||
|
```bash
|
||||||
|
*/5 * * * * /home/heejae/scripts/ssh_tunnel_monitor.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 참고 링크
|
||||||
|
- [PostgreSQL 공식 문서](https://www.postgresql.org/docs/)
|
||||||
|
- [psycopg2 문서](https://www.psycopg.org/docs/)
|
||||||
|
- [SSH 터널링 가이드](https://www.ssh.com/academy/ssh/tunneling)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*마지막 업데이트: 2025-08-20*
|
||||||
196
robeing-monitor-integration.md
Normal file
196
robeing-monitor-integration.md
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
# Robeing Monitor 통합 작업 문서
|
||||||
|
|
||||||
|
## 작업 완료 사항 (2025-08-20)
|
||||||
|
|
||||||
|
### 1. UUID 변환 기능 구현
|
||||||
|
- **문제**: Slack User ID (예: U091UNVE41M)와 PostgreSQL의 UUID 형식 불일치로 인한 데이터베이스 조회 실패
|
||||||
|
- **해결**: 모든 서비스에 일관된 UUID 변환 로직 적용
|
||||||
|
```python
|
||||||
|
namespace = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
|
||||||
|
user_uuid = str(uuid.uuid5(namespace, slack_id))
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 수정된 파일들:
|
||||||
|
- `/home/heejae/robeing-monitor/app/api/items.py` - UUID 변환 헬퍼 함수 추가
|
||||||
|
- `/home/heejae/rb8001/app/skills/email_integration.py` - UUID 변환 적용
|
||||||
|
- `/home/heejae/skill-email/services/db_credentials_provider.py` - UUID 변환 적용
|
||||||
|
|
||||||
|
### 2. Robeing Monitor API 확장
|
||||||
|
- **새 엔드포인트**: `/api/items/gmail/{user_id}/token`
|
||||||
|
- skill-email이 Gmail 토큰 데이터를 가져올 수 있도록 지원
|
||||||
|
- Slack ID를 자동으로 UUID로 변환
|
||||||
|
- scopes를 JSON 배열로 파싱하여 반환
|
||||||
|
|
||||||
|
### 3. Skill-Email API Provider 구현
|
||||||
|
- **새 파일**: `/home/heejae/skill-email/services/api_credentials_provider.py`
|
||||||
|
- robeing-monitor API를 통해 Gmail 자격증명을 가져오는 Provider
|
||||||
|
- 기존 DB 직접 연결 방식을 API 호출로 대체
|
||||||
|
- Result 타입 시스템과 호환되도록 구현
|
||||||
|
|
||||||
|
### 4. 환경 설정 변경
|
||||||
|
- **skill-email/docker-compose.yml**:
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- TOKEN_PROVIDER=api
|
||||||
|
- ROBEING_MONITOR_URL=http://localhost:9024
|
||||||
|
```
|
||||||
|
- **robeing-monitor/.env**:
|
||||||
|
```
|
||||||
|
DATABASE_URL=postgresql://robeings:robeings@localhost:5433/main_db
|
||||||
|
```
|
||||||
|
|
||||||
|
## 현재 아키텍처
|
||||||
|
|
||||||
|
```
|
||||||
|
[rb8001] ─────> [skill-email] ─────> [robeing-monitor] ─────> [PostgreSQL]
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
└─ Slack ID ──────┴───── API 호출 ────────┴─── UUID 변환 ───────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 데이터 흐름:
|
||||||
|
1. rb8001이 Slack User ID로 skill-email 호출
|
||||||
|
2. skill-email이 robeing-monitor API 호출 (Slack ID 전달)
|
||||||
|
3. robeing-monitor가 Slack ID를 UUID로 변환
|
||||||
|
4. PostgreSQL에서 데이터 조회 후 반환
|
||||||
|
|
||||||
|
## 해결된 문제들
|
||||||
|
|
||||||
|
1. **UUID 타입 에러**: "invalid input syntax for type uuid: 'U091UNVE41M'"
|
||||||
|
- 모든 서비스에서 일관된 UUID 변환 적용으로 해결
|
||||||
|
|
||||||
|
2. **데이터베이스 연결 문제**:
|
||||||
|
- SSH 터널 설정 (localhost:5433 → 124.55.18.179:5432)
|
||||||
|
- 올바른 데이터베이스 이름 사용 (main_db)
|
||||||
|
|
||||||
|
3. **Scopes 파싱 문제**:
|
||||||
|
- PostgreSQL에 문자열로 저장된 scopes를 JSON 배열로 변환
|
||||||
|
|
||||||
|
## 남은 작업 사항
|
||||||
|
|
||||||
|
### 1. 토큰 갱신 메커니즘
|
||||||
|
- **현재 상태**: Gmail access token이 만료됨
|
||||||
|
- **필요 작업**:
|
||||||
|
- OAuth 재인증 플로우 구현
|
||||||
|
- Refresh token을 사용한 자동 갱신 로직
|
||||||
|
- robeing-monitor에 토큰 업데이트 API 추가
|
||||||
|
|
||||||
|
### 2. 에러 처리 개선
|
||||||
|
- **필요 작업**:
|
||||||
|
- 토큰 만료 시 사용자에게 재인증 안내
|
||||||
|
- Slack에서 "죄송합니다" 대신 구체적인 오류 메시지 표시
|
||||||
|
- 재시도 로직 구현
|
||||||
|
|
||||||
|
### 3. 모니터링 및 로깅
|
||||||
|
- **필요 작업**:
|
||||||
|
- API 호출 성공/실패 메트릭 수집
|
||||||
|
- 토큰 만료 예측 및 사전 알림
|
||||||
|
- 감사 로그 (gmail_audit_logs 테이블) 활용
|
||||||
|
|
||||||
|
### 4. 성능 최적화
|
||||||
|
- **고려 사항**:
|
||||||
|
- API 호출 캐싱
|
||||||
|
- 연결 풀링 최적화
|
||||||
|
- 불필요한 UUID 변환 최소화
|
||||||
|
|
||||||
|
## SSH 터널 및 PostgreSQL 접속
|
||||||
|
|
||||||
|
### SSH 터널 설정
|
||||||
|
```bash
|
||||||
|
# SSH 터널 시작
|
||||||
|
sshpass -p "19800508" ssh -o StrictHostKeyChecking=no -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51123
|
||||||
|
|
||||||
|
# 터널 확인
|
||||||
|
nc -zv localhost 5433
|
||||||
|
|
||||||
|
# 터널 프로세스 확인
|
||||||
|
pgrep -f "ssh.*5433:localhost:5432"
|
||||||
|
```
|
||||||
|
|
||||||
|
### PostgreSQL 접속
|
||||||
|
```bash
|
||||||
|
# SSH를 통한 원격 실행
|
||||||
|
sshpass -p "19800508" ssh -o StrictHostKeyChecking=no admin@124.55.18.179 -p 51123 "PGPASSWORD=robeings psql -h localhost -U robeings -d main_db -c 'SELECT * FROM gmail_tokens'"
|
||||||
|
|
||||||
|
# 로컬 터널을 통한 접속 (psql 클라이언트 필요)
|
||||||
|
PGPASSWORD=robeings psql -h localhost -p 5433 -U robeings -d main_db
|
||||||
|
```
|
||||||
|
|
||||||
|
### 주요 테이블
|
||||||
|
- `gmail_tokens`: Gmail OAuth 토큰 저장
|
||||||
|
- `gmail_audit_logs`: Gmail 작업 감사 로그
|
||||||
|
- `robeing_stats`: Robeing 레벨 정보
|
||||||
|
- `slack_user_mapping`: Slack-UUID 매핑 (현재 미사용)
|
||||||
|
|
||||||
|
## 테스트 명령어
|
||||||
|
|
||||||
|
### Robeing Monitor API 테스트
|
||||||
|
```bash
|
||||||
|
# Gmail 아이템 조회
|
||||||
|
curl -s http://localhost:9024/api/items/gmail -H "X-User-Id: U091UNVE41M" | python3 -m json.tool
|
||||||
|
|
||||||
|
# 토큰 데이터 조회
|
||||||
|
curl -s http://localhost:9024/api/items/gmail/U091UNVE41M/token -H "X-User-Id: U091UNVE41M" | python3 -m json.tool
|
||||||
|
```
|
||||||
|
|
||||||
|
### Skill-Email 테스트
|
||||||
|
```bash
|
||||||
|
# 이메일 전송 테스트
|
||||||
|
curl -X POST http://localhost:8501/send \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"to": "test@example.com",
|
||||||
|
"subject": "Test",
|
||||||
|
"body": "Test email",
|
||||||
|
"user_id": "U091UNVE41M"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker 관리
|
||||||
|
|
||||||
|
### Robeing Monitor
|
||||||
|
```bash
|
||||||
|
cd /home/heejae/robeing-monitor
|
||||||
|
docker compose down && docker compose up -d --build
|
||||||
|
docker logs robeing_monitor --tail 50
|
||||||
|
```
|
||||||
|
|
||||||
|
### Skill-Email
|
||||||
|
```bash
|
||||||
|
cd /home/heejae/skill-email
|
||||||
|
docker compose down && docker compose up -d --build
|
||||||
|
docker logs skill-email --tail 50
|
||||||
|
```
|
||||||
|
|
||||||
|
## 중요 참고사항
|
||||||
|
|
||||||
|
1. **UUID Namespace**: 모든 서비스에서 동일한 namespace UUID 사용 필수
|
||||||
|
- `6ba7b810-9dad-11d1-80b4-00c04fd430c8`
|
||||||
|
|
||||||
|
2. **데이터베이스**:
|
||||||
|
- 실제 데이터는 `main_db`에 저장됨
|
||||||
|
- `auth_db`는 존재하지 않음
|
||||||
|
|
||||||
|
3. **포트 정보**:
|
||||||
|
- robeing-monitor: 9024
|
||||||
|
- skill-email: 8501
|
||||||
|
- PostgreSQL (SSH tunnel): 5433
|
||||||
|
|
||||||
|
4. **환경변수 우선순위**:
|
||||||
|
- Docker 컨테이너는 .env 파일과 docker-compose.yml의 environment 섹션 모두 참조
|
||||||
|
- 재빌드 필요 시 `docker compose down && docker compose up -d --build` 실행
|
||||||
|
|
||||||
|
## 다음 단계 권장사항
|
||||||
|
|
||||||
|
1. **즉시 필요**:
|
||||||
|
- Gmail OAuth 토큰 재인증 구현
|
||||||
|
- 토큰 자동 갱신 메커니즘
|
||||||
|
|
||||||
|
2. **단기 개선**:
|
||||||
|
- 에러 메시지 개선
|
||||||
|
- 로깅 시스템 강화
|
||||||
|
|
||||||
|
3. **장기 개선**:
|
||||||
|
- 마이크로서비스 간 통신 표준화
|
||||||
|
- API Gateway 패턴 고려
|
||||||
|
- 중앙 집중식 인증/인가 시스템
|
||||||
Loading…
x
Reference in New Issue
Block a user