
本文介绍如何正确配置 logging 并结合全局计数器,精准记录目标函数(如图像识别成功时)的调用次数,并将日志统一写入指定文件(如 anomaly.log),避免因日志对象作用域或重复初始化导致的日志丢失问题。
本文介绍如何正确配置 logging 并结合全局计数器,精准记录目标函数(如图像识别成功时)的调用次数,并将日志统一写入指定文件(如 `anomaly.log`),避免因日志对象作用域或重复初始化导致的日志丢失问题。
在自动化脚本(如基于 pyautogui 的图像检测)中,常需监控某项操作(例如成功定位 1.png)的发生频次,并将每次触发事件持久化记录到专用日志文件中。实现该需求的关键在于两点:确保日志对象在函数内可访问,以及保证计数逻辑准确、线程安全(单线程场景下即避免作用域错误)。
以下是一个优化后的完整示例,已修复原始代码中的核心问题:
- ❌ 错误:
hello()中直接调用logging.info(),实际写入的是basicConfig配置的bandit.log,而非目标anomaly.log; - ❌ 错误:
logger()被调度为每秒执行一次,导致重复添加 Handler,引发日志重复输出甚至句柄泄漏; - ✅ 修正:将日志配置抽离为独立函数
setup_logger(),仅执行一次,并返回可复用的logger实例; - ✅ 修正:使用
global call_count确保计数器跨调用累积,且在locateOnScreen成功后才递增并记录。
import logging
import pyautogui
import schedule
import time
def setup_logger():
# 主日志配置:输出到 bandit.log(可选,用于系统级信息)
logging.basicConfig(
level=logging.INFO,
filename="bandit.log",
filemode="w",
format="%(asctime)s - %(levelname)s - %(message)s"
)
# 创建专用 logger 实例,用于 anomaly.log
logger = logging.getLogger("anomaly_tracker")
logger.setLevel(logging.INFO)
logger.propagate = False # 阻止向上级 root logger 传递
# 添加专属 FileHandler 到 anomaly.log
handler = logging.FileHandler("anomaly.log", mode="a") # 追加模式,避免覆盖历史
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
# 全局 logger 实例(配置仅执行一次)
logger = setup_logger()
# 全局调用计数器
call_count = 0
def hello():
global call_count
try:
# 尝试定位图像(建议缓存 location 结果,避免重复调用)
location = pyautogui.locateOnScreen("1.png", confidence=0.9)
if location is not None: # 显式判断,更清晰可靠
call_count += 1
logger.info(f"Image '1.png' found. Total occurrences: {call_count}")
except pyautogui.ImageNotFoundException:
pass # 图像未找到,静默处理
# 调度任务:每秒执行一次 hello()
schedule.every(1).seconds.do(hello)
# 主循环
if __name__ == "__main__":
print("Monitoring started. Press Ctrl+C to stop.")
try:
while True:
schedule.run_pending()
time.sleep(0.5) # 更低延迟响应,同时减轻 CPU 占用
except KeyboardInterrupt:
logger.info("Monitoring stopped by user.")
print("Monitoring stopped.")
✅ 关键注意事项:
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
-
不要在定时任务中反复调用日志配置函数 ——
setup_logger()必须且仅需执行一次,否则会重复添加 Handler,造成日志重复写入; -
优先复用
logger对象而非logging模块顶层函数 ——logging.info()默认使用 root logger,与自定义 Handler 无关; -
图像查找应避免两次调用
locateOnScreen—— 原始代码中先try/except又再次调用,效率低下且可能因图像短暂消失导致结果不一致;建议保存首次结果并复用; -
使用
mode="a"打开anomaly.log—— 防止程序重启后日志被清空; -
为 logger 指定有意义的名称(如
"anomaly_tracker") —— 提升日志可读性与后期过滤能力。
通过以上结构化设计,你不仅能稳定记录每次 1.png 被识别的事件及累计次数,还能确保日志分类清晰、可追溯、易维护,真正满足生产级自动化监控的需求。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










