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 循环任务

.