所以现在我们有很多 python 脚本,我们正在尝试整合它们并修复和冗余。我们正在尝试做的事情之一是确保所有 sys.stdout/sys.stderr 都进入 python 日志记录模块。
现在最重要的是,我们希望打印出以下内容:
[<ERROR LEVEL>] | <TIME> | <WHERE> | <MSG>
现在所有Python错误消息中的sys.stdout / sys.stderr消息几乎都是[LEVEL] - MSG的格式,它们都是使用sys.stdout/sys.stderr编写的。我可以在 sys.stdout 包装器和 sys.stderr 包装器中解析罚款。然后根据解析的输入调用相应的日志记录级别。
所以基本上我们有一个名为 foo 的包和一个名为 log 的子包。在__init__.py
我们定义如下:
def initLogging(default_level = logging.INFO, stdout_wrapper = None, \
stderr_wrapper = None):
"""
Initialize the default logging sub system
"""
root_logger = logging.getLogger('')
strm_out = logging.StreamHandler(sys.__stdout__)
strm_out.setFormatter(logging.Formatter(DEFAULT_LOG_TIME_FORMAT, \
DEFAULT_LOG_TIME_FORMAT))
root_logger.setLevel(default_level)
root_logger.addHandler(strm_out)
console_logger = logging.getLogger(LOGGER_CONSOLE)
strm_out = logging.StreamHandler(sys.__stdout__)
#strm_out.setFormatter(logging.Formatter(DEFAULT_LOG_MSG_FORMAT, \
# DEFAULT_LOG_TIME_FORMAT))
console_logger.setLevel(logging.INFO)
console_logger.addHandler(strm_out)
if stdout_wrapper:
sys.stdout = stdout_wrapper
if stderr_wrapper:
sys.stderr = stderr_wrapper
def cleanMsg(msg, is_stderr = False):
logy = logging.getLogger('MSG')
msg = msg.rstrip('\n').lstrip('\n')
p_level = r'^(\s+)?\[(?P<LEVEL>\w+)\](\s+)?(?P<MSG>.*)$'
m = re.match(p_level, msg)
if m:
msg = m.group('MSG')
if m.group('LEVEL') in ('WARNING'):
logy.warning(msg)
return
elif m.group('LEVEL') in ('ERROR'):
logy.error(msg)
return
if is_stderr:
logy.error(msg)
else:
logy.info(msg)
class StdOutWrapper:
"""
Call wrapper for stdout
"""
def write(self, s):
cleanMsg(s, False)
class StdErrWrapper:
"""
Call wrapper for stderr
"""
def write(self, s):
cleanMsg(s, True)
现在我们将在我们的一个脚本中调用它,例如:
import foo.log
foo.log.initLogging(20, foo.log.StdOutWrapper(), foo.log.StdErrWrapper())
sys.stdout.write('[ERROR] Foobar blew')
这将被转换为错误日志消息。喜欢:
[ERROR] | 20090610 083215 | __init__.py | Foobar Blew
现在的问题是,当我们这样做时,记录错误消息的模块现在是__init__
(对应于foo.log.__init__.py
文件)这违背了整个目的。
我尝试对 stderr/stdout 对象进行深层复制/浅层复制,但这没有任何作用,它仍然显示消息发生的模块__init__.py
。我怎样才能做到这一点,这样就不会发生这种情况?