我在python项目中使用日志记录。我的问题是关于在我的项目中构造日志记录的正确和优雅的方法,因为我将首先描述我正在使用的结构。
我有3个主要的.py脚本,即acquisition.py、actuation.py和management.py,它们在启动时被称为服务。上面的三个脚本导入network.py和devices.py。
我想组织与三个主脚本相关联的每个文件的日志记录,所以我希望有: acquisition.log、actuation.log和management.log。在这些日志中,我希望拥有调用network.py a device.py (使用命名空间%(名称))的相应日志。
示例(acquisition.log):
INFO acquisition.thread 2016-03-17 12:26:02,069 in Thread 70de3b66-e14b-11e5-8953-80fa5b0ae007
DEBUG acquisition 2016-03-17 12:26:02,070 Thread launched 70de3b66-e14b-11e5-8953-80fa5b0ae007
INFO acquisition.devices 2016-03-17 12:26:03,072 Variable_R read: 0013a20040c1bb0b temperature1
ERROR acquisition.devices 2016-03-17 12:26:19,076 variable.read.DeviceConfigurationError: 0013a20040c1bb0b
INFO acquisition.thread 2016-03-17 12:26:19,077 exit Thread 70ddfa20-e14b-11e5-8953-80fa5b0ae007
ERROR acquisition.devices 2016-03-17 12:26:25,085 variable.read.DeviceConfigurationError: 0013a20040c1bb0b
INFO acquisition.thread 2016-03-17 12:26:25,086 exit Thread 70de3b66-e14b-11e5-8953-80fa5b0ae007在本例中,您可以看到对于同一个日志文件,我可以从不同的文件中进行日志记录,它可以在日志名称空间acquisition.thread和acquisition.devices.中看到。
我实现这一目标的方法是拥有一个记录器函数,用于在每个文件中创建一个后备记录器,我将在其中进行日志记录。然后,如果我想记录该文件中的信息,我将在主脚本文件中修改导入文件中创建的记录器。
解释上述内容的代码示例:
acquisition.py (主脚本):
imports...
import logger_sys
import logging
import xnetwork
import xdevices
# Log configuration
log_name = os.path.basename(__file__).strip(".py")
logit = logger_sys.setup_logger(log_name, log_name) #internal logger for main file
logger_thread = logging.getLogger(log_name + '.thread')
#Log configuration of external files
xnetwork.logger = logging.getLogger(log_name + '.network')
xdevices.logger = logging.getLogger(log_name + '.devices')
logit.info("START acquisition_service")
# REST OF THE CODE... xdevices.py:
import logger_sys
# Fallback logger in case the calling script doesnt modify logger
log_name = __name__.strip(".py") + '_fallback'
logger = logger_sys.setup_logger(log_name, log_name, stream_hdlr=False)
# REST OF THE CODE...xnetworks.py:
import logger_sys
# Fallback logger in case the calling script doesnt modify logger
log_name = __name__.strip(".py") + '_fallback'
logger = logger_sys.setup_logger(log_name, log_name, stream_hdlr=False)
# REST OF THE CODE...logger_sys.py:
import logging, sys, os
from global_settings import RUNNING_MODE, DEBUG, STAGING, PRODUCTION
def setup_logger(namespace, filename, stream_hdlr=True):
logger = logging.getLogger(namespace)
handler_format = logging.Formatter("%(levelname)s %(name)s %(asctime)s %(message)s")
log_handler = logging.FileHandler(filename + ".log")
logger.addHandler(log_handler)
log_handler.setFormatter(handler_format)
if RUNNING_MODE == DEBUG:
if stream_hdlr:
log_handler = logging.StreamHandler(sys.stdout)
logger.addHandler(log_handler)
log_handler.setFormatter(handler_format)
logger.setLevel(logging.DEBUG)
elif RUNNING_MODE == STAGING or RUNNING_MODE == PRODUCTION:
logger.setLevel(logging.INFO)
return logger目标?
提前谢谢你
发布于 2016-03-24 18:13:32
您应该学习官方的伐木食谱和一些正确记录日志的复杂项目。我建议阅读请求源代码,看看一个相当复杂的项目是如何进行日志记录的。
也许从你的烹饪书中得到的关键是:
对logging.getLogger('someLogger')的多次调用返回对同一个记录器对象的引用。这不仅在同一个模块中是正确的,而且在相同的Python解释器进程中跨模块也是如此。
一种典型的方法是在文件的顶部设置如下内容:
import logging
log = logging.getLogger(__name__)这使得log是全局的,因此可以在函数中使用它,而无需将log作为参数传递:
def add(x, y):
log.debug('Adding {} and {}'.format(x, y))
return x + y如果您正在创建一些长期运行的服务,并且打算记录所有/大部分/多个函数调用,请考虑使用装饰器。我建议使用这篇文章来自“新鲜图书开发”博客作为使用装饰器进行日志记录的介绍。听起来您的程序可能会从装饰方法中受益。
https://stackoverflow.com/questions/36205426
复制相似问题