본문으로 바로가기

소개

 

Config 파일을 통해서 코드를 건드리지 않고 편하게 관리하는 방법에 대해 알아보겠습니다.

여러 파일 포맷을 지원하지만 보편적인 JSON 형식을 사용해보겠습니다.

 

파일 포맷

  • JSON

  • INI

  • YAML

 

 

예제 1

 

핸들러, 포매터 등을 다음과 같은 형식으로 지정합니다.

loggers 필드에는 핸들러와 포매터의 조합한 로거를 정의할 수 있습니다.

 

logger.json

{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters": {
      "default": {
        "format": "%(levelname)s :: %(asctime)s :: %(module)s ::%(name)s\n%(message)s",
        "datefmt": "%Y-%m-%d %H:%M:%S"
      },
      "error": {
        "format": "%(levelname)s :: %(asctime)s :: %(module)s ::%(name)s :: %(lineno)s\n%(message)s",
        "datefmt": "%Y-%m-%d %H:%M:%S"
      }
    },
    "handlers": {
      "console": {
        "class": "logging.StreamHandler",
        "level": "DEBUG",
        "formatter": "default"
      },
      "file": {
        "class": "logging.FileHandler",
        "level": "ERROR",
        "formatter": "error",
        "filename": "error.log"
      }
    },
    "loggers": {
      "loggger-1": {
        "level": "DEBUG",
        "handlers": ["console", "file"],
        "propagate": true
      }
    }
  }

 

ex2-1.py

import logging
import logging.config
import json

if __name__ == '__main__':
    with open('logger.json', 'r') as f:
        config = json.load(f)
    logging.config.dictConfig(config)

    logger = logging.getLogger('loggger-1')
    logger.debug('debug level !')
    logger.info('info level !')
    logger.error('error level !')

 

 

Config 파일을 읽어서 logging.config.dictConfig() 함수에 넘겨주어 설정을 합니다.

with open('logger.json', 'r') as f:
        config = json.load(f)
    logging.config.dictConfig(config)

 

위에서 정의한 "logger-1" 로거를 불러옵니다.

logger = logging.getLogger('loggger-1')

 

streamHandler 의 레벨은 DEBUG 이므로 모두 출력이 되고 있습니다.

logger = logging.getLogger('loggger-1')
logger.debug('debug level !')
logger.info('info level !')
logger.error('error level !')
DEBUG :: 2020-08-16 22:07:40 :: ex2-1 ::loggger-1
debug level !
INFO :: 2020-08-16 22:07:40 :: ex2-1 ::loggger-1
info level !
ERROR :: 2020-08-16 22:07:40 :: ex2-1 ::loggger-1
error level !

 

fileHandler 의 레벨은 ERROR 이상 이었습니다.

 

 

예제 2

 

loggers 필드에 두 개의 로거를 정의해서 테스트했습니다.

 

debug-logger : DEBUG / console

error-logger : ERROR / console, file

 

logger2.json

{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters": {
      "default": {
        "format": "%(levelname)s :: %(asctime)s :: %(module)s ::%(name)s :: %(message)s",
        "datefmt": "%Y-%m-%d %H:%M:%S"
      },
      "error": {
        "format": "%(levelname)s :: %(asctime)s :: %(module)s ::%(name)s :: %(lineno)s :: %(message)s",
        "datefmt": "%Y-%m-%d %H:%M:%S"
      }
    },
    "handlers": {
      "console": {
        "class": "logging.StreamHandler",
        "level": "DEBUG",
        "formatter": "default"
      },
      "file": {
        "class": "logging.FileHandler",
        "level": "ERROR",
        "formatter": "error",
        "filename": "error.log"
      }
    },
    "loggers": {
      "debug-logger": {
        "level": "DEBUG",
        "handlers": ["console"],
        "propagate": true
      },
      "error-logger": {
        "level": "ERROR",
        "handlers": ["console", "file"],
        "propagate": true
      }
    }
  }

 

ex2-2.py

import logging
import logging.config
import json

if __name__ == '__main__':
    with open('logger2.json', 'r') as f:
        config = json.load(f)
    logging.config.dictConfig(config)

    debug_logger = logging.getLogger('debug-logger')
    debug_logger.debug('debug')
    debug_logger.info('info')
    debug_logger.error('error')

    error_logger = logging.getLogger('error-logger')
    error_logger.debug('debug')
    error_logger.info('info')
    error_logger.error('error')
    error_logger.error('critical')
DEBUG :: 2020-08-16 23:05:43 :: ex2-2 ::debug-logger :: debug
INFO :: 2020-08-16 23:05:43 :: ex2-2 ::debug-logger :: info
ERROR :: 2020-08-16 23:05:43 :: ex2-2 ::debug-logger :: error
ERROR :: 2020-08-16 23:05:43 :: ex2-2 ::error-logger :: error
ERROR :: 2020-08-16 23:05:43 :: ex2-2 ::error-logger :: critical

 

 

참고

 

조금 더 체계적인 Python Logging

Introduction Python으로 코드를 짤 때, 로그를 띄우는 방법으로 print('[*] Message')를 정말 많이 써 왔습니다. 군더더기 없고, 유연하고, dependency 없이 아무 위치에나 넣을 수 있다는 점이 좋았습니다. '좋

hwangheek.github.io