• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4import datetime
5import logging
6import logging.handlers
7import os
8import socket
9import time
10
11from config import rpm_config
12
13import common
14from autotest_lib.site_utils import log_socket_server
15from autotest_lib.site_utils.rpm_control_system import rpm_infrastructure_exception
16
17LOGGING_FORMAT = rpm_config.get('GENERAL', 'logging_format')
18RECEIVERS = rpm_config.get('RPM_INFRASTRUCTURE',
19                           'email_notification_recipients').split(',')
20SUBJECT_LINE = (rpm_config.get('GENERAL', 'email_subject_line_format') %
21                socket.gethostname())
22
23
24class 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
61def 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
76def 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
88def 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
99def _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
110def _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@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