Skip to content

Instantly share code, notes, and snippets.

@bwrsandman
Last active January 1, 2016 08:19
Show Gist options
  • Save bwrsandman/8117236 to your computer and use it in GitHub Desktop.
Save bwrsandman/8117236 to your computer and use it in GitHub Desktop.
Raven Sentry patch to OpenERP 7.0 Server
=== added file 'openerp/bzr_client.py'
--- openerp/bzr_client.py 1970-01-01 00:00:00 +0000
+++ openerp/bzr_client.py 2013-12-26 19:03:41 +0000
@@ -0,0 +1,65 @@
+# -*- encoding: utf-8 -*-
+###############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Savoir-faire Linux
+# (<http://www.savoirfairelinux.com>).
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+###############################################################################
+
+from raven import Client
+from bzrlib.branch import Branch
+from bzrlib.errors import NotBranchError
+import os
+
+
+class BzrClient(Client):
+ """Subclass raven.Client to be able to report Bazaar revno as Module versions"""
+
+ def __init__(self, dsn=None, **options):
+ self.bzr_revs = {}
+ return super(BzrClient, self).__init__(dsn=dsn, **options)
+
+ def set_rev_version(self, path):
+ """Given path, get source and revno, careful not to raise any exceptions"""
+ try:
+ branch, rel_path = Branch.open_containing(path)
+ branch.lock_read()
+ # Clean name
+ name = (branch.get_parent().replace('bazaar.launchpad.net/', 'lp:')
+ .replace('%7E', '~')
+ .replace('%2Bbranch/', '')
+ .replace('bzr+ssh://', ''))
+ self.bzr_revs[name] = 'r%i' % branch.revno()
+ branch.unlock()
+ except NotBranchError:
+ return
+ except:
+ if branch.is_locked():
+ branch.unlock()
+ return
+
+ def build_msg(self, event_type, data=None, date=None,
+ time_spent=None, extra=None, stack=None, public_key=None,
+ tags=None, **kwargs):
+ """Add bzr revnos to msg's modules"""
+ res = super(BzrClient, self).build_msg(event_type, data, date,
+ time_spent, extra, stack, public_key,
+ tags, **kwargs)
+ res['modules'] = dict(res['modules'].items() + self.bzr_revs.items())
+ return res
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== modified file 'openerp/netsvc.py'
--- openerp/netsvc.py 2013-05-14 10:33:33 +0000
+++ openerp/netsvc.py 2013-12-26 19:01:26 +0000
@@ -47,6 +47,68 @@
_logger = logging.getLogger(__name__)
+# Raven->Sentry setup
+# Need raven and raven_sanitize_openerp installed
+# If any steps here fail, client is set to None and will not run any raven code later in execution
+try:
+ from openerp.tools import config
+ from bzr_client import BzrClient
+ import platform
+ processors = (
+ 'raven.processors.SanitizePasswordsProcessor',
+ 'raven_sanitize_openerp.OpenerpPasswordsProcessor'
+ )
+ if config.get('sentry_dsn'):
+ # Get DSN info from config file or ~/.openerp_serverrc (recommended)
+ dsn = config.get('sentry_dsn')
+ # Send the following library versions, include all eggs
+ include_paths = [
+ 'openerp',
+ 'sentry',
+ 'raven',
+ 'raven_sanitize_openerp',
+ ] + [os.path.basename(i).split('-')[0] for i in sys.path if i.endswith('.egg')]
+ # Add tags, OS and bzr revisions for Server and Addons
+ tags = {
+ 'OS': (" ".join(platform.linux_distribution()).strip() or
+ " ".join(platform.win32_ver()).strip() or
+ " ".join((platform.system(), platform.release(), platform.machine()))),
+ }
+ # Create Client
+ client = BzrClient(dsn=dsn,
+ processors=processors,
+ include_paths=include_paths,
+ tags=tags)
+ # Using bzrlib find revision numbers for server and addons
+ client.set_rev_version(config.get('root_path') + "/..", )
+ # Create and test message for Sentry
+ client.captureMessage('Sentry Tracking Activated!')
+ else:
+ logging.warn("Sentry DSN not defined in config file")
+ client = None
+except ImportError as e:
+ logging.warn("Unable to import Raven Sentry Client: " + e.message)
+ client = None
+except BaseException as e:
+ logging.warn("Unknown Raven Sentry Client Error: " + e.message)
+ client = None
+
+
+def sentry_intercept_exception():
+ """Intercept OpenERP exception and raise a different one if raven is well connected to Sentry"""
+ try:
+ if client and not client.state.did_fail():
+ # Store exc_info in case another exception is raised.
+ exc_info = sys.exc_info()
+ # Using bzrlib find revision numbers for server and addons
+ for path in config.get('addons_path').split(','):
+ client.set_rev_version(path)
+ client.captureException(exc_info=exc_info)
+ raise openerp.osv.osv.except_osv("Error!", """An internal OpenERP error occurred.
+A report was sent to the IT department""")
+ finally:
+ pass
+
def close_socket(sock):
""" Closes a socket instance cleanly
@@ -312,10 +374,13 @@
except openerp.exceptions.DeferredException, e:
_logger.exception(tools.exception_to_unicode(e))
post_mortem(e.traceback)
+ sentry_intercept_exception()
raise
except Exception, e:
_logger.exception(tools.exception_to_unicode(e))
post_mortem(sys.exc_info())
+ if type(e) not in (openerp.osv.osv.except_osv, openerp.osv.orm.except_orm):
+ sentry_intercept_exception()
raise
def post_mortem(info):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment