forked from butscher/WikidPad
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExceptionLogger.py
140 lines (102 loc) · 4.02 KB
/
ExceptionLogger.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
import sys, traceback, time, os, os.path
EL = None
# Maximum file size of log file before it is thrown away
FILE_CLEAR_LIMIT = 512 * 1024
# global exception control
class StdErrReplacement:
def write(self, data):
global EL
# try:
# import ExceptionLogger as EL
# except ImportError:
# # This should only happen while interpreter shuts down
# return
try:
f = open(getLogDestDir(), "a")
try:
if not EL._timestampPrinted:
# Only write for first occurrence in session
f.write(EL._exceptionSessionTimeStamp)
EL._timestampPrinted = True
EL._previousStdOut.write(data)
f.write(data)
finally:
f.close()
except:
pass # TODO
def writelines(self, it):
for l in it:
self.write(l)
#
def onException(typ, value, trace):
global EL
try:
# import ExceptionLogger as EL
## traceback.print_exception(typ, value, trace, file=EL._previousStdOut)
f = open(getLogDestDir(), "a")
try:
if not EL._timestampPrinted:
# Only write for first exception in session
f.write(EL._exceptionSessionTimeStamp)
EL._timestampPrinted = True
EL._exceptionOccurred = True
EL.traceback.print_exception(typ, value, trace, file=f)
EL.traceback.print_exception(typ, value, trace, file=EL._previousStdOut)
finally:
f.close()
except:
EL._previousStdOut.write("Exception occurred during global exception handling:\n")
EL.traceback.print_exc(file=EL._previousStdOut)
EL._previousStdOut.write("Original exception:\n")
EL.traceback.print_exception(typ, value, trace, file=EL._previousStdOut)
EL._previousExcepthook(typ, value, trace)
def setLogDestDir(path):
global EL
try:
logPath = os.path.join(path, "WikidPad_Error.log")
if os.path.exists(logPath) and os.stat(logPath).st_size > FILE_CLEAR_LIMIT:
bakLogPath = os.path.join(path, "WikidPad_Error_bak.log")
try:
os.unlink(bakLogPath)
except:
pass
try:
os.rename(logPath, bakLogPath)
except:
pass
except:
pass
EL._exceptionDestDir = path
EL._exceptionLogFileName = "WikidPad_Error.log"
def getLogDestDir():
global EL
return os.path.join(EL._exceptionDestDir, EL._exceptionLogFileName)
def startLogger(versionstring):
global EL
import ExceptionLogger as EL2
EL = EL2
EL._exceptionDestDir = os.path.dirname(os.path.abspath(sys.argv[0]))
EL._exceptionLogFileName = "WikidPad_Init_Error.log"
EL._exceptionSessionTimeStamp = \
time.strftime("\n\nVersion: '" + versionstring +
"' Session start: %Y-%m-%d %H:%M:%S\n")
EL._exceptionOccurred = False
EL._timestampPrinted = False
EL._previousStdErr = sys.stderr
sys.stderr = StdErrReplacement()
EL._previousStdOut = sys.stdout
sys.stdout = StdErrReplacement()
EL._previousExcepthook = sys.excepthook
sys.excepthook = onException
# Record errors while initializing optional components (external renderers,
# spell checking). User can then retrieve the log and send it as bug report
# if a component fails unexpectedly.
_optionalComponentErrorLog = []
def logOptionalComponentException(header):
global _optionalComponentErrorLog
log = traceback.format_exc()
_optionalComponentErrorLog.append(
"---- " + header + " ----\n" + log + "\n")
def getOptionalComponentErrorLog():
global _optionalComponentErrorLog
return "".join(_optionalComponentErrorLog)