다음과 같은 구조의 작은 파이썬 프로젝트가 있습니다-
Project
-- pkg01
-- test01.py
-- pkg02
-- test02.py
-- logging.conf
기본 로깅 모듈을 사용하여 stdout 및 로그 파일에 메시지를 인쇄하려고합니다. 로깅 모듈을 사용하려면 약간의 초기화가 필요합니다.
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('pyApp')
logger.info('testing')
현재 메시지 로깅을 시작하기 전에 모든 모듈에서이 초기화를 수행합니다. 이 초기화를 한 곳에서 한 번만 수행하여 프로젝트 전체에 로깅하여 동일한 설정을 재사용 할 수 있습니까?
답변
모범 사례는 각 모듈에서 다음과 같이 로거를 정의하는 것입니다.
import logging
logger = logging.getLogger(__name__)
모듈 상단 근처에서 모듈의 다른 코드에서
logger.debug('My message with %s', 'variable data')
모듈 내에서 로깅 활동을 세분화해야하는 경우 다음을 사용하십시오.
loggerA = logging.getLogger(__name__ + '.A')
loggerB = logging.getLogger(__name__ + '.B')
과에 기록 loggerA
하고 loggerB
적절하게.
기본 프로그램에서 다음을 수행하십시오.
def main():
"your program code"
if __name__ == '__main__':
import logging.config
logging.config.fileConfig('/path/to/logging.conf')
main()
또는
def main():
import logging.config
logging.config.fileConfig('/path/to/logging.conf')
# your program code
if __name__ == '__main__':
main()
참조 여기에 여러 개의 모듈에서 로그온하고, 여기에 다른 코드에 의해 라이브러리 모듈로 사용되는 코드에 대한 로깅 구성.
업데이트 :을 호출 할 때 Python 2.6 이상을 사용 fileConfig()
하고 있는지 지정할 disable_existing_loggers=False
수 있습니다 (자세한 내용 은 문서 를 참조하십시오). 기본값은 True
이전 버전과의 호환성을위한 것으로, 모든 로거가 fileConfig()
해당 조상 또는 구성에서 명시 적으로 이름을 지정하지 않는 한 모든 로거가 비활성화됩니다 . 값을로 설정하면 False
기존 로거가 그대로 유지됩니다. Python 2.7 / Python 3.2 이상을 사용하는 경우 구성을보다 잘 제어 할 수있는 dictConfig()
것보다 더 나은 API 를 고려할 수 fileConfig()
있습니다.
답변
실제로 모든 로거는 부모의 패키지 로거의 자식입니다 (즉 ,의 package.subpackage.module
구성을 상속 package.subpackage)
하므로 루트 로거를 구성하기 만하면됩니다).logging.config.fileConfig
대한 고유 한 구성) 또는 logging.basicConfig
(루트 로거를 설정하여) . 사용자의 입력 모듈에서 설정 로깅 ( __main__.py
또는 예를 들어, 실행 원하는대로 main_script.py
.이 __init__.py
뿐만 아니라 작동)
basicConfig 사용 :
# package/__main__.py
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
fileConfig를 사용하여 :
# package/__main__.py
import logging
import logging.config
logging.config.fileConfig('logging.conf')
다음을 사용하여 모든 로거를 만듭니다.
# package/submodule.py
# or
# package/subpackage/submodule.py
import logging
log = logging.getLogger(__name__)
log.info("Hello logging!")
자세한 정보는 고급 로깅 학습서를 참조하십시오 .
답변
나는 항상 아래와 같이합니다.
단일 파이썬 파일을 사용하여 내 로그를 ‘ log_conf.py
‘ 라는 단일 패턴으로 구성하십시오.
#-*-coding:utf-8-*-
import logging.config
def singleton(cls):
instances = {}
def get_instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return get_instance()
@singleton
class Logger():
def __init__(self):
logging.config.fileConfig('logging.conf')
self.logr = logging.getLogger('root')
다른 모듈에서는 구성을 가져 오기만하면됩니다.
from log_conf import Logger
Logger.logr.info("Hello World")
이것은 간단하고 효율적으로 기록하는 단일 패턴입니다.
답변
이 답변 중 일부는 모듈 상단에서 수행하는 작업을 제안합니다.
import logging
logger = logging.getLogger(__name__)
이것이 매우 나쁜 관행으로 간주된다는 것이 나의 이해입니다 . 그 이유는 파일 구성이 기본적으로 모든 기존 로거를 비활성화하기 때문입니다. 예 :
#my_module
import logging
logger = logging.getLogger(__name__)
def foo():
logger.info('Hi, foo')
class Bar(object):
def bar(self):
logger.info('Hi, bar')
그리고 메인 모듈에서 :
#main
import logging
# load my module - this now configures the logger
import my_module
# This will now disable the logger in my module by default, [see the docs][1]
logging.config.fileConfig('logging.ini')
my_module.foo()
bar = my_module.Bar()
bar.bar()
기존의 로거가 fileconfig 호출에 의해 비활성화되었으므로 logging.ini에 지정된 로그가 비어 있습니다.
이 문제를 해결할 수는 있지만 (disable_existing_Loggers = False) 실제로 라이브러리의 많은 클라이언트는이 동작에 대해 알지 못하며 로그를받지 않습니다. 항상 logging.getLogger를 로컬로 호출하여 클라이언트가 쉽게 사용할 수 있도록하십시오. 모자 팁 : Victor Lin의 웹 사이트 에서이 동작에 대해 배웠습니다. .
따라서 항상 logging.getLogger를 로컬로 호출하는 것이 좋습니다. 예 :
#my_module
import logging
logger = logging.getLogger(__name__)
def foo():
logging.getLogger(__name__).info('Hi, foo')
class Bar(object):
def bar(self):
logging.getLogger(__name__).info('Hi, bar')
또한 기본에서 fileconfig를 사용하는 경우 라이브러리 디자이너가 모듈 레벨 로거 인스턴스를 사용하는 경우를 대비하여 disable_existing_loggers = False를 설정하십시오.
답변
여러 모듈에서 하나의 로깅 라이브러리 인스턴스를 사용하는 간단한 방법은 다음과 같은 해결책이었습니다.
base_logger.py
import logging
logger = logging
logger.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)
다른 파일들
from base_logger import logger
if __name__ == '__main__':
logger.info("This is an info message")
답변
다른 해결책으로 던지기.
내 모듈의 init .py에는 다음과 같은 것이 있습니다.
# mymodule/__init__.py
import logging
def get_module_logger(mod_name):
logger = logging.getLogger(mod_name)
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
return logger
그런 다음 각 모듈에서 로거가 필요합니다.
# mymodule/foo.py
from [modname] import get_module_logger
logger = get_module_logger(__name__)
로그가 누락되면 해당 모듈에서 소스를 구별 할 수 있습니다.
답변
이와 같은 것을 생각 해낼 수도 있습니다!
def get_logger(name=None):
default = "__app__"
formatter = logging.Formatter('%(levelname)s: %(asctime)s %(funcName)s(%(lineno)d) -- %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
log_map = {"__app__": "app.log", "__basic_log__": "file1.log", "__advance_log__": "file2.log"}
if name:
logger = logging.getLogger(name)
else:
logger = logging.getLogger(default)
fh = logging.FileHandler(log_map[name])
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.setLevel(logging.DEBUG)
return logger
위의 내용이 별도의 모듈에 정의되어 있고 다른 모듈로 가져온 경우 로깅이 필요한 경우 동일한 모듈과 전체 프로젝트에서 여러 로거를 사용할 수 있습니다.
a=get_logger("__app___")
b=get_logger("__basic_log__")
a.info("Starting logging!")
b.debug("Debug Mode")