로깅

로깅 (Logging)

멀티에이전트 앱이 실제로 무슨 일을 하는지 파악하려면 로그가 필요해요. AutoGen은 Python 내장 logging 모듈을 사용해요. 그런데 AutoGen의 로깅은 크게 두 종류로 나뉘어요. 이 구분을 이해하면 "디버깅용 로그"와 "시스템이 소비할 로그"를 제대로 다룰 수 있어요.

출처: Logging — AutoGen 공식 문서

  • 추적 로깅(Trace logging): 디버깅용으로, 사람이 읽을 수 있는 메시지를 내보내 "지금 코드에서 무슨 일이 일어나고 있는지" 개발자가 이해하도록 도와줘요. 다른 시스템이 이 로그의 내용·형식에 의존해서는 안 돼요. 로거 이름은 TRACE_LOGGER_NAME이에요.
  • 구조화 로깅(Structured logging): 다른 시스템이 소비할 수 있는 구조화된 이벤트를 내보내요. 내용과 형식을 다른 시스템이 의존할 수 있어요. 로거 이름은 EVENT_LOGGER_NAME이에요. 가능한 이벤트 목록은 autogen_core.logging 모듈에서 확인할 수 있어요.
  • ROOT_LOGGER_NAME은 모든 로그를 켜거나 끄는 데 사용할 수 있어요.

로깅 출력 활성화

추적 로깅을 활성화하려면:

import logging
from autogen_core import TRACE_LOGGER_NAME

logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger(TRACE_LOGGER_NAME)
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)

구조화 로깅을 활성화하려면:

import logging
from autogen_core import EVENT_LOGGER_NAME

logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger(EVENT_LOGGER_NAME)
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.INFO)

구조화 로깅 (Structured logging)

구조화 로깅을 쓰면, 형식화된 문자열 하나에 의존하는 대신 실제 이벤트와 모든 필드를 다루는 처리 로직을 작성할 수 있어요. 커스텀 이벤트를 정의해서 내보내고, 핸들러에서 받는 예를 볼게요.

import logging
from dataclasses import dataclass

@dataclass
class MyEvent:
    timestamp: str
    message: str

class MyHandler(logging.Handler):
    def __init__(self) -> None:
        super().__init__()

    def emit(self, record: logging.LogRecord) -> None:
        try:
            # Use the StructuredMessage if the message is an instance of it
            if isinstance(record.msg, MyEvent):
                print(f"Timestamp: {record.msg.timestamp}, Message: {record.msg.message}")
        except Exception:
            self.handleError(record)

사용 예:

logger = logging.getLogger(EVENT_LOGGER_NAME)
logger.setLevel(logging.INFO)
my_handler = MyHandler()
logger.handlers = [my_handler]

로그 내보내기 (Emitting logs)

TRACE_LOGGER_NAMEEVENT_LOGGER_NAME은 각 종류의 루트 로거예요. 로그를 내보내는 코드는 이 로거들의 자식 로거를 사용해야 해요. 예를 들어 my_module이라는 모듈에서 추적 로그를 내보내려면:

import logging
from autogen_core import TRACE_LOGGER_NAME

logger = logging.getLogger(f"{TRACE_LOGGER_NAME}.my_module")

구조화 로그를 내보내려면:

import logging
from dataclasses import dataclass
from autogen_core import EVENT_LOGGER_NAME

@dataclass
class MyEvent:
    timestamp: str
    message: str

logger = logging.getLogger(EVENT_LOGGER_NAME + ".my_module")
logger.info(MyEvent("timestamp", "message"))

핵심 포인트는, 로거 이름에 "루트 + 모듈명" 패턴을 사용해서 어느 모듈이 기록했는지 계층적으로 관리하고, 구조화 이벤트는 dataclass 그대로 로거에 넘겨 처리 코드에서 필드에 접근한다는 거예요.

더 알아보기 (Learn more)