Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event handlers awkward interaction with the Django RollbarNotifierMiddleware #393

Open
phillipuniverse opened this issue Oct 25, 2021 · 0 comments

Comments

@phillipuniverse
Copy link

phillipuniverse commented Oct 25, 2021

I am having an issue where it appears the only clean option to initialize Rollbar event handlers (e.g. rollbar.events.add_payload_handler) is within the RollbarNotifierMiddleware as a subclass of __init__. This does work, but it's not very clean.

Here is my ROLLBAR variable in settings.py:

ROLLBAR = {
    'access_token': env.str('ROLLBAR_ACCESS_TOKEN', ''),
    'environment': 'dev',
    'branch': master,
    'root': '/usr/src/app/',
    'enabled': ROLLBAR_ENABLED,
    'locals': {
        'enabled': True,
        'safe_repr': False,
    },
    'ignorable_404_urls': (
        re.compile('.*'),  # never report a 404 to Rollbar
    ),
}

Then at the end of settings.py I want to add a payload handler to add trace information from OpenTelemetry:

import rollbar
from django.conf import settings

def transform_rollbar_payload(
        payload: Dict[str, Any], **kwargs: Dict[str, Any]
) -> Dict[str, Any]:
    data = payload["data"]
    custom = data.get("custom", {})

    custom['service'] = settings.SERVICE
    custom['env'] = settings.ENVIRONMENT
    custom['version'] = settings.VERSION
    span = trace.get_current_span()
    if span != trace.span.INVALID_SPAN:
        ctx = span.get_span_context()
        if ctx != trace.span.INVALID_SPAN_CONTEXT:
            custom['trace_id'] = ctx.trace_id
            custom['span_id'] = ctx.span_id

    data["custom"] = custom
    return payload

rollbar.events.add_payload_handler(transform_rollbar_payload)

When I configure it like this, the RollbarNotifierMiddleware sees that there is an access token in the Rollbar settings and then unconditionally calls rollbar.init:

rollbar.init(access_token, environment, **kw)

But when this happens, the rollbar.init() calls rollbar.events.reset(). This clears out my previously-added payload handler since it was added prior to Django initializing middleware and thus the RollbarNotifierMiddleware invoking rollbar.init().

I see a few options, none of which I'm particularly thrilled about:

  1. Subclass RollbarNotifierMiddleware, call super.__init__(), and then call rollbar.events.add_payload_handler() (this is the one I went with):
    class TracedRollbarNotifierMiddleware(RollbarNotifierMiddleware):
        """
        The default RollbarNotifierMiddleware unconditionally does a rollbar.init() itself with the given access token
        """
        def __init__(self, get_response=None):
            super().__init__(get_response)
            import rollbar
            from django.conf import settings
    
            def transform_rollbar_payload(
                    payload: Dict[str, Any], **kwargs: Dict[str, Any]
            ) -> Dict[str, Any]:
                data = payload["data"]
                custom = data.get("custom", {})
    
                custom['service'] = settings.SERVICE
                custom['env'] = settings.ENVIRONMENT
                custom['version'] = settings.VERSION
                span = trace.get_current_span()
                if span != trace.span.INVALID_SPAN:
                    ctx = span.get_span_context()
                    if ctx != trace.span.INVALID_SPAN_CONTEXT:
                        custom['trace_id'] = ctx.trace_id
                        custom['span_id'] = ctx.span_id
    
                data["custom"] = custom
                return payload
    
            rollbar.events.add_payload_handler(transform_rollbar_payload)
  2. Move the event handler registration to within a Django AppConfig.ready(), I presume this happens after middleware instantiation
  3. Call rollbar.init() myself, but still set a ROLLBAR = {'access_token': 'not-used'} in settings.py so that the middleware will still be activated (RollbarNotifierMiddleware is skipped unless this is set)

So what is the intended use of event handlers with the RollbarNotifierMiddleware? Where in the lifecycle should I be adding these?

@phillipuniverse phillipuniverse changed the title Event handlers awkward interaction with the RollbarNotifierMiddleware Event handlers awkward interaction with the DJango RollbarNotifierMiddleware Oct 25, 2021
@phillipuniverse phillipuniverse changed the title Event handlers awkward interaction with the DJango RollbarNotifierMiddleware Event handlers awkward interaction with the Django RollbarNotifierMiddleware Oct 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant