diff --git a/agent-office/app/config.py b/agent-office/app/config.py index 638f61d..1f680b0 100644 --- a/agent-office/app/config.py +++ b/agent-office/app/config.py @@ -45,10 +45,9 @@ import re as _re # path_prefix_regex: lotto 컨테이너에 personal/blog/todo 도 같이 있어 # /api/lotto 만 골라내기 위한 정규식. business log (source='log') 는 모두 통과. AGENT_CONTAINER_MAP: dict[str, tuple[str, int, _re.Pattern]] = { - "lotto": ("lotto", 8000, _re.compile(r"^/api/lotto")), - # Phase 2 에서 추가: - # "stock": ("stock", 8000, _re.compile(r"^/api/(stock|trade|portfolio)")), - # "music": ("music-lab", 8000, _re.compile(r"^/api/music")), - # "insta": ("insta-lab", 8000, _re.compile(r"^/api/insta")), - # "realestate": ("realestate-lab", 8000, _re.compile(r"^/api/realestate")), + "lotto": ("lotto", 8000, _re.compile(r"^/api/lotto")), + "stock": ("stock", 8000, _re.compile(r"^/api/(stock|trade|portfolio)")), + "music": ("music-lab", 8000, _re.compile(r"^/api/music")), + "insta": ("insta-lab", 8000, _re.compile(r"^/api/insta")), + "realestate": ("realestate-lab", 8000, _re.compile(r"^/api/realestate")), } diff --git a/docker-compose.yml b/docker-compose.yml index 1df9cbd..2ac73d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -51,8 +51,15 @@ services: - OLLAMA_MODEL=${OLLAMA_MODEL:-qwen3:14b} - CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080} - WEBAI_API_KEY=${WEBAI_API_KEY:-} + - PYTHONPATH=/app:/shared volumes: - ${RUNTIME_PATH}/data/stock:/app/data + - ${RUNTIME_PATH}/_shared:/shared/_shared:ro + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] interval: 60s @@ -86,9 +93,16 @@ services: - REDIS_URL=${REDIS_URL:-redis://redis:6379} - INTERNAL_API_KEY=${INTERNAL_API_KEY:-} - MUSIC_RENDER_URL=${MUSIC_RENDER_URL:-http://192.168.45.59:18711} + - PYTHONPATH=/app:/shared volumes: - ${RUNTIME_PATH}/data/music:/app/data - ${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: - redis healthcheck: @@ -163,8 +177,15 @@ services: - CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080} - REDIS_URL=${REDIS_URL:-redis://redis:6379} - INTERNAL_API_KEY=${INTERNAL_API_KEY:-} + - PYTHONPATH=/app:/shared volumes: - ${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: - redis healthcheck: @@ -185,8 +206,15 @@ services: - DATA_GO_KR_API_KEY=${DATA_GO_KR_API_KEY:-} - CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080} - AGENT_OFFICE_URL=${AGENT_OFFICE_URL:-http://agent-office:8000} + - PYTHONPATH=/app:/shared volumes: - ${RUNTIME_PATH}/data/realestate:/app/data + - ${RUNTIME_PATH}/_shared:/shared/_shared:ro + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] interval: 60s diff --git a/insta-lab/app/main.py b/insta-lab/app/main.py index e8998e9..06a7dd9 100644 --- a/insta-lab/app/main.py +++ b/insta-lab/app/main.py @@ -10,6 +10,7 @@ from fastapi import FastAPI, HTTPException, BackgroundTasks, Body, Query from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from pydantic import BaseModel +from _shared.access_log import install as install_access_log from .config import ( 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) app = FastAPI() +install_access_log(app) app.include_router(internal_router) app.add_middleware( diff --git a/music-lab/app/main.py b/music-lab/app/main.py index b228ad4..1b5002d 100644 --- a/music-lab/app/main.py +++ b/music-lab/app/main.py @@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional from fastapi import FastAPI, HTTPException, BackgroundTasks, Query from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel +from _shared.access_log import install as install_access_log from .db import ( init_db, @@ -34,6 +35,7 @@ import redis.asyncio as aioredis from .internal_router import router as internal_router app = FastAPI() +install_access_log(app) REDIS_URL = os.getenv("REDIS_URL", "redis://redis:6379") redis_client = aioredis.from_url(REDIS_URL, decode_responses=False) diff --git a/realestate-lab/app/main.py b/realestate-lab/app/main.py index 50a7dac..5a6a538 100644 --- a/realestate-lab/app/main.py +++ b/realestate-lab/app/main.py @@ -6,6 +6,7 @@ from contextlib import asynccontextmanager from fastapi import BackgroundTasks, FastAPI, Query, HTTPException from fastapi.middleware.cors import CORSMiddleware from apscheduler.schedulers.background import BackgroundScheduler +from _shared.access_log import install as install_access_log from .db import ( init_db, get_announcements, get_announcement, create_announcement, @@ -68,6 +69,7 @@ async def lifespan(app: FastAPI): app = FastAPI(lifespan=lifespan) +install_access_log(app) _cors_origins = os.getenv("CORS_ALLOW_ORIGINS", "http://localhost:3007,http://localhost:8080").split(",") app.add_middleware( diff --git a/stock/app/main.py b/stock/app/main.py index 572e8bc..e39c5f1 100644 --- a/stock/app/main.py +++ b/stock/app/main.py @@ -9,6 +9,7 @@ from fastapi.middleware.cors import CORSMiddleware import requests from apscheduler.schedulers.background import BackgroundScheduler 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") logger = logging.getLogger("stock") @@ -28,6 +29,7 @@ from .auth import verify_webai_key from . import webai_cache app = FastAPI() +install_access_log(app) # Screener 라우터 등록 from app.screener.router import router as screener_router