프로그래밍 문법/python

logging이란?

씩씩한 IT블로그 2021. 2. 15. 16:24
반응형

logging이란?

logging은 오류의 발생위치 및 종류를 확인하는 도구이다.

사용자별로 필요한 오류의 종류에 맞게 logging의 객체를 만들고 확인하고 싶은 위치에 logging코드를 추가한다.

그럼 해당 위치에서 사용자가 지정한 오류를 확인할 수 있다.

아래의 예시와 같이 쓴다.

(example)

 

전체 flow

먼저 전체 플로우를 미리 보면 아래와 같다

 

아래에서 구체적인 과정을 설명한다. 사진에 보이는 순서와 번호대로 매핑했다.

 

logging 과정

1. logging 객체 생성 

logging의 객체를 생성하고 레벨을 설정한다. 레벨은 아래에서 설명한다.

    #1.logger 객체
    logger = logging.getLogger("brave_log") #객체 생성
    logger.setLevel(logging.DEBUG) # 레벨 설정

 

2. handler 객체

그 다음은 logging객체에 handler객체를 추가해야 한다.

handler는 logger(logging의 객체)가 찾은 오류를 어떻게 사용자에게 보여줄지 결정해 준다.

handler은 총 15가지가 있다. 아래의 파이썬 공식싸이트에서 모든 종류를 확인할 수 있다.

docs.python.org/3.7/howto/logging.html#useful-handlers

handler는 생성 -> 레벨설정 -> 포멧설정 -> logging객체에 추가 순으로 진행된다.

 

    2.1 handler 객체 생성

	#2.handler 객체
    fileHandeler = logging.FileHandler(filename="./test.txt") #2.1객체생성
    streamHandler = logging.StreamHandler()

 

    2.2 레벨설정

    fileHandeler.setLevel(logging.INFO) #2.2레벨 설정
    streamHandler.setLevel(logging.DEBUG)

핸들러마다 레벨을 설정해주어야 한다.

핸들러에 레벨을 설정해주면, 특정 레벨을 실행했을 때 해당 레벨 이상의 핸들러만 동작을 한다.

레벨의 순서는 아래와 같다. (1번이 제일 낮은 레벨이고 5번이 제일 높은 레벨이다.)

  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

위 코드처럼 streamHandler의 레벨을 DEBUGfileHandler의 레벨을 INFO로 설정하고 DEBUG와 INFO를 실행했다고 가정하자.

- debug() 실행시
streamHandler(콘솔창에 오류찍음)는 debug레벨이기 때문에 콘솔창에 'debug'레벨이상의 오류는 다 찍힌다. 따라서 'debug'가 찍힌다.
하지만 fileHandler(로그파일에 오류찍음)는 info레벨이기 때문에 info레벨 이상만 찍힌다. 따라서 로그 파일에 'debug'가 찍히지 않는다.

- info() 실행시
streamHandler(콘솔창에 오류찍음)는 debug레벨 이상은 다 찍히기 때문에 콘솔장에 'info'가 찍힌다
또한 fileHandler(로그파일에 오류찍음)는 info레벨이상은 다 찍히기 때문에 파일로그창에도 'info'가 찍히는 것이다

따라서 결과는 아래와 같다

콘솔창
로그 텍스트파일

 

    2.3 포매팅 객체 생성, 2.4 포메팅 설정

#2.3포멧 생성
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") 

#2.4포멧 설정
fileHandeler.setFormatter(formatter) 
streamHandler.setFormatter(formatter)

로그메세지를 어떤식으로 출력할지 정하는 과정이다.  위와같이 설정하면 아래와 같이 출력된다

포메팅의 종류는 아래와 같다. ( 파이썬 공식문서 : docs.python.org/ko/3.7/library/logging.html#logging.Formatter )

args

직접 포맷할 필요는 없습니다.

message 를 생성하기 위해 msg 에 병합되는 인자의 튜플. 또는 (인자가 하나뿐이고 딕셔너리일 때) 병합을 위해 값이 사용되는 딕셔너리.

asctime

%(asctime)s

사람이 읽을 수 있는, LogRecord 가 생성된 시간. 기본적으로 〈2003-07-08 16:49:45,896〉 형식입니다 (쉼표 뒤의 숫자는 밀리 초 부분입니다).

created

%(created)f

LogRecord 가 생성된 시간 (time.time() 이 반환하는 시간).

exc_info

직접 포맷할 필요는 없습니다.

예외 튜플 (sys.exc_info 에서 제공) 또는, 예외가 발생하지 않았다면, None.

filename

%(filename)s

pathname 의 파일명 부분.

funcName

%(funcName)s

로깅 호출을 포함하는 함수의 이름.

levelname

%(levelname)s

메시지의 텍스트 로깅 수준 ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').

levelno

%(levelno)s

메시지의 숫자 로깅 수준 (DEBUG, INFO, WARNING, ERROR, CRITICAL).

lineno

%(lineno)d

로깅 호출이 일어난 소스 행 번호 (사용 가능한 경우).

message

%(message)s

로그 된 메시지. msg % args 로 계산됩니다. Formatter.format() 이 호출 될 때 설정됩니다.

module

%(module)s

모듈 (filename 의 이름 부분).

msecs

%(msecs)d

LogRecord 가 생성된 시간의 밀리 초 부분.

msg

직접 포맷할 필요는 없습니다.

원래 로깅 호출에서 전달된 포맷 문자열. args 와 병합하여 message 를 만듭니다. 또는 임의의 객체 (임의의 객체를 메시지로 사용하기 를 보세요).

name

%(name)s

로깅 호출에 사용된 로거의 이름.

pathname

%(pathname)s

로깅 호출이 일어난 소스 파일의 전체 경로명 (사용 가능한 경우).

process

%(process)d

프로세스 ID (사용 가능한 경우).

processName

%(processName)s

프로세스 이름 (사용 가능한 경우).

relativeCreated

%(relativeCreated)d

logging 모듈이 로드된 시간을 기준으로 LogRecord가 생성된 시간 (밀리 초).

stack_info

직접 포맷할 필요는 없습니다.

현재 스레드의 스택 바닥에서 이 레코드를 생성한 로깅 호출의 스택 프레임까지의 스택 프레임 정보 (사용 가능한 경우).

thread

%(thread)d

스레드 ID (사용 가능한 경우).

threadName

%(threadName)s

스레드 이름 (사용 가능한 경우).

 

3. loggger에 핸들러 추가

    #3.logger에 handler 추가
    logger.addHandler(fileHandeler)
    logger.addHandler(streamHandler)

 

전체 코드

1. 소스코드

import logging.handlers

def logger_object():
    #1.logger 객체
    logger = logging.getLogger("brave_log") #객체 생성
    logger.setLevel(logging.DEBUG) # 레벨 설정

    #2.handler 객체
    fileHandeler = logging.FileHandler(filename="./test.txt") #2.1객체생성
    streamHandler = logging.StreamHandler()

    fileHandeler.setLevel(logging.INFO) #2.2레벨 설정
    streamHandler.setLevel(logging.DEBUG)

    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") #2.3포멧 생성

    fileHandeler.setFormatter(formatter) #2.4포멧 설정
    streamHandler.setFormatter(formatter)

    #3.logger에 handler 추가
    logger.addHandler(fileHandeler)
    logger.addHandler(streamHandler)

    return logger

logger=logger_object()

logger.debug('debug')
logger.info('info')
logger.warning('warning')
logger.error('error')
logger.critical('critical')

 

2. 결과

콘솔창
로그 txt파일

 

( 파이썬 logging 공식문서 : docs.python.org/ko/3.7/library/logging.html#logging.Handler )

반응형