본문 바로가기
Python

[Python] Logging 모듈로 로그 남기기

by teamnova 2021. 8. 26.

안녕하세요!

오늘은 파이썬 기본 라이브러리 중 하나인 'Logging' 모듈을 이용하여 로그를 남겨보도록 하겠습니다.

 

테스트 환경

- Ubuntu 18.04.5 LTS

- Python 3.6.9

 

1. Logging 모듈?

Logging 모듈은 파이썬 기본 라이브러리 중 하나로, 로그 Level을 정의하여 중요도를 정할 수 있고 콘솔 상에 표기되는 로그 뿐만 아니라 파일 형태로 로그를 생성 할 수 있습니다.

 

2. 사용법

2-1. Logger 인스턴스 생성

먼저 logging 모듈을 사용하기 위해서 import logging 을 해줍니다.

다음으로 logger 인스턴스를 생성해주는데

아래 '__name__' 은 logger의 이름을 설정해주는 부분입니다.

 

import logging

# logger instance 생성
logger = logging.getLogger(__name__)

아무런 이름 없이 호출하게 되면 자동으로 root logger 로 설정되며,

모든 logger의 부모와 같은 형태가 됩니다.

(해당 내용은 포스트 아래에서 한번 더 다뤄보도록 하겠습니다.)

 

원하는 logger의 이름을 String 자료형으로 입력해주면 됩니다.

 

 

2-2. Handler 설정

로그를 기록할 때,

handler 설정을 통해 콘솔창에 출력하는 것과 파일에 로그가 기록되도록 설정할 수 있습니다.

# handler 생성 (stream, file)
streamHandler = logging.StreamHandler()
fileHandler = logging.FileHandler('./test.log')

# logger instance에 handler 설정
logger.addHandler(streamHandler)
logger.addHandler(fileHandler)

StreamHandler() : 콘솔 출력

FileHandler() : 파일 출력

 

FileHandler 에 로그를 생성할 디렉토리+파일을 설정 해주시면

해당 파일이 없을 시, 파일이 생성되면서 로그가 출력되고

파일이 있을 시, 기존 파일에 이어서 로그가 출력됩니다.

 

handler 생성 후 logger에 설정을 추가해 줍니다.

logger.addHandler()

 

# logger instnace로 log 찍기
logger.setLevel(level=logging.DEBUG)
logger.debug('my DEBUG log')
logger.info('my INFO log')
logger.warning('my WARNING log')
logger.error('my ERROR log')
logger.critical('my CRITICAL log')

 

위 코드는 로그를 출력하기 위한 코드 입니다. 앞선 코드들 아래에 추가 한 뒤 출력하게 되면 아래와 같이 출력 됩니다.

콘솔 출력 결과
파일 출력 결과

 

2-3. 출력

위에서 handler 설정 후 로그 출력까지 진행해 보았습니다.

로그 출력 시 Debug, Info, Warning 등 로그의 Level을 설정 할 수 있는데요.

 

DEBUG 간단히 문제를 진단하고 싶을 때 필요한 자세한 정보를 기록함
INFO 계획대로 작동하고 있음을 알리는 확인 메시지
WARNING 소프트웨어가 작동은 하고 있지만,

예상치 못한 일이 발생했거나 할 것으로 예측된다는 것을 알림
ERROR 중대한 문제로 인해 소프트웨어가 몇몇 기능들을 수행하지 못함을 알림
CRITICAL 작동이 불가능한 수준의 심각한 에러가 발생함을 알림

 

위 표와 같이 Level을 설정 하여 로그를 출력할 수 있으며,

setLevel() 메소드를 이용하여, 출력 범위를 정할 수 있습니다.

 

# logger instnace로 log 찍기
logger.setLevel(level=logging.ERROR) #logging.DEBUG -> logging.ERROR
logger.debug('my DEBUG log')
logger.info('my INFO log')
logger.warning('my WARNING log')
logger.error('my ERROR log')
logger.critical('my CRITICAL log')

 

setLevel() 을 DEBUG로 설정 했을 때와 ERROR로 설정했을때, 아래와 같이 출력 결과물이 달라집니다.

 

* logging.DEBUG

* logging.ERROR

 

Level을 설정해주지 않았을 때, 기본 셋팅 값인 WARNING으로 설정 됩니다.

 

 

2-4. Formatter 설정

로그 출력 시 입력하는 데이터(message) 외 원하는 데이터를 미리 설정하여 출력 할 수 있습니다.

formatter 설정을 통해 출력할 로그의 폼을 아래 예시와 같이 사용이 가능합니다.

 

# formatter 생성
formatter = logging.Formatter('[%(asctime)s][%(levelname)s|%(filename)s:%(lineno)s] >> %(message)s')

# handler 생성 (stream, file)
streamHandler = logging.StreamHandler()

# logger instance에 fomatter 설정
streamHandler.setFormatter(formatter)

 

* 출력

 

위 코드와 같이 설정 후, 출력을 하게 되면 아래 콘솔창과 같이 로그가 출력됩니다.

 

사용 방법은 다음과 같습니다.

%(format 명칭)s

%(format 명칭)f

%(format 명칭)d

속성 format 설명
asctime %(asctime)s 인간이 읽을 수 있는 시간 표시
created %(created)f logRecord가 만들어진 시간
filename %(filename)s pathname의 file 이름 부분
funcName %(funcName)s logging call을 포함하는 function의 이름
levelname %(levelname)s 메시지의 Text logging level: 예) INFO
lineno %(lineno)d logging call이 발생한 코드의 line 숫자
module %(module)s filename의 모듈 이름 부분
message %(message)s 메시지
name %(name)s logger의 이름
pathname %(pathname)s full pathname
thread %(thread)d thread ID
threadName %(threadName)s thread 이름

 

 

3. 전체 코드

import logging

# logger instance 생성
logger = logging.getLogger(__name__)

# formatter 생성
formatter = logging.Formatter('[%(asctime)s][%(levelname)s|%(filename)s:%(lineno)s] >> %(message)s')

# handler 생성 (stream, file)
streamHandler = logging.StreamHandler()
fileHandler = logging.FileHandler('./test.log')

# logger instance에 fomatter 설정
streamHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)

# logger instance에 handler 설정
logger.addHandler(streamHandler)
logger.addHandler(fileHandler)

# logger instnace로 log 찍기
logger.setLevel(level=logging.DEBUG)
logger.debug('my DEBUG log')
logger.info('my INFO log')
logger.warning('my WARNING log')
logger.error('my ERROR log')
logger.critical('my CRITICAL log')

 

 

 

+ root logger 와 하위 logger

root logger와 my logger 를 생성 후

my logger 를 출력하게 되면, 상위 root logger 에 전파 되기 때문에 아래와 같이 두번 출력이 됩니다.

# 루트 로거 생성
rootLogger = logging.getLogger()
rootLogger.setLevel(logging.INFO)
rootStreamHandler = logging.StreamHandler()
rootLogger.addHandler(rootStreamHandler)

# my 로거 생성
myLogger = logging.getLogger("my")
myLogger.setLevel(logging.INFO)
myStreamHandler = logging.StreamHandler()
myLogger.addHandler(myStreamHandler)

# my 로거 출력
myLogger.info("My Logger Info")

 

상위 root logger에 전파되는것을 막으려면

 

myLogger.propagate = 0
#or
myLogger.propagate = False

 

'propagate' 옵션을 '0' 또는 'False' 로 설정 해주시면 됩니다.

 

 

 

참고 포스팅

* logging 모듈 사용

https://stickode.com/detail.html?no=2359 

 

스틱코드

 

stickode.com