Home | History | Annotate | Download | only in rpm_control_system
      1 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 import datetime
      5 import logging
      6 import logging.handlers
      7 import os
      8 import socket
      9 import time
     10 
     11 from config import rpm_config
     12 
     13 import common
     14 from autotest_lib.site_utils import log_socket_server
     15 from autotest_lib.site_utils.rpm_control_system import rpm_infrastructure_exception
     16 
     17 LOGGING_FORMAT = rpm_config.get('GENERAL', 'logging_format')
     18 RECEIVERS = rpm_config.get('RPM_INFRASTRUCTURE',
     19                            'email_notification_recipients').split(',')
     20 SUBJECT_LINE = (rpm_config.get('GENERAL', 'email_subject_line_format') %
     21                 socket.gethostname())
     22 
     23 
     24 class SuspendableSMTPHandler(logging.handlers.SMTPHandler):
     25     """SMTPHandler that can have it's emails suspended."""
     26     _suspend_start_time = datetime.datetime.now()
     27     _suspend_time_hrs = 0
     28 
     29 
     30     def suspend_emails(self, hours):
     31         """Suspend email notifications.
     32 
     33         @param hours: How many hours to suspend email notifications.
     34         """
     35         self._suspend_start_time = datetime.datetime.now()
     36         self._suspend_time_hrs = int(hours, 0)
     37 
     38 
     39     def resume_emails(self):
     40         """Resume email notifications."""
     41         self._suspend_time_hrs = 0
     42 
     43 
     44     def emit(self, record):
     45         """Emit a log record.
     46 
     47         This subclassed version only emits the log record if emails are not
     48         suspended.
     49 
     50         @param record: Log record object we want to emit/record.
     51         """
     52         if datetime.datetime.now() < (self._suspend_start_time +
     53                 datetime.timedelta(hours=self._suspend_time_hrs)):
     54             return
     55         record.msg += ('\n\nTo disable these emails use rpm_client from your '
     56                        'local checkout. For a 12 hour suspension run: '
     57                        'site_utils/rpm_control_system/rpm_client.py -d 12')
     58         return super(SuspendableSMTPHandler, self).emit(record)
     59 
     60 
     61 def set_up_logging_to_file(log_dir, log_filename_format=None):
     62     """
     63     Correctly set up logging to have the correct format/level, log to a file,
     64     and send out email notifications in case of error level messages.
     65 
     66     @param log_dir: The directory in which log files should be created.
     67     @param log_filename_format: Format to use to create the log file.
     68 
     69     @returns email_handler: Logging handler used to send out email alerts.
     70     """
     71     logging.basicConfig(filename=_logfile_path(log_dir, log_filename_format),
     72                         level=logging.INFO, format=LOGGING_FORMAT)
     73     _set_common_logger_options()
     74 
     75 
     76 def start_log_server(log_dir, log_filename_format):
     77     """Start log server to accept logging through a TCP server.
     78 
     79     @param log_dir: The directory in which log files should be created.
     80     @param log_filename_format: Format to use to create the log file.
     81     """
     82     log_filename = _logfile_path(log_dir, log_filename_format)
     83     log_socket_server.LogSocketServer.start(filename=log_filename,
     84                                             level=logging.INFO,
     85                                             format=LOGGING_FORMAT)
     86 
     87 
     88 def set_up_logging_to_server():
     89     """Sets up logging option when using a logserver."""
     90     if log_socket_server.LogSocketServer.port is None:
     91         raise rpm_infrastructure_exception.RPMLoggingSetupError(
     92                 'set_up_logging failed: Log server port is unknown.')
     93     socketHandler = logging.handlers.SocketHandler(
     94             'localhost', log_socket_server.LogSocketServer.port)
     95     logging.getLogger().addHandler(socketHandler)
     96     _set_common_logger_options()
     97 
     98 
     99 def _logfile_path(log_dir, log_filename_format):
    100     """Get file name of log based on given log_filename_format.
    101 
    102     @param log_filename_format: Format to use to create the log file.
    103     """
    104     log_filename = time.strftime(log_filename_format)
    105     if not os.path.isdir(log_dir):
    106         os.makedirs(log_dir)
    107     return os.path.join(log_dir, log_filename)
    108 
    109 
    110 def _set_common_logger_options():
    111     """Sets the options common to both file and server based logging."""
    112     logger = logging.getLogger()
    113     if rpm_config.getboolean('GENERAL', 'debug'):
    114         logger.setLevel(logging.DEBUG)
    115     email_handler = SuspendableSMTPHandler('localhost', 'rpm (at] google.com',
    116                                            RECEIVERS, SUBJECT_LINE, None)
    117     email_handler.setLevel(logging.ERROR)
    118     email_handler.setFormatter(logging.Formatter(LOGGING_FORMAT))
    119     logger.addHandler(email_handler)
    120