1
|
1 |
|
from __future__ import print_function |
2
|
1 |
|
import logging |
3
|
1 |
|
import os |
4
|
1 |
|
import os.path |
5
|
1 |
|
import sys |
6
|
|
|
|
7
|
1 |
|
logging.getLogger(__name__).addHandler(logging.NullHandler()) |
8
|
|
|
|
9
|
|
|
|
10
|
1 |
|
class LogHelper(object): |
11
|
|
|
"""Provide focal point for logging. LOG_DIR is useful when output of script |
12
|
|
|
is saved into file. Log preloading is a way to log outcome before |
13
|
|
|
the output itself. |
14
|
|
|
""" |
15
|
1 |
|
FORMATTER = logging.Formatter('%(levelname)s - %(message)s') |
16
|
1 |
|
INTERMEDIATE_LOGS = {'pass': [], 'fail': []} |
17
|
1 |
|
LOG_DIR = None |
18
|
1 |
|
LOG_FILE = None |
19
|
|
|
|
20
|
1 |
|
@staticmethod |
21
|
1 |
|
def find_name(original_path, suffix=""): |
22
|
|
|
"""Find file name which is still not present in given directory |
23
|
|
|
|
24
|
|
|
Returns |
25
|
|
|
path -- original_path + number + suffix |
26
|
|
|
""" |
27
|
|
|
log_number = 0 |
28
|
|
|
# search for valid log directory, as we can run more than one |
29
|
|
|
# run per minute, first has only timestamp, rest has numbered suffix |
30
|
|
|
logging.debug("Searching for viable {0}{1}".format(original_path, |
31
|
|
|
suffix)) |
32
|
|
|
while True: |
33
|
|
|
if not log_number: |
34
|
|
|
log_number_suffix = "" |
35
|
|
|
else: |
36
|
|
|
log_number_suffix = "-{0}".format(log_number) |
37
|
|
|
|
38
|
|
|
path = original_path + log_number_suffix + suffix |
39
|
|
|
if os.path.exists(path): |
40
|
|
|
log_number += 1 |
41
|
|
|
else: |
42
|
|
|
break |
43
|
|
|
logging.debug("Found {0}".format(path)) |
44
|
|
|
return path |
45
|
|
|
|
46
|
1 |
|
@classmethod |
47
|
|
|
def add_console_logger(cls, logger, level): |
48
|
|
|
"""Convenience function to set defaults for console logger""" |
49
|
|
|
console_handler = logging.StreamHandler() |
50
|
|
|
console_handler.setFormatter(cls.FORMATTER) |
51
|
|
|
console_handler.setLevel(level) |
52
|
|
|
print('Setting console output to log level {0}'.format(level, |
53
|
|
|
sys.stderr)) |
54
|
|
|
logger.addHandler(console_handler) |
55
|
|
|
|
56
|
1 |
|
@classmethod |
57
|
|
|
def add_logging_dir(cls, logger, _dirname): |
58
|
|
|
"""Convenience function to set default logging into file. |
59
|
|
|
|
60
|
|
|
Also sets LOG_DIR and LOG_FILE |
61
|
|
|
""" |
62
|
|
|
os.makedirs(_dirname) |
63
|
|
|
logfile = os.path.join(_dirname, 'test_suite.log') |
64
|
|
|
|
65
|
|
|
file_handler = logging.FileHandler(logfile) |
66
|
|
|
file_handler.setLevel(logging.DEBUG) |
67
|
|
|
file_handler.setFormatter(cls.FORMATTER) |
68
|
|
|
logger.info('Logging into {0}'.format(logfile)) |
69
|
|
|
logger.addHandler(file_handler) |
70
|
|
|
cls.LOG_DIR = _dirname |
71
|
|
|
cls.LOG_FILE = logfile |
72
|
|
|
|
73
|
1 |
|
@classmethod |
74
|
1 |
|
def preload_log(cls, log_level, log_line, log_target=None): |
75
|
|
|
"""Save log for later use. Fill named buffer `log_target`with the log |
76
|
|
|
line for later use. |
77
|
|
|
|
78
|
|
|
Special case: |
79
|
|
|
If `log_target` is default, i.e. None, all buffers will be filled with |
80
|
|
|
the same log line. |
81
|
|
|
""" |
82
|
|
|
|
83
|
|
|
if log_target is None: |
84
|
|
|
# None means "All" |
85
|
|
|
for target in cls.INTERMEDIATE_LOGS: |
86
|
|
|
cls.INTERMEDIATE_LOGS[target] += [(log_level, log_line)] |
87
|
|
|
else: |
88
|
|
|
cls.INTERMEDIATE_LOGS[log_target] += [(log_level, log_line)] |
89
|
|
|
|
90
|
1 |
|
@classmethod |
91
|
|
|
def log_preloaded(cls, log_target): |
92
|
|
|
"""Log messages preloaded in one of the named buffers. Wipe out all |
93
|
|
|
buffers afterwards. |
94
|
|
|
""" |
95
|
|
|
for log_level, log_line in cls.INTERMEDIATE_LOGS[log_target]: |
96
|
|
|
logging.log(log_level, log_line) |
97
|
|
|
# cleanup |
98
|
|
|
for target in cls.INTERMEDIATE_LOGS: |
99
|
|
|
cls.INTERMEDIATE_LOGS[target] = [] |
100
|
|
|
|