Python

[Python] Logging(로깅)

웹개발자(진) 2024. 3. 23. 22:08
반응형
잡담

 

토욜일에 나가서 파이썬 수업듣고 옵니다. 날씨가 많이 풀려서 매화 피고 난린데.. 나도 나가서 꽃구경 가고싶다.


 

Logging(로깅)

 

파이썬 로깅(logging)은 파이썬에서 프로그램 실행 중에 발생하는 이벤트를 기록하는 것을 말합니다.

이벤트는 예외 발생, 정보 메시지, 경고 등 다양한 것들을 포함할 수 있습니다.

로깅은 프로그램의 디버깅, 오류 추적, 성능 모니터링 등에 유용하게 사용될 수 있습니다.

파이썬에서 로깅을 사용하는 주요 장점은 다음과 같습니다:

  1. 유연성: 로깅 시스템은 다양한 로그 레벨을 제공하여 어떤 이벤트를 기록할지 선택할 수 있습니다. 이는 디버깅, 정보, 경고, 오류 등과 같이 다양한 수준의 로그를 기록할 수 있음을 의미합니다.
  2. 구성 가능성: 파이썬 로깅 시스템은 로깅의 형식, 로그의 방향(파일, 콘솔 등), 로그 레벨 등을 구성할 수 있는 다양한 옵션을 제공합니다.
  3. 성능: 로깅 시스템은 성능에 대한 고려가 되어 있으며, 필요한 경우에도 로그를 효율적으로 기록할 수 있습니다.
  4. 표준화: 파이썬의 로깅 모듈은 표준 라이브러리에 포함되어 있으므로 추가 설치가 필요하지 않습니다.

파이썬 로깅은 logging 모듈을 사용하여 구현됩니다. 이 모듈은 로깅의 기능을 제공하며, 로그 레벨, 로그 포맷, 로그 핸들러 등을 설정하여 로깅을 구성할 수 있습니다. 기본적으로 파이썬은 WARNING 레벨 이상의 모든 로그를 출력하지만, 필요에 따라 설정을 변경할 수 있습니다.

 


 

Logging Level

로깅 레벨(logging level)은 로그 메시지의 중요도를 나타내는데 사용됩니다.

각 로그 메시지에는 로깅 레벨이 지정되어 있으며, 설정된 로깅 레벨보다 낮은 레벨의 메시지는 무시됩니다. 로깅 레벨은 다음과 같은 순서로 정의됩니다(낮은 순서부터 높은 순서):

  1. DEBUG: 가장 낮은 수준의 로그 메시지입니다. 디버깅 목적으로 사용됩니다. 프로그램 실행 중에 세부 정보를 제공합니다.
  2. INFO: 정보성 로그 메시지입니다. 프로그램이 정상적으로 진행되고 있는지 나타냅니다. 예를 들어, 어떤 작업이 시작되었거나 완료되었음을 알리는 데 사용될 수 있습니다.
  3. WARNING: 경고성 로그 메시지입니다. 프로그램이 예기치 않은 상황에 진입했지만, 여전히 정상적으로 실행되고 있음을 나타냅니다. 잠재적인 문제를 나타냅니다.
  4. ERROR: 오류 로그 메시지입니다. 프로그램이 예외 또는 오류 상태에 진입했음을 나타냅니다. 프로그램의 실행이 중단되지는 않았지만, 문제가 발생했음을 알립니다.
  5. CRITICAL: 가장 높은 수준의 로그 메시지입니다. 심각한 오류를 나타냅니다. 프로그램이 중단되었거나 중대한 문제가 발생했음을 나타냅니다.

로깅 레벨은 각각 정수 값으로도 표현될 수 있으며, 아래와 같은 상응하는 정수 값이 있습니다:

  • DEBUG: 10
  • INFO: 20
  • WARNING: 30
  • ERROR: 40
  • CRITICAL: 50

로깅 레벨은 로거(logger), 핸들러(handler) 및 필터(filter)에 대해 설정할 수 있습니다. 일반적으로 로거 수준은 가장 낮은 수준으로 설정되며, 핸들러와 필터는 필요에 따라 로깅 레벨을 상속받거나 설정할 수 있습니다. 이를 통해 로그 메시지의 출력을 효율적으로 제어할 수 있습니다.

 


 

