LogPrinter._print_log_message()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
import traceback
2
3
from pyprint.ColorPrinter import ColorPrinter
4
5
from coalib.output.printers.LOG_LEVEL import LOG_LEVEL, LOG_LEVEL_COLORS
6
from coalib.processes.communication.LogMessage import LogMessage
7
8
9
class LogPrinter:
10
    """
11
    The LogPrinter class allows to print log messages to an underlying Printer.
12
13
    This class is an adapter, means you can create a LogPrinter from every
14
    existing Printer instance.
15
    """
16
17
    def __init__(self,
18
                 printer,
19
                 log_level=LOG_LEVEL.INFO,
20
                 timestamp_format="%X"):
21
        """
22
        Creates a new log printer from an existing Printer.
23
24
        :param printer:          The underlying Printer where log messages
25
                                 shall be written to. If you inherit from
26
                                 LogPrinter, set it to self.
27
        :param log_level:        The minimum log level, everything below will
28
                                 not be logged.
29
        :param timestamp_format: The format string for the
30
                                 datetime.today().strftime(format) method.
31
        """
32
        self._printer = printer
33
        self.log_level = log_level
34
        self.timestamp_format = timestamp_format
35
36
    @property
37
    def printer(self):
38
        """
39
        Returns the underlying printer where logs are printed to.
40
        """
41
        return self._printer
42
43
    def _get_log_prefix(self, log_level, timestamp):
44
        datetime_string = timestamp.strftime(self.timestamp_format)
45
46
        if datetime_string != "":
47
            datetime_string = "[" + datetime_string + "]"
48
49
        return '[{}]{}'.format(LOG_LEVEL.reverse.get(log_level, "ERROR"),
50
                               datetime_string)
51
52
    def debug(self, *messages, delimiter=" ", timestamp=None, **kwargs):
53
        self.log_message(LogMessage(LOG_LEVEL.DEBUG,
54
                                    *messages,
55
                                    delimiter=delimiter,
56
                                    timestamp=timestamp),
57
                         **kwargs)
58
59
    def info(self, *messages, delimiter=" ", timestamp=None, **kwargs):
60
        self.log_message(LogMessage(LOG_LEVEL.INFO,
61
                                    *messages,
62
                                    delimiter=delimiter,
63
                                    timestamp=timestamp),
64
                         **kwargs)
65
66
    def warn(self, *messages, delimiter=" ", timestamp=None, **kwargs):
67
        self.log_message(LogMessage(LOG_LEVEL.WARNING,
68
                                    *messages,
69
                                    delimiter=delimiter,
70
                                    timestamp=timestamp),
71
                         **kwargs)
72
73
    def err(self, *messages, delimiter=" ", timestamp=None, **kwargs):
74
        self.log_message(LogMessage(LOG_LEVEL.ERROR,
75
                                    *messages,
76
                                    delimiter=delimiter,
77
                                    timestamp=timestamp),
78
                         **kwargs)
79
80
    def log(self, log_level, message, timestamp=None, **kwargs):
81
        self.log_message(LogMessage(log_level,
82
                                    message,
83
                                    timestamp=timestamp),
84
                         **kwargs)
85
86
    def log_exception(self,
87
                      message,
88
                      exception,
89
                      log_level=LOG_LEVEL.ERROR,
90
                      timestamp=None,
91
                      **kwargs):
92
        """
93
        If the log_level of the printer is greater than DEBUG, it prints
94
        only the message. If it is DEBUG or lower, it shows the message
95
        along with the traceback of the exception.
96
97
        :param message:   The message to print.
98
        :param exception: The exception to print.
99
        :param log_level: The log_level of this message (not used when
100
                          logging the traceback. Tracebacks always have
101
                          a level of DEBUG).
102
        :param timestamp: The time at which this log occured. Defaults to
103
                          the current time.
104
        :param kwargs:    Keyword arguments to be passed when logging the
105
                          message (not used when logging the traceback).
106
        """
107
        if not isinstance(exception, BaseException):
108
            raise TypeError("log_exception can only log derivatives of "
109
                            "BaseException.")
110
111
        traceback_str = "\n".join(
112
            traceback.format_exception(type(exception),
113
                                       exception,
114
                                       exception.__traceback__))
115
116
        self.log(log_level, message, timestamp=timestamp, **kwargs)
117
        self.log_message(
118
            LogMessage(LOG_LEVEL.DEBUG,
119
                       "Exception was:" + "\n" + traceback_str,
120
                       timestamp=timestamp),
121
            **kwargs)
122
123
    def log_message(self, log_message, **kwargs):
124
        if not isinstance(log_message, LogMessage):
125
            raise TypeError("log_message should be of type LogMessage.")
126
127
        if log_message.log_level < self.log_level:
128
            return
129
130
        self._print_log_message(
131
            self._get_log_prefix(log_message.log_level, log_message.timestamp),
132
            log_message,
133
            **kwargs)
134
135
    def _print_log_message(self, prefix, log_message, **kwargs):
136
        """
137
        Override this if you want to influence how the log message is printed.
138
139
        If the underlying printer is a ColorPrinter, then colored logging is
140
        used. You can turn it off in the underlying ColorPrinter if you want to
141
        print uncolored.
142
143
        :param prefix:      The prefix to print (as string).
144
        :param log_message: The LogMessage object to print.
145
        :param kwargs:      Any other keyword arguments.
146
        """
147
        if isinstance(self._printer, ColorPrinter):
148
            self.printer.print(prefix,
149
                               end=" ",
150
                               color=LOG_LEVEL_COLORS[log_message.log_level],
151
                               **kwargs)
152
            self.printer.print(log_message.message, **kwargs)
153
        else:
154
            self.printer.print(prefix, log_message.message, **kwargs)
155