P2: print→logging 전환, 포트폴리오 중복 제거, Docker healthcheck 추가

- backend/main.py: logging 모듈 도입, print() 제거
- stock-lab/main.py: print() → logger 전환, _calc_portfolio_totals 공용 함수 추출
- stock-lab/scraper.py: logging 모듈 도입, print() 제거
- docker-compose.yml: 전 서비스 healthcheck 블록 추가 (30s 간격, 3회 재시도)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-03 01:45:39 +09:00
parent 6a1a2c4552
commit 819c35adfc
4 changed files with 58 additions and 17 deletions

View File

@@ -66,10 +66,22 @@ def is_market_open(d: date_type) -> bool:
return d.weekday() < 5 and d.strftime("%Y-%m-%d") not in _HOLIDAYS
def _calc_portfolio_totals(items, prices):
"""포트폴리오 총 매입/평가금 계산 (snapshot과 API에서 공용)"""
total_buy = 0
total_eval = 0
for item in items:
buy_amount = item["avg_price"] * item["quantity"]
current_price = prices.get(item["ticker"], item["avg_price"])
total_buy += buy_amount
total_eval += current_price * item["quantity"]
return total_buy, total_eval
def save_daily_snapshot():
today = date_type.today()
if not is_market_open(today):
print(f"[Snapshot] {today} 휴장일 — 스킵")
logger.info(f"Snapshot: {today} 휴장일 — 스킵")
return
today_str = today.strftime("%Y-%m-%d")
@@ -80,16 +92,13 @@ def save_daily_snapshot():
if items:
tickers = list({item["ticker"] for item in items})
prices = get_current_prices(tickers)
total_eval = sum(
prices.get(item["ticker"], item["avg_price"]) * item["quantity"]
for item in items
)
_, total_eval = _calc_portfolio_totals(items, prices)
else:
total_eval = 0
total_assets = total_eval + total_cash
upsert_asset_snapshot(today_str, total_eval, total_cash, total_assets)
print(f"[Snapshot] {today_str} 저장 완료: eval={total_eval}, cash={total_cash}, total={total_assets}")
logger.info(f"Snapshot: {today_str} 저장 eval={total_eval}, cash={total_cash}, total={total_assets}")
@app.on_event("startup")
def on_startup():
@@ -108,7 +117,7 @@ def on_startup():
scheduler.start()
def run_scraping_job():
print("[StockLab] Starting news scraping...")
logger.info("뉴스 스크래핑 시작")
# 1. 국내
articles_kr = fetch_market_news()
@@ -119,7 +128,7 @@ def run_scraping_job():
# count_world = save_articles(articles_world)
count_world = 0
print(f"[StockLab] Saved {count_kr} domestic, {count_world} overseas articles.")
logger.info(f"스크래핑 완료: 국내 {count_kr}건, 해외 {count_world}")
@app.get("/health")
def health():