X-Git-Url: https://git.ralfj.de/saartuer.git/blobdiff_plain/72033b3361e5f60ae1e0086f9326d815e4cec845..05d80f06d0d28433e7b730e6290b79c7d0e32c6b:/libtuer.py diff --git a/libtuer.py b/libtuer.py index 1f8a034..05607f6 100644 --- a/libtuer.py +++ b/libtuer.py @@ -1,28 +1,57 @@ import logging, logging.handlers, os, time, queue, threading, subprocess +import traceback, smtplib +import email.mime.text, email.util + +# Logging configuration +syslogLevel = logging.INFO +mailLevel = logging.CRITICAL # must be "larger" than syslog level! +mailAddress = 'post+tuer'+'@'+'ralfj.de' + +# Mail logging handler +def sendeMail(subject, text, receivers, sender='sphinx@hacksaar.de', replyTo=None): + if not isinstance(type(receivers), list): receivers = [receivers] + # construct content + msg = email.mime.text.MIMEText(text.encode('UTF-8'), 'plain', 'UTF-8') + msg['Subject'] = subject + msg['Date'] = email.utils.formatdate(localtime=True) + msg['From'] = sender + msg['To'] = ', '.join(receivers) + if replyTo is not None: + msg['Reply-To'] = replyTo + # FIXME set time + # put into envelope and send + s = smtplib.SMTP('ralfj.de') + s.sendmail(sender, receivers, msg.as_string()) + s.quit() # logging function class Logger: def __init__ (self): - self.logger = logging.getLogger("tuerd") - self.logger.setLevel(logging.INFO) - self.handler = logging.handlers.SysLogHandler(address = '/dev/log', facility = logging.handlers.SysLogHandler.LOG_LOCAL0) - self.logger.addHandler(self.handler) + self.syslog = logging.getLogger("tuerd") + self.syslog.setLevel(syslogLevel) + self.syslog.addHandler(logging.handlers.SysLogHandler(address = '/dev/log', + facility = logging.handlers.SysLogHandler.LOG_LOCAL0)) - def log (self, lvl, what): + def _log (self, lvl, what): thestr = "%s[%d]: %s" % ("osspd", os.getpid(), what) - print (thestr) - self.logger.log(lvl, thestr) + # console log + print(thestr) + # syslog + self.syslog.log(lvl, thestr) + # mail log + if lvl >= mailLevel: + sendeMail('Kritischer Türfehler', what, mailAddress) def debug(self, what): - self.log(logging.DEBUG, what) + self._log(logging.DEBUG, what) def info(self, what): - self.log(logging.INFO, what) + self._log(logging.INFO, what) def warning(self, what): - self.log(logging.WARNING, what) + self._log(logging.WARNING, what) def error(self, what): - self.log(logging.ERROR, what) + self._log(logging.ERROR, what) def critical(self, what): - self.log(logging.CRITICAL, what) + self._log(logging.CRITICAL, what) logger = Logger() @@ -33,7 +62,7 @@ def fire_and_forget (cmd, log, prefix): with open("/dev/null", "w") as fnull: retcode = subprocess.call(cmd, stdout=fnull, stderr=fnull) if retcode is not 0: - log("%sReturn code %d at command: %s" % (prefix,retcode,str(cmd))) + logger.error("%sReturn code %d at command: %s" % (prefix,retcode,str(cmd))) t = threading.Thread(target=_fire_and_forget) t.start() @@ -42,7 +71,8 @@ class ThreadFunction(): _CALL = 0 _TERM = 1 - def __init__(self, f): + def __init__(self, f, name): + self.name = name self._f = f self._q = queue.Queue() self._t = threading.Thread(target=self._thread_func) @@ -52,39 +82,45 @@ class ThreadFunction(): while True: (cmd, data) = self._q.get() # run command - if cmd == _CALL: + if cmd == ThreadFunction._CALL: try: self._f(*data) - except Exception: - logger.error("ThreadFunction: Got exception out of handler thread: %s" % str(e)) - elif cmd == _TERM: + except Exception as e: + logger.critical("ThreadFunction: Got exception out of handler thread %s: %s" % (self.name, str(e))) + logger.debug(traceback.format_exc()) + elif cmd == ThreadFunction._TERM: assert data is None break else: logger.error("ThreadFunction: Command %d does not exist" % cmd) def __call__(self, *arg): - self._q.put((self._CALL, arg)) + self._q.put((ThreadFunction._CALL, arg)) def stop(self): - self._q.put((_TERM, None)) + self._q.put((ThreadFunction._TERM, None)) self._t.join() # Thread timer-repeater class: Call a function every seconds class ThreadRepeater(): - def __init__(self, f, sleep_time): + def __init__(self, f, sleep_time, name): + self.name = name self._f = f self._stop = False self._sleep_time = sleep_time self._t = threading.Thread(target=self._thread_func) self._t.start() - def _thread_func(): + def _thread_func(self): while True: if self._stop: break - self._f() - time.sleep(sleep_time) + try: + self._f() + except Exception as e: + logger.critical("ThreadRepeater: Got exception out of handler thread %s: %s" % (self.name, str(e))) + logger.debug(traceback.format_exc()) + time.sleep(self._sleep_time) def stop(self): self._stop = True