Logging Module

파이썬의 로깅(logging) 모듈은 프로그램 실행 중에 메시지를 기록하는 기능을 제공하는 표준 라이브러리 모듈입니다. 이 모듈은 로그 레벨 설정, 로그 메시지의 형식화, 로그 메시지를 파일 또는 다른 목적지로 전송하는 등의 다양한 기능을 제공합니다.

로깅 모듈의 핵심 개념은 다음과 같습니다:

  1. Logger(로거): 로그 메시지를 생성하는 주체입니다. 로그 메시지는 로거를 통해 생성되며, 로거는 로깅 레벨 및 다양한 속성을 가질 수 있습니다.
  2. Handler(핸들러): 로그 메시지를 적절한 목적지로 보내는 역할을 합니다. 핸들러는 파일, 콘솔, 네트워크 소켓 등으로 로그 메시지를 보낼 수 있습니다.
  3. Formatter(포매터): 로그 메시지의 형식을 지정하는 역할을 합니다. 포매터는 로그 메시지를 출력하는 형식을 지정할 수 있습니다.

 

로깅 모듈을 사용하여 로그를 설정하고 기록하는 과정

  1. 로깅 레벨 설정: 어떤 레벨의 로그 메시지를 기록할 것인지 설정합니다.
  2. 로거 생성: 로그 메시지를 생성할 로거를 생성합니다.
  3. 핸들러 추가: 로그 메시지를 어디로 보낼 것인지 핸들러를 추가합니다.
  4. 포매터 설정: 로그 메시지의 형식을 지정하는 포매터를 설정합니다.
  5. 로그 메시지 생성 및 기록: 로그 메시지를 생성하고 로거를 통해 기록합니다.

 


 

로거 객체 생성

로거(logger) 객체를 생성하는 방법은 파이썬의 logging 모듈을 사용하여 다음과 같이 할 수 있습니다:


    import logging

    # 로거 생성
    logger = logging.getLogger('my_logger')

    # 루트 로거 생성
    root_logger = logging.getLogger()

 

위 코드에서 getLogger() 함수를 사용하여 이름이 'my_logger'인 로거 객체를 생성합니다. 이 이름은 로거 객체의 식별을 위한 것이며, 식별 가능한 문자열이면 됩니다.

logging.root 또는 logging.getLogger()를 호출하면 루트 로거를 가져올 수 있습니다.

 


 

로그 메세지 출력

로거(logger) 객체를 사용하여 로그 메시지를 출력하는 방법은 debug(), info(), warning(), error(), critical() 메서드를 호출하는 것입니다.

이 메서드들은 각각 다른 로그 레벨에 해당합니다. 아래는 각 메서드의 사용 예시입니다.


    import logging

    logger = logging.getLogger('my_logger')

    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')
 

 

# 결과
This is a warning message
This is an error message
This is a critical message

 

debug()와 info()는 출력 되지 않습니다.

기본적으로 로깅 레벨은 WARNING으로 설정되어 있기 때문입니다.

 


 

로깅 헨들러

로깅 핸들러(logging handler)는 로그 메시지를 적절한 목적지로 보내는 역할을 합니다.

예를 들어, 콘솔 출력, 파일 저장, 네트워크 전송 등의 목적지로 로그 메시지를 보낼 수 있습니다.

로깅 핸들러는 Handler 클래스를 상속하여 사용자가 지정한 목적지로 로그 메시지를 전송합니다.

 

파이썬의 로깅 핸들러는 다양한 종류가 있으며, 주요한 핸들러들은 다음과 같습니다:

  1. StreamHandler: 콘솔로 로그 메시지를 출력합니다.
  2. FileHandler: 파일로 로그 메시지를 저장합니다.
  3. RotatingFileHandler: 파일을 일정 크기나 개수에 따라 자동으로 회전하여 저장합니다.
  4. TimedRotatingFileHandler: 파일을 일정 시간 간격으로 자동으로 회전하여 저장합니다.
  5. SocketHandler: 네트워크 소켓을 통해 로그 메시지를 전송합니다.
  6. SysLogHandler: 시스템 로그에 로그 메시지를 전송합니다.
  7. SMTPHandler: 이메일로 로그 메시지를 전송합니다.

    import logging

    # 로거 객체 생성
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.DEBUG)

    # 핸들러 생성 (파일 출력)
    file_handler = logging.FileHandler('my_log.log')
    file_handler.setLevel(logging.DEBUG)

    # 포매터 생성
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)

    # 핸들러 추가
    logger.addHandler(file_handler)

    # 로그 메시지 출력
    logger.debug('This is a debug message')
    logger.info('This is an info message')

 

