Python 日志记录中标准输出捕获的最大递归深度
我的记录器配置如下:Python 日志记录中标准输出捕获的最大递归深度,python,logging,recursion,jenkins,Python,Logging,Recursion,Jenkins,我的记录器配置如下: #!/usr/bin/env python # -*- coding: utf-8 -*- import logging import logging.handlers import sys import os import re class MaskFormatter(logging.Formatter): def __init__(self, fmt, masks): logging.Formatter.__init__(self, fmt
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import logging.handlers
import sys
import os
import re
class MaskFormatter(logging.Formatter):
def __init__(self, fmt, masks):
logging.Formatter.__init__(self, fmt)
self.masks = masks
def format(self, record):
result = logging.Formatter.format(self, record)
if result is not None:
result = self.masks.sub("*" * 25, result)
return result
class LoggerWriter:
def __init__(self, level):
# self.level is really like using log.debug(message)
# at least in my case
self.level = level
def write(self, message):
# if statement reduces the amount of newlines that are
# printed to the logger
if message != '\n':
self.level("stdout: " + message)
def flush(self):
# create a flush method so things can be flushed when
# the system wants to. Not sure if simply 'printing'
# sys.stderr is the correct way to do it, but it seemed
# to work properly for me.
self.level("stderr: " + sys.stderr)
VERBOSE = 5
log = logging.getLogger("my_logger")
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("selenium").setLevel(logging.INFO)
logging.addLevelName(5, "VERBOSE")
masks_compile = re.compile('|'.join(map(re.escape, ["some_pass_1", "some_pass_2"])))
c_formatter = MaskFormatter('%(message)s', masks_compile)
f_formatter = MaskFormatter('%(asctime)s %(name)s %(levelname)s: \t %(message)s', masks_compile)
f_handler = logging.handlers.RotatingFileHandler(os.path.join(os.path.expanduser("~"), "tests.log"), mode='a', maxBytes=3000000, backupCount=10)
f_handler.setFormatter(f_formatter)
f_handler.setLevel(logging.DEBUG)
c_handler = logging.StreamHandler(sys.stdout)
c_handler.setFormatter(c_formatter)
c_handler.setLevel(int(os.environ.get("logging_level", "5")))
log.addHandler(c_handler)
log.addHandler(f_handler)
log.setLevel(int(os.environ.get("logging_level", "5")))
sys.stdout = LoggerWriter(log.debug)
sys.stderr = LoggerWriter(log.warning)
注意,我正在捕获stdout和stderr
在Jenkins上运行时,我随机遇到的问题是,在记录简单消息时,记录器进入最大递归。测试失败的方式各不相同,但每个测试都会在“self.level”(“stdout:+message”)行中进入这种递归
其中一个堆栈跟踪:
File "C:\Python27\lib\unittest\case.py", line 384, in doCleanups
function(*args, **kwargs)
File "C:\jenkins\workspace\PLC_Tests_Core_Functionalities_Win7_64b_Nightly\automation\tests\ds_setup.py", line 191, in failedReset
log.info("Test failed, will reinstall DS and set subscribed to initial ones")
File "C:\Python27\lib\logging\__init__.py", line 1160, in info
self._log(INFO, msg, args, **kwargs)
File "C:\Python27\lib\logging\__init__.py", line 1279, in _log
self.handle(record)
File "C:\Python27\lib\logging\__init__.py", line 1289, in handle
self.callHandlers(record)
File "C:\Python27\lib\logging\__init__.py", line 1329, in callHandlers
hdlr.handle(record)
File "C:\Python27\lib\logging\__init__.py", line 757, in handle
self.emit(record)
File "C:\Python27\lib\logging\handlers.py", line 82, in emit
self.handleError(record)
File "C:\Python27\lib\logging\__init__.py", line 810, in handleError
None, sys.stderr)
File "C:\Python27\lib\traceback.py", line 124, in print_exception
_print(file, 'Traceback (most recent call last):')
File "C:\Python27\lib\traceback.py", line 13, in _print
file.write(str+terminator)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\jenkins\workspace\PLC_Tests_Core_Functionalities_Win7_64b_Nightly\automation\pages\log.py", line 36, in write
self.level("stdout: " + message)
File "C:\Python27\lib\logging\__init__.py", line 1172, in warning
self._log(WARNING, msg, args, **kwargs)
File "C:\Python27\lib\logging\__init__.py", line 1279, in _log
self.handle(record)
File "C:\Python27\lib\logging\__init__.py", line 1289, in handle
self.callHandlers(record)
File "C:\Python27\lib\logging\__init__.py", line 1329, in callHandlers
hdlr.handle(record)
File "C:\Python27\lib\logging\__init__.py", line 757, in handle
self.emit(record)
File "C:\Python27\lib\logging\handlers.py", line 82, in emit
self.handleError(record)
File "C:\Python27\lib\logging\__init__.py", line 810, in handleError
None, sys.stderr)
File "C:\Python27\lib\traceback.py", line 124, in print_exception
_print(file, 'Traceback (most recent call last):')
File "C:\Python27\lib\traceback.py", line 13, in _print
file.write(str+terminator)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\jenkins\workspace\PLC_Tests_Core_Functionalities_Win7_64b_Nightly\automation\pages\log.py", line 36, in write
self.level("stdout: " + message)
File "C:\Python27\lib\logging\__init__.py", line 1172, in warning
self._log(WARNING, msg, args, **kwargs)
File "C:\Python27\lib\logging\__init__.py", line 1279, in _log
self.handle(record)
File "C:\Python27\lib\logging\__init__.py", line 1289, in handle
self.callHandlers(record)
File "C:\Python27\lib\logging\__init__.py", line 1329, in callHandlers
hdlr.handle(record)
File "C:\Python27\lib\logging\__init__.py", line 757, in handle
self.emit(record)
File "C:\Python27\lib\logging\handlers.py", line 82, in emit
self.handleError(record)
File "C:\Python27\lib\logging\__init__.py", line 810, in handleError
None, sys.stderr)
File "C:\Python27\lib\traceback.py", line 124, in print_exception
_print(file, 'Traceback (most recent call last):')
File "C:\Python27\lib\traceback.py", line 13, in _print
file.write(str+terminator)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
File "C:\Python27\lib\site-packages\nose\plugins\xunit.py", line 129, in write
s.write(data)
我使用以下工具运行测试:
nosetests -v -s --with-xunit --xunit-file=path/to/xml path/to/tests --with-allure --logdir=path/to/output
我认为问题来自尝试从同一个流(stdout)读写。因此,我假设您的目的是捕获应用程序创建的所有stdout/stderr消息(如从第三方模块记录)。在这种情况下,最好将所有记录器配置为将消息传播到父记录器,并添加根记录器,以您选择的方式记录数据 如果日志结构复杂,我建议使用来发现:
import logging_tree
import nose
logging_tree.printout()
...
因此,我们得到了记录器oyeah,确切地说-我的意图是从其他模块捕获内容;你的建议似乎更合理。被接受为答案。
import logging
logging.getLogger("nose").propagate = True
logging.getLogger().addHandler(<Your handler>)
logging.getLogger().setLevel(logging.DEBUG)