# HG changeset patch # User Pascal Volk # Date 1257484551 0 # Node ID 3acd8a788a6fe10f196bf6e3868593884b158e82 initial commit: »don't fear the nervous delete finger« diff -r 000000000000 -r 3acd8a788a6f .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Nov 06 05:15:51 2009 +0000 @@ -0,0 +1,6 @@ +# use glob syntax. +syntax: glob + +*.py? +.*.swp +.swp diff -r 000000000000 -r 3acd8a788a6f mailtb.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mailtb.py Fri Nov 06 05:15:51 2009 +0000 @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +""" +Sends information about uncaught exceptions per email. + +""" + +import sys +import smtplib +import traceback +from os import environ as env +from time import ctime, gmtime, localtime, strftime, time + +# make sure that the web server can write to this file +mail_error_file = '/tmp/mailtb_error.log' +mail_config = {# sender information + 'from_addr': '', + 'from_name': '', + # smtp auth information (if necessary, else leave blank) + 'auth_user': '', + 'auth_pass': '', + # recipient information + 'rcpt_addr': '', + 'rcpt_name': '', + # smtp server information + 'smtp_host': 'localhost', + 'smtp_port': 25, # 25 smtp, 587 submission, 465 ssmtp (obsolete) + 'smtp_tls': False, # True or False (use starttls on port 25/587) + # subject of the email + 'subject': 'Exception Notification' + } + +def log_mail_error(error, timestamp): + try: + prefix = strftime('%b %d %H:%M:%S', localtime(timestamp)) + line = error.message if len(error.message) else error.args + logfile = open(mail_error_file, 'a') + logfile.write('%s %s: %s\n' % (prefix, error.__class__.__name__, line)) + logfile.close() + except: + pass + +def send_header(): + write = sys.stdout.write + #write('Content-Type: text/html; charset=utf-8\r\n') + write('Content-Type: application/xhtml+xml; charset=utf-8\r\n') + write('Status: 500 Internal Server Error\r\n\r\n') + sys.stdout.flush() + +def send_error_page(): + send_header() + print """ + + + Internal Server Error + + + +

Internal Server Error

+

So wie es aussieht, ging bei der Bearbeitung Ihrer Anfrage etwas + schief.

+

Sofern Sie den Fehler verursacht haben, dürfen Sie jetzt ein schlechtes + Gewissen haben.
+ Die Administration wird sich bei nächster Gelegenheit um das Problem + kümmern. Bitte haben Sie dafür etwas Verständnis.

+

Error 500

+

Sorry

+ +""" + +def send_mail(info): + global mail_config + mail_config['now'] = time() + mail_config['host'] = info['host'] if info['host'] != 'n/a' else 'localhost' + mail_config['date'] = strftime('%a, %d %b %Y %H:%M:%S +0000', + gmtime(mail_config['now'])) + body = """Hi, + +an uncaught exception has occurred. The details are as follows: + + Type: %(extype)s + Message: %(message)s + +Traceback (most recent call last): +%(traceback)s + +Additional information: + Date: %(date)s + Request: %(method)s %(uri)s %(protocol)s + Referrer: %(referer)s + Client: %(addr)s/%(port)s + U-Agent: %(agent)s +""" % info + header = """Date: %(date)s +From: "%(from_name)s" <%(from_addr)s> +To: "%(rcpt_name)s" <%(rcpt_addr)s> +Subject: %(subject)s +Message-ID: <%(now)f.%(now)X@mailtb.%(host)s> +Auto-Submitted: auto-generated +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +""" % mail_config + + try: + if mail_config['smtp_port'] != 465: + smtp = smtplib.SMTP(mail_config['smtp_host'], + mail_config['smtp_port']) + if mail_config['smtp_tls']: + smtp.starttls() + else: + smtp = smtplib.SMTP_SSL(mail_config['smtp_host'], + mail_config['smtp_port']) + if len(mail_config['auth_user']) and len(mail_config['auth_pass']): + smtp.login(mail_config['auth_user'], mail_config['auth_pass']) + smtp.sendmail(mail_config['from_addr'], mail_config['rcpt_addr'], + '\n'.join((header, body))) + except Exception, e: + # try to log it (fire and forget) + log_mail_error(e, mail_config['now']) + finally: + smtp.quit() + +def mailtbhook(extype, exval, extb): + info = {} + if type(extype) is type: + info['extype'] = extype.__name__ + else: + info['extype'] = str(extype).split("'")[1] + if hasattr(exval, 'message'): + info['message'] = exval.message if len(exval.message) else 'n/a' + else: + info['message'] = str(exval) + info['traceback'] = ''.join(['%s\n' % l for l in traceback.format_tb(extb)]) + + info['date'] = ctime() + for k in ('HTTP_HOST', 'HTTP_REFERER', 'HTTP_USER_AGENT', 'REMOTE_ADDR', + 'REMOTE_PORT', 'REQUEST_METHOD', 'REQUEST_URI', 'SERVER_PROTOCOL'): + info[k.split('_')[-1].lower()] = env[k] if env.has_key(k) else 'n/a' + + send_mail(info) + send_error_page() + +def enable(): + sys.excepthook = mailtbhook