Created
December 17, 2010 02:50
-
-
Save samuel/744413 to your computer and use it in GitHub Desktop.
Supervisor event listener that emails on a proces writing to stderr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import smtplib | |
import sys | |
import time | |
from optparse import OptionParser | |
from supervisor import childutils | |
class ErrorMailer(object): | |
def __init__(self, address, processes=None): | |
self.address = address | |
self.processes = processes | |
self.stdin = sys.stdin | |
self.stdout = sys.stdout | |
self.mailcmd = "mail" | |
def run(self): | |
last_email = {} | |
while True: | |
headers, payload = childutils.listener.wait(self.stdin, self.stdout) | |
if headers['eventname'] not in ('PROCESS_STATE_EXITED', 'PROCESS_LOG_STDERR'): | |
childutils.listener.ok(self.stdout) | |
continue | |
if headers['eventname'] == 'PROCESS_STATE_EXITED': | |
pheaders, pdata = childutils.eventdata(payload+'\n') | |
if int(pheaders['expected']): | |
childutils.listener.ok(self.stdout) | |
continue | |
msg = ('Process %(processname)s in group %(groupname)s exited ' | |
'unexpectedly (pid %(pid)s) from state %(from_state)s' % | |
pheaders) | |
subject = ' %s crashed at %s' % (pheaders['processname'], | |
childutils.get_asctime()) | |
# self.stderr.write('unexpected exit, mailing\n') | |
# self.stderr.flush() | |
self.mail(subject, msg) | |
childutils.listener.ok(self.stdout) | |
else: # PROCESS_LOG_STDERR | |
pheaders, pdata = childutils.eventdata(payload) | |
name = pheaders['processname'] | |
now = time.time() | |
if now - last_email.get(name, 0) < 30: | |
childutils.listener.ok(self.stdout) | |
continue | |
last_email[name] = now | |
subject = ('Process %(processname)s in group %(groupname)s wrote to stderr' | |
% pheaders) | |
# self.stderr.write('wrote to stderr, mailing\n') | |
# self.stderr.flush() | |
self.mail(subject, pdata.strip()) | |
childutils.listener.ok(self.stdout) | |
def mail(self, subject, msg): | |
fromaddress = "root@localhost" | |
body = "\r\n".join(( | |
"From: %s" % fromaddress, | |
"To: %s" % self.address, | |
"Subject: %s" % subject, | |
"", | |
msg, | |
)) | |
server = smtplib.SMTP('localhost') | |
server.sendmail(fromaddress, [self.address], body) | |
server.quit() | |
def build_parser(): | |
parser = OptionParser(usage="Usage: %prog [options]") | |
parser.add_option("-p", "--process", dest="processes", help="Process name", action="append") | |
parser.add_option("-m", "--address", dest="address", help="Email address") | |
return parser | |
def main(): | |
parser = build_parser() | |
options, system = parser.parse_args() | |
if not options.address: | |
parser.error("must specify an email address") | |
prog = ErrorMailer(processes=options.processes, address=options.address) | |
prog.run() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@samuel what did your
supervisord.conf
config file look like to map events to this?