forked from dotPY-hax/log4py
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogger.py
120 lines (103 loc) · 3.83 KB
/
logger.py
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
from datetime import datetime as dt
import traceback
import sys
class Color():
""" ANSI color codes """
BLACK = '30m'
RED = '31m'
GREEN = '32m'
YELLOW = '33m'
BLUE = '34m'
PURPLE = '35m'
CYAN = '36m'
WHITE = '37m'
NORMAL = '\033[0;'
BOLD = '\033[1;'
FAINT = '\033[2;'
ITALIC = '\033[3;'
UNDERLINE = '\033[4;'
BLINK = '\033[5;'
NEGATIVE = '\033[7;'
CROSSED = '\033[9;'
END = '\033[0m'
ESCAPE_PREFIX = '\033['
CLEAR_LINE = '\033[2K'
MOVE_TO_START_OF_LINE = '\033[0G'
# cancel SGR codes if we don't write to a terminal
if not __import__('sys').stdout.isatty():
for _ in dir():
if isinstance(_, str) and _[0] != '_':
locals()[_] = ''
else:
# set Windows console in VT mode
if __import__('platform').system() == 'Windows':
kernel32 = __import__('ctypes').windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
del kernel32
def test():
color = ['black', 'red', 'green', 'yellow', 'blue', 'purple', 'cyan', 'white']
modes = ['normal', 'bold', 'faint', 'italic', 'underline', 'blink', 'negative', 'crossed']
col1 = max(len(c) for c in color)
col2 = max(len(m) for m in modes)
width = col1 + col2 + 1
for color in color:
c = Color.__dict__[color.upper()]
cname = color[0].upper() + color[1:].lower()
for mode in modes:
m = Color.__dict__[mode.upper()]
mname = mode[0].upper() + mode[1:].lower()
print(f'{m}{c}{(mname + " " + cname):<{width}}{Color.END} ', prefix='', end='')
print()
class Logger():
def __init__(self, name):
self.name = name
def log_raw(self, level, level_color, text_color, *args, sep=' ', end='\n', **kwargs):
# timestamp = dt.now().astimezone().strftime('[%F %T %Z] ')
timestamp = dt.now().astimezone().strftime('[%T] ')
prefix = Color.NORMAL + level_color + timestamp + Color.BOLD + level_color + f'[{level} {self.name}]: ' + Color.END
if text_color:
prefix += Color.NORMAL + text_color
end = Color.END + end
msg = sep.join(arg if type(arg) == str else repr(arg) for arg in args)
if Color.ESCAPE_PREFIX in msg:
end = Color.END + end
msg = prefix + ('\n' + prefix).join(msg.split('\n'))
msg = Color.CLEAR_LINE + Color.MOVE_TO_START_OF_LINE + msg
print(msg, end=end, **kwargs)
def log(self, level, *args, **kwargs):
"""
Log a message at level `level`.
Extends normal builtin `print`. Uses same arguments after `level`.
"""
getattr(self, level)(*args, **kwargs)
def success(self, *args, **kwargs):
"""
Log success.
Extends normal builtin `print`. Uses same arguments.
"""
self.log_raw('SUCCESS', Color.GREEN, Color.GREEN, *args, **kwargs)
def info(self, *args, **kwargs):
"""
Log info.
Extends normal builtin `print`. Uses same arguments.
"""
self.log_raw('INFO', Color.BLUE, '', *args, **kwargs)
def warn(self, *args, **kwargs):
"""
Log warning.
Extends normal builtin `print`. Uses same arguments.
"""
self.log_raw('WARN', Color.YELLOW, Color.YELLOW, *args, **kwargs)
def error_exception(self, msg, exception, **kwargs):
"""
Log an exception as a warning.
"""
self.error(f' {msg} '.center(80, '-'))
self.error(traceback.format_exc())
self.error('-'*80)
def error(self, *args, **kwargs):
"""
Log errors in red.
Extends normal builtin `print`. Uses same arguments.
"""
self.log_raw('ERROR', Color.RED, Color.RED, file=sys.stderr, *args, **kwargs)