feat(P2): stock/music-lab/insta-lab/realestate-lab access_log 적용 + AGENT_CONTAINER_MAP 4개 매핑

This commit is contained in:
2026-05-28 08:38:36 +09:00
parent cfbb3c24b8
commit 378f5210d4
6 changed files with 41 additions and 6 deletions

View File

@@ -46,9 +46,8 @@ import re as _re
# /api/lotto 만 골라내기 위한 정규식. business log (source='log') 는 모두 통과. # /api/lotto 만 골라내기 위한 정규식. business log (source='log') 는 모두 통과.
AGENT_CONTAINER_MAP: dict[str, tuple[str, int, _re.Pattern]] = { AGENT_CONTAINER_MAP: dict[str, tuple[str, int, _re.Pattern]] = {
"lotto": ("lotto", 8000, _re.compile(r"^/api/lotto")), "lotto": ("lotto", 8000, _re.compile(r"^/api/lotto")),
# Phase 2 에서 추가: "stock": ("stock", 8000, _re.compile(r"^/api/(stock|trade|portfolio)")),
# "stock": ("stock", 8000, _re.compile(r"^/api/(stock|trade|portfolio)")), "music": ("music-lab", 8000, _re.compile(r"^/api/music")),
# "music": ("music-lab", 8000, _re.compile(r"^/api/music")), "insta": ("insta-lab", 8000, _re.compile(r"^/api/insta")),
# "insta": ("insta-lab", 8000, _re.compile(r"^/api/insta")), "realestate": ("realestate-lab", 8000, _re.compile(r"^/api/realestate")),
# "realestate": ("realestate-lab", 8000, _re.compile(r"^/api/realestate")),
} }

View File

