>source

아래에 로거 구성 클래스 my_logger.py가 있습니다.

def my_logger(module_name, log_file):
    logger = logging.getLogger(module_name)
    logger.setLevel(logging.DEBUG)
    # Create handlers
    c_handler = logging.StreamHandler()
    f_handler = logging.handlers.RotatingFileHandler(filename=log_file)
    c_handler.setLevel(logging.DEBUG)
    f_handler.setLevel(logging.DEBUG)
    # Create formatters and add it to handlers
    c_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    c_handler.setFormatter(c_format)
    f_handler.setFormatter(f_format)
    # Add handlers to the logger
    logger.addHandler(c_handler)
    logger.addHandler(f_handler)
    return logger

이 my_logger.py는 패키지 루트 디렉토리에 있습니다.

my_package:
    my_logger.py
    test.py
    api/api.py
    logs/

그런 다음 내 test.py에서 :

abspath = os.path.abspath(os.path.dirname(__file__))
logger_info = logger.my_logger("test_info", os.path.join(abspath,"../logs/info.log"))
logger_debug = logger.my_logger("test_debug", os.path.join(abspath,"../logs/debug.log"))
logger_error = logger.my_logger("test_error", os.path.join(abspath,"../logs/error.log"))
logger_info.info('Info test ...')
logger_debug.debug('Debug test ...')
logger_error.error('Error test ...')

debug.log에 대한 디버깅, info.log에 대한 정보 및 error.log에 대한 오류를 디버깅하고 싶습니다.

기록 할 각 파일에 대해 각 파일에 다음 3 줄을 추가해야합니다.

logger_info = logger.my_logger(module_info, os.path.join(abspath,"../logs/info.log"))
logger_debug = logger.my_logger(module_debug, os.path.join(abspath,"../logs/debug.log"))
logger_error = logger.my_logger(module_error, os.path.join(abspath,"../logs/error.log"))

