-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathloggers.py
More file actions
149 lines (113 loc) · 5.08 KB
/
Copy pathloggers.py
File metadata and controls
149 lines (113 loc) · 5.08 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import logging
import os
import sys
import time
DEFAULT_LOG_FORMAT = ["%(asctime)s", "%(name)s", "%(levelname)s", "%(message)s"]
class BaseLogger(logging.getLoggerClass()):
# can configure level=logging.[CRITICAL(50), FATAL(CRITICAL), ERROR(40), WARNING(30), WARN(WARNING)
# INFO(20), DEBUG(10), NOTSET(0 - default)]
# for various log_format options see help(logging.Formatter)
def __init__(self, name=None, level=logging.NOTSET, log_format=None):
if log_format is None:
log_format = DEFAULT_LOG_FORMAT
if name is None:
log_format = log_format[:1] + log_format[2:]
log_format = " - ".join(log_format)
if name is None:
name = type(self).__name__
super(BaseLogger, self).__init__(name, level=level)
# create formatter
self.formatter = logging.Formatter(log_format)
def _set_format(self, *args, **kwargs):
self.formatter = logging.Formatter(*args, **kwargs)
list(map(lambda handler: handler.setFormatter(self.formatter), self.handlers))
def _initialize_handler(self):
list(map(lambda handler: handler.setLevel(self.level), self.handlers))
# attach formatter to handlers
list(map(lambda handler: handler.setFormatter(self.formatter), self.handlers))
def close(self):
logging.shutdown([x.__weakref__ for x in self.handlers])
def dump_location(self):
for handler in self.handlers:
if isinstance(handler, logging.FileHandler):
print("%s. Writing (%s) to file <%s>" % (type(self).__name__, logging.getLevelName(handler.level), handler.baseFilename,))
class FileLogger(BaseLogger):
def __init__(self, filename, *args, ext="log", path="logs", add_timestamp=False, should_overwrite=True, **kwargs):
super(FileLogger, self).__init__(*args, **kwargs)
if not os.path.exists(path):
os.makedirs(path)
filename = os.path.join(path, filename)
if add_timestamp:
filename += time.strftime("-%Y-%m-%d-%H%M%S")
self._filename = {"fname": filename, "ext": ext}
self._mode = 'w' if should_overwrite else 'a'
self._cur_handler = None
self._cur_fname = ""
self._new_file()
def _new_file(self):
if "index" not in self._filename:
f_name = "%s.%s" % (self._filename["fname"], self._filename["ext"],)
self._filename["index"] = 0
else:
f_name = "%s_%s.%s" % (self._filename["fname"], self._filename["index"], self._filename["ext"],)
self._filename["index"] += 1
if self._cur_handler is not None:
self.removeHandler(self._cur_handler)
self._cur_handler = logging.FileHandler(f_name, mode=self._mode)
self._cur_fname = f_name
self.addHandler(self._cur_handler)
self._initialize_handler()
def get_location(self):
return ".".join([self._filename["fname"], self._filename["ext"]])
class CSVLogger(FileLogger):
def __init__(self, *args, **kwargs):
if "ext" not in kwargs:
kwargs["ext"] = "csv"
kwargs["log_format"] = "%(message)s"
self._delimiter = kwargs.pop("delimiter", ",")
self._other_del = kwargs.pop("other_delimiter", "-")
self._titles = []
super(CSVLogger, self).__init__(*args, **kwargs)
def space(self, num_spaces=1):
self.info("\n" * num_spaces)
def info(self, *args, **kwargs):
if "new_file" in kwargs:
self._new_file()
args = [arg.replace(self._delimiter, self._other_del).replace(" ", "") if self._delimiter in arg else arg
for arg in map(str, args)]
super(CSVLogger, self).info(self._delimiter.join(args))
def set_titles(self, *args):
self._titles = args
self.info(*args)
def log_info(self, **kwargs):
vals = [kwargs.get(x, "") for x in self._titles]
self.info(*vals)
class PrintLogger(BaseLogger):
def __init__(self, *args, **kwargs):
super(PrintLogger, self).__init__(*args, **kwargs)
self.addHandler(logging.StreamHandler(stream=sys.stdout)) # create console handler
self._initialize_handler()
class EmptyLogger(BaseLogger):
def __init__(self, *args, **kwargs):
super(EmptyLogger, self).__init__(*args, **kwargs)
self.addHandler(logging.NullHandler())
self._initialize_handler()
# self.disabled = True
def multi_logger(loggers, name="MultiLogger"):
res = BaseLogger(name)
for logger in loggers:
for handler in logger.handlers:
res.addHandler(handler)
return res
if __name__ == "__main__":
# loggers_list = [FileLogger("temp_file"), PrintLogger("test_me")]
# i = multi_logger(loggers_list)
log = PrintLogger()
log.info("bla")
print("Bla")
# MetaClass perfect explanation:
# http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python/6581949#6581949
# class LoggedTestCase(unittest.TestCase):
# __metaclass__ = LogThisTestCase
# logger = logging.getLogger("unittestLogger")
# logger.setLevel(logging.DEBUG) # or whatever you prefer