我有脚本的集合,我想他们产生最小的改动统一日志消息模块做记录的实际信息。
我写了一个小模块'custom_logger',我打算从主应用程序调用一次,让它返回一个记录器,然后我将继续使用。
我会导入到应用程序的子模块只能(或者更确切地说,我希望他们)
- 只能“进口记录日志” - 这样没有具体到我的网站需要做如果有人发现它们有用,它们就会运行。
- 应该只是记录与log.info/error('message消息“),而不添加任何特定的站点到他们
- 应该使用已配置‘与所有的格式和左撇子,而不是根’记录影响根记录的配置
* custom_logger.py *
import logging
import logging.handlers
import os
import sys
def getLogger(name='root', loglevel='INFO'):
logger = logging.getLogger(name)
# if logger 'name' already exists, return it to avoid logging duplicate
# messages by attaching multiple handlers of the same type
if logger.handlers:
return logger
# if logger 'name' does not already exist, create it and attach handlers
else:
# set logLevel to loglevel or to INFO if requested level is incorrect
loglevel = getattr(logging, loglevel.upper(), logging.INFO)
logger.setLevel(loglevel)
fmt = '%(asctime)s %(filename)-18s %(levelname)-8s: %(message)s'
fmt_date = '%Y-%m-%dT%T%Z'
formatter = logging.Formatter(fmt, fmt_date)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
if logger.name == 'root':
logger.warning('Running: %s %s',
os.path.basename(sys.argv[0]),
' '.join(sys.argv[1:]))
return logger
然后是它有什么不的什么作品例子几个测试消息的子模块。
submodule.py
import sys
import custom_logger
import logging
class SubClass(object):
def __init__(self):
# NOK (no idea why since by default (no name parameter), it should return the root logger)
#log = logging.getLogger()
#log.info('message from SubClass/__init__')
# OK (works as expected)
#log = logging.getLogger('root')
#log.info('message from SubClass/__init__')
# OK (works as expected)
log = custom_logger.getLogger('root')
log.info('message from SubClass/__init__')
def SomeMethod(self):
# OK but I'd have to define `log` for every method, which is unacceptable
# Please see question below all code snippets
log = custom_logger.getLogger('root')
log.info('message from SubClass/SomeMethod')
和主要应用:app.py这里没有什么特别的:
#!/usr/bin/python
import custom_logger
import submodule
log = custom_logger.getLogger('root', loglevel='DEBUG')
log.debug('debug message')
log.info('info message')
log.warning('warning message')
log.error('error message')
a = submodule.SubClass() # this should produce a log message
a.SomeMethod() # so should this
输出,我以后和我得到我,只是以极其丑陋的方式:
% ./app.py
2013-04-08T03:07:46BST custom_logger.py WARNING : Running: app.py
2013-04-08T03:07:46BST app.py DEBUG : debug message
2013-04-08T03:07:46BST app.py INFO : info message
2013-04-08T03:07:46BST app.py WARNING : warning message
2013-04-08T03:07:46BST app.py ERROR : error message
2013-04-08T03:07:46BST submodule.py INFO : message from SubClass/__init__
2013-04-08T03:07:46BST submodule.py INFO : message from SubClass/SomeMethod
我希望能够在app.py中定义一个记录器,然后在子模块中只使用标准的Python日志记录库来使用app.py中已配置的记录器。
此外,一个丑陋的解决方法:如果我把下面的代码在submodule.py进口后:
log = custom_logger.getLogger('root')
之前我在记录器被app.py配置,有效地使子模块将被执行,不是我的应用程序配置日志
另一个解决办法我认为是:子类的constuctor内,我可以定义
self.log = custom_logger.getLogger('root')
然后用self.log.error( '一些错误')。必须有更好的方法 - 如果您能提出有用的建议或指出我误解了文档的地方,我会非常感激!
PS。我花了很多时间阅读Python日志记录howto(basic和advanced)和cookbook,如果我错过了某些有用的东西,请指出。
谢谢!
谢谢米哈伊。我想我会有更多的时间来看看它,但我需要等待周末。到目前为止,我已经能够通过在submodule.py中将日志定义为getLogger对象来使我的类可以完成所有工作(附加格式器,处理程序和设置日志级别)。我希望这可以在不将事物放在类定义之外的情况下完成。 我的问题更多的是“为什么我所做的某些方法没有按预期工作,因为我想了解其背后的原因,而不是将代码交给我,但我非常感谢您的帮助: ) – 2013-04-10 01:27:35
我更新了我的答案,除此之外,您可以查看模块的代码。您可以看到根记录器在导入过程中被实例化了,我也不明白为什么getLogger(“root”)不能正常工作在所有情况下(你可以在app.py中执行getLogger(),在submodule.py中执行getLogger(“root”),你将得到你所需要的东西,但是反之亦然) – Mihai 2013-04-10 14:15:47
如何使用stdout重定向到文件例如python ./app.py >> file.log? – 2016-04-14 11:37:45