파이썬에서의 로깅
logging 라이브러리
기초 사용법
- (1)
import logging 을 통해 표준 라이브러리를 임포트한다.
- (2)
logging.getLogger() 를 이용해 로거 인스턴스를 생성한다.
- (3) 처리할 로그 레벨, 수행할 작업(파일 기록/스트림 등), 기록할 파일명 등 설정을 수행한다.
- (4)
logger.info(message) 와 같은 함수를 이용해 로깅을 수행한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| import logging # logging 표준 라이브러리를 사용한다.
def logging_basic():
# 로거 객체를 생성
logger_name = "logging_basic" # 로거 이름 설정
logger = logging.getLogger(logger_name)
# 로깅 설정
filename = "logs/logging_basic_log.log" # 로그를 기록할 파일 경로 설정
logging.basicConfig(
filename=filename, # 로그를 기록할 파일 경로
level=logging.DEBUG, # 로거가 처리할 최소 로그 레벨
encoding='utf-8' # 파일 인코딩
)
# basicConfig : 간단한 기본 로깅 설정
# filename 을 지정하면 FileHandler 로 파일에 로그를 기록하며,
# filename 을 지정하지 않으면 StreamHandler 로 콘솔에 로그를 출력한다.
# 로그 메시지를 기록한다.
logger.info("info 메시지입니다.")
logger.debug("debug 메시지입니다.")
logger.warning("warning 메시지입니다.")
logger.error("error 메시지입니다.")
if __name__ == "__main__":
logging_basic()
|
로그 레벨
- 로그 레벨은 기본적으로
NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL 6단계로 구성된다.
- 이들은 각각 정수값으로 표현되는데, 순서대로 0, 10, 20, 30, 40, 50 이다.
- 여기에 사용자가 커스터마이징 하여 새로운 로그 레벨을 넣을 수도 있다.
- 로그 레벨은 아래 세 부분에서 사용된다.
- (1) 로거가 처리할 최소의 로그 레벨
- (2) 핸들러가 처리할 최소의 로그 레벨
- (3) 로그 메시지의 로그 레벨
- 로거 또는 핸들러는, 자신에게 설정된 로그 레벨 미만의 로그는 처리하지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| import logging
from logging import LogRecord
def log_level_test():
# 로거 객체를 생성
logger_name = "log_level"
logger = logging.getLogger(logger_name)
# 로깅 설정
filename = "logs/log_level_log.log"
logging.basicConfig(filename=filename,
level=logging.INFO, # 로거가 처리할 최소의 로그 레벨을 INFO 로 정함
encoding='utf-8')
# 로그 레벨은 기본적으로 6개의 단계로 이루어져 있다.
# 그리고 이들은 정수값을 가지고 있다.
# logging.__init__.py 파일에서 자세하게 살펴볼 수 있다.
"""
CRITICAL = FATAL = 50
ERROR = 40
WARNING = WARN = 30
INFO = 20
DEBUG = 10
NOTSET = 0
"""
# 로그 메시지를 기록한다.
# 설정한 레벨 미만의 로그는 기록되지 않는다.
logger.debug("debug 메시지입니다.")
logger.info("info 메시지입니다.")
logger.warning("warning 메시지입니다.")
logger.error("error 메시지입니다.")
if __name__ == "__main__":
log_level_test()
|
- 아래는 로그가 저장된 log_level_log.log 파일이다.
- 로거의 로그 레벨인
INFO 미만인 logger.debug()를 통해 보내진 로그메시지는 기록되지 않은 것을 볼 수 있다.
1
2
3
4
| # log_level_log.log
INFO:log_level:info 메시지입니다.
WARNING:log_level:warning 메시지입니다.
ERROR:log_level:error 메시지입니다.
|
파일에 로깅하기 - 편집 모드
- 파일에 로깅할 때는 w(쓰기), a(추가), r(읽기) 세 가지 모드(mode) 가 존재한다.
- 모드는 로거 안의 파일 핸들러(추후에 소개)를 선언할 때 설정해줄 수 있다.
w(쓰기) : 로그 파일을 새로 쓴다. 기존의 내용이 사라지니 주의!
a(추가) : 기존의 내용에 이어서 로그를 추가한다.
r(읽기) : 읽기 전용으로, 로깅에 사용할 수 없다. 오류가 발생하니 주의!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| import logging # logging 표준 라이브러리를 사용한다.
def logging_to_file():
# 로거 객체를 생성
logger_name = "log_to_file"
logger = logging.getLogger(logger_name)
logger.propagate = False # 전파 방지
# 로깅 설정
filename = "logs/log_to_file_log.log"
logging.basicConfig(filename=filename,
level=logging.INFO,
encoding='utf-8')
"""
파일에 로그를 작성할 때에는 "편집 모드" 를 지정할 수 있다.
편집모드는 w(쓰기), a(추가), r(읽기) 세 가지가 있다.
"""
# 기본 편집 모드는 a(추가) 이다.
logger.info("file에 로깅하는 첫 메시지입니다.")
logger.info("file에 로깅하는 두 번째 메시지입니다.")
with open(filename, 'r') as f:
print(f.readlines())
# 편집 모드를 w(쓰기)로 하면 -> 이전의 내용이 없어지고, 새로 쓰여진다.
logger.handlers.clear()
file_handler = logging.FileHandler(filename=filename, mode='w',encoding='utf-8')
file_handler.setLevel(logging.INFO)
logger.addHandler(file_handler)
logger.error("w(쓰기 모드)로 로깅한 새로운 로그입니다.")
with open(filename, 'r') as f:
print(f.readlines())
# 편집 모드를 a(추가)로 바꾼다면 -> 이전의 내용에 이어서 로그가 작성된다.
logger.handlers.clear()
file_handler = logging.FileHandler(filename=filename, mode='a',encoding='utf-8')
file_handler.setLevel(logging.INFO)
logger.addHandler(file_handler)
logger.error("a(추가 모드)로 로깅한 추가 편집 메시지입니다.")
with open(filename, 'r') as f:
print(f.readlines())
# 로깅 설정을 "읽기"로 바꾼다면
logger.handlers.clear()
file_handler = logging.FileHandler(filename=filename, mode='r', encoding='utf-8')
file_handler.setLevel(logging.INFO)
logger.addHandler(file_handler)
logger.error("읽기 전용 메시지입니다.") # 에러 발생 : io.UnsupportedOperation: not writable
if __name__ == "__main__":
logging_to_file()
|
메시지 포맷 정하기 (간단)
- 로그 메시지의 포맷을 정할 수 있다.
- 자세한 내용은 추후 포매터(Formatter) 부분에서 다루도록 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| import logging # logging 표준 라이브러리를 사용한다.
def change_message_format():
# 로거 객체를 생성
logger_name = "message_format"
logger = logging.getLogger(logger_name)
# 로깅 설정
filename = "logs/message_format_log.log"
logging.basicConfig(filename=filename, level=logging.INFO, encoding='utf-8')
# 기본적인(basicConfig) 메시지 포맷 테스트
logger.error("기본적인(basicConfig) 메시지 포맷 테스트")
# 포맷 변경
# 자세한 포맷 작성법은 logging.__init__.py 의 Formatter 클래스 부분에서 확인 가능
logger.propagate = False # 전파 방지
logger.handlers.clear()
new_format = logging.Formatter("%(lineno)s %(levelname)s - %(process)s %(filename)s %(message)s") # 새로운 포맷
file_handler = logging.FileHandler(filename=filename, mode='a', encoding='utf-8')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(new_format) # 포맷 설정
logger.addHandler(file_handler)
logger.error("로깅 포맷 설정을 바꿔보았습니다.")
if __name__ == "__main__":
change_message_format()
|
1
2
| ERROR:message_format:기본적인(basicConfig) 메시지 포맷 테스트
24 ERROR - 8912 logging_04_message_format.py 로깅 포맷 설정을 바꿔보았습니다.
|
날짜 표시 형식 바꾸기
- 로그 생성 날짜(asctime) 의 표현 방식을
datefmt 파라미터로 지정할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| import logging # logging 표준 라이브러리를 사용한다.
import time
def log_datetime():
# 로거 객체를 생성
logger_name = "datetime_format"
logger = logging.getLogger(logger_name)
# 로깅 설정
filename = "logs/datetime_format_log.log"
logging.basicConfig(filename=filename, level=logging.INFO, encoding='utf-8',
format="%(asctime)s - %(message)s")
# 기본적인 시간 표현
logger.info("기본적인 datetime format 입니다.")
# 시간 표현 방법 변경
logger.propagate = False
new_format = logging.Formatter(fmt="%(asctime)s - %(message)s",
datefmt="%Y년 %m월 %d일 %H시 %M분 %S초") # 새로운 포맷
file_handler = logging.FileHandler(filename=filename, mode='a', encoding='utf-8')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(new_format) # 포맷 설정
logger.addHandler(file_handler)
logger.error("변경된 datetime format 입니다.")
if __name__ == "__main__":
log_datetime()
|
1
2
| 2025-11-03 22:22:21,510 - 기본적인 datetime format 입니다.
2025년 11월 03일 22시 22분 21초 - 변경된 datetime format 입니다.
|
Reference
https://docs.python.org/3/library/logging.html
https://docs.python.org/ko/3/howto/logging.html
Comments