diff --git a/.travis.yml b/.travis.yml index e71384052..fbd4b8c32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ install: - git clone https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - travis_install_nightly - - sudo pip install python-ldap + - sudo pip install python-ldap raven raven_sanitize_openerp bzr GitPython - printf '[options]\n\nrunning_env = dev' > ${HOME}/.openerp_serverrc script: diff --git a/sentry_logger/__init__.py b/sentry_logger/__init__.py new file mode 100644 index 000000000..d0b714b9e --- /dev/null +++ b/sentry_logger/__init__.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2010 - 2014 Savoir-faire Linux +# (). +# +# 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 . +# +############################################################################### + +import logging +import cgitb + +from openerp.tools import config +from openerp.addons.web.controllers.main import Session + +from .odoo_sentry_client import OdooClient +from .odoo_sentry_handler import OdooSentryHandler + + +root_logger = logging.root + +processors = ( + 'raven.processors.SanitizePasswordsProcessor', + 'raven_sanitize_openerp.OpenerpPasswordsProcessor' +) +if config.get(u'sentry_dsn'): + cgitb.enable() + # Get DSN info from config file or ~/.openerp_serverrc (recommended) + dsn = config.get('sentry_dsn') + # Create Client + client = OdooClient( + dsn=dsn, + processors=processors, + ) + handler = OdooSentryHandler(client, level=logging.ERROR) + root_logger.addHandler(handler) +else: + root_logger.warn(u"Sentry DSN not defined in config file") + client = None + + +# Inject sentry_activated to session to display error message or not +old_session_info = Session.session_info + + +def session_info(self, req): + res = old_session_info(self, req) + res['sentry_activated'] = bool(client) + return res + +Session.session_info = session_info diff --git a/sentry_logger/__openerp__.py b/sentry_logger/__openerp__.py new file mode 100644 index 000000000..ea9fe08c0 --- /dev/null +++ b/sentry_logger/__openerp__.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2010 - 2014 Savoir-faire Linux +# (). +# +# 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 . +# +############################################################################## + +{ + 'name': "Sentry Logger", + + 'summary': "Sentry integration", + 'description': """ +Sentry +====== + +Integration with Sentry Error reporting engine. + +Insert sentry DSN to ~/.openerp_serverrc with value: + sentry_dsn = sync+ + + +Optional Dependencies +--------------------- + +* bzrlib (for revno reporting on module repositories from LP) + +Notes +----- + +Module may slow down spawning of workers (~1s) due to the access of openerp +configuration + +Contributors +------------ +* Sandy Carter (sandy.carter@savoirfairelinux.com) +""", + + 'author': "Savoir-faire Linux", + 'website': "http://www.savoirfairelinux.com", + + # Categories can be used to filter modules in modules listing + # Check /addons/base/module/module_data.xml of the full list + 'category': 'Extra Tools', + 'version': '1.0', + + # any module necessary for this one to work correctly + 'depends': ['web'], + 'external_dependencies': { + 'python': [ + 'raven', + 'raven_sanitize_openerp', + 'git', + ], + }, + 'data': [ + ], + + 'demo': [ + ], + + 'qweb': [ + 'static/src/xml/base.xml', + ], + + 'tests': [ + ], +} diff --git a/sentry_logger/i18n/fr.po b/sentry_logger/i18n/fr.po new file mode 100644 index 000000000..60f983804 --- /dev/null +++ b/sentry_logger/i18n/fr.po @@ -0,0 +1,32 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * sentry_logger +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-10-15 22:09+0000\n" +"PO-Revision-Date: 2014-10-15 18:11-0500\n" +"Last-Translator: Sandy Carter \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"Language: fr\n" +"X-Generator: Poedit 1.6.9\n" + +#. module: sentry_logger +#. openerp-web +#: code:addons/sentry_logger/static/src/xml/base.xml:8 +#, python-format +msgid "A detailed report has been sent to the technical support team." +msgstr "Un rapport a été envoyé à l'équipe technique." + +#. module: sentry_logger +#. openerp-web +#: code:addons/sentry_logger/static/src/xml/base.xml:7 +#, python-format +msgid "An internal OpenERP error has occurred." +msgstr "Une erreur interne à OpenERP est survenue." diff --git a/sentry_logger/i18n/sentry_logger.pot b/sentry_logger/i18n/sentry_logger.pot new file mode 100644 index 000000000..dd2226936 --- /dev/null +++ b/sentry_logger/i18n/sentry_logger.pot @@ -0,0 +1,30 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * sentry_logger +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-10-15 22:09+0000\n" +"PO-Revision-Date: 2014-10-15 22:09+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sentry_logger +#. openerp-web +#: code:addons/sentry_logger/static/src/xml/base.xml:8 +#, python-format +msgid "A detailed report has been sent to the technical support team." +msgstr "" + +#. module: sentry_logger +#. openerp-web +#: code:addons/sentry_logger/static/src/xml/base.xml:7 +#, python-format +msgid "An internal OpenERP error has occurred." +msgstr "" diff --git a/sentry_logger/odoo_sentry_client.py b/sentry_logger/odoo_sentry_client.py new file mode 100644 index 000000000..5cccc0d38 --- /dev/null +++ b/sentry_logger/odoo_sentry_client.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2010 - 2014 Savoir-faire Linux +# (). +# +# 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 . +# +############################################################################### + +import logging +import platform +import os +import sys +from raven import Client +try: + from bzrlib.branch import Branch as Bzr + from bzrlib.errors import NotBranchError +except ImportError: + Bzr = False +try: + from git import Git, GitCommandError +except ImportError: + Git = False + +from openerp.tools import config +_logger = logging.getLogger(__name__) + + +class OdooClient(Client): + """Subclass raven.Client to be able to report Module versions and + commit numbers""" + + def __init__(self, dsn=None, **options): + """Set up Sentry Client, add version numbers to sentry package + Send a message when Activate + """ + # Send the following library versions and include all eggs in sys.path + 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()))), + } + self.revnos = {} + super(OdooClient, self).__init__( + dsn=dsn, include_paths=include_paths, tags=tags, **options) + self.set_rev_versions() + # Create and test message for Sentry + self.captureMessage(u'Sentry Tracking Activated!') + + def set_rev_versions(self): + """Given path, get source and revno, careful not to raise any + exceptions""" + paths = set(config.get('addons_path').split(',')) + bzr_paths = ( + p for p in paths if os.path.exists(os.path.join(p, '.bzr')) + ) + git_paths = ( + p for p in paths if os.path.exists(os.path.join(p, '.git')) + ) + if Bzr: + self.set_rev_bzr_version(bzr_paths) + if Git: + self.set_rev_git_version(git_paths) + + def set_rev_bzr_version(self, paths): + for path in paths: + try: + branch, rel_path = Bzr.open_containing(path) + branch.lock_read() + # Clean name + name = branch.get_parent() + name = name.replace(u'bazaar.launchpad.net/', u'lp:') + name = name.replace(u'%7E', u'~') + name = name.replace(u'%2Bbranch/', u'') + name = name.replace(u'bzr+ssh://', u'') + self.revnos[name] = u'r%i' % branch.revno() + branch.unlock() + except NotBranchError: + continue + finally: + if branch.is_locked(): + branch.unlock() + + def set_rev_git_version(self, paths): + for path in paths: + try: + git_repo = Git(path) + name = os.path.basename(path) + self.revnos[name] = git_repo.log('-1', pretty='%H') + except GitCommandError: + continue + + def build_msg(self, event_type, data=None, date=None, + time_spent=None, extra=None, stack=None, public_key=None, + tags=None, **kwargs): + """Add revnos to msg's modules""" + res = super(OdooClient, self).build_msg( + event_type, data, date, time_spent, extra, stack, public_key, + tags, **kwargs) + res['modules'] = dict(res['modules'].items() + self.revnos.items()) + # Sanitize frames from dispatch since they contain passwords + try: + for values in res['exception']['values']: + values['stacktrace']['frames'] = [ + f for f in values['stacktrace']['frames'] + if f.get('function') not in ['dispatch', 'dispatch_rpc'] + ] + except KeyError: + pass + return res diff --git a/sentry_logger/odoo_sentry_handler.py b/sentry_logger/odoo_sentry_handler.py new file mode 100644 index 000000000..9bc6be22d --- /dev/null +++ b/sentry_logger/odoo_sentry_handler.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# ############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2010 - 2014 Savoir-faire Linux +# (). +# +# 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 . +# +############################################################################### + +from psycopg2._psycopg import TransactionRollbackError + +from openerp.osv.orm import except_orm +from openerp.osv.osv import except_osv +from openerp.addons.web.session import SessionExpiredException +from raven.handlers.logging import SentryHandler + + +odoo_exception_black_list = [ + except_orm, + except_osv, + SessionExpiredException, + TransactionRollbackError, +] + + +class OdooSentryHandler(SentryHandler, object): + + def can_record(self, record): + if record.exc_info and record.exc_info[0] in odoo_exception_black_list: + return False + if record.module == 'osv' and record.msg == 'Uncaught exception': + return False + return super(OdooSentryHandler, self).can_record(record) diff --git a/sentry_logger/static/src/xml/base.xml b/sentry_logger/static/src/xml/base.xml new file mode 100644 index 000000000..ac7ec8cd8 --- /dev/null +++ b/sentry_logger/static/src/xml/base.xml @@ -0,0 +1,25 @@ + + + + + + + +
+

An internal OpenERP error has occurred.

+
+A detailed report has been sent to the technical support team. +
+
+ + +
+
+
+
+
+ +
+
+ +