forked from OCA/server-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hooks.py
154 lines (124 loc) · 4.9 KB
/
hooks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# Copyright 2016-2017 Versada <https://versada.eu/>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
import warnings
from collections import abc
import odoo.http
from odoo.service.server import server
from odoo.tools import config as odoo_config
from . import const
from .logutils import (
InvalidGitRepository,
SanitizeOdooCookiesProcessor,
fetch_git_sha,
get_extra_context,
)
_logger = logging.getLogger(__name__)
HAS_SENTRY_SDK = True
try:
import sentry_sdk
from sentry_sdk.integrations.logging import ignore_logger
from sentry_sdk.integrations.threading import ThreadingIntegration
from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
except ImportError: # pragma: no cover
HAS_SENTRY_SDK = False # pragma: no cover
_logger.debug(
"Cannot import 'sentry-sdk'.\
Please make sure it is installed."
) # pragma: no cover
def before_send(event, hint):
"""Prevent the capture of any exceptions in
the DEFAULT_IGNORED_EXCEPTIONS list
-- or --
Add context to event if include_context is True
and sanitize sensitive data"""
exc_info = hint.get("exc_info")
if exc_info is None and "log_record" in hint:
# Odoo handles UserErrors by logging the raw exception rather
# than a message string in odoo/http.py
try:
module_name = hint["log_record"].msg.__module__
class_name = hint["log_record"].msg.__class__.__name__
qualified_name = module_name + "." + class_name
except AttributeError:
qualified_name = "not found"
if qualified_name in const.DEFAULT_IGNORED_EXCEPTIONS:
return None
if event.setdefault("tags", {})["include_context"]:
cxtest = get_extra_context(odoo.http.request)
info_request = ["tags", "user", "extra", "request"]
for item in info_request:
info_item = event.setdefault(item, {})
info_item.update(cxtest.setdefault(item, {}))
raven_processor = SanitizeOdooCookiesProcessor()
raven_processor.process(event)
return event
def get_odoo_commit(odoo_dir):
"""Attempts to get Odoo git commit from :param:`odoo_dir`."""
if not odoo_dir:
return
try:
return fetch_git_sha(odoo_dir)
except InvalidGitRepository:
_logger.debug("Odoo directory: '%s' not a valid git repository", odoo_dir)
def initialize_sentry(config):
"""Setup an instance of :class:`sentry_sdk.Client`.
:param config: Sentry configuration
:param client: class used to instantiate the sentry_sdk client.
"""
enabled = config.get("sentry_enabled", False)
if not (HAS_SENTRY_SDK and enabled):
return
_logger.info("Initializing sentry...")
if config.get("sentry_odoo_dir") and config.get("sentry_release"):
_logger.debug(
"Both sentry_odoo_dir and \
sentry_release defined, choosing sentry_release"
)
if config.get("sentry_transport"):
warnings.warn(
"`sentry_transport` has been deprecated. "
"Its not neccesary send it, will use `HttpTranport` by default.",
DeprecationWarning,
stacklevel=1,
)
options = {}
for option in const.get_sentry_options():
value = config.get("sentry_%s" % option.key, option.default)
if isinstance(option.converter, abc.Callable):
value = option.converter(value)
options[option.key] = value
exclude_loggers = const.split_multiple(
config.get("sentry_exclude_loggers", const.DEFAULT_EXCLUDE_LOGGERS)
)
if not options.get("release"):
options["release"] = config.get(
"sentry_release", get_odoo_commit(config.get("sentry_odoo_dir"))
)
# Change name `ignore_exceptions` (with raven)
# to `ignore_errors' (sentry_sdk)
options["ignore_errors"] = options["ignore_exceptions"]
del options["ignore_exceptions"]
options["before_send"] = before_send
options["integrations"] = [
options["logging_level"],
ThreadingIntegration(propagate_hub=True),
]
# Remove logging_level, since in sentry_sdk is include in 'integrations'
del options["logging_level"]
client = sentry_sdk.init(**options)
sentry_sdk.set_tag("include_context", config.get("sentry_include_context", True))
if exclude_loggers:
for item in exclude_loggers:
ignore_logger(item)
# The server app is already registered so patch it here
if server:
server.app = SentryWsgiMiddleware(server.app)
# Patch the wsgi server in case of further registration
odoo.http.Application = SentryWsgiMiddleware(odoo.http.Application)
with sentry_sdk.push_scope() as scope:
scope.set_extra("debug", False)
sentry_sdk.capture_message("Starting Odoo Server", "info")
return client
def post_load():
initialize_sentry(odoo_config)