summaryrefslogtreecommitdiff
path: root/python3/vdebug/log.py
blob: 5dadea35e17d8fdb1182170d74398b21306ea0ac (plain)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import os
import sys
import time

from . import error


class Logger:
    """ Abstract class for all logger implementations.

    Concrete classes will log messages using various methods,
    e.g. write to a file.
    """

    (ERROR, INFO, DEBUG) = (0, 1, 2)
    TYPES = ("ERROR", "Info", "Debug")
    debug_level = ERROR

    def __init__(self, debug_level):
        self.debug_level = int(debug_level)

    def log(self, string, level):
        """ Log a message """
        if level > self.debug_level:
            return
        self._actual_log(string, level)

    def _actual_log(self, string, level):
        """ Actually perform the logging (to be implemented in subclasses) """
        pass

    def shutdown(self):
        """ Action to perform when closing the logger """
        pass

    @staticmethod
    def time():
        """ Get a nicely formatted time string """
        return time.strftime("%a %d %Y %H:%M:%S", time.localtime())

    def format(self, string, level):
        """ Format the error message in a standard way """
        display_level = self.TYPES[level]
        return "- [%s] {%s} %s" % (display_level, self.time(), string)


class WindowLogger(Logger):

    """ Log messages to a window.

    The window object is passed in on construction, but
    only created if a message is written.
    """

    def __init__(self, debug_level, window):
        self.window = window
        super(WindowLogger, self).__init__(debug_level)

    def shutdown(self):
        if self.window is not None:
            self.window.is_open = False

    def _actual_log(self, string, level):
        if not self.window.is_open:
            self.window.create("rightbelow 6new")
        self.window.write(self.format(string, level)+"\n")


class FileLogger(Logger):

    """ Log messages to a window.

    The window object is passed in on construction, but
    only created if a message is written.
    """

    def __init__(self, debug_level, filename):
        self.filename = os.path.expanduser(filename)
        self.f = None
        super(FileLogger, self).__init__(debug_level)

    def __open(self):
        try:
            self.f = open(self.filename, 'w')
        except IOError as e:
            raise error.LogError("Invalid file name '%s' for log file: %s"
                                 % (self.filename, e))
        except:
            raise error.LogError("Error using file '%s' as a log file: %s"
                                 % (self.filename, sys.exc_info()[0]))

    def shutdown(self):
        if self.f is not None:
            self.f.close()

    def _actual_log(self, string, level):
        if self.f is None:
            self.__open()
        self.f.write(self.format(string, level)+"\n")
        self.f.flush()


class Log:

    loggers = {}

    def __init__(self, string, level=Logger.INFO):
        Log.log(string, level)

    @classmethod
    def log(cls, string, level=Logger.INFO):
        for logger in cls.loggers.values():
            logger.log(string, level)

    @classmethod
    def set_logger(cls, logger):
        k = logger.__class__.__name__
        if k in cls.loggers:
            cls.loggers[k].shutdown()
        cls.loggers[k] = logger

    @classmethod
    def remove_logger(cls, type):
        if type in cls.loggers:
            cls.loggers[type].shutdown()
            return True
        print("Failed to find logger %s in list of loggers" % type)
        return False

    @classmethod
    def shutdown(cls):
        for logger in cls.loggers.values():
            logger.shutdown()
        cls.loggers = {}