Martin Thorsen Ranang
Martin Thorsen Ranang

Reputation: 2415

TurboGears and backlash: How to add extra, per-request context to Raven for more informative Sentry reports?

Through backlash, TurboGears supports error reporting to Sentry via Raven. Enabling the error reporting is quite easy, just add the appropriate setting in the .ini configuration file, for example:

[DEFAULT]
debug = false
trace_errors.sentry_dsn = https://[…]
trace_slowreqs.enable = true
trace_slowreqs.sentry_dsn = https://[…]

set debug = false

According to Raven's documentation, adding more context to what gets reported should be as simple as

def handle_request(request):  # In TurboGears, this would be a controller instead.
    client.context.merge({'user': {
        'email': request.user.email
    }})
    try:
        ...
    finally:
        client.context.clear()

However, now I wonder what is the easiest, or most correct, way to get hold of the client instance that backlash will use for reporting? I would like to add per-request information, typically from within the request handlers, or Controller methods.

Upvotes: 2

Views: 199

Answers (1)

amol
amol

Reputation: 1791

Editing the raven context is currently quite hard as the error reporters are not registered anywhere, so you cannot say "hey give me the error reporters" and look for the Sentry one in that list.

Currently the only way is to register an after_config hook, gather the Raven Client during the configuration process and store it somewhere accessible.

Changing backlash middlewares to store the reporters somewhere accessible should be fairly easy (e.g. the environ) but currently it's not available.

By the way here is a short example of the after_config solution that should make the client available as tg.app_globals.sentry_clients, copy it in your app_cfg.py and it should do what you expect (didn't have time to try it, sorry if you find errors), then you can get the context from the client whenever is needed:

def gather_sentry_client(app):
    from backlash import TraceErrorsMiddleware, TraceSlowRequestsMiddleware

    try:
        trace_errors_app = app.app.application
    except:
        return app

    if not isinstance(trace_errors_app, TraceErrorsMiddleware):
        return app

    trace_errors_client = None
    for reporter in trace_errors_app.reporters:
        if hasattr(reporter, 'client'):
            trace_errors_client = reporter.client

    slow_reqs_app = trace_errors_app.app
    slow_reqs_client = None
    if isinstance(slow_reqs_app, TraceSlowRequestsMiddleware):
        for reporter in slow_reqs_app.reporters:
            if hasattr(reporter, 'client'):
                slow_reqs_client = reporter.client

    from tg import config
    app_globals = config['tg.app_globals']
    app_globals.sentry_clients = {
        'errors': trace_errors_client,
        'slowreqs': slow_reqs_client
    }
    return app    

from tg import hooks
hooks.register('after_config', gather_sentry_client)

Upvotes: 4

Related Questions