아래는 확장성과 유지보수성을 극대화한 Python 로깅 설정파일입니다.
모든 Best Practice를 적용하여 파일 로깅, 콘솔 로깅, 원격 로깅, 로그 로테이션, JSON 포맷 로그, Slack 알림까지 포함한 설정을 만들었습니다.
logging_config.yaml
(YAML 기반 설정파일)version: 1
# 로그 포맷 정의
formatters:
standard:
format: "[%(asctime)s] [%(levelname)s] [%(name)s] [%(filename)s:%(lineno)d] - %(message)s"
datefmt: "%Y-%m-%d %H:%M:%S"
json:
format: '{"time": "%(asctime)s", "level": "%(levelname)s", "logger": "%(name)s", "file": "%(filename)s", "line": %(lineno)d, "message": "%(message)s"}'
detailed:
format: "%(asctime)s | %(levelname)s | %(name)s | %(filename)s:%(lineno)d | %(message)s | %(process)d | %(threadName)s"
# 핸들러 정의
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: standard
stream: ext://sys.stdout
file:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: standard
filename: logs/app.log
maxBytes: 10485760 # 10MB
backupCount: 5
encoding: utf-8
timed_file:
class: logging.handlers.TimedRotatingFileHandler
level: INFO
formatter: detailed
filename: logs/app_timed.log
when: midnight
interval: 1
backupCount: 7
encoding: utf-8
json_file:
class: logging.FileHandler
level: INFO
formatter: json
filename: logs/app.json
encoding: utf-8
slack:
class: my_logging_handlers.SlackHandler
level: ERROR
formatter: standard
token: "xoxb-..." # Slack API Token
channel: "#alerts"
syslog:
class: logging.handlers.SysLogHandler
level: WARNING
formatter: standard
address: "/dev/log"
# 로거 정의
loggers:
my_app:
level: DEBUG
handlers: [console, file, timed_file, json_file, slack, syslog]
propagate: no
# 기본 로거 설정 (루트 로거)
root:
level: WARNING
handlers: [console, file]
항목 | 설명 |
---|---|
version: 1 |
로깅 설정 버전 (Python 표준) |
Formatters | 로그 출력 형식을 정의하는 부분 |
standard |
기본 로그 포맷 (날짜, 로그레벨, 로거명, 파일명, 라인번호, 메시지) |
json |
JSON 형식으로 로그 저장 가능 |
detailed |
추가적인 정보(프로세스 ID, 쓰레드 정보)를 포함하는 포맷 |
Handlers | 로그를 저장하는 방식 |
console |
터미널(표준 출력)에 로그 출력 |
file |
크기에 따라 파일을 회전하는 핸들러 (RotatingFileHandler ) |
timed_file |
날짜에 따라 파일을 자동으로 회전하는 핸들러 (TimedRotatingFileHandler ) |
json_file |
JSON 형식으로 로그를 저장하는 핸들러 |
slack |
ERROR 이상 로그가 발생하면 Slack으로 전송 |
syslog |
시스템 로그 서버(/dev/log )에 저장 |
Loggers | 특정 로거에 대해 설정하는 부분 |
my_app |
my_app 네임스페이스의 모든 로그가 지정된 핸들러를 거쳐 출력 |
Root Logger | 설정되지 않은 모든 로거가 따르는 기본 설정 |
Slack 알림을 위해 별도의 핸들러를 만들어야 합니다.
my_logging_handlers.py
import logging
import requests
class SlackHandler(logging.Handler):
def __init__(self, token, channel):
super().__init__()
self.token = token
self.channel = channel
def emit(self, record):
log_entry = self.format(record)
payload = {
"channel": self.channel,
"text": f"🚨 {record.levelname}: {log_entry}",
}
headers = {
"Authorization": f"Bearer {self.token}",
"Content-Type": "application/json",
}
try:
requests.post("https://slack.com/api/chat.postMessage", json=payload, headers=headers)
except Exception as e:
print(f"Slack logging failed: {e}")
import logging
import logging.config
import yaml
# YAML 로깅 설정 불러오기
with open("logging_config.yaml", "r") as f:
config = yaml.safe_load(f)
logging.config.dictConfig(config)
logger = logging.getLogger("my_app")
# 로깅 예제
logger.debug("이것은 디버그 메시지입니다")
logger.info("이것은 정보 메시지입니다")
logger.warning("이것은 경고 메시지입니다")
logger.error("이것은 에러 메시지입니다")
logger.critical("이것은 치명적 오류 메시지입니다")
queue.Queue
)