위 코드에서는 FileHandler를 사용하여 로그 메시지를 파일로 저장하도록 설정했습니다. 이 핸들러를 생성하고 로거에 추가한 후, 로그 메시지를 출력하면 해당 파일에 로그 메시지가 저장됩니다.

 


 

로깅 메세지 포멧

파이썬 로깅(logging) 모듈을 사용하여 로그 메시지를 형식화하기 위해서는 포맷 문자열을 사용하여 로그 메시지의 형식을 지정할 수 있습니다.

이 포맷 문자열에는 로그 레코드의 속성을 나타내는 특수한 토큰들이 포함될 수 있습니다.

로깅 모듈에서 사용할 수 있는 주요 토큰들은 다음과 같습니다:

  • %(asctime): 현재 시간을 나타내는 문자열
  • %(name): 로거의 이름
  • %(levelname): 로그 레벨 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  • %(message): 로그 메시지 자체

asctime, levelname, message 등을 포함하는 기본 로그 메시지 형식은 다음과 같습니다:


    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'

 

이 포맷 문자열은 각 로그 레코드의 속성을 형식화하는 데 사용됩니다.

예를 들어, 위 형식을 사용하여 다음과 같이 로그 메시지를 출력할 수 있습니다:


    import logging

    logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                        level=logging.INFO)

    logger = logging.getLogger('my_logger')

    logger.info('This is an informational message')

 

# 결과
2022-01-01 12:00:00,000 - my_logger - INFO - This is an informational message

 


 

로그 필터링

로그 필터링(logging filtering)은 로깅 이벤트를 특정 기준에 따라 걸러내는 것을 말합니다.

이를 통해 특정 조건을 만족하는 로그 메시지만 기록하거나 출력할 수 있습니다.

파이썬의 logging 모듈에서는 Filter 클래스를 사용하여 로그 필터를 정의하고 적용할 수 있습니다.

   
    import logging

    # 로거 생성 및 레벨 설정
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.WARNING) # 로거 레벨 설정

    # 스트림 핸들러 생성 및 레벨 설정
    stream_handler = logging.StreamHandler()

    # 파일 핸들러 생성 및 레벨 설정
    file_handler = logging.FileHandler('app.log', mode='w')
    # 핸들러에 레벨을 설정 하면 logger의 레벨에 추가로 필터링 됨
    file_handler.setLevel(logging.ERROR)

    # 핸들러를 로거에 추가
    logger.addHandler(stream_handler)
    logger.addHandler(file_handler)

    # 로그 메시지 출력 (WARNING 이상만 출력됨)
    logger.debug('This is a debug message')   # 콘솔, 파일에 출력되지 않음
    logger.info('This is an info message')    # 콘솔, 파일에 출력되지 않음
    logger.warning('This is a warning message') # 콘솔 출력됨, 파일 출력되지 않음
    logger.error('This is an error message')  # 콘솔, 파일에 출력됨

 


 

로그 회전(Log rotation)

로그 회전(Log rotation)은 로그 파일의 크기나 날짜에 따라 일정한 기준으로 로그 파일을 분할하거나 회전시키는 것을 말합니다.

이를 통해 큰 로그 파일을 관리하고 로그를 정리할 수 있습니다.

파이썬의 logging 모듈에서는 RotatingFileHandler와 TimedRotatingFileHandler를 사용하여 로그 회전을 구현할 수 있습니다.

  1. RotatingFileHandler: 이 핸들러는 로그 파일의 크기나 개수에 따라 자동으로 로그 파일을 회전합니다. 새로운 로그 메시지가 추가될 때마다 로그 파일이 일정 크기를 초과하거나 일정 개수의 파일을 초과하는 경우, 가장 오래된 로그 파일이 삭제되고 새로운 로그 파일이 생성됩니다.
  2. TimedRotatingFileHandler: 이 핸들러는 로그 파일을 시간에 따라 자동으로 회전합니다. 지정된 시간 간격에 따라 로그 파일이 새로 생성되고 이전 로그 파일이 백업되거나 삭제됩니다.

RotatingFileHandler


    import logging
    from logging.handlers import RotatingFileHandler

    # 로그 회전 핸들러 생성
    handler = RotatingFileHandler('app.log', maxBytes=10000, backupCount=5)

    # 로거에 핸들러 추가
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.INFO)
    logger.addHandler(handler)

    # 로그 메시지 출력
    for i in range(1000):
        logger.info(f'This is log message {i}')
       

 

 

# 결과
app.log.2, app.log.1, app.log 파일이 생성되었습니다.

 

 

TimedRotatingFileHandler


    import logging
    from logging.handlers import TimedRotatingFileHandler
    import time

    # 로그 회전 핸들러 생성 (매일 자정에 로그 파일 교체)
    handler = TimedRotatingFileHandler('app.log', when='S', interval=2, backupCount=7)

    # 로거에 핸들러 추가
    logger = logging.getLogger('my_logger')
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)

    # 로그 메시지 출력
    for i in range(3):
        time.sleep(1)
        logger.info(f'{i}: This is an info message')
       

 

#결과
app.log.년월일시분초, app.log 파일이 생성되었습니다.

 

위 코드에서 TimedRotatingFileHandler를 생성할 때 다음과 같은 매개변수를 사용합니다:

  • filename: 로그 파일의 경로와 파일명을 지정합니다.
  • when: 로그 파일이 회전되는 시점을 지정합니다. 여기서 'midnight'는 자정을 의미합니다.
  • interval: 로그 파일을 회전하는 주기를 지정합니다. 여기서는 1일 간격으로 회전합니다.
  • backupCount: 유지할 백업 파일의 개수를 지정합니다. 새로운 파일이 생성될 때마다 이전 파일은 백업되거나 삭제됩니다.

로깅종합

  1. 로거 객체 생성: logging.getLogger() 함수를 사용하여 로거 객체를 생성합니다. 이때 로거의 이름을 지정할 수 있습니다.
  2. 로거 레벨 설정: logger.setLevel() 메서드를 사용하여 로거의 레벨을 설정합니다. 설정된 레벨보다 낮은 레벨의 로그 메시지는 기록되지 않습니다.
  3. 핸들러 객체 생성: 로그 메시지를 어디로 보낼지를 결정하는 핸들러 객체를 생성합니다. StreamHandler, FileHandler, RotatingFileHandler, TimedRotatingFileHandler 등을 사용할 수 있습니다.
  4. 핸들러 레벨 설정: handler.setLevel() 메서드를 사용하여 핸들러의 레벨을 설정합니다. 이 설정은 핸들러에 의해 처리되는 로그 메시지의 최소 레벨을 결정합니다.
  5. 핸들러에 포매터 지정: handler.setFormatter() 메서드를 사용하여 핸들러에 포매터를 지정합니다. 이를 통해 로그 메시지의 형식을 지정할 수 있습니다.
  6. 로거에 핸들러 추가: logger.addHandler() 메서드를 사용하여 로거에 핸들러를 추가합니다. 이렇게 하면 로거는 해당 핸들러를 통해 로그 메시지를 전송합니다.

    import logging

    # 로거 객체 생성
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.DEBUG)

    # 파일 핸들러 생성
    file_handler = logging.FileHandler('my_log.log')
    file_handler.setLevel(logging.DEBUG)

    # 콘솔 핸들러 생성
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)

    # 포매터 생성
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # 핸들러에 포매터 지정
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)

    # 로거에 핸들러 추가
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)

    # 로그 메시지 출력
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')

 

 

 

반응형

'Python' 카테고리의 다른 글

[Python] 가상환경 - venv  (0) 2024.04.03
[Python] YAML  (1) 2024.03.23