@@ -51,8 +51,15 @@ services:
- OLLAMA_MODEL=${OLLAMA_MODEL:-qwen3:14b} - OLLAMA_MODEL=${OLLAMA_MODEL:-qwen3:14b}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080} - CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
- WEBAI_API_KEY=${WEBAI_API_KEY:-} - WEBAI_API_KEY=${WEBAI_API_KEY:-}
- PYTHONPATH=/app:/shared
volumes: volumes:
- ${RUNTIME_PATH}/data/stock:/app/data - ${RUNTIME_PATH}/data/stock:/app/data
- ${RUNTIME_PATH}/_shared:/shared/_shared:ro
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
healthcheck: healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 60s interval: 60s
@@ -86,9 +93,16 @@ services:
- REDIS_URL=${REDIS_URL:-redis://redis:6379} - REDIS_URL=${REDIS_URL:-redis://redis:6379}
- INTERNAL_API_KEY=${INTERNAL_API_KEY:-} - INTERNAL_API_KEY=${INTERNAL_API_KEY:-}
- MUSIC_RENDER_URL=${MUSIC_RENDER_URL:-http://192.168.45.59:18711} - MUSIC_RENDER_URL=${MUSIC_RENDER_URL:-http://192.168.45.59:18711}
- PYTHONPATH=/app:/shared
volumes: volumes:
- ${RUNTIME_PATH}/data/music:/app/data - ${RUNTIME_PATH}/data/music:/app/data
- ${RUNTIME_PATH:-.}/data/videos:/app/data/videos - ${RUNTIME_PATH:-.}/data/videos:/app/data/videos
- ${RUNTIME_PATH}/_shared:/shared/_shared:ro
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
depends_on: depends_on:
- redis - redis
healthcheck: healthcheck:
@@ -163,8 +177,15 @@ services:
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080} - CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
- REDIS_URL=${REDIS_URL:-redis://redis:6379} - REDIS_URL=${REDIS_URL:-redis://redis:6379}
- INTERNAL_API_KEY=${INTERNAL_API_KEY:-} - INTERNAL_API_KEY=${INTERNAL_API_KEY:-}
- PYTHONPATH=/app:/shared
volumes: volumes:
- ${RUNTIME_PATH}/data/insta:/app/data - ${RUNTIME_PATH}/data/insta:/app/data
- ${RUNTIME_PATH}/_shared:/shared/_shared:ro
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
depends_on: depends_on:
- redis - redis
healthcheck: healthcheck:
@@ -185,8 +206,15 @@ services:
- DATA_GO_KR_API_KEY=${DATA_GO_KR_API_KEY:-} - DATA_GO_KR_API_KEY=${DATA_GO_KR_API_KEY:-}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080} - CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
- AGENT_OFFICE_URL=${AGENT_OFFICE_URL:-http://agent-office:8000} - AGENT_OFFICE_URL=${AGENT_OFFICE_URL:-http://agent-office:8000}
- PYTHONPATH=/app:/shared
volumes: volumes:
- ${RUNTIME_PATH}/data/realestate:/app/data - ${RUNTIME_PATH}/data/realestate:/app/data
- ${RUNTIME_PATH}/_shared:/shared/_shared:ro
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
healthcheck: healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 60s interval: 60s

View File

@@ -10,6 +10,7 @@ from fastapi import FastAPI, HTTPException, BackgroundTasks, Body, Query
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse from fastapi.responses import FileResponse
from pydantic import BaseModel from pydantic import BaseModel
from _shared.access_log import install as install_access_log
from .config import ( from .config import (
CORS_ALLOW_ORIGINS, NAVER_CLIENT_ID, ANTHROPIC_API_KEY, CORS_ALLOW_ORIGINS, NAVER_CLIENT_ID, ANTHROPIC_API_KEY,
@@ -27,6 +28,7 @@ REDIS_URL = os.getenv("REDIS_URL", "redis://redis:6379")
redis_client = aioredis.from_url(REDIS_URL, decode_responses=False) redis_client = aioredis.from_url(REDIS_URL, decode_responses=False)
app = FastAPI() app = FastAPI()
install_access_log(app)
app.include_router(internal_router) app.include_router(internal_router)
app.add_middleware( app.add_middleware(

View File

@@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional
from fastapi import FastAPI, HTTPException, BackgroundTasks, Query from fastapi import FastAPI, HTTPException, BackgroundTasks, Query
from fastapi.middleware.cors import CORSMiddleware 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 .db import ( from .db import (
init_db, init_db,
@@ -34,6 +35,7 @@ import redis.asyncio as aioredis
from .internal_router import router as internal_router from .internal_router import router as internal_router
app = FastAPI() app = FastAPI()
install_access_log(app)
REDIS_URL = os.getenv("REDIS_URL", "redis://redis:6379") REDIS_URL = os.getenv("REDIS_URL", "redis://redis:6379")
redis_client = aioredis.from_url(REDIS_URL, decode_responses=False) redis_client = aioredis.from_url(REDIS_URL, decode_responses=False)

View File

@@ -6,6 +6,7 @@ from contextlib import asynccontextmanager
from fastapi import BackgroundTasks, FastAPI, Query, HTTPException from fastapi import BackgroundTasks, FastAPI, Query, HTTPException
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from _shared.access_log import install as install_access_log
from .db import ( from .db import (
init_db, get_announcements, get_announcement, create_announcement, init_db, get_announcements, get_announcement, create_announcement,
@@ -68,6 +69,7 @@ async def lifespan(app: FastAPI):
app = FastAPI(lifespan=lifespan) app = FastAPI(lifespan=lifespan)
install_access_log(app)
_cors_origins = os.getenv("CORS_ALLOW_ORIGINS", "http://localhost:3007,http://localhost:8080").split(",") _cors_origins = os.getenv("CORS_ALLOW_ORIGINS", "http://localhost:3007,http://localhost:8080").split(",")
app.add_middleware( app.add_middleware(

View File

@@ -9,6 +9,7 @@ from fastapi.middleware.cors import CORSMiddleware
import requests import requests
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from pydantic import BaseModel from pydantic import BaseModel
from _shared.access_log import install as install_access_log
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s %(message)s") logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s %(message)s")
logger = logging.getLogger("stock") logger = logging.getLogger("stock")
@@ -28,6 +29,7 @@ from .auth import verify_webai_key
from . import webai_cache from . import webai_cache
app = FastAPI() app = FastAPI()
install_access_log(app)
# Screener 라우터 등록 # Screener 라우터 등록
from app.screener.router import router as screener_router from app.screener.router import router as screener_router