问题:
在进行UI自动化时,想要输出每次查找元素的日志,引入logging模块,并设置logging.INFO,但是实际上运行正常,但控制台并没有输出日志:
class BasePage:
_driver = None
_params={}
_base_url = ""
logging.basicConfig(level=logging.INFO)
def __init__(self,driver:WebDriver = None):
if driver is None:
# 和瀏覽器打開的調試端口進行通信,瀏覽器要使用 --remote-debugging-port=9222 開啟調試
chrome_options = Options()
chrome_options.debugger_address = "127.0.0.1:9222"
self._driver = webdriver.Chrome(options=chrome_options)
self._driver.maximize_window()
self._driver.implicitly_wait(3)
else:
self._driver = driver
if self._base_url != "":
self._driver.get(self._base_url)
@handlie_blacklist
def find(self,by,locator):
# 调用find函数即打印日志
logging.info(f"find:{locator}")
if by == None:
result=self._driver.find_element(*locator)
else:
result = self._driver.find_element(by,locator)
return result
解决思路:
反复检查这段代码无误后,只能深入 logging.basicConfig
函数看看这个 python 自带的日志配置函数究竟做了什么(截取一部分)
def basicConfig(**kwargs):
_acquireLock()
try:
if len(root.handlers) == 0:
handlers = kwargs.pop("handlers", None)
if handlers is None:
if "stream" in kwargs and "filename" in kwargs:
raise ValueError("'stream' and 'filename' should not be "
"specified together")
else:
if "stream" in kwargs or "filename" in kwargs:
raise ValueError("'stream' or 'filename' should not be "
"specified together with 'handlers'")
if handlers is None:
filename = kwargs.pop("filename", None)
mode = kwargs.pop("filemode", 'a')
if filename:
h = FileHandler(filename, mode)
else:
stream = kwargs.pop("stream", None)
h = StreamHandler(stream)
handlers = [h]
dfs = kwargs.pop("datefmt", None)
style = kwargs.pop("style", '%')
if style not in _STYLES:
raise ValueError('Style must be one of: %s' % ','.join(
_STYLES.keys()))
fs = kwargs.pop("format", _STYLES[style][1])
fmt = Formatter(fs, dfs, style)
for h in handlers:
if h.formatter is None:
h.setFormatter(fmt)
root.addHandler(h)
分析这段程序,有个if
语句判断 root.handlers
为空,则会运行后续代码给将每个 handler 添加到根 logger 的逻辑。推测root.handlers 不为空。
看下这个函数basicConfig()
说明部分
"""
Do basic configuration for the logging system.
This function does nothing if the root logger already has handlers
configured. It is a convenience method intended for use by simple scripts
to do one-shot configuration of the logging package.
The default behaviour is to create a StreamHandler which writes to
sys.stderr, set a formatter using the BASIC_FORMAT format string, and
add the handler to the root logger.
A number of optional keyword arguments may be specified, which can alter
the default behaviour.
"""
渣道翻译:
对日志系统进行基本配置。
如果根日志记录器已经有处理程序,则此函数不执行任何操作配置。它是一种便于简单脚本使用的方法对日志包进行一次性配置。
默认行为是创建一个写入的StreamHandler。使用BASIC_FORMAT格式字符串设置格式化程序,以及将处理程序添加到根日志记录器。
可以指定许多可选关键字参数,这些参数可以更改默认的行为。
即在图1代码调用logging.basicConfig
前已经调用了一次basicConfig
,导致设置失效,其实还是使用系统默认的日志文件,根记录器始终默认为警告级别
。
打个断点验证下:
说明:
在调用logging.basicConfig
前打印了root处理器的handles是有两个的,但是进一步去追踪是哪个地方先行调用了basicConfig
,目前我还没有头绪,若有方法,望告知。
解决:
在logging.basicConfig
前清理已有 handlers
root_logger = logging.getLogger()
for h in root_logger.handlers[:]:
root_logger.removeHandler(h)
logging.basicConfig(level=logging.INFO)
注意:不要写成for h in root_logger.handlers:
再次执行代码,控制台就正常输出日志了,完事收工!
参考帖子:
追踪方法很好:python logging 模块配置咋不起作用了?
其他logging相关知识:
python中logging日志模块详解
Python日志输出——logging模块
干货:
Python中内置的日志模块logging用法详解
python logging 替代print 输出内容到控制台和重定向到文件