Improved bugsnag reporting
- Include release stage, which should be 'production' or 'development', and gets postfixed by '-debug' when running in debug mode. - Properly logging remote IP address when proxied through HAProxy; - Log user ID, email, username, roles, and capabilities; - Remove authentication tokens from logged session; - Log request data and JSON separately. - Added request endpoint.
This commit is contained in:
parent
ec42d033b3
commit
6a541e0662
@ -183,9 +183,14 @@ class PillarServer(Eve):
|
|||||||
import bugsnag
|
import bugsnag
|
||||||
from bugsnag.handlers import BugsnagHandler
|
from bugsnag.handlers import BugsnagHandler
|
||||||
|
|
||||||
|
release_stage = self.config.get('BUGSNAG_RELEASE_STAGE', 'unconfigured')
|
||||||
|
if self.config.get('DEBUG'):
|
||||||
|
release_stage += '-debug'
|
||||||
|
|
||||||
bugsnag.configure(
|
bugsnag.configure(
|
||||||
api_key=bugsnag_api_key,
|
api_key=bugsnag_api_key,
|
||||||
project_root="/data/git/pillar/pillar",
|
project_root="/data/git/pillar/pillar",
|
||||||
|
release_stage=release_stage
|
||||||
)
|
)
|
||||||
|
|
||||||
bs_handler = BugsnagHandler()
|
bs_handler = BugsnagHandler()
|
||||||
@ -196,9 +201,9 @@ class PillarServer(Eve):
|
|||||||
# but it passes the app to the connect() call, which causes an
|
# but it passes the app to the connect() call, which causes an
|
||||||
# error. Since we only have one app, we can do without.
|
# error. Since we only have one app, we can do without.
|
||||||
from flask import got_request_exception
|
from flask import got_request_exception
|
||||||
from bugsnag.flask import add_flask_request_to_notification
|
from . import bugsnag_extra
|
||||||
|
|
||||||
bugsnag.before_notify(add_flask_request_to_notification)
|
bugsnag.before_notify(bugsnag_extra.add_pillar_request_to_notification)
|
||||||
got_request_exception.connect(self.__notify_bugsnag)
|
got_request_exception.connect(self.__notify_bugsnag)
|
||||||
|
|
||||||
self.log.info('Bugsnag setup complete')
|
self.log.info('Bugsnag setup complete')
|
||||||
|
51
pillar/bugsnag_extra.py
Normal file
51
pillar/bugsnag_extra.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Keys in the user's session dictionary that are removed before sending to Bugsnag.
|
||||||
|
SESSION_KEYS_TO_REMOVE = ('blender_id_oauth_token', 'user_id')
|
||||||
|
|
||||||
|
|
||||||
|
def add_pillar_request_to_notification(notification):
|
||||||
|
"""Adds request metadata to the Bugsnag notifications.
|
||||||
|
|
||||||
|
This basically copies bugsnag.flask.add_flask_request_to_notification,
|
||||||
|
but is altered to include Pillar-specific metadata.
|
||||||
|
"""
|
||||||
|
from flask import request, session
|
||||||
|
from bugsnag.wsgi import request_path
|
||||||
|
import pillar.auth
|
||||||
|
|
||||||
|
if not request:
|
||||||
|
return
|
||||||
|
|
||||||
|
notification.context = "%s %s" % (request.method,
|
||||||
|
request_path(request.environ))
|
||||||
|
|
||||||
|
if 'id' not in notification.user:
|
||||||
|
user: pillar.auth.UserClass = pillar.auth.current_user._get_current_object()
|
||||||
|
notification.set_user(id=user.user_id,
|
||||||
|
email=user.email,
|
||||||
|
name=user.username)
|
||||||
|
notification.user['roles'] = sorted(user.roles)
|
||||||
|
notification.user['capabilities'] = sorted(user.capabilities)
|
||||||
|
|
||||||
|
session_dict = dict(session)
|
||||||
|
for key in SESSION_KEYS_TO_REMOVE:
|
||||||
|
try:
|
||||||
|
del session_dict[key]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
notification.add_tab("session", session_dict)
|
||||||
|
notification.add_tab("environment", dict(request.environ))
|
||||||
|
|
||||||
|
remote_addr = request.remote_addr
|
||||||
|
forwarded_for = request.headers.get('X-Forwarded-For')
|
||||||
|
if forwarded_for:
|
||||||
|
remote_addr = f'{forwarded_for} (proxied via {remote_addr})'
|
||||||
|
|
||||||
|
notification.add_tab("request", {
|
||||||
|
"url": request.base_url,
|
||||||
|
"headers": dict(request.headers),
|
||||||
|
"params": dict(request.form),
|
||||||
|
"data": {'request.data': request.data,
|
||||||
|
'request.json': request.get_json()},
|
||||||
|
"endpoint": request.endpoint,
|
||||||
|
"remote_addr": remote_addr,
|
||||||
|
})
|
@ -63,6 +63,7 @@ GOOGLE_SITE_VERIFICATION = ''
|
|||||||
ADMIN_USER_GROUP = '5596e975ea893b269af85c0e'
|
ADMIN_USER_GROUP = '5596e975ea893b269af85c0e'
|
||||||
SUBSCRIBER_USER_GROUP = '5596e975ea893b269af85c0f'
|
SUBSCRIBER_USER_GROUP = '5596e975ea893b269af85c0f'
|
||||||
BUGSNAG_API_KEY = ''
|
BUGSNAG_API_KEY = ''
|
||||||
|
BUGSNAG_RELEASE_STAGE = 'development'
|
||||||
|
|
||||||
ALGOLIA_USER = '-SECRET-'
|
ALGOLIA_USER = '-SECRET-'
|
||||||
ALGOLIA_API_KEY = '-SECRET-'
|
ALGOLIA_API_KEY = '-SECRET-'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user