이것이 정상적인 관행입니까? 모든 모듈의 모든 로그 메시지가 logs/아래의 동일한 3 개 파일에 들어가기를 원합니다.

  • 답변 # 1

    짧은 답변

    당신이 묘사 한 것을 정확히 달성하기 위해, 3 개의 핸들러 (예제에 있음)가 필요하고 기본 수준을 상단의 해당 수준으로 설정합니다. 핸들러의 레벨을 별도로 설정할 필요가 없습니다.

    import logging
    from logging import handlers
    def my_logger(module_name, log_file, level):
        logger = logging.getLogger(module_name)
        logger.setLevel(level)
        # Create handlers
        c_handler = logging.StreamHandler()
        f_handler = handlers.RotatingFileHandler(filename=log_file)
        # Create formatters and add it to handlers
        c_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
        f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
        c_handler.setFormatter(c_format)
        f_handler.setFormatter(f_format)
        # Add handlers to the logger
        logger.addHandler(c_handler)
        logger.addHandler(f_handler)
        return logger
    if __name__ == "__main__":
        logger_info = my_logger("test_info", "info.log", logging.INFO)
        logger_debug = my_logger("test_debug", "debug.log", logging.DEBUG)
        logger_error = my_logger("test_error", "error.log", logging.ERROR)
        logger_info.info('Info test ...')
        logger_debug.debug('Debug test ...')
        logger_error.error('Error test ...')
    
    

    산출:

    python test_logger2.py 
    2020-12-04 16:57:00,771 - test_info - INFO - 29 - Info test ...
    2020-12-04 16:57:00,771 - test_debug - DEBUG - 30 - Debug test ...
    2020-12-04 16:57:00,771 - test_error - ERROR - 31 - Error test ...
    cat info.log 
    2020-12-04 16:57:00,771 - test_info - INFO - 29 - Info test ...
    cat debug.log 
    2020-12-04 16:57:00,771 - test_debug - DEBUG - 30 - Debug test ...
    cat error.log 
    2020-12-04 16:57:00,771 - test_error - ERROR - 31 - Error test ...
    
    

    긴 대답 :

    왜 3 부인가?
    당신은 당신의 my_logger 함수를 3 번, 호출 할 때마다 새 파일 처리기 및 로거에 추가 된 새 스트림 처리기입니다. 이것이 콘솔에 3 개의 복사본이 표시되는 이유입니다 (3 개의 스트림 처리기). 또한 모든 핸들러가 DEBUG 수평. 이것이 세 개의 로거가 모두 사용자가 제공 한 로그를 인쇄하는 이유입니다. 당신은 원하지 않습니다 ERROR 처리/인쇄 로그 처리기 DEBUG / INFO 레벨을 설정해야합니다. ERROR .

    이것이 로깅에 대한 표준 접근 방식이라고 생각하지 않습니다. 대신 4 개의 핸들러 (stream, file_debug, file_info, file_error)가있는 단일 로거가 있어야합니다. 또한 디버그 로그 파일에는 모든 로그가 포함되어야하며 정보 로그 파일에는 정보 로그 및 오류 로그가 포함되어야합니다. 아래 세부 정보.

    import logging
    from logging import handlers
    def main():
        logger = logging.getLogger()
        c_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
        # You need to set the default level to the lowest (DEBUG)
        logger.setLevel(logging.DEBUG)
        c_handler = logging.StreamHandler()
        c_handler.setLevel(logging.DEBUG)
        c_handler.setFormatter(c_format)
        f1_handler = handlers.RotatingFileHandler("debug.log")
        f1_handler.setLevel(logging.DEBUG)
        f1_handler.setFormatter(c_format)
        f2_handler = logging.handlers.RotatingFileHandler("info.log")
        f2_handler.setLevel(logging.INFO)
        f2_handler.setFormatter(c_format)
        f3_handler = logging.handlers.RotatingFileHandler("error.log")
        f3_handler.setLevel(logging.ERROR)
        f3_handler.setFormatter(c_format)
        logger.addHandler(c_handler)
        logger.addHandler(f1_handler)
        logger.addHandler(f2_handler)
        logger.addHandler(f3_handler)
        logger.debug("A debug line")
        logger.info("An info line")
        logger.error("An error line")
    if __name__ == "__main__":
        main()
    
    
    

    출력은 다음과 같습니다.

    python test_logger.py 
    2020-12-04 16:48:56,247 - root - DEBUG - 32 - A debug line
    2020-12-04 16:48:56,248 - root - INFO - 33 - An info line
    2020-12-04 16:48:56,248 - root - ERROR - 34 - An error line
    cat debug.log 
    2020-12-04 16:49:06,673 - root - DEBUG - 32 - A debug line
    2020-12-04 16:49:06,673 - root - INFO - 33 - An info line
    2020-12-04 16:49:06,673 - root - ERROR - 34 - An error line
    cat info.log 
    2020-12-04 16:49:06,673 - root - INFO - 33 - An info line
    2020-12-04 16:49:06,673 - root - ERROR - 34 - An error line
    cat error.log 
    2020-12-04 16:49:06,673 - root - ERROR - 34 - An error line
    
    

    여기 당신은 당신의 debug.log 파일에는 다른 수준의 로그도 포함되며 info.log 파일에는 오류 로그도 포함되어 있습니다. 이것이 로그 수준의 전체 근거이기 때문입니다. 낮은 수준은 높은 수준의 로그도 추적해야합니다 ( DEBUG < INFO < WARNING < ERROR ). 그렇기 때문에 원하는 것은 표준 방식이 아니지만 짧은 답변에 설명 된대로 완벽하게 달성 할 수 있습니다.

관련 자료

  • 이전 javascript - ExpressJS에서 일부 경로와 다른 경로에서 정적 파일을 제공하는 방법
  • 다음 reactjs - 여러 아코디언에 대한 React의 부모 및 자식 구성 요소 스타일링