SuperFeatures / how /utils /logging.py
YannisK's picture
temp state
32408ed
"""Logging-related functionality"""
import time
import logging
# Logging
def init_logger(log_path):
"""Return a logger instance which logs to stdout and, if log_path is not None, also to a file"""
logger = logging.getLogger("HOW")
logger.setLevel(logging.DEBUG)
stdout_handler = logging.StreamHandler()
stdout_handler.setLevel(logging.INFO)
stdout_handler.setFormatter(logging.Formatter('%(name)s %(levelname)s: %(message)s'))
logger.addHandler(stdout_handler)
if log_path:
file_handler = logging.FileHandler(log_path)
file_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s: %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
# Stopwatch
class LoggingStopwatch:
"""Stopwatch context that produces one message when entered and another one when exited,
with the time spent in the context embedded in the exiting message.
:param str message: Message to be logged at the start and finish. If the first word
of the message ends with 'ing', convert to passive for finish message.
:param callable log_start: Will be called with given message at the start
:param callable log_finish: Will be called with built message at the finish. If None, use
log_start
"""
def __init__(self, message, log_start, log_finish=None):
self.message = message
self.log_start = log_start
self.log_finish = log_finish if log_finish is not None else log_start
self.time0 = None
def __enter__(self):
self.time0 = time.time()
if self.log_start:
self.log_start(self.message.capitalize())
def __exit__(self, exc_type, exc_val, exc_tb):
# Build message
words = self.message.split(" ")
secs = "%.1fs" % (time.time() - self.time0)
if words[0].endswith("ing"):
words += [words.pop(0).replace("ing", "ed"), "in", secs]
else:
words += ["(%.1f)" % secs]
# Log message
if self.log_finish:
self.log_finish(" ".join(words).capitalize())