""" app/core/logging_config.py --------------------------- HUTAMS 표준 로깅 설정 모듈. Uvicorn 로거에 통합하여 모든 서비스 레이어에서 타임스탬프·레벨·모듈명이 포함된 상세 로그를 출력한다. """ import logging import logging.config import sys # ── 로그 핸들러 & 포매터 설정 ────────────────────────────────────────────────── LOGGING_CONFIG = { "version": 1, "disable_existing_loggers": False, "formatters": { # 개발용: 컬러 없이 시간·레벨·모듈·메시지 풀 포맷 "detailed": { "format": "%(asctime)s [%(levelname)-8s] %(name)s:%(lineno)d — %(message)s", "datefmt": "%Y-%m-%d %H:%M:%S", }, # Uvicorn 접근 로그용 (기존 형식 유지) "access": { "()": "uvicorn.logging.AccessFormatter", "fmt": '%(levelprefix)s %(client_addr)s — "%(request_line)s" %(status_code)s', }, }, "handlers": { # 터미널 출력 (UTF-8 강제 인코딩 — Windows cp949 이모지 크래시 방지) "console": { "class": "logging.StreamHandler", "formatter": "detailed", "stream": "ext://sys.stdout", }, # 파일 로그: 최대 10MB, 최대 5개 롤링 "file": { "class": "logging.handlers.RotatingFileHandler", "formatter": "detailed", "filename": "hutams.log", "maxBytes": 10 * 1024 * 1024, # 10 MB "backupCount": 5, "encoding": "utf-8", }, }, "loggers": { # HUTAMS 자체 서비스 로거 — DEBUG부터 파일·콘솔 모두 출력 "uvicorn.error": { "handlers": ["console", "file"], "level": "DEBUG", "propagate": False, }, "uvicorn.access": { "handlers": ["console"], "level": "INFO", "propagate": False, }, }, "root": { "handlers": ["console", "file"], "level": "DEBUG", }, } def setup_logging(): """FastAPI 앱 시작 시 1회 호출하여 로깅 설정을 적용한다.""" # Windows: stdout을 UTF-8로 재설정하여 이모지 인코딩 에러 방지 if sys.platform == "win32": try: import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") except Exception: pass logging.config.dictConfig(LOGGING_CONFIG)