我有一个小的python项目,它有以下结构-
Project
-- pkg01
-- test01.py
-- pkg02
-- test02.py
-- logging.conf
我计划使用默认日志记录模块将消息打印到标准输出和日志文件。
要使用日志记录模块,需要进行一些初始化
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')
和log到loggerA和loggerB。
在你的主程序中,执行以下操作:
def main():
"your program code"
if __name__ == '__main__':
import logging.config
logging.config.fileConfig('/path/to/logging.conf')
main()
or
def main():
import logging.config
logging.config.fileConfig('/path/to/logging.conf')
# your program code
if __name__ == '__main__':
main()
在这里可以查看来自多个模块的日志记录,在这里可以查看将被其他代码用作库模块的代码的日志记录配置。
Update: When calling fileConfig(), you may want to specify disable_existing_loggers=False if you're using Python 2.6 or later (see the docs for more information). The default value is True for backward compatibility, which causes all existing loggers to be disabled by fileConfig() unless they or their ancestor are explicitly named in the configuration. With the value set to False, existing loggers are left alone. If using Python 2.7/Python 3.2 or later, you may wish to consider the dictConfig() API which is better than fileConfig() as it gives more control over the configuration.
实际上,每个日志记录器都是父日志记录器的子日志记录器(例如,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!")
有关更多信息,请参阅高级日志记录教程。
你也可以想出这样的东西!
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")
最好的做法是单独创建一个模块,该模块只有一个方法,我们的任务是为调用方法提供一个记录器处理程序。将该文件保存为m_logger.py
import logger, logging
def getlogger():
# logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
#ch = logging.StreamHandler()
ch = logging.FileHandler(r'log.txt')
ch.setLevel(logging.DEBUG)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)
return logger
现在,只要需要记录器处理程序,就调用getlogger()方法。
from m_logger import getlogger
logger = getlogger()
logger.info('My mssg')