2019년 4월 21일 일요일

python 에서 logging 사용하기(using logging in python)


python3에서 로그를 사용하기 위한 logging이라는 패키지가 있습니다. 핸들러도 있고 설명도 복잡해서 뭐라는건지 잘 이해가 안되어서 자주 사용할만한 클래스를 만들었습니다. 그럼 소스 코드부터 보고 가시겠습니다.


import logging
import os
from logging import handlers

class CustomLog:
    def __init__(self):
        pass

    def getLogger(self, filename, NEED_BACKUP_FILE = True, NEED_SCREEN_AND_FILE = True, level=logging.DEBUG, format='%(asctime)s,%(message)s', maxBytes=10*1024*1024, backupCount = 10, encoding='utf-8'):
        self.logger = logging.getLogger()
        # log level은 아래 순서에 따른다. setLevel 과 같거나 큰 출력만 나오게 된다.
        # logger.setLevel(logging.CRITICAL) 인 경우 logger.critical() 만 나온다
        #
        # logger.debug("debug")
        # logger.info("info")
        # logger.warning("warning")
        # logger.error("error")
        # logger.critical("critical")
        self.logger.setLevel(level)

        # 포맷을 결정한다. 좀더 자세한 정보는 다음 링크를 참조한다
        # https://docs.python.org/3/library/logging.html#logrecord-attributes
        logFormatter = logging.Formatter(format)

        if NEED_BACKUP_FILE == True:
            rotatingHandler = handlers.RotatingFileHandler(filename=filename, maxBytes=maxBytes, backupCount = backupCount, encoding=encoding)
            rotatingHandler.setFormatter(logFormatter)
            self.logger.addHandler(rotatingHandler)
        else:
            fileHandler = logging.FileHandler(filename)
            fileHandler.setFormatter(logFormatter)
            self.logger.addHandler(fileHandler)

        # StreamHandler 는 self.logger.critical("critical") 이런 형태의 로그가 화면으로도 나오고 file로도 저장이 되도록 한다
        if NEED_SCREEN_AND_FILE == True:
            streamHandler = logging.StreamHandler()
            streamHandler.setFormatter(logFormatter)
            self.logger.addHandler(streamHandler)
        return self.logger

1. 파일에 기록하기

로깅 함수를 사용하는 이유는 파일에 기록을 하려는 목적이 있습니다. 화면에만 하고 싶으면 print 함수로도 충분합니다.
파일 핸들러를 등록하는것은 아래 함수 입니다. 물론 기본으로 등록하지는 않고 NEED_BACKUP_FILE false 일 경우에만 등록하게 됩니다.
            fileHandler = logging.FileHandler(filename)
            fileHandler.setFormatter(logFormatter)
            self.logger.addHandler(fileHandler)
NEED_BACKUP_FILE == True 인 경우 백업 파일이란것을 만들게 되는데 파일이 일정크기가 되면 백업을 시도합니다. 해당 기능을 사용하고 싶지 않으면 False 처리하면 됩니다.

2. 로그의 레벨 시스템

기본적으로 알아야 하는 내용은 아래 부분입니다.
        # logger.debug("debug")
        # logger.info("info")
        # logger.warning("warning")
        # logger.error("error")
        # logger.critical("critical")
레벨이 존재하고 logger.info("출력을 원하는 텍스트") 라고 하면 info level로 로그가 화면에 출력이 되어야 하지만 실제는 로그 시스템의 level이 뭘로 되어있느냐에 따라 출력이 될 수도 안될 수도 있습니다. 즉 logger.setLevel(level) 함수에 의해 출력 레벨이 결정 되는데 해당 값보다는 큰것만 출력이 되게 됩니다.
이해가 잘안되면 level=logging.DEBUG 이 기본값으로 설정했으므로 모든 문구가 출력이 됩니다.

3. 출력 포맷

출력 포맷은 아래 함수에 의해 결정 됩니다.
 logFormatter = logging.Formatter(format)
기본값으로는 아래와같은 형태로 되어 있어서 시간+로그가 출력되도록 되어있습니다.
format='%(asctime)s,%(message)s'

4. 화면으로의 출력

기본은 파일에만 로그가 출력됩니다. 일반적으로는 화면에도 출력을 원할때가 있습니다.
이때 NEED_SCREEN_AND_FILE True 값을 설정하면 화면에도 출력이 가능하도록 핸들러를 등록합니다.
        if NEED_SCREEN_AND_FILE == True:
            streamHandler = logging.StreamHandler()
            streamHandler.setFormatter(logFormatter)
            self.logger.addHandler(streamHandler)

5. 사용 예제


import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../util/')))
import customlog

if __name__ == "__main__":
    logname = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test.log')
    logsystem = customlog.CustomLog()
    logger = logsystem.getLogger(logname)

    print("test")
    logger.debug("debug test")
    logger.info("info test")
    logger.warning("warning test")
    logger.error("error test")
    logger.critical("critical test")

소스에서 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../util/'))) 이 부분은 customlog의 path가 같은 폴더에 있지 않아서 import 하기 위해서 추가된 코드 입니다.
logname = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test.log') 저장하고자 하는 파일 이름을 설정합니다.
logger = logsystem.getLogger(logname)을 하게 되면 기본적으로 파일 출력과 화면을 동시에 지원하며 backup 파일도 지원되는 logger를 만들게 됩니다.

화면 출력은 아래와 같이 나옵니다.

test
2019-04-21 18:23:58,166,debug test
2019-04-21 18:23:58,167,info test
2019-04-21 18:23:58,169,warning test
2019-04-21 18:23:58,179,error test
2019-04-21 18:23:58,181,critical test

파일은 아래와 같이 나오게 됩니다.
2019-04-21 18:23:58,166,debug test
2019-04-21 18:23:58,167,info test
2019-04-21 18:23:58,169,warning test
2019-04-21 18:23:58,179,error test
2019-04-21 18:23:58,181,critical test


python logger,colored log (컬러 로거 logger)

python 멀티 로그 레벨을 가지는 로거(how to set multi setlevel in python logger)


댓글 없음:

댓글 쓰기