# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import datetime
import logging
import logging.handlers
import os
import socket
import time
from config import rpm_config
import common
from autotest_lib.site_utils import log_socket_server
from autotest_lib.site_utils.rpm_control_system import rpm_infrastructure_exception
LOGGING_FORMAT = rpm_config.get('GENERAL', 'logging_format')
RECEIVERS = rpm_config.get('RPM_INFRASTRUCTURE',
'email_notification_recipients').split(',')
SUBJECT_LINE = (rpm_config.get('GENERAL', 'email_subject_line_format') %
socket.gethostname())
class SuspendableSMTPHandler(logging.handlers.SMTPHandler):
"""SMTPHandler that can have it's emails suspended."""
_suspend_start_time = datetime.datetime.now()
_suspend_time_hrs = 0
def suspend_emails(self, hours):
"""Suspend email notifications.
@param hours: How many hours to suspend email notifications.
"""
self._suspend_start_time = datetime.datetime.now()
self._suspend_time_hrs = int(hours, 0)
def resume_emails(self):
"""Resume email notifications."""
self._suspend_time_hrs = 0
def emit(self, record):
"""Emit a log record.
This subclassed version only emits the log record if emails are not
suspended.
@param record: Log record object we want to emit/record.
"""
if datetime.datetime.now() < (self._suspend_start_time +
datetime.timedelta(hours=self._suspend_time_hrs)):
return
record.msg += ('\n\nTo disable these emails use rpm_client from your '
'local checkout. For a 12 hour suspension run: '
'site_utils/rpm_control_system/rpm_client.py -d 12')
return super(SuspendableSMTPHandler, self).emit(record)
def set_up_logging_to_file(log_dir, log_filename_format=None):
"""
Correctly set up logging to have the correct format/level, log to a file,
and send out email notifications in case of error level messages.
@param log_dir: The directory in which log files should be created.
@param log_filename_format: Format to use to create the log file.
@returns email_handler: Logging handler used to send out email alerts.
"""
logging.basicConfig(filename=_logfile_path(log_dir, log_filename_format),
level=logging.INFO, format=LOGGING_FORMAT)
_set_common_logger_options()
def start_log_server(log_dir, log_filename_format):
"""Start log server to accept logging through a TCP server.
@param log_dir: The directory in which log files should be created.
@param log_filename_format: Format to use to create the log file.
"""
log_filename = _logfile_path(log_dir, log_filename_format)
log_socket_server.LogSocketServer.start(filename=log_filename,
level=logging.INFO,
format=LOGGING_FORMAT)
def set_up_logging_to_server():
"""Sets up logging option when using a logserver."""
if log_socket_server.LogSocketServer.port is None:
raise rpm_infrastructure_exception.RPMLoggingSetupError(
'set_up_logging failed: Log server port is unknown.')
socketHandler = logging.handlers.SocketHandler(
'localhost', log_socket_server.LogSocketServer.port)
logging.getLogger().addHandler(socketHandler)
_set_common_logger_options()
def _logfile_path(log_dir, log_filename_format):
"""Get file name of log based on given log_filename_format.
@param log_filename_format: Format to use to create the log file.
"""
log_filename = time.strftime(log_filename_format)
if not os.path.isdir(log_dir):
os.makedirs(log_dir)
return os.path.join(log_dir, log_filename)
def _set_common_logger_options():
"""Sets the options common to both file and server based logging."""
logger = logging.getLogger()
if rpm_config.getboolean('GENERAL', 'debug'):
logger.setLevel(logging.DEBUG)
email_handler = SuspendableSMTPHandler('localhost', 'rpm@google.com',
RECEIVERS, SUBJECT_LINE, None)
email_handler.setLevel(logging.ERROR)
email_handler.setFormatter(logging.Formatter(LOGGING_FORMAT))
logger.addHandler(email_handler)