기본적인 사용방법

해당 글에서는 python의 logging 기본적인 사용방법을 다룬다. 관련해서 마주할 수 있는 에러 상황이나, 좀 더 다양한 상황을 다룰 수 있는 logging 사용방법을 기술해 보았다.

 

 

추가적으로 해당 글에서는 특정 메시지를 어떤 레벨로 로깅해야 하는지와 같은 철학은 다루지 않음을 감안해 주시면 좋겠다.

 

 

짧은 글이기에 바로 본론으로 들어가보자. 코드는 짧고 간결하다.

 

 

import logging

logging.basicConfig(filename='../logs/crawl.log', format='%(asctime)s %(levelname)s %(message)s')
logging.getLogger().setLevel(logging.INFO) # Optional

logging.info("This message is logged with INFO level")

logging.warn("This message is logged with WARNING level")

 

 

이 정도의 코드만으로도 대부분의 파이썬 프로그램은 로깅이 가능하다.

 

 

logging.basicConfig()

 

 

로깅을 기록하기 위한 기본적인 설정이 이뤄진다. 위의 코드에서는 파일 이름과 로깅 시 메시지에 앞서 기록될 템플릿이 명시되어 있다.

 

 

주의해야 할 점은 명시한 파일의 경우, logging이 자동으로 생성해주지 않는다는 것이다. 직접 touch나 vi를 통해 생성해야 한다.

 

 

logging.getLogger().setLevel(logging.INFO)

logging의 기본 로깅 레벨은 WARNING으로 INFO의 레벨로 설정된 메시지는 로그에 남지 않는다. 해당 코드에서는 INFO까지도 기록하기 위해 해당 라인을 추가해 보았다.

 

 

logging.info("This message is logged with INFO level")

INFO 레벨의 로깅이다.

 

 

logging.warn("This message is logged with WARN level")

WARN 레벨의 로깅이다.

 

 

다만 이렇게 했는데도, 해당 파일에 로깅이 되지 않는 문제가 생길 수 있다.

경험상 순서대로 3가지 정도를 점검해 볼 수 있다

1. 경로가 정확한지, 또 파일은 정상적으로 생성이 된 상태인지

2. 로깅 레벨이 당초 의도한 대로 설정되어 있는지 (WARN인 경우 INFO는 당연히 기록되지 않는다.)

3. 권한이 충분한지, py 파일이 로그 파일에 접근하여 쓰기 작업을 진행할 수 있는 권한이 있는지

 

 

이 정도 문법만으로도 사실 충분하지만 handler라는 친구를 통해 더욱 유연하게 상황에 맞는 로그를 작성할 수 있다.

 

logging.FileHandler

import logging

# logging 객체를 생성한다
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)

# 디버그 레벨 핸들러를 생성한다
debug_handler = logging.FileHandler('../logging/debug.log')
debug_handler.setLevel(logging.DEBUG)
debug_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
debug_handler.setFormatter(debug_formatter)

# 에러 레벨 핸들러를 생성한다
error_handler = logging.FileHandler('error.log')
error_handler.setLevel(logging.ERROR)
error_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
error_handler.setFormatter(error_formatter)

# 생성한 logging 객체에 핸들러들을 등록한다
logger.addHandler(debug_handler)
logger.addHandler(error_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')

 


Handler의 역할은 다양할 수 있지만, 앞선 코드와 같이 다양한 핸들러가 각기 다른 로깅 레벨에 맞춰 해당 메시지를 처리하는 경우에 활용할 수 있다.

 

 

debug_handler = logging.FileHandler('../logging/debug.log')

 

 

파일 핸들러를 만든다. 이때의 파라미터는 작성될 파일의 이름이다. 앞선 basicConfig와 동일하게 파일은 생성해주지 않는다.

 

 

debug_handler.setLevel(logging.DEBUG)
debug_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') 
debug_handler.setFormatter(debug_formatter)

 

 

예상하셨겠지만, 디폴트 레벨 설정 부분과 로그 메시지의 앞쪽에 붙게 되는 템플릿이다.

 

 

이후 생성한 핸들러를 객체에 등록하면 설정이 완료된다.

 

 

logger.addHandler(debug_handler)

 

 

아래의 getLogger 메소드는 로깅 객체를 반환한다. 

 

 

logger = logging.getLogger('my_logger')

 

 

 

my_logger는 해당 logging object를 식별할 수 있는 일종의 키이다. 이후에 다시 my_logger를 getLogger에 넣어준다면 동일한 로깅 객체가 반환된다.

 

 

 

사실 FileHandler 말고 기능이 좀 더 풍부한 RotatingFileHandler와 TimeRoatatingFileHandler라는 클래스도 존재한다. 대단한 친구들은 아니고, FileHandler보다 좀 더 풍부한 기능들을 제공한다고 생각하면 된다. FileHandler를 상속받는 친구들이다.


FileHandler의 경우 다소 한계점들이 존재한다. 만약 로그 파일이 특정 사이즈에 도달하 경우 FileHandler는 기존 파일에 작성하던 걸 멈추고 파일을 닫는다. 결과적으로 로깅이 멈춘다.


반면 RotatingFileHandler, TimeRoatatingFileHandler에서는 FileHandler와 거의 동일한 역할을 수행하지만 몇 가지 추가적인 기능이 붙어있다.


예를 들어 RotatingFileHandler의 경우, maxBytes를 통해 최대 몇 바이트까지 쓰게 되면, 기존 파일을 닫고 새로운 파일을 열어 로깅을 이어나가도록 지정할 수 있다. (기본값은 0으로 닫지 않고 쭉 작성)


backupCount라는 옵션을 통해 백업의 최대 개수를 지정할 수도 있다. (기본값은 0)

'Programming Language > Python' 카테고리의 다른 글

게으른 로깅  (0) 2023.07.29
[pytest] @pytest.fixture  (0) 2023.05.02