Tak więc mamy teraz wiele skryptów Pythona i staramy się je skonsolidować i naprawić i zwolnień. Jedną z rzeczy, które próbujemy wykonać, jest upewnienie się, że wszystkie sys.stdout/sys.stderr trafiają do modułu logowania Pythona.Przekierowywanie sys.stdout do logowania Python
Teraz najważniejsze jest, chcemy wydrukować następuje:
[<ERROR LEVEL>] | <TIME> | <WHERE> | <MSG>
Teraz wszystkie sys.stdout/wiad sys.stderr prawie we wszystkich komunikatów o błędach python są w formacie [poziom ] - MSG, które są napisane przy użyciu sys.stdout/sys.stderr. Mogę parsować grzywnę w opakowaniu sys.stdout i w opakowaniu sys.stderr. Następnie wywołaj odpowiedni poziom rejestrowania, w zależności od analizowanego wejścia.
W zasadzie mamy pakiet o nazwie foo i podpakiet o nazwie log. W __init__.py
nam określić, co następuje:
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)
teraz nazwalibyśmy to w jednym z naszych scenariuszy na przykład:
import foo.log
foo.log.initLogging(20, foo.log.StdOutWrapper(), foo.log.StdErrWrapper())
sys.stdout.write('[ERROR] Foobar blew')
który byłby przekształcony wiadomości dziennika błędów. Jak:
[ERROR] | 20090610 083215 | __init__.py | Foobar Blew
Teraz problem jest, gdy to zrobimy, moduł gdzie komunikat o błędzie był zalogowany jest obecnie __init__
(odpowiadające foo.log.__init__.py
pliku), który pokonuje cały cel.
Próbowałem zrobić deepCopy/shallowCopy obiektów stderr/stdout, ale to nic nie robi, to nadal mówi moduł, którego wiadomość pojawiła się w __init__.py
. Jak mogę to zrobić, aby tak się nie stało?