feat(P3): 5개 서비스 비즈니스 이벤트 logger.info 보강
This commit is contained in:
@@ -80,6 +80,7 @@ def extract_for_category(category: str, limit: int = KEYWORDS_PER_CATEGORY) -> L
|
|||||||
"articles_count": sum(1 for a in articles if kw["keyword"] in a["title"]),
|
"articles_count": sum(1 for a in articles if kw["keyword"] in a["title"]),
|
||||||
})
|
})
|
||||||
saved.append({"id": kid, **kw, "category": category})
|
saved.append({"id": kid, **kw, "category": category})
|
||||||
|
logger.info(f"키워드 추출 완료: category={category!r}, count={len(saved)}")
|
||||||
return saved
|
return saved
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ async def _bg_create_slate(task_id: str, keyword: str, category: str, keyword_id
|
|||||||
"submitted_at": datetime.now(kst).isoformat(),
|
"submitted_at": datetime.now(kst).isoformat(),
|
||||||
}
|
}
|
||||||
await redis_client.rpush("queue:insta-render", json.dumps(payload))
|
await redis_client.rpush("queue:insta-render", json.dumps(payload))
|
||||||
|
logger.info(f"슬레이트 생성 완료: slate_id={sid}, keyword={keyword!r}, category={category!r}")
|
||||||
# 사용자는 GET /api/insta/tasks/{task_id}로 폴링 — worker가 webhook으로 status update
|
# 사용자는 GET /api/insta/tasks/{task_id}로 폴링 — worker가 webhook으로 status update
|
||||||
db.update_task(task_id, "processing", 70, "Redis 큐 푸시 → Windows worker 대기 중", result_id=sid)
|
db.update_task(task_id, "processing", 70, "Redis 큐 푸시 → Windows worker 대기 중", result_id=sid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -219,6 +220,7 @@ async def _bg_render(task_id: str, slate_id: int):
|
|||||||
"submitted_at": datetime.now(kst).isoformat(),
|
"submitted_at": datetime.now(kst).isoformat(),
|
||||||
}
|
}
|
||||||
await redis_client.rpush("queue:insta-render", json.dumps(payload))
|
await redis_client.rpush("queue:insta-render", json.dumps(payload))
|
||||||
|
logger.info(f"렌더 큐 푸시 완료: slate_id={slate_id}, task_id={task_id}")
|
||||||
db.update_task(task_id, "processing", 30, "Redis 큐 푸시 → Windows worker 대기 중")
|
db.update_task(task_id, "processing", 30, "Redis 큐 푸시 → Windows worker 대기 중")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("queue push failed")
|
logger.exception("queue push failed")
|
||||||
|
|||||||
@@ -704,6 +704,7 @@ def api_recommend(
|
|||||||
|
|
||||||
metrics = calc_metrics(chosen)
|
metrics = calc_metrics(chosen)
|
||||||
overlap = calc_recent_overlap(chosen, draws, last_k=avoid_recent_k)
|
overlap = calc_recent_overlap(chosen, draws, last_k=avoid_recent_k)
|
||||||
|
logger.info(f"추천 생성 완료: numbers={chosen}, tries={tries}, saved={saved['saved']}")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": saved["id"],
|
"id": saved["id"],
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
"""브리핑 저장/조회 + 큐레이터 사용량 엔드포인트."""
|
"""브리핑 저장/조회 + 큐레이터 사용량 엔드포인트."""
|
||||||
|
import logging
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from .. import db
|
from .. import db
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/lotto")
|
router = APIRouter(prefix="/api/lotto")
|
||||||
|
|
||||||
|
|
||||||
@@ -38,6 +41,7 @@ class BriefingRequest(BaseModel):
|
|||||||
@router.post("/briefing", status_code=201)
|
@router.post("/briefing", status_code=201)
|
||||||
def save_briefing(body: BriefingRequest):
|
def save_briefing(body: BriefingRequest):
|
||||||
bid = db.save_briefing(body.model_dump())
|
bid = db.save_briefing(body.model_dump())
|
||||||
|
logger.info(f"브리핑 저장 완료: id={bid}, draw_no={body.draw_no}, model={body.model!r}, input_tokens={body.tokens_input}, output_tokens={body.tokens_output}")
|
||||||
return {"ok": True, "id": bid}
|
return {"ok": True, "id": bid}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import uuid
|
import uuid
|
||||||
@@ -9,6 +10,8 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from _shared.access_log import install as install_access_log
|
from _shared.access_log import install as install_access_log
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
from .db import (
|
from .db import (
|
||||||
init_db,
|
init_db,
|
||||||
create_task, get_task,
|
create_task, get_task,
|
||||||
@@ -159,9 +162,11 @@ async def generate_music(req: GenerateRequest):
|
|||||||
|
|
||||||
task_id = str(uuid.uuid4())
|
task_id = str(uuid.uuid4())
|
||||||
params = req.model_dump()
|
params = req.model_dump()
|
||||||
|
logger.info(f"음악 생성 요청: provider={provider}, title={req.title!r}, genre={req.genre!r}, task_id={task_id}")
|
||||||
create_task(task_id, params, provider=provider)
|
create_task(task_id, params, provider=provider)
|
||||||
job_type = "suno_generation" if provider == "suno" else "local_generation"
|
job_type = "suno_generation" if provider == "suno" else "local_generation"
|
||||||
await _push_render_job(task_id, job_type, params)
|
await _push_render_job(task_id, job_type, params)
|
||||||
|
logger.info(f"음악 생성 큐 푸시 완료: task_id={task_id}, job_type={job_type}")
|
||||||
return {"task_id": task_id, "provider": provider}
|
return {"task_id": task_id, "provider": provider}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -256,6 +256,7 @@ def order_stock(req: OrderRequest):
|
|||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
logger.error(f"Order Error: {resp.status_code}")
|
logger.error(f"Order Error: {resp.status_code}")
|
||||||
return JSONResponse(status_code=resp.status_code, content=resp.json())
|
return JSONResponse(status_code=resp.status_code, content=resp.json())
|
||||||
|
logger.info(f"Order Response: {req.action} {req.ticker} x{req.quantity} → OK")
|
||||||
return resp.json()
|
return resp.json()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
status = resp.status_code if resp is not None else 502
|
status = resp.status_code if resp is not None else 502
|
||||||
@@ -279,6 +280,7 @@ def ai_coach(req: AiCoachRequest):
|
|||||||
|
|
||||||
allowed_models = {"claude-haiku-4-5-20251001", "claude-sonnet-4-6"}
|
allowed_models = {"claude-haiku-4-5-20251001", "claude-sonnet-4-6"}
|
||||||
model = req.model if req.model in allowed_models else "claude-haiku-4-5-20251001"
|
model = req.model if req.model in allowed_models else "claude-haiku-4-5-20251001"
|
||||||
|
logger.info(f"AI Coach 호출: model={model}, prompt_len={len(req.prompt)}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
@@ -298,7 +300,10 @@ def ai_coach(req: AiCoachRequest):
|
|||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
logger.error(f"Anthropic API error: {resp.status_code}")
|
logger.error(f"Anthropic API error: {resp.status_code}")
|
||||||
return JSONResponse(status_code=resp.status_code, content={"error": "AI API error"})
|
return JSONResponse(status_code=resp.status_code, content={"error": "AI API error"})
|
||||||
return resp.json()
|
data = resp.json()
|
||||||
|
usage = data.get("usage", {})
|
||||||
|
logger.info(f"AI Coach 응답 완료: model={model}, input={usage.get('input_tokens', '?')}, output={usage.get('output_tokens', '?')}")
|
||||||
|
return data
|
||||||
except requests.Timeout:
|
except requests.Timeout:
|
||||||
return JSONResponse(status_code=504, content={"error": "AI API timeout"})
|
return JSONResponse(status_code=504, content={"error": "AI API timeout"})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -4,12 +4,15 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
from . import schemas
|
from . import schemas
|
||||||
from .registry import NODE_REGISTRY, GATE_REGISTRY
|
from .registry import NODE_REGISTRY, GATE_REGISTRY
|
||||||
from .. import webai_cache
|
from .. import webai_cache
|
||||||
@@ -246,6 +249,7 @@ def post_run(body: schemas.RunRequest):
|
|||||||
telegram_payload=schemas.TelegramPayload(**payload),
|
telegram_payload=schemas.TelegramPayload(**payload),
|
||||||
warnings=result.warnings,
|
warnings=result.warnings,
|
||||||
)
|
)
|
||||||
|
logger.info(f"Screener 완료: mode={body.mode}, asof={asof.isoformat()}, survivors={result.survivors_count}, top_n={top_n}")
|
||||||
# SP-A2 — preview 모드 결과 캐시 저장.
|
# SP-A2 — preview 모드 결과 캐시 저장.
|
||||||
if body.mode == "preview":
|
if body.mode == "preview":
|
||||||
webai_cache.cache_set_screener(body.mode, body.top_n, body.weights, response)
|
webai_cache.cache_set_screener(body.mode, body.top_n, body.weights, response)
|
||||||
|
|||||||
Reference in New Issue
Block a user