Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 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. |
Simran Basi | 4e3d118 | 2013-06-25 16:12:30 -0700 | [diff] [blame] | 4 | import datetime |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 5 | import logging |
| 6 | import logging.handlers |
Scott Zawalski | 201d6be | 2012-09-21 15:56:25 -0400 | [diff] [blame] | 7 | import os |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 8 | import socket |
| 9 | import time |
| 10 | |
| 11 | from config import rpm_config |
Dan Shi | b7610b5 | 2014-05-06 11:09:49 -0700 | [diff] [blame] | 12 | |
| 13 | import common |
Dan Shi | 1a34c36 | 2014-04-11 16:37:04 -0700 | [diff] [blame] | 14 | from autotest_lib.site_utils import log_socket_server |
Fang Deng | a89fc9c | 2014-08-13 17:36:23 -0700 | [diff] [blame] | 15 | from autotest_lib.site_utils.rpm_control_system import rpm_infrastructure_exception |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 16 | |
| 17 | LOGGING_FORMAT = rpm_config.get('GENERAL', 'logging_format') |
Simran Basi | 4e3d118 | 2013-06-25 16:12:30 -0700 | [diff] [blame] | 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) |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 59 | |
| 60 | |
Prathmesh Prabhu | 90b0c95 | 2017-09-15 16:11:12 -0700 | [diff] [blame] | 61 | def set_up_logging_to_file(log_dir, log_filename_format=None): |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 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. |
Simran Basi | 4e3d118 | 2013-06-25 16:12:30 -0700 | [diff] [blame] | 65 | |
Prathmesh Prabhu | 90b0c95 | 2017-09-15 16:11:12 -0700 | [diff] [blame] | 66 | @param log_dir: The directory in which log files should be created. |
Simran Basi | 4e3d118 | 2013-06-25 16:12:30 -0700 | [diff] [blame] | 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. |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 70 | """ |
Prathmesh Prabhu | 90b0c95 | 2017-09-15 16:11:12 -0700 | [diff] [blame] | 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: |
Fang Deng | a89fc9c | 2014-08-13 17:36:23 -0700 | [diff] [blame] | 91 | raise rpm_infrastructure_exception.RPMLoggingSetupError( |
| 92 | 'set_up_logging failed: Log server port is unknown.') |
Prathmesh Prabhu | 90b0c95 | 2017-09-15 16:11:12 -0700 | [diff] [blame] | 93 | socketHandler = logging.handlers.SocketHandler( |
| 94 | 'localhost', log_socket_server.LogSocketServer.port) |
| 95 | logging.getLogger().addHandler(socketHandler) |
| 96 | _set_common_logger_options() |
Dan Shi | 1a34c36 | 2014-04-11 16:37:04 -0700 | [diff] [blame] | 97 | |
Prathmesh Prabhu | 90b0c95 | 2017-09-15 16:11:12 -0700 | [diff] [blame] | 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() |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 113 | if rpm_config.getboolean('GENERAL', 'debug'): |
Prathmesh Prabhu | 90b0c95 | 2017-09-15 16:11:12 -0700 | [diff] [blame] | 114 | logger.setLevel(logging.DEBUG) |
Simran Basi | 4e3d118 | 2013-06-25 16:12:30 -0700 | [diff] [blame] | 115 | email_handler = SuspendableSMTPHandler('localhost', 'rpm@google.com', |
| 116 | RECEIVERS, SUBJECT_LINE, None) |
Simran Basi | 7498d20 | 2012-07-10 15:21:28 -0700 | [diff] [blame] | 117 | email_handler.setLevel(logging.ERROR) |
| 118 | email_handler.setFormatter(logging.Formatter(LOGGING_FORMAT)) |
Prathmesh Prabhu | 90b0c95 | 2017-09-15 16:11:12 -0700 | [diff] [blame] | 119 | logger.addHandler(email_handler) |