bootstrap-vz/bootstrapvz/base/log.py

85 lines
2.7 KiB
Python
Raw Normal View History

2014-03-23 16:04:03 +01:00
"""This module holds functions and classes responsible for formatting the log output
both to a file and to the console.
.. module:: log
"""
2013-06-23 22:30:41 +02:00
import logging
def get_log_filename(manifest_path):
2014-03-23 16:04:03 +01:00
"""Returns the path to a logfile given a manifest
The logfile name is constructed from the current timestamp and the basename of the manifest
Args:
manifest_path (str): The path to the manifest
Returns:
str. The path to the logfile
"""
2013-06-23 22:30:41 +02:00
import os.path
from datetime import datetime
manifest_basename = os.path.basename(manifest_path)
manifest_name, _ = os.path.splitext(manifest_basename)
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
filename = "{timestamp}_{name}.log".format(timestamp=timestamp, name=manifest_name)
return filename
2013-06-23 22:30:41 +02:00
2013-06-26 20:14:37 +02:00
2013-06-23 22:30:41 +02:00
def setup_logger(logfile=None, debug=False):
2014-03-23 16:04:03 +01:00
"""Sets up the python logger to log to both a file and the console
Args:
logfile (str): Path to a logfile
debug (bool): Whether to log debug output to the console
"""
2013-06-23 22:30:41 +02:00
root = logging.getLogger()
2014-03-23 16:04:03 +01:00
# Make sure all logging statements are processed by our handlers, they decide the log level
2013-06-23 22:30:41 +02:00
root.setLevel(logging.NOTSET)
# Only enable logging to file if a destination was supplied
if logfile is not None:
# Create a file log handler
file_handler = logging.FileHandler(logfile)
# Absolute timestamps are rather useless when bootstrapping, it's much more interesting
# to see how long things take, so we log in a relative format instead
file_handler.setFormatter(FileFormatter('[%(relativeCreated)s] %(levelname)s: %(message)s'))
# The file log handler always logs everything
file_handler.setLevel(logging.DEBUG)
root.addHandler(file_handler)
2013-06-23 22:30:41 +02:00
2014-03-23 16:04:03 +01:00
# Create a console log handler
2013-06-23 22:30:41 +02:00
import sys
console_handler = logging.StreamHandler(sys.stderr)
2014-03-23 16:04:03 +01:00
# We want to colorize the output to the console, so we add a formatter
2013-06-23 22:30:41 +02:00
console_handler.setFormatter(ConsoleFormatter())
2014-03-23 16:04:03 +01:00
# Set the log level depending on the debug argument
2013-06-23 22:30:41 +02:00
if debug:
console_handler.setLevel(logging.DEBUG)
else:
console_handler.setLevel(logging.INFO)
root.addHandler(console_handler)
class ConsoleFormatter(logging.Formatter):
2014-03-23 16:04:03 +01:00
"""Formats log statements for the console
"""
2013-06-26 20:14:37 +02:00
level_colors = {logging.ERROR: 'red',
logging.WARNING: 'magenta',
logging.INFO: 'blue',
}
2013-06-23 22:30:41 +02:00
def format(self, record):
if(record.levelno in self.level_colors):
2014-03-23 16:04:03 +01:00
# Colorize the message if we have a color for it (DEBUG has no color)
2013-06-26 20:14:37 +02:00
from termcolor import colored
record.msg = colored(record.msg, self.level_colors[record.levelno])
2013-06-23 22:30:41 +02:00
return super(ConsoleFormatter, self).format(record)
class FileFormatter(logging.Formatter):
2014-03-23 16:04:03 +01:00
"""Formats log statements for output to file
Currently this is just a stub
"""
2013-06-23 22:30:41 +02:00
def format(self, record):
return super(FileFormatter, self).format(record)