如何在Telepot DelegatorBot出现错误时接收通知并记录日志?
解决Telepot DelegatorBot网络异常的日志记录问题
针对你遇到的Telepot机器人网络中断时无法直接捕获错误日志的问题,这里有几个实用的方案,无需重定向标准输出就能实现错误感知和日志记录:
方案1:自定义Telepot的日志处理器
Telepot底层使用Python的logging模块,我们可以直接修改它的日志配置,把错误信息定向到日志文件,而非控制台输出。
- 首先导入
logging模块,配置文件日志处理器,指定日志级别和格式 - 获取Telepot的日志实例,添加自定义处理器并移除默认的控制台输出处理器
示例代码:
import logging import telepot from telepot.delegate import DelegatorBot, per_chat_id, create_open # 配置自定义日志 telepot_logger = logging.getLogger('telepot') telepot_logger.setLevel(logging.ERROR) # 创建文件日志处理器 file_handler = logging.FileHandler('telepot_errors.log') log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(log_formatter) # 添加处理器到Telepot日志实例 telepot_logger.addHandler(file_handler) # 移除默认的控制台输出处理器(如果存在) for handler in telepot_logger.handlers[:]: if isinstance(handler, logging.StreamHandler): telepot_logger.removeHandler(handler) # 初始化你的机器人 TOKEN = '你的机器人Token' bot = DelegatorBot(TOKEN, [ (per_chat_id(), create_open(你的聊天处理器类, timeout=10)), ]) bot.run_forever()
方案2:捕获run_forever的外层异常
虽然Telepot内部会自行处理部分异常并重试,但仍有部分网络相关异常会抛出到外层,我们可以用try-except块包裹run_forever,捕获这些异常并记录日志。
- 重点捕获网络类异常(如
requests.exceptions.ConnectionError、socket.timeout)和Telegram API相关错误 - 使用
logging.error记录错误,加上exc_info=True可以保存完整的回溯信息
示例代码(Python 2.7兼容版):
import logging import telepot import time import requests import socket from telepot.delegate import DelegatorBot, per_chat_id, create_open from telepot.exception import TelegramError # 配置日志文件 logging.basicConfig( filename='bot_errors.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s' ) TOKEN = '你的机器人Token' bot = DelegatorBot(TOKEN, [ (per_chat_id(), create_open(你的聊天处理器类, timeout=10)), ]) while True: try: bot.run_forever() except (requests.exceptions.ConnectionError, socket.timeout, TelegramError) as e: # 记录网络或API错误,包含回溯信息 logging.error(u"网络/Telegram API错误: %s" % str(e), exc_info=True) time.sleep(5) # 延迟5秒后重试 except Exception as e: # 捕获其他未知错误 logging.error(u"未知错误: %s" % str(e), exc_info=True) break
方案3:重写Telepot的Loop类
Telepot的run_forever基于Loop类实现,我们可以继承这个类,重写run_forever方法,在内部添加错误捕获和日志逻辑。
示例代码:
import logging import telepot from telepot.loop import Loop from telepot.delegate import DelegatorBot, per_chat_id, create_open # 配置日志 logging.basicConfig( filename='loop_errors.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s' ) class CustomLoop(Loop): def run_forever(self, allowed_updates=None): try: # 调用父类的run_forever方法 super(CustomLoop, self).run_forever(allowed_updates=allowed_updates) except Exception as e: logging.error(u"Loop运行错误: %s" % str(e), exc_info=True) # 递归调用实现重试 self.run_forever(allowed_updates=allowed_updates) # 初始化机器人并替换为自定义Loop TOKEN = '你的机器人Token' bot = DelegatorBot(TOKEN, [ (per_chat_id(), create_open(你的聊天处理器类, timeout=10)), ]) bot._loop = CustomLoop(bot) bot.run_forever()
注意事项
- 确保日志文件所在路径有写入权限,避免无法生成日志
exc_info=True参数会把完整的错误回溯信息写入日志,和你提供的Traceback内容一致,便于排查问题- 由于你的环境是Python 2.7,代码中使用了
u""字符串和super(CustomLoop, self)的兼容写法
内容的提问来源于stack exchange,提问作者lucidbrot
相关产品推荐
相关产品推荐

