APSchelduler调度器事件监听
来自CloudWiki
背景介绍
scheduler的基本应用在前面已经介绍过了,但仔细思考一下:如果程序有异常抛出会影响整个调度任务吗?请看下面的代码,运行一下看看会发生什么情况。
# -*- coding: utf-8 -*- # Time: 2018/10/13 19:01:30 # File Name: ex_interval.py from datetime import datetime import os from apscheduler.schedulers.blocking import BlockingScheduler def tick(): print(1/0) print('Tick! The time is: %s' % datetime.now()) if __name__ == '__main__': scheduler = BlockingScheduler() scheduler.add_job(tick, 'interval', seconds=3) print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C ')) try: scheduler.start() except (KeyboardInterrupt, SystemExit): pass
输出:
Job "tick (trigger: interval[0:00:03], next run at: 2020-03-09 12:20:17 CST)" raised an exception Traceback (most recent call last): File "C:\Users\thinkpad\AppData\Local\Programs\Python\Python37\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job retval = job.func(*job.args, **job.kwargs) File "D:\teaching\自动化运维\练习\ex_interval.py", line 10, in tick print(1/0) ZeroDivisionError: division by zero Job "tick (trigger: interval[0:00:03], next run at: 2020-03-09 12:20:20 CST)" raised an exception Traceback (most recent call last): File "C:\Users\thinkpad\AppData\Local\Programs\Python\Python37\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job retval = job.func(*job.args, **job.kwargs) File "D:\teaching\自动化运维\练习\ex_interval.py", line 10, in tick print(1/0) ZeroDivisionError: division by zero
可以看出每5秒抛出一次报错信息。任何代码都可能会抛出异常,关键是如何第一时间知道发生导常事件,APScheduler提供了事件监听来解决这一问题。
将上述代码稍做调整,加入日志记录和事件监听。
加入事件监听
在调度器中加入事件监听(listen_event.py)。
导入必要的包
from datetime import datetime import os from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR import datetime import logging
定义任务
def tick(): print(1/0) print('Tick! The time is: %s' % datetime.now())
配置日志记录器
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename='log1.txt', filemode='a')
编写监听器
def my_listener(event): if event.exception: print ('任务出错了!!!!!!') else: print ('任务照常运行...')
添加日志记录器和事件监听器
if __name__ == '__main__': scheduler = BlockingScheduler() scheduler.add_job(tick, 'interval', seconds=3) scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR) scheduler._logger = logging print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C ')) try: scheduler.start() except (KeyboardInterrupt, SystemExit): pass
完整代码
# -*- coding: utf-8 -*- # Time: 2018/10/13 19:01:30 # File Name: ex_interval.py from datetime import datetime import os from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR import datetime import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename='log1.txt', filemode='a') def tick(): print(1/0) print('Tick! The time is: %s' % datetime.now()) def my_listener(event): if event.exception: print ('任务出错了!!!!!!') else: print ('任务照常运行...') if __name__ == '__main__': scheduler = BlockingScheduler() scheduler.add_job(tick, 'interval', seconds=3) scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR) scheduler._logger = logging print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C ')) try: scheduler.start() except (KeyboardInterrupt, SystemExit): pass
实例:配置事件监听
代码:
# -*- coding: utf-8 -*- # !/usr/local/bin/python # Time: 2018/10/13 20:30:38 # Description: # File Name: listen_event.py from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR import datetime import logging #添加日志配置代码 def aps_test(x): print (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x) def date_test(x): print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x) print (1/0) #监听器定义代码 scheduler = BlockingScheduler() scheduler.add_job(func=date_test, args=('一次性任务,会出错',), \ next_run_time=datetime.datetime.now() + \ datetime.timedelta(seconds=15), id='date_task') scheduler.add_job(func=aps_test, args=('循环任务',), \ trigger='interval', seconds=3, id='interval_task') #为调度器添加监听器 #为调度器添加日志记录器 scheduler.start()
输出:
2020-03-09 14:42:43 循环任务 任务照常运行... 2020-03-09 14:42:46 循环任务 任务照常运行... 2020-03-09 14:42:49 循环任务 任务照常运行... 2020-03-09 14:42:52 循环任务 任务照常运行... 2020-03-09 14:42:55 一次性任务,会出错 任务出错了!!!!!! 2020-03-09 14:42:55 循环任务
.