직접 만든 로깅 래퍼 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import logging
from logging.handlers import TimedRotatingFileHandler
from typing import Literal
import time
import os

DEBUG_MODE = 0
LOG_LEVEL_TYPE = Literal["DEBUG", "INFO", "WARNING", "ERROR"]
LOG_WHEN = Literal["S", "M", "H", "D", "midnight", "W{0}", "W{1}", "W{2}", "W{3}", "W{4}", "W{5}", "W{6}"]

# logger
class DefaultLogger():
    
    def __init__(self,
                 logger_log_level:LOG_LEVEL_TYPE = "INFO",
                 file_log_level:LOG_LEVEL_TYPE = "WARNING",
                 console_log_level:LOG_LEVEL_TYPE = "DEBUG",
                 log_dir:str = "logs",
                 log_format:str = "[%(asctime)s] %(levelname)s (%(filename)s) [line : %(lineno)d] - %(message)s",
                 when:LOG_WHEN = "D",
                 interval:str|int = 1,
                 retention_period_day:str|int = 90
                 ):
        self.logger = None
        # log level
        self.logger_log_level = self._log_level_convert(logger_log_level)
        self.file_log_level = self._log_level_convert(file_log_level)
        self.console_log_level = self._log_level_convert(console_log_level)
        # log dir and format
        self.log_dir = log_dir
        self.log_format = log_format
        # file rotating setting
        self.when = when
        self.interval = int(interval)
        self.retention_period_day = int(retention_period_day)
    
    def _log_level_convert(self, log_level:LOG_LEVEL_TYPE):
        return logging._nameToLevel[log_level]
    
    def check_log_dir(self, log_dir):
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
    
    def get_logger(self, logger_name:str, file_name:str, encoding:str="utf-8"):
        
        self.logger = logging.getLogger(logger_name)
        self.logger.setLevel(self.logger_log_level)
        self.logger.propagate = False
        
        # remove existing handlers
        if self.logger.hasHandlers():
            self.logger.handlers.clear()
        
        # setting log_dir path and retention period
        filename = os.path.join(self.log_dir, file_name)
        backup_count = 90
        if self.when == "D":
            backup_count = int(self.retention_period_day / self.interval)
        elif self.when == "H":
            backup_count = int(self.retention_period_day * 24 / self.interval)
        elif self.when == "M":
            backup_count = int(self.retention_period_day * 24 * 60 / self.interval)
        elif self.when == "S":
            backup_count = int(self.retention_period_day * 24 * 60 * 60 / self.interval)
        
        # check log dir
        self.check_log_dir(self.log_dir)
        
        # handler
        file_handler = TimedRotatingFileHandler(filename=filename,
                                                backupCount=backup_count,
                                                encoding=encoding,
                                                when=self.when,
                                                interval=self.interval)
        console_handler = logging.StreamHandler()
        file_handler.setLevel(self.file_log_level)
        console_handler.setLevel(self.console_log_level)
        
        # formatter
        formatter = logging.Formatter(fmt=self.log_format)
        file_handler.setFormatter(formatter)
        console_handler.setFormatter(formatter)
        
        # return logger
        self.logger.addHandler(file_handler)
        self.logger.addHandler(console_handler)
        
        return self.logger

# test code
if DEBUG_MODE==0:
    logger_name = "default_logger"
    file_name = "default_log"
    config = DefaultLogger()
    logger = config.get_logger(logger_name, file_name)
elif DEBUG_MODE==1:
    logger_name = "test_logger"
    file_name = "test_log"
    config = DefaultLogger(when="S", interval=3)
    logger = config.get_logger(logger_name, file_name)
    for i in range(20):
        logger.error(f"test log : {i}")
        time.sleep(1)

"""
usage
# usage(1) : 기본 로깅 설정으로 간편하게
from log_manager import logger
logger.info("abc")

# usage(2) : 로깅 설정 커스텀
config = DefaultLogger(설정 커스텀...)
logger = config.get_logger(logger_name, file_name)
logger.info("abc")
"""

Reference

https://docs.python.org/3/library/logging.html
https://docs.python.org/ko/3/howto/logging.html

Comments