You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
4.9 KiB

  1. # -*- coding: utf-8 -*-
  2. ###############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # This module copyright (C) 2010 - 2014 Savoir-faire Linux
  6. # (<http://www.savoirfairelinux.com>).
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU Affero General Public License as
  10. # published by the Free Software Foundation, either version 3 of the
  11. # License, or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Affero General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU Affero General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. #
  21. ###############################################################################
  22. import logging
  23. import platform
  24. import os
  25. import sys
  26. from raven import Client
  27. try:
  28. from bzrlib.branch import Branch as Bzr
  29. from bzrlib.errors import NotBranchError
  30. except ImportError:
  31. Bzr = False
  32. try:
  33. from git import Git, GitCommandError
  34. except ImportError:
  35. Git = False
  36. from openerp.tools import config
  37. _logger = logging.getLogger(__name__)
  38. class OdooClient(Client):
  39. """Subclass raven.Client to be able to report Module versions and
  40. commit numbers"""
  41. def __init__(self, dsn=None, **options):
  42. """Set up Sentry Client, add version numbers to sentry package
  43. Send a message when Activate
  44. """
  45. # Send the following library versions and include all eggs in sys.path
  46. include_paths = [
  47. 'openerp',
  48. 'sentry',
  49. 'raven',
  50. 'raven_sanitize_openerp',
  51. ] + [os.path.basename(i).split('-')[0]
  52. for i in sys.path if i.endswith('.egg')]
  53. # Add tags, OS and bzr revisions for Server and Addons
  54. tags = {
  55. 'OS': (" ".join(platform.linux_distribution()).strip() or
  56. " ".join(platform.win32_ver()).strip() or
  57. " ".join((platform.system(), platform.release(),
  58. platform.machine()))),
  59. }
  60. self.revnos = {}
  61. super(OdooClient, self).__init__(
  62. dsn=dsn, include_paths=include_paths, tags=tags, **options)
  63. self.set_rev_versions()
  64. # Create and test message for Sentry
  65. self.captureMessage(u'Sentry Tracking Activated!')
  66. def set_rev_versions(self):
  67. """Given path, get source and revno, careful not to raise any
  68. exceptions"""
  69. paths = set(config.get('addons_path').split(','))
  70. bzr_paths = (
  71. p for p in paths if os.path.exists(os.path.join(p, '.bzr'))
  72. )
  73. git_paths = (
  74. p for p in paths if os.path.exists(os.path.join(p, '.git'))
  75. )
  76. if Bzr:
  77. self.set_rev_bzr_version(bzr_paths)
  78. if Git:
  79. self.set_rev_git_version(git_paths)
  80. def set_rev_bzr_version(self, paths):
  81. for path in paths:
  82. try:
  83. branch, rel_path = Bzr.open_containing(path)
  84. branch.lock_read()
  85. # Clean name
  86. name = branch.get_parent()
  87. name = name.replace(u'bazaar.launchpad.net/', u'lp:')
  88. name = name.replace(u'%7E', u'~')
  89. name = name.replace(u'%2Bbranch/', u'')
  90. name = name.replace(u'bzr+ssh://', u'')
  91. self.revnos[name] = u'r%i' % branch.revno()
  92. branch.unlock()
  93. except NotBranchError:
  94. continue
  95. finally:
  96. if branch.is_locked():
  97. branch.unlock()
  98. def set_rev_git_version(self, paths):
  99. for path in paths:
  100. try:
  101. git_repo = Git(path)
  102. name = os.path.basename(path)
  103. self.revnos[name] = git_repo.log('-1', pretty='%H')
  104. except GitCommandError:
  105. continue
  106. def build_msg(self, event_type, data=None, date=None,
  107. time_spent=None, extra=None, stack=None, public_key=None,
  108. tags=None, **kwargs):
  109. """Add revnos to msg's modules"""
  110. res = super(OdooClient, self).build_msg(
  111. event_type, data, date, time_spent, extra, stack, public_key,
  112. tags, **kwargs)
  113. res['modules'] = dict(res['modules'].items() + self.revnos.items())
  114. # Sanitize frames from dispatch since they contain passwords
  115. try:
  116. for values in res['exception']['values']:
  117. values['stacktrace']['frames'] = [
  118. f for f in values['stacktrace']['frames']
  119. if f.get('function') not in ['dispatch', 'dispatch_rpc']
  120. ]
  121. except KeyError:
  122. pass
  123. return res