##// END OF EJS Templates
appenligth: make it optional if library is not installed
super-admin -
r4937:08819a6d default
parent child Browse files
Show More
@@ -1,100 +1,101 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 middleware to handle appenlight publishing of errors
22 middleware to handle appenlight publishing of errors
23 """
23 """
24 import logging
24 import logging
25
25
26 log = logging.getLogger(__name__)
26 log = logging.getLogger(__name__)
27
27
28 appenlight_installed = False
29
30 try:
31 from appenlight_client import make_appenlight_middleware
32 from appenlight_client.exceptions import get_current_traceback
33 from appenlight_client.wsgi import AppenlightWSGIWrapper
34 appenlight_installed = True
35 except ImportError:
36 log.info('Appenlight packages not present, skipping appenlight setup')
37
38
28
39 def track_exception(environ):
29 def track_exception(environ):
30 from appenlight_client.exceptions import get_current_traceback
31
40 if 'appenlight.client' not in environ:
32 if 'appenlight.client' not in environ:
41 return
33 return
42
34
43 # pass the traceback object to middleware
35 # pass the traceback object to middleware
44 environ['appenlight.__traceback'] = get_current_traceback(
36 environ['appenlight.__traceback'] = get_current_traceback(
45 skip=1,
37 skip=1,
46 show_hidden_frames=True,
38 show_hidden_frames=True,
47 ignore_system_exceptions=True)
39 ignore_system_exceptions=True
40 )
48
41
49
42
50 def track_extra_information(environ, section, value):
43 def track_extra_information(environ, section, value):
51 """
44 """
52 Utility function to attach extra information in case of an error condition.
45 Utility function to attach extra information in case of an error condition.
53
46
54 It will take care of attaching this information to the right place inside
47 It will take care of attaching this information to the right place inside
55 of `environ`, so that the appenight client can pick it up.
48 of `environ`, so that the appenight client can pick it up.
56 """
49 """
57 environ.setdefault('appenlight.extra', {})
50 environ.setdefault('appenlight.extra', {})
58 environ['appenlight.extra'][section] = value
51 environ['appenlight.extra'][section] = value
59
52
60
53
61 def wrap_in_appenlight_if_enabled(app, settings, appenlight_client=None):
54 def wrap_in_appenlight_if_enabled(app, settings, appenlight_client=None):
62 """
55 """
63 Wraps the given `app` for appenlight support.
56 Wraps the given `app` for appenlight support.
64
57
65 .. important::
58 .. important::
66
59
67 Appenlight expects that the wrapper is executed only once, that's why
60 Appenlight expects that the wrapper is executed only once, that's why
68 the parameter `appenlight_client` can be used to pass in an already
61 the parameter `appenlight_client` can be used to pass in an already
69 existing client instance to avoid that decorators are applied more than
62 existing client instance to avoid that decorators are applied more than
70 once.
63 once.
71
64
72 This is in use to support our setup of the vcs related middlewares.
65 This is in use to support our setup of the vcs related middlewares.
73
66
74 """
67 """
75 if appenlight_installed and settings['appenlight']:
68 if settings['appenlight']:
69 try:
70 from appenlight_client import make_appenlight_middleware
71 from appenlight_client.wsgi import AppenlightWSGIWrapper
72 except ImportError:
73 log.info('Appenlight packages not present, skipping appenlight setup')
74 return app, appenlight_client
75
76 app = RemoteTracebackTracker(app)
76 app = RemoteTracebackTracker(app)
77 if not appenlight_client:
77 if not appenlight_client:
78 app = make_appenlight_middleware(app, settings)
78 app = make_appenlight_middleware(app, settings)
79 appenlight_client = app.appenlight_client
79 appenlight_client = app.appenlight_client
80 else:
80 else:
81 app = AppenlightWSGIWrapper(app, appenlight_client)
81 app = AppenlightWSGIWrapper(app, appenlight_client)
82
82 return app, appenlight_client
83 return app, appenlight_client
83
84
84
85
85 class RemoteTracebackTracker(object):
86 class RemoteTracebackTracker(object):
86 """
87 """
87 Utility middleware which forwards VCSServer remote traceback information.
88 Utility middleware which forwards VCSServer remote traceback information.
88 """
89 """
89
90
90 def __init__(self, app):
91 def __init__(self, app):
91 self.application = app
92 self.application = app
92
93
93 def __call__(self, environ, start_response):
94 def __call__(self, environ, start_response):
94 try:
95 try:
95 return self.application(environ, start_response)
96 return self.application(environ, start_response)
96 except Exception as e:
97 except Exception as e:
97 if hasattr(e, '_vcs_server_traceback'):
98 if hasattr(e, '_vcs_server_traceback'):
98 track_extra_information(
99 track_extra_information(
99 environ, 'remote_traceback', e._vcs_server_traceback)
100 environ, 'remote_traceback', e._vcs_server_traceback)
100 raise
101 raise
General Comments 0
You need to be logged in to leave comments. Login now