-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreefxbase.py
173 lines (137 loc) · 6.17 KB
/
reefxbase.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
#!/user/bin/python
import abc # Abstract Base Class
from email.mime.text import MIMEText
import datetime
import Queue
import threading
import traceback
import signal
import smtplib
import sys
import time
from constants import MessageCodes, MessageTypes, Statuses, DebugLevels, EventLevels
import db
class ReefXBase(threading.Thread):
__metaclass__ = abc.ABCMeta
def __init__(self):
super(ReefXBase, self).__init__()
DEBUG_LEVEL = DebugLevels.ALL
def run(self):
try:
self.setup()
self.dowork()
# TODO: When is this used?
self.teardown("ReefXBase: System Shutdown")
self.debug("Exiting")
return
except Exception as e:
self.logexception(e)
self.reportexception(e)
@abc.abstractmethod
def dowork(self):
"""Implement this method in subclasses to perform tasks"""
return
def reportexception(self, e):
""" Override this class to implement a custom exception reporter """
return
def setup(self):
print self.name() + "Override this method to run any setup code"
return
def teardown(self, message):
print self.name() + ": Override this method to run any teardown code"
return
def printline(self, value):
try:
print("{0} {1}: {2}".format(time.strftime("%H:%M:%S"), self.name(), value))
except IOError:
pass
def name(self):
return self.__class__.__name__
def debug(self, message, debugLevel = DebugLevels.NONE):
self.logevent(EventLevels.DEBUG, "DEBUG", message, debugLevel)
def traceback(self):
self.printline("Traceback")
for line in traceback.format_stack():
print line.strip()
def logaudit(self, eventCode, message, additional=''):
self.logevent(EventLevels.AUDIT, eventCode, message, additional=additional)
def loginformation(self, eventCode, message, additional=''):
self.logevent(EventLevels.INFORMATION, eventCode, message, additional=additional)
def logwarning(self, eventCode, message, additional=''):
self.logevent(EventLevels.WARNING, eventCode, message, additional=additional)
def logalert(self, eventCode, message, additional=''):
self.logevent(EventLevels.ALERT, eventCode, message, additional=additional)
def logevent(self, eventLevel, eventCode, message, debugLevel = DebugLevels.NONE, additional = ''):
if type(debugLevel) is not int or type(self.DEBUG_LEVEL) is not int:
self.printline("debugLevel should be int: {0}, {1}".format(debugLevel, self.DEBUG_LEVEL))
debugLevel = debugLevel | self.DEBUG_LEVEL
if eventLevel < EventLevels.WARNING:
levelMessage = ""
elif eventLevel == EventLevels.WARNING:
levelMessage = " (WARNING)"
elif eventLevel == EventLevels.ALERT:
levelMessage = " (ALERT)"
elif eventLevel == EventLevels.EXCEPTION:
levelMessage = " (EXCEPTION)"
if eventLevel >= EventLevels.INFORMATION or debugLevel & DebugLevels.SCREEN:
self.printline("{0}{1}".format(message, levelMessage))
if eventLevel >= EventLevels.AUDIT or debugLevel & DebugLevels.DB:
db.logevent(self.name(), eventLevel, eventCode, message, additional)
def logexception(self, exception):
try:
try:
ex_type, ex, tb = sys.exc_info()
tb_output = ''
for tb_line in traceback.format_tb(tb, 100):
tb_output += tb_line + "\r\n"
except Exception as e:
ex_type = ''
ex = ''
tb = ''
try:
print "logging error"
with open("/tmp/reefx_log.txt", "a") as log:
log.write(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + ": " + str(self.name()) +
" " + str(exception) + "\r\n"
" (" + str(ex_type) + ", " + str(ex) + ")\r\n")
log.write(tb_output)
except Exception as e:
print "Logging error to file failed " + str(self.name()) + ", " + str(exception)
print str(e)
try:
self.logevent(EventLevels.EXCEPTION, str(ex_type), str(exception), additional = tb_output)
except Exception as e:
print "Logging error to DB failed " + str(self.name()) + ", " + str(exception)
print str(e)
try:
self.sendemail("ReefX Exception", "{0}\r\n{1}: {2}\r\n{3}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), ex_type, exception, tb_output))
except Exception as e:
print "Logging error to email failed " + str(self.name()) + ", " + str(exception)
print str(e)
except IOError:
pass
def sendemail(self, subject, text):
self.logaudit("Sending email", subject, additional=text)
try:
# Define email addresses to use
addr_to = '[email protected]'
addr_from = '[email protected]'
# Define SMTP email server details
smtp_server = 'smtp.nsw.exemail.com.au'
#smtp_user = '' # Apparently not required
#smtp_pass = '' # Ditto
# Construct email
msg = MIMEText(text)
msg['To'] = addr_to
msg['From'] = addr_from
msg['Subject'] = subject
# Send the message via an SMTP server
s = smtplib.SMTP(smtp_server)
#s.login(smtp_user, smtp_pass) - Not required if using exetel smtp server
s.sendmail(addr_from, addr_to, msg.as_string())
s.quit()
self.debug("Email sent")
except Exception as e:
self.logalert("Sending Email Failed", str(e))
#TODO: self.setstatus(alert)... requires consolidation of base classes
#TODO: increment failure count. Reboot if x consecutive failures.