File size: 2,192 Bytes
32408ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"""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())