add errors module (sys.excepthook), made win32 filemon use it
This commit is contained in:
parent
b6d48d692f
commit
ec71a8463c
2 changed files with 105 additions and 4 deletions
72
edbob/errors.py
Normal file
72
edbob/errors.py
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# edbob -- Pythonic Software Framework
|
||||||
|
# Copyright © 2010-2012 Lance Edgar
|
||||||
|
#
|
||||||
|
# This file is part of edbob.
|
||||||
|
#
|
||||||
|
# edbob is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Affero General Public License as published by the Free
|
||||||
|
# Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# edbob is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||||
|
# more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with edbob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
"""
|
||||||
|
``edbob.errors`` -- Error Alert Emails
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import socket
|
||||||
|
import logging
|
||||||
|
from traceback import format_exception
|
||||||
|
from cStringIO import StringIO
|
||||||
|
|
||||||
|
import edbob
|
||||||
|
from edbob.mail import sendmail_with_config
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def init(config):
|
||||||
|
"""
|
||||||
|
Creates a system-wide exception hook which logs exceptions and emails them
|
||||||
|
to configured recipient(s).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def excepthook(type, value, traceback):
|
||||||
|
log.exception("An exception occurred")
|
||||||
|
email_exception(type, value, traceback)
|
||||||
|
sys.__excepthook__(type, value, traceback)
|
||||||
|
|
||||||
|
sys.excepthook = excepthook
|
||||||
|
|
||||||
|
|
||||||
|
def email_exception(type, value, traceback):
|
||||||
|
"""
|
||||||
|
Sends an email containing a traceback to the configured recipient(s).
|
||||||
|
"""
|
||||||
|
|
||||||
|
body = StringIO()
|
||||||
|
|
||||||
|
hostname = socket.gethostname()
|
||||||
|
body.write("An exception occurred.\n")
|
||||||
|
body.write("\n")
|
||||||
|
body.write("Machine Name: %s (%s)\n" % (hostname, socket.gethostbyname(hostname)))
|
||||||
|
body.write("Local Time: %s\n" % (edbob.local_time().strftime('%Y-%m-%d %H:%M:%S %Z%z')))
|
||||||
|
body.write("\n")
|
||||||
|
body.write("%s\n" % ''.join(format_exception(type, value, traceback)))
|
||||||
|
|
||||||
|
sendmail_with_config('errors', body.getvalue())
|
||||||
|
body.close()
|
|
@ -27,16 +27,17 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
import sys
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
import Queue
|
import Queue
|
||||||
|
from traceback import format_exception
|
||||||
|
|
||||||
import edbob
|
import edbob
|
||||||
from edbob.filemon import MonitorProfile
|
from edbob.filemon import MonitorProfile
|
||||||
from edbob.filemon.win32 import WatcherWin32, ACTION_CREATE, ACTION_UPDATE
|
from edbob.filemon.win32 import WatcherWin32, ACTION_CREATE, ACTION_UPDATE
|
||||||
from edbob.win32 import file_is_free
|
from edbob.win32 import file_is_free
|
||||||
|
|
||||||
import sys
|
|
||||||
if sys.platform == 'win32': # docs should build for everyone
|
if sys.platform == 'win32': # docs should build for everyone
|
||||||
import win32serviceutil
|
import win32serviceutil
|
||||||
import win32service
|
import win32service
|
||||||
|
@ -94,8 +95,9 @@ class FileMonitorService(win32serviceutil.ServiceFramework):
|
||||||
except Queue.Empty:
|
except Queue.Empty:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if ftype == 'file' and action in (
|
# if ftype == 'file' and action in (
|
||||||
ACTION_CREATE, ACTION_UPDATE):
|
# ACTION_CREATE, ACTION_UPDATE):
|
||||||
|
if ftype == 'file' and action == ACTION_CREATE:
|
||||||
self.do_actions(key, fpath)
|
self.do_actions(key, fpath)
|
||||||
win32api.SleepEx(250, True)
|
win32api.SleepEx(250, True)
|
||||||
|
|
||||||
|
@ -118,7 +120,34 @@ class FileMonitorService(win32serviceutil.ServiceFramework):
|
||||||
func = action
|
func = action
|
||||||
args = []
|
args = []
|
||||||
func = edbob.load_spec(func)
|
func = edbob.load_spec(func)
|
||||||
func(path, *args)
|
|
||||||
|
try:
|
||||||
|
func(path, *args)
|
||||||
|
except:
|
||||||
|
|
||||||
|
exc_info = sys.exc_info()
|
||||||
|
|
||||||
|
# Call the system exception hook in case anything special has
|
||||||
|
# been registered there, e.g. if edbob.errors.init() has
|
||||||
|
# happened. Note that this is especially necessary since
|
||||||
|
# PythonService.exe doesn't seem to honor sys.excepthook.
|
||||||
|
sys.excepthook(*exc_info)
|
||||||
|
|
||||||
|
# Go ahead and write exception info to the Windows Event Log
|
||||||
|
# while we're at it.
|
||||||
|
msg = "File monitor action failed.\n"
|
||||||
|
msg += "\n"
|
||||||
|
msg += "Profile: %s\n" % key
|
||||||
|
msg += "Action: %s\n" % action
|
||||||
|
msg += "File Path: %s\n" % path
|
||||||
|
msg += "\n"
|
||||||
|
msg += ''.join(format_exception(*exc_info))
|
||||||
|
servicemanager.LogErrorMsg(msg)
|
||||||
|
|
||||||
|
# Don't re-raise the exception since the service should
|
||||||
|
# continue running despite any problems it encounters. But
|
||||||
|
# this file probably shouldn't be processed any further.
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue