1"""Scheduler email manager.""" 2 3 4import logging 5import os 6import re 7import socket 8import time 9import traceback 10 11import common 12from autotest_lib.client.common_lib import global_config 13from autotest_lib.site_utils import gmail_lib 14 15 16CONFIG_SECTION = 'SCHEDULER' 17 18 19class EmailNotificationManager(object): 20 """Scheduler email notification manager.""" 21 22 def __init__(self): 23 """Initialize the manager.""" 24 self._emails = [] 25 self._notify_address = global_config.global_config.get_config_value( 26 CONFIG_SECTION, "notify_email", default='') 27 28 29 def send_email(self, to_string, subject, body): 30 """Mails out emails to the addresses listed in to_string. 31 32 @param to_string: is split into a list which can be delimited by any of: 33 ';', ',', ':' or any whitespace. 34 @param subject: String, email subject. 35 @param body: String, message body 36 """ 37 # Create list from string removing empty strings from the list. 38 to_list = [x for x in re.split('\s|,|;|:', to_string) if x] 39 if not to_list: 40 return 41 to_string = ','.join(to_list) 42 try: 43 gmail_lib.send_email(to_string, subject, body) 44 except Exception: 45 logging.exception('Sending email failed:') 46 47 48 def enqueue_notify_email(self, subject, message): 49 """Enqueue a message that will be sent later. 50 51 @param subject: String, subject of the message. 52 @param message: String, message to enqueue. 53 """ 54 logging.error(subject + '\n' + message) 55 if not self._notify_address: 56 return 57 58 body = 'Subject: ' + subject + '\n' 59 body += "%s / %s / %s\n%s" % (socket.gethostname(), 60 os.getpid(), 61 time.strftime("%X %x"), message) 62 self._emails.append(body) 63 64 65 def send_queued_emails(self): 66 """Send queued emails.""" 67 if not self._emails: 68 return 69 subject = 'Scheduler notifications from ' + socket.gethostname() 70 separator = '\n' + '-' * 40 + '\n' 71 body = separator.join(self._emails) 72 73 self.send_email(self._notify_address, subject, body) 74 self._emails = [] 75 76 77 def log_stacktrace(self, reason): 78 """Log an exception and enqueue it. 79 80 @param reason: An exception to log and send. 81 """ 82 logging.exception(reason) 83 message = "EXCEPTION: %s\n%s" % (reason, traceback.format_exc()) 84 self.enqueue_notify_email("monitor_db exception", message) 85 86 87manager = EmailNotificationManager() 88