Browse Source
Merge pull request #44 from savoirfairelinux/sentry
Merge pull request #44 from savoirfairelinux/sentry
Add sentry integration modulepull/98/head
Pedro M. Baeza
10 years ago
8 changed files with 412 additions and 1 deletions
-
2.travis.yml
-
64sentry_logger/__init__.py
-
82sentry_logger/__openerp__.py
-
32sentry_logger/i18n/fr.po
-
30sentry_logger/i18n/sentry_logger.pot
-
132sentry_logger/odoo_sentry_client.py
-
46sentry_logger/odoo_sentry_handler.py
-
25sentry_logger/static/src/xml/base.xml
@ -0,0 +1,64 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2010 - 2014 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/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
|
||||
|
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 |
@ -0,0 +1,82 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2010 - 2014 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/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
{ |
||||
|
'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+<Your Sentry DSN> |
||||
|
|
||||
|
|
||||
|
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 <odoo>/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': [ |
||||
|
], |
||||
|
} |
@ -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 <sandy.carter@savoirfairelinux.com>\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." |
@ -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 "" |
@ -0,0 +1,132 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2010 - 2014 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/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
|
||||
|
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 |
@ -0,0 +1,46 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# ############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2010 - 2014 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 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) |
@ -0,0 +1,25 @@ |
|||||
|
<?xml version = "1.0" encoding="utf-8"?> |
||||
|
<templates> |
||||
|
|
||||
|
<t t-extend="CrashManager.error"> |
||||
|
<t t-jquery="div.oe_error_detail" t-operation="replace"> |
||||
|
|
||||
|
<!-- Hide traceback from users --> |
||||
|
<div t-if="session.sentry_activated" class="oe_error_detail"> |
||||
|
<h2>An internal OpenERP error has occurred.</h2> |
||||
|
<div class="oe_view_nocontent"> |
||||
|
A detailed report has been sent to the technical support team. |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Original error message --> |
||||
|
<div t-if="!session.sentry_activated" class="oe_error_detail"> |
||||
|
<pre><t t-esc="error.message"/></pre> |
||||
|
<hr/> |
||||
|
<pre><t t-esc="error.data.debug"/></pre> |
||||
|
</div> |
||||
|
|
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
</templates> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue