forked from andreas-p/admin4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger.py
174 lines (140 loc) · 4.1 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
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# The Admin4 Project
# (c) 2013-2022 Andreas Pflug
#
# Licensed under the Apache License,
# see LICENSE.TXT for conditions of usage
import time, traceback
loglines=[]
querylines=[]
queryfile=None
logfile=None
class LOGLEVEL:
NONE=0
DEBUG=1
INFO=2
ERROR=3
CRIT=4
@staticmethod
def Text(level):
return ["None", "Debug", "Info", "Error", "Critical"][level]
loglevel=LOGLEVEL.NONE
querylevel=LOGLEVEL.NONE
class _Line:
def __init__(self):
self.timestamp=time.time()
def Timestamp(self):
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.timestamp))
def LevelText(self):
return LOGLEVEL.Text(self.level)
def LevelImageId(self):
from adm import images
if self.level:
return images.GetId(self.LevelText())
return -1
def __getitem__(self, name):
return self.__dict__.get(name)
class LogLine(_Line):
def __init__(self, level, text, tb=None):
_Line.__init__(self)
self.level=level
self.text=text
self.tb=tb
class QueryLine(_Line):
def __init__(self, level, cmd, error=None, result=None):
_Line.__init__(self)
self.level=level
indent=-1
lines=[]
if cmd:
for line in cmd.splitlines():
line=line.rstrip()
sline=line.lstrip()
if not len(sline):
continue
if indent < 0:
indent = len(line)-len(sline)
lines.append(sline)
else:
ind=len(line)-len(sline) -indent
empty=""
for _i in range(ind):
empty += " "
lines.append(empty + sline)
self.cmd = "\n".join(lines)
self.error=error
self.result=result
def __getitem__(self, name):
if name == 'err+result':
if self.error:
if self.result:
return "%s - %s" % (self.error, self.result)
else:
return self.error
return self.result
return self.__dict__.get(name)
if False:
loglines.append( LogLine(LOGLEVEL.DEBUG, "Debug message", None))
loglines.append( LogLine(LOGLEVEL.INFO, "info message", None))
loglines.append( LogLine(LOGLEVEL.ERROR, "error message", None))
loglines.append( LogLine(LOGLEVEL.CRIT, "critical message", None))
querylines.append( QueryLine(LOGLEVEL.DEBUG, "Debug message", None, "Some weird result"))
querylines.append( QueryLine(LOGLEVEL.ERROR, "error message", "Some failure", None))
def _log(level, fmt, args, tb=None):
if level < loglevel and not tb:
return
txt=fmt % args
line=LogLine(level, txt, tb)
loglines.append(line)
if logfile:
try:
f=open(logfile, 'a')
f.write("%s %s: %s\n" % (line.Timestamp(), line.LevelText(), txt))
if tb:
f.write("%s\n" % tb)
except Exception as e:
print ("CANNOT LOG", e)
pass
def trace(offset, level, fmt, *args):
if True:
txt=fmt % args
stack=traceback.extract_stack()
lst=[]
for i in range(len(stack)-offset, len(stack)-offset-level, -1):
file=stack[i][0].split('/')[-1]
lst.append("%s (%s:%d)" % (stack[i][2], file, stack[i][1]))
print (txt, "Stack:", " ".join(lst))
def debug(fmt, *args):
_log(LOGLEVEL.DEBUG, fmt, args)
def error(fmt, *args):
_log(LOGLEVEL.ERROR, fmt, args)
def exception(fmt, *args):
"""
exception(formatStr, [args])
logs error and exception traceback
"""
_log(LOGLEVEL.ERROR, fmt, args, traceback.format_exc())
def sysexception(extype, args, tb):
try: txtargs= " ".join(args)
except: txtargs=""
try: txttb="".join(traceback.format_tb(tb))
except: txttb=""
_log(LOGLEVEL.ERROR, "%s: %s %s", (extype.__name__, txtargs, txttb))
def querylog(cmd, result=None, error=None):
cmd=str(cmd)
line=None
if querylevel > LOGLEVEL.DEBUG or error:
line=QueryLine(LOGLEVEL.ERROR, cmd, error, result)
elif querylevel == LOGLEVEL.DEBUG:
line=QueryLine(LOGLEVEL.DEBUG, cmd, error, result)
if line:
querylines.append(line)
global queryfile
if queryfile:
try:
f=open(queryfile, 'a')
f.write(line.cmd)
f.write("\n\n")
f.close()
except:
_log(LOGLEVEL.ERROR, "Query Log File %s cannot be written.", queryfile)
queryfile=None