Source code for logger

"""logger
================

Handle logging.
"""


import os
import sys
import logging
import logging.handlers

from antslib import configer


CFG = configer.read_config('main')
logfile_main = os.path.join(CFG['log_dir'], 'ants.log')
logfile_ok = os.path.join(CFG['log_dir'], 'ok.log')
logfile_changed = os.path.join(CFG['log_dir'], 'changed.log')
logfile_failed = os.path.join(CFG['log_dir'], 'failed.log')
logfile_recap = os.path.join(CFG['log_dir'], 'recap.log')


[docs]def get_logger(name, logfile=False, maxBytes=0, formatter='default'): """Return logging object with handler and formatter.""" if logfile: handler = logging.handlers.RotatingFileHandler(logfile, maxBytes=maxBytes, backupCount=5, delay=True) handler.setLevel(logging.INFO) else: handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.DEBUG) if formatter is 'default': handler.setFormatter(logging.Formatter('%(asctime)s\t%(message)s', datefmt='%b %d %Y %H:%M:%S %Z')) elif formatter is 'simple': handler.setFormatter(logging.Formatter('%(message)s')) else: raise ValueError('Formatter must be simple or default') logger = logging.getLogger(name) logger.setLevel(logging.INFO) logger.addHandler(handler) return logger
[docs]def status_file_rollover(): """Rotate log files for ok/changed/failed at the start of every ansible run Keep track of ok/changed/failed and play recap on a per run basis. Hence, rotate them at the start of each run. Code for rotation based on https://stackoverflow.com/questions/4654915/rotate-logfiles-each-time-the-application-is-started-python """ if os.path.isdir(CFG['log_dir']): status_files = [[ok_logger, logfile_ok], [changed_logger, logfile_changed], [failed_logger, logfile_failed], [recap_logger, logfile_recap]] for (logger, logfile) in status_files: if os.path.isfile(logfile): console_logger.debug("Logfile rollover for file %s" % logfile) logger.handlers[0].doRollover() return
[docs]def log_recap(start_time, end_time, status_line): """Log play recap in a dedicated form.""" recap_logger.info('****PLAY TIME****') recap_logger.info('Start time: %s' % start_time) recap_logger.info('End time: %s' % end_time) recap_logger.info('Total: %s' % (end_time - start_time)) recap_logger.info('****PLAY RECAP****') recap_logger.info(status_line.rstrip()) recap_logger.info('Client status: %s' % parse_client_status(status_line)) return
[docs]def parse_client_status(status_line): """Read client status from recap log. Status can have one of the following forms: * ok * changed * failed We expect IndexError because play recap will be empty if no matching hosts were found. Client status will be set to failed in that case. Status will also be set to failed of no log file could be found.""" status = 'failed' try: status_list = status_line.split(':')[1].split() for f in status_list: g = f.split('=') if g[1] != '0': status = g[0] except IndexError: pass return status
[docs]def write_log(line, task_line=None, debug=False): """Write log to stdout and log files. Highlight ansible run status in stdout.""" if not os.path.isdir(CFG['log_dir']): configer.create_dir(CFG['log_dir']) if line.startswith('ok:'): if task_line is not None: ok_logger.info(task_line.rstrip()) console_logger.info("\033[0;32m%s\033[0;0m" % line.rstrip()) ok_logger.info(line.rstrip()) elif line.startswith('changed:'): if task_line is not None: changed_logger.info(task_line.rstrip()) console_logger.info("\033[1;33m%s\033[0;0m" % line.rstrip()) changed_logger.info(line.rstrip()) elif line.startswith('failed:') or line.startswith('fatal:'): if task_line is not None: failed_logger.info(task_line.rstrip()) console_logger.info("\033[0;31m%s\033[0;0m" % line.rstrip()) failed_logger.info(line.rstrip()) elif line.startswith('skipping:'): console_logger.info("\033[1;36m%s\033[0;0m" % line.rstrip()) else: console_logger.info(line.rstrip()) logfile_logger.info(line.rstrip()) return
console_logger = get_logger("console_logger", formatter='simple') logfile_logger = get_logger("logfile_logger", logfile_main, 5000000) ok_logger = get_logger("ok_logger", logfile_ok) changed_logger = get_logger("changed_logger", logfile_changed) failed_logger = get_logger("failed_logger", logfile_failed) recap_logger = get_logger("recap_logger", logfile_recap) if __name__ == '__main__': pass