def exit(self): tool.write_to_log("Exiting Job Scheduler Thread") self.__running = False if self.__parent and hasattr(self.__parent, 'js_thread'): self.__parent.js_thread.join() self.__parent.js_thread = None
def __start_job(self, job_profile): tool.write_to_log("Job '{0}' is now starting".format( job_profile['Job_Name'])) job_class = Job(deepcopy(job_profile)) timeout = get_timeout(hours=job_profile['Timeout_HH'], minutes=job_profile['Timeout_MM']) thread = Thread(target=process_job, args=(job_class, )) thread.daemon = True thread.start() self.__jobs[job_profile['Job_Name']] = [ thread, job_class, timeout, self ]
def start(self): tool.write_to_log("Starting Job Scheduler Thread") from time import sleep self.__running = True self.__jobs = dict() try: initiated = True while self.__running: job_names = local_config['Jobs'].keys() for job_name in job_names: if job_name in local_config['Jobs'].keys(): job_profile = local_config['Jobs'][job_name] self.__job_validate(job_profile, initiated) self.__job_watch(job_profile) initiated = False sleep(1) except Exception as e: tool.write_to_log(format_exc(), 'critical') tool.write_to_log("Job Main - ECode '{0}', {1}".format( type(e).__name__, str(e))) finally: self.__kill_all_jobs() tool.write_to_log("Job Scheduler Thread has been stopped")
def remove_dir(dir_filepath): if exists(dir_filepath): from shutil import rmtree for filename in listdir(dir_filepath): file_path = join(dir_filepath, filename) try: if isfile(file_path) or islink(file_path): unlink(file_path) elif isdir(file_path): rmtree(file_path) except Exception as e: tool.write_to_log( 'Failed to delete %s. Reason: %s' % (file_path, e), 'warning') pass
def email_results(self, err_msg=None): if self.__job_profile and self.__task_profiles: try: self.write_job_log("Job '%s' is sending e-mail to distros" % self.__job_profile['Job_Name']) self.__err_msg = err_msg self.__package_tasks() self.__package_email() self.__package_attach() self.__email.send() self.write_job_log("Job '%s' is e-mail was sent successfully" % self.__job_profile['Job_Name']) except Exception as e: tool.write_to_log(format_exc(), 'critical') tool.write_to_log("Email - ECode '{0}', {1}".format( type(e).__name__, str(e)))
def __kill_job(job, job_name, reason): if job and job_name and reason and not job[1].tasks_finished: message = "failed execution because %s" % reason try: if job[0].is_alive(): job[1].terminate(kill_thread=True) job[0].join() job[1].email_results(message) except Exception as e: tool.write_to_log(format_exc(), 'critical') tool.write_to_log("Kill Job - ECode '{0}', {1}".format( type(e).__name__, str(e))) pass finally: job[1].close_email()
def terminate(self, kill_thread=False): from KGlobal.sql import SQLEngineClass self.__kill_thread = kill_thread if self.__sql_engine and isinstance(self.__sql_engine, SQLEngineClass): self.__sql_engine.close_connections(destroy_self=True) if self.__sub_proc and self.__sub_proc.poll() is None: tool.write_to_log( "Job '{0}' - Attempting to kill process thread {1}".format( self.job_name, self.__sub_proc.pid)) try: kill(self.__sub_proc.pid, -9) except Exception as e: self.write_job_log(format_exc()) tool.write_to_log("Job '{0}' kill ECode '{1}', {2}".format( self.job_name, type(e).__name__, str(e))) pass self.__sql_engine = None self.__sub_proc = None
def __init__(self, parent): tool.write_to_log("Initializing Job Scheduler") self.__parent = parent
def __package_email(self): if self.__to_email and self.__job_profile['Job_Name']: from exchangelib import Message body = list() self.__email = Message(account=email_engine) names = [ str(email.split('@')[0]).title() for email in self.__to_email ] if self.__to_email: self.__email.to_recipients = self.__gen_email_list( self.__to_email) if self.__cc_email: self.__email.cc_recipients = self.__gen_email_list( self.__cc_email) body.append('Happy {0} {1},\n'.format( datetime.today().strftime("%A"), '; '.join(names))) if self.__err_msg: tool.write_to_log( "Job '{0}' failed job execution due to {1}".format( self.__job_profile['Job_Name'], self.__err_msg)) self.__email.subject = "<Job Failed> Job \"%s\"" % self.__job_profile[ 'Job_Name'] sub_body = "Job \"{0}\", {1}".format( self.__job_profile['Job_Name'], self.__err_msg) else: tool.write_to_log("Job '%s' completed successfully" % self.__job_profile['Job_Name']) self.__email.subject = "Job \"%s\" completed successfully" % self.__job_profile[ 'Job_Name'] sub_body = "Job \"{0}\" completed successfully".format( self.__job_profile['Job_Name']) body.append("{0}. Total job runtime was {1}.\n".format( sub_body, parse_time(self.job_start, datetime.now()))) for task_profile in self.__task_profiles: if task_profile['Task_Type'] == 1: task_type = 'Stored Proc' else: task_type = 'Program' if task_profile['Task_Error']: body.append( '\t\u2022 {0} "{1}" <Failed Task> ({2}) [Err Code: {3}]' .format( task_type, task_profile['Task_Name'], parse_time(task_profile['Task_Start'], task_profile['Task_End']), task_profile['Task_Error'][0])) else: body.append( '\t\u2022 {0} "{1}" <Succeeded Task> ({2})'.format( task_type, task_profile['Task_Name'], parse_time(task_profile['Task_Start'], task_profile['Task_End']))) body.append("\nYour's Truly,\n") body.append("The BI Team") self.__email.body = '\n'.join(body)
def __package_attach(self): if self.__attachments: from zipfile import ZipFile from exchangelib import FileAttachment from portalocker import Lock file_dir = join(attach_dir, datetime.today().__format__("%Y%m%d")) file_path = join( file_dir, '{0}_{1}.zip'.format( hash(datetime.now().__format__("%I:%M:%S %p")), self.__job_profile['Job_Name'])) if not exists(file_dir): makedirs(file_dir) if exists(file_path): try: remove(file_path) except Exception as e: tool.write_to_log( "Attach File Rem - ECode '{0}', {1}".format( type(e).__name__, str(e))) return zip_file = ZipFile(file_path, mode='w') try: for attachment in self.__attachments: try: if isfile(attachment) and exists( attachment) and stat(attachment).st_size > 0: zip_file.write(attachment, basename(attachment)) except Exception as e: self.write_job_log(format_exc()) tool.write_to_log( "Job '{0}' failed to zip file due to ECode '{1}', {2}" .format(self.__job_profile['Job_Name'], type(e).__name__, str(e))) pass finally: if isfile(attachment) and exists( attachment) and stat(attachment).st_size > 0: remove(attachment) except Exception as e: self.write_job_log(format_exc()) tool.write_to_log( "Job '{0}' failed to zip file in mainloop due to ECode '{1}', {2}" .format(self.__job_profile['Job_Name'], type(e).__name__, str(e))) pass finally: zip_file.close() if exists(file_path) and stat(file_path).st_size > 0: with Lock(file_path, 'rb') as f: self.__email.attach( FileAttachment(name=basename(file_path), content_type='zip', content=f.read(), is_inline=False)) elif exists(file_path): remove(file_path) try: unlink(file_dir) except Exception as e: tool.write_to_log("Dir Unlink - ECode '{0}', {1}".format( type(e).__name__, str(e))) pass