Search code examples
python-3.xaws-lambdasentry

How to forward messages to Sentry with a clean scope (no runtime information)


I'm forwarding alert messages from a AWS Lambda function to Sentry using the sentry_sdk in Python. The problem is that even if I use scope.clear() before capture_message() the events I receive in sentry are enriched with information about the runtime environment where the message is captured in (the AWS lambda python environment) - which in this scenario is completly unrelated to the actual alert I'm forwarding.

My Code:

sentry_sdk.init(dsn, environment="name-of-stage")
with sentry_sdk.push_scope() as scope:
  # Unfortunately this does not get rid of lambda specific context information.  
  scope.clear()  
  # here I set relevant information which works just fine.
  scope.set_tag("priority", "high") 
  result = sentry_sdk.capture_message("mymessage")

The behaviour does not change if I pass scope as an argument to capture_message().

The tag I set manually is beeing transmitted just fine. But I also receive information about the Python runtime - therefore scope.clear() either does not behave like I expect it to OR capture_message gathers additional information itself.

Can someone explain how to only capture the information I'm actively assigning to the scope with set_tag and similar functions and surpress everything else?

Thank you very much


Solution

  • While I didn't find an explaination for the behaviour I was able to solve my problem (Even though it' a little bit hacky).

    The solution was to use the sentry before_send hook in the init step like so:

    sentry_sdk.init(dsn, environment="test", before_send=cleanup_event)
    with sentry_sdk.push_scope() as scope:
      sentry_sdk.capture_message(message, state, scope)
    # when using sentry from lambda don't forget to flush otherwise messages can get lost.
    sentry_sdk.flush()
    

    Then in the cleanup_event function it gets a little bit ugly. I basically iterate over the keys of the event and remove the ones I do not want to show up. Since some Keys hold objects and some (like "tags") are a list with [key, value] entries this was quite some hassle.

    KEYS_TO_REMOVE = {
       "platform": [],
       "modules": [],
       "extra": ["sys.argv"],
       "contexts": ["runtime"],
    }
    TAGS_TO_REMOVE = ["runtime", "runtime.name"]
    
    def cleanup_event(event, hint):
      for (k, v) in KEYS_TO_REMOVE.items():
        with suppress(KeyError):
            if v:
                for i in v:
                    del event[k][i]
            else:
                del event[k]
      for t in event["tags"]:
        if t[0] in TAGS_TO_REMOVE:
            event["tags"].remove(t)
      return event