所以現在我們有很多python腳本,我們正在嘗試整合它們並修復和裁減。我們試圖做的一件事是確保所有的sys.stdout/sys.stderr進入python日誌記錄模塊。將sys.stdout重定向到python logging
現在最主要的是,我們希望達到以下打印出來:
[<ERROR LEVEL>] | <TIME> | <WHERE> | <MSG>
現在所有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對象的deepCopy/shallowCopy,但是什麼都不做,它仍然說在__init__.py
中發生了這個消息。我怎麼能這樣做,這不會發生?