Python:定时任务
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Abstract: 定时任务
import os
import re
import sys
import logging
import datetime
import threading,time
sys.path.append(os.path.dirname(os.path.split(os.path.realpath(__file__))[0]))
from lib.mail import Mail
from tornado.template import Template,Loader
from model.morule import MoRule
from model.mojob import MoJobTimer,MoJobLog
from conf.style_dic import DicMap
from service.alarmhandler import AlarmHandler
from lib.database2org import ModelMap
from lib.databaseBkorg import ModelMapBak
class Timer(threading.Thread):
'''
定时任务
self.isPlay和self.fnPlay保证程序执行完毕才退出,而不是直接退出
self.lastDo声明当定时器收到结束命令的时候是否最后执行一次,以保证数据的完整性
'''
#初始化定时任务相关参数
def __init__(self,fn,args=(),interval=0,lastDo=True):
threading.Thread.__init__(self)
self.fn = fn
self.args = args
self.interval = interval
self.lastDo = lastDo
self.setDaemon(True) #设置该线程为守护线程
self.isPlay = True
self.fnPlay = False
def __do(self):
logging.info('start sched: %s',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
#self.fnPlay = True
apply(self.fn,self.args)
self.fnPlay = False
def run(self):
'''
线程执行体
'''
while self.isPlay:
time.sleep(self.interval)
self.__do()
def stop(self):
self.isPlay = False
print self.fnPlay
while True:
if not self.fnPlay : break
time.sleep(0.01)
if self.lastDo : self.__do()
logging.info('close sched: %s',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
class ExtTimerRun(object):
'''
定时任务执行体,加入了执行方式,执行间隔设置等业务内容
'''
def __init__(self):
'''
初始化执行间隔和报警标识
'''
self.__interval = 5.0
self.isAlarm = False
def __timerFunc(self,rule_id,alarm_type,note_id,mail_id,timer_id):
'''
线程实际执行的方法体
'''
timer_job = MoJobTimer.mgr(ismaster=True).one(timer_id)
#记录线程开始执行时间
t = MoJobLog.new()
t.timer_id,t.timer_name = timer_id,timer_job.name
t.thr_name,t.is_alive = self.__timer.getName(),self.__timer.isAlive()
t.job_status = DicMap.RUN_START
t = t.save()
log_id = t.id
#扫描到停止线程请求,则调用线程暂停请求
if timer_job.is_run<>DicMap.THREAD_RUN:
logging.info('===>Stopping the timer.The timer is %s',timer_id)
MoJobTimer.mgr(ismaster=True).raw("update mo_job_timer set is_run='%s' where id=%s"%(DicMap.THREAD_STOPING,timer_id))
self.__timer.stop()
MoJobTimer.mgr(ismaster=True).raw("update mo_job_timer set is_run='%s' where id=%s"%(DicMap.THREAD_STOP,timer_id))
#记录线程日志差值
log = MoJobLog.mgr(ismaster=True).one(log_id)
log.end_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log.job_status = DicMap.RUN_STOP
t.use_time = '%s秒'%((datetime.datetime.now()-log.start_time).seconds)
t = t.save()
return
#对定时任务执行类型进行过滤
now_time = datetime.datetime.now()
timeEq = datetime.timedelta(minutes=0)
#按时间段执行
if DicMap.JOB_TYPE_BETWEEN==timer_job.job_type:
start_time = timer_job.start_time
end_time = timer_job.end_time
#如果不在时间段内,则结束定时任务运行
if (start_time - now_time)>timeEq or (now_time - end_time)>timeEq:
MoJobTimer.mgr(ismaster=True).raw("update mo_job_timer set is_run='%s' where id=%s"%(DicMap.THREAD_STOPING,timer_id)
)
self.__timer.stop()
return
#按时间点执行
elif DicMap.JOB_TYPE_POINT==timer_job.job_type:
trigger_time = timer_job.trigger_time
timeSpace = datetime.timedelta(minutes=40)
start_time = trigger_time - timeSpace
end_time = trigger_time + timeSpace
if not ((now_time - start_time)>timeEq and (end_time - now_time)>timeEq):
time.sleep(30*60)
else:
if timer_job.interval==DicMap.INTERVAL_DAY:
timer_job.trigger_time = timer_job.trigger_time + datetime.timedelta(days=1)
elif timer_job.interval==DicMap.INTERVAL_WEEK:
timer_job.trigger_time = timer_job.trigger_time + datetime.timedelta(days=7)
elif timer_job.interval==DicMap.INTERVAL_MONTH:
timer_job.trigger_time = timer_job.trigger_time + datetime.timedelta(days=30)
timer_job = timer_job.save()
#标志当前线程体正在执行,确保数据的完整,避免在停止线程时产生脏数据
self.__timer.fnPlay = True
#获取规则数据,驱动执行,获取执行结果,并发送模板报警
rule = MoRule.mgr(ismaster=True).one(rule_id)
rs = []
thrName = self.__timer.getName()
MoJobLog.mgr(ismaster=True).raw("update mo_job_log set job_status='%s' where id=%s"%(DicMap.RUN_EXECU,log_id))
#规则类型:简单汇总、使用执行体
if rule.rule_type==DicMap.CORE_DRIVER_TYPE_SIMPLE_SUMMARY and rule.is_use_task==DicMap.YES:
logging.info("Run Simple SQL.")
runTask = rule.run_task #执行体
rs = ModelMap().raw(runTask)
if len(rs)>0:
self.isAlarm = True
logging.info('The runTask is : %s',runTask)
elif rule.rule_type==DicMap.CORE_DRIVER_TYPE_SIMPLE_PROCEDURE and rule.is_use_task==DicMap.YES:
procName = rule.proc_name #存储过程名
logging.info("Run Procedure %s .",procName)
param = (thrName,)
result = ModelMap().call(procName,param)
if result.data:
self.isAlarm = True
runTask = rule.run_task
out_exec_timestamp = result.data[0][0]
query_sql = runTask%out_exec_timestamp
rs = ModelMap().raw(query_sql)
delete_sql = "DELETE FROM temp_op_monitor_proc WHERE exec_timestamp='%s'"%out_exec_timestamp
ModelMap(ismaster=True).raw(delete_sql)
elif rule.rule_type==DicMap.CORE_DRIVER_TYPE_JUMP_SUMMARY and rule.is_use_task==DicMap.YES:
logging.info("Run Over Database SQL.")
runTask = rule.run_task #执行体
runTaskSlave = rule.run_task_slave #从库执行体
rs_master = ModelMap().raw(runTask)
if len(rs_master)>0:
self.isAlarm = True
fd_arr = re.findall( r'(?<=/\$).+?(?=\$/)' , runTaskSlave )
for rec in rs_master:
master_rec_keys = rec.keys()
runTaskSlaveTmp = runTaskSlave
#完成动态参数替换
for slave_key in fd_arr:
slave_key = slave_key.strip()
if rec.has_key(slave_key):
rep_key = '/$'+slave_key+'$/'
runTaskSlaveTmp = runTaskSlaveTmp.replace(rep_key,str(rec.get(slave_key)))
rs_slave = ModelMapBak().raw(runTaskSlaveTmp)
if rs_slave and len(rs_slave)>0:
rs_slave_rec = rs_slave[0]
rs.append(dict(rec,**rs_slave_rec))
else:
pass
#是否发警报
if self.isAlarm:
AlarmHandler.alarm(self,rule.data_head,rs,alarm_type,note_id,mail_id,timer_id)
#记录线程日志差值
log = MoJobLog.mgr(ismaster=True).one(log_id)
log.end_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log.use_time = '%s秒'%((datetime.datetime.now()-log.start_time).seconds)
log.job_status = DicMap.RUN_STOP
log = log.save()
def createTimer(self, interval,rule_id,alarm_type,note_id,mail_id,timer_id):
'''
定时任务线程创建,并启动线程
'''
self.__interval = interval
self.__timer = Timer(self.__timerFunc,(rule_id,alarm_type,note_id,mail_id,timer_id,),self.__interval,False)
self.__timer.start()
th_info = self.__timer.getName()
th_isAlive = self.__timer.isAlive()
#logging.info("The thread info .thread-Name:%s isAlive:%s ",(th_info,th_isAlive))
return th_info,th_isAlive
if __name__ == "__main__":
print "start timer"
t = ExtTimerRun()
#每隔一秒执行一次
t.createTimer(1)
while True:
pass
--------------------------------------------------------------------------------------------------------
定时任务的使用
logging.info("---->start timer. ")
#创建定时任务,并执行
t = ExtTimerRun()
MoJobTimer.mgr(ismaster=True).raw("update mo_job_timer set run_status='%s'where id=%s" %(DicMap.RUN_START,timer_id), ())
thrID,thrStatus = t.createTimer(self.interval,rule_id,alarm_type,note_id,mail_id,timer_id)
浙公网安备 33010602011771号