현재 우리의 프로그램이 어떤 상태를 가지고 있는지, 외부출력을 하게 만들어서 개발자등이 눈으로 직접 확인하는 것 입니다.
파이썬에서 로깅 모듈은 기본 라이브러리에 포함되어 있기 때문에, 굳이 따로 설치 할 필요는 없습니다.
import logging
if __name__ == '__main__':
logging.error("something wrong!!")
결과: ERROR:root:somthing wrong!!
파이썬 로깅 level의 기본 설정은 WARNING 입니다. 따라서 DEBUG < INFO < WARNING < ERROR < CRITICAL
이 순서에서 더 높은 레벨인 ERROR 는 출력이 되지만, 하위레벨 (INFO,DEBUG) 은 출력이 안됩니다.
센서로 부터 데이터를 받는 IoT 서비스에서 로깅을 출력 할 때 DATA 만을 확인해 보고 싶을 경우가 있습니다. 이 경우 DEBUG 보다 한단계 아래에 로깅 설정을 할 수 있게 되는데요
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
위처럼 각 레벨에는 숫자가 10단위로 적용되어 있습니다. 예상 할 수 있다시피, 내부에서는
if level > 세팅된 레벨:
출력
식으로 되어 있어서 세팅된 레벨보다 출력레벨이 클 경우에 한 해서만 출력하고 있습니다.
if ERROR > INFO : 세팅이 INFO 면 ERROR 는 출력
if DEBUG > INFO : 세팅이 INFO 면 DEBUG 는 출력하지 않음
따라서 DATA = 15 이렇게 설정해 두면, DEBUG 정보는 출력하지 않고, DATA 레벨만 출력하게 됩니다.
사용 예는 아래와 같습니다.
logging.addLevelName(15, "DATA")
logging.DATA = 15
logger.log(logging.DATA, "message")
import logging
if __name__ == '__main__':
mylogger = logging.getLogger("my") #4-1
mylogger.setLevel(logging.INFO) #4-2
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 4-5
stream_hander = logging.StreamHandler() #4-3
stream_hander.setFormatter(formatter) #4-5
mylogger.addHandler(stream_hander) #4-3
file_handler = logging.FileHandler('my.log') #4-4
mylogger.addHandler(file_handler) #4-4
mylogger.info("server start!!!") #4-3
결과: server start!!! #4-3
이렇게 호출하면 "my" 라는 특정 로거를 생성하게 됩니다.
그냥 매개변수 없이 logging.getLogger()
or logging.getLogger("")
이렇게 만들 수도 있습니다.
이렇게 하면 루트로거 를 리턴하게 되며, 루트로거는 로깅시스템의 기본로거이고 기본레벨은 warning 을 가지고 있습니다.
setLevel 메소드를 통해서 INFO 레벨 이상은 출력 하도록 설정 하였습니다. (DEBUG 출력 안함)
핸들러란 내가 로깅한 정보가 출력되는 위치 설정하는 것을 말합니다. 위에서는 콘솔을 통해 출력하도록 설정 했지만, 파일,DB,소켓,큐등을 통해 출력 하도록 설정 할 수도 있습니다.
logging.FileHandler 클래스를 통해 객체를 만들어서 나의 로거에 추가해주면 됩니다. 현재 디렉토리에 파일(my.log)이 만들어 질 것 입니다.
파일은 a 모드로 열리는게 디폴트입니다. a 모드란 같은 이름의 파일이 이미 있다면, 파일 끝에 추가하여 쓰고, 없다면 쓰기용으로 파일 만들라는 뜻입니다.
server start!!! 라는 메세지 말고도, 이 메세지가 언제 쓰여졌는지, 어떤 모듈에서 쓰여졌는지 등 기타 정보를 같이 출력하고 싶을 것입니다. 이때 포매팅이란 것을 하게 되는데요.
asctime 시간
name 로거이름
levelname 로깅레벨
message 메세지
이것 말고도 모듈이름, 파일이름, 출력라인넘버등 다앙하게 많으니, 더 많은 정보는 메뉴얼을 참고 하시구요. 위에서는 포매터를 콘솔출력에 한정해서 적용했기에 파일은 기존 그대로 출력 될 것입니다. 파일도 포매팅되게 하고 싶으면 역시 포매터를 파일 핸들러에도 추가하세요.
log는 서버에서 많이 사용한다. 어떤 형식으로든지 log를 출력하고 싶을 때 사용한다.
import logging
# 로그 생성
logger = logging.getLogger()
# 로그의 출력 기준 설정
logger.setLevel(logging.INFO)
#log 출력 형식
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(messages)s")
# log를 console에 출력
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
#log를 파일에 출력
file_handler = logging.FileHandler("my.log")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
for i in range(10):
logger.info(f"{i}번째 방문입니다.")
(임의의 이름으로 생성된 logger는 모두 root logger의 자손이 됩니다.)
이벤트의 심각도는 DEBUG, INFO, WARNING, ERROR, CRITICAL 순입니다. 기본 설정은 WARNING으로 DEBUG와 INFO log들은 출력되지 않지만, setLevel 함수로 이를 설정해 줄 수 있습니다.
위처럼 logger.setLevel(logging.INFO)로 설정한 경우, INFO에 대한 log도 출력으로 확인할 수 있습니다.
%(asctime)s - %(name)s - %(levelname)s - %(message)s
이는 각각 시간, logger의 이름, INFO/ERROR 등의 log레벨의 종류, 메시지입니다.
file_handler는 파일에 쓰는 것이기 때문에 원하는 파일명을 파라미터로 넣어주면 되겠습니다.
또한 위에서 선언한 formatter를 각각 적용해줍니다.
이제 반복문을 통해 10번의 log를 출력해 보았는데요, 아래와 같이 console창에 출력도 되고 또한 my.log라는 파일에도 잘 출력된 것을 확인할 수 있습니다.
logging에 대한 공식 문서는 https://docs.python.org/ko/3/howto/logging.html 여기에서 더욱 자세히 확인할 수 있습니다.
자료 출처