Python

[python] import logging ๋กœ๊น…์— ๋Œ€ํ•ด

์ฃผ์˜ ๐Ÿฑ 2023. 1. 16. 17:17
728x90

์—ฌ๋Ÿฌ ์˜คํ”ˆ์†Œ์Šค๋“ค์„ ๊ณต๋ถ€ํ•˜๋ฉด์„œ logging์— ๋Œ€ํ•ด ์ฒ˜์Œ ์ ‘ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์–ด๋””๊นŒ์ง€ ์ง„ํ–‰์ด ๋˜์—ˆ๊ณ , ์–ด๋””์„œ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ๋กœ๊ทธ๋ถ„์„์„ ํ•˜๋Š”๋ฐ ์ด๋Ÿฌํ•œ ์ž‘์—…์ด ๋ฐ”๋กœ logging์—์„œ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒƒ์ด๋‹ค. 

 

์•„๋ž˜ ํŒŒ์ด์ฌ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ๋กœ๊น…์— ๋Œ€ํ•ด ์ฝ์–ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

https://docs.python.org/ko/3/howto/logging.html

์ด ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด : 

๋กœ๊น…์€ ์–ด๋–ค ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ์‹คํ–‰๋  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ถ”์ ํ•˜๋Š” ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค. ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์ž๋Š” ์ฝ”๋“œ์— ๋กœ๊น… ํ˜ธ์ถœ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๋Š” ์„ ํƒ์ ์œผ๋กœ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ (์ฆ‰, ์ด๋ฒคํŠธ ๋ฐœ์ƒ๋งˆ๋‹ค ์ž ์žฌ์ ์œผ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ)๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ์„ค๋ช… ๋ฉ”์‹œ์ง€๋กœ ๊ธฐ์ˆ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๋Š” ๋˜ํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฒคํŠธ์— ๋ถ€์—ฌํ•œ ์ค‘์š”๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค; ์ค‘์š”๋„๋Š” ์ˆ˜์ค€(level) ๋˜๋Š” ์‹ฌ๊ฐ๋„(severity) ๋ผ๊ณ ๋„ ๋ถ€๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ผ๊ณ  ํ•œ๋‹ค. 

 

๋กœ๊น… ์‚ฌ์šฉ๋ฐฉ๋ฒ•

 

์„ค์น˜์—†์ด import ๋ฌธ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. 

import logging

๋กœ๊น…์€ Logger ํด๋ž˜์Šค(=loggers) ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ˆ˜ํ–‰๋œ๋‹ค. 

logger = logging.getLogger(__name__)

์ด๋ ‡๊ฒŒ ๋กœ๊ฑฐ์˜ ์ด๋ฆ„์„ ์ง€์„ ๋•Œ๋Š” ๋กœ๊น…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ ๋ชจ๋“ˆ์—์„œ ๋ชจ๋“ˆ ์ˆ˜์ค€ ๋กœ๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. 

setLevel๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ ˆ๋ฒจ์„ ์„ค์ •ํ•œ๋‹ค. 

logger.setLevel(logging.DEBUG)

level ์‚ฌ์šฉํ•  ๋•Œ
DEBUG ์ƒ์„ธํ•œ ์ •๋ณด. ๋ณดํ†ต ๋ฌธ์ œ๋ฅผ ์ง„๋‹จํ•  ๋•Œ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
INFO ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ํ™•์ธ.
WARNING ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ผ์ด ๋ฐœ์ƒํ–ˆ๊ฑฐ๋‚˜ ๊ฐ€๊นŒ์šด ๋ฏธ๋ž˜์— ๋ฐœ์ƒํ•  ๋ฌธ์ œ(์˜ˆ๋ฅผ ๋“ค์–ด ใ€ˆ๋””์Šคํฌ ๊ณต๊ฐ„ ๋ถ€์กฑใ€‰)์— ๋Œ€ํ•œ ํ‘œ์‹œ. ์†Œํ”„ํŠธ์›จ์–ด๋Š” ์—ฌ์ „ํžˆ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
ERROR ๋”์šฑ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๋กœ ์ธํ•ด, ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ์ผ๋ถ€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
CRITICAL ์‹ฌ๊ฐํ•œ ์—๋Ÿฌ. ํ”„๋กœ๊ทธ๋žจ ์ž์ฒด๊ฐ€ ๊ณ„์† ์‹คํ–‰๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

**๋กœ๊ฑฐ๊ฐ€ ์ฒ˜๋ฆฌํ•  ๊ฐ€์žฅ ๋‚ฎ์€ ์‹ฌ๊ฐ๋„์˜ ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. debug์€ ๊ฐ€์žฅ ๋‚ฎ์€ ๋‚ด์žฅ ์‹ฌ๊ฐ๋„ ์ˆ˜์ค€์ด๊ณ  critical์€ ๊ฐ€์žฅ ๋†’์€ ๋‚ด์žฅ ์‹ฌ๊ฐ๋„์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‹ฌ๊ฐ๋„ ์ˆ˜์ค€์ด INFO์ด๋ฉด ๋กœ๊ฑฐ๋Š” INFO, WARNING, ERROR ๋ฐ CRITICAL ๋ฉ”์‹œ์ง€๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ  DEBUG ๋ฉ”์‹œ์ง€๋Š” ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๋ฉด ๋กœ๊ฑฐ๋ฅผ ์ƒ์„ฑํ•œ ๊ฒƒ์ด๋‹ค. 

 

 

3. ๋กœ๊น… ๋ฉ”์‹œ์ง€ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

๋กœ๊น… ๋ฉ”์‹œ์ง€๋„ ํŒŒ์ด์ฌ์—์„œ ๋ฌธ์ž์—ด ํฌ๋งคํŒ…ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปค์Šคํ…€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

logging.Formatter.__init__(fmt=None, datefmt=None, style='%')

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

 ์•„๋ž˜์™€ ๊ฐ™์€ ์†์„ฑ๋“ค์„ ์ฐธ์กฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์ด๋ฆ„ ํฌ๋งท ์„ค๋ช…
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 ์Šค๋ ˆ๋“œ ์ด๋ฆ„ (์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ).

 

 

import logging

logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)

logging.debug('This message should appear on the console')

logging.info('So should this')

logging.warning('And this, too')

์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:::

DEBUG:This message should appear on the console

INFO:So should this

WARNING:And this, too

***ํ•˜์ง€๋งŒ, ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ์„ ์œ„ํ•ด์„œ๋Š” levelname (์‹ฌ๊ฐ๋„), message (์ด๋ฒคํŠธ ์„ค๋ช…, ๋ณ€์ˆ˜ ๋ฐ์ดํ„ฐ ํฌํ•จ) ์™€ ์•„๋งˆ๋„ ๋ฐœ์ƒ ์‹œ๊ฐ์„ ํ‘œ์‹œํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฉ”์‹œ์ง€์— ๋‚ ์งœ/์‹œ๊ฐ„ ํ‘œ์‹œ

์ด๋ฒคํŠธ์˜ ๋‚ ์งœ์™€ ์‹œ๊ฐ„์„ ํ‘œ์‹œํ•˜๋ ค๋ฉด, ํฌ๋งท ๋ฌธ์ž์—ด์— ‘%(asctime)s’ ์„ ๋„ฃ๊ธฐ

import logging

logging.basicConfig(format='%(asctime)s %(message)s')

logging.warning('is when this event was logged.')

์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:::

 

2010-12-12 11:41:42,612 is when this event was logged.

***(์œ„์— ๋‚˜์˜จ) ๋‚ ์งœ/์‹œ๊ฐ„ ํ‘œ์‹œ์˜ ๊ธฐ๋ณธ ํฌ๋งท์€ ISO8601 ๋˜๋Š” RFC 3339์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ ์งœ/์‹œ๊ฐ„์˜ ํฌ๋งท์„ ์ข€ ๋” ์ œ์–ดํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ์ด ์˜ˆ์ œ์—์„œ์™€๊ฐ™์ด basicConfig ์— datefmt ์ธ์ž๋ฅผ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค:

import logging

logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')

logging.warning('is when this event was logged.')

์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:::

 

12/12/2010 11:46:36 AM is when this event was logged.

datefmt ์ธ์ž์˜ ํ˜•์‹์€ time.strftime() ์— ์˜ํ•ด ์ง€์›๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•