Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

Status 2025-10-09: This project is deprecated.

The Python sentry-sdk has a before_send hook that lets you scrub Sentry events before they’re sent. Fillmore makes it easier to set up a before_send scrubber and test it.

Code:

https://github.com/mozilla-services/fillmore

Issues:

https://github.com/mozilla-services/fillmore/issues

License:

MPL v2

Documentation:

https://fillmore.readthedocs.io/

Goals

Goals of Fillmore:

  1. make it easier to configure Sentry event scrubbing in a way that you can reason about

  2. make it easier to test your scrubbing code so you know it’s working over time

  3. scrub in a resilient manner and default to emitting some signal when it kicks up errors so you know when your error handling code is kicking up errors

From that, Fillmore has the following features:

  • lets you specify keys to scrub in a Sentry event

  • resilient to errors–if it fails, it will emit a signal that you can see and alert on

  • links to relevant Sentry documentation, projects, and other things

  • testing infrastructure to use in your integration tests

Install

Run:

$ pip install fillmore

Quickstart

Example:

# examples/myapp/myapp/app.py
import logging
import logging.config

from fillmore.libsentry import set_up_sentry
from fillmore.scrubber import Scrubber, Rule, build_scrub_query_string


# Set up logging to capture fillmore error messages
logging.getLogger("fillmore").setLevel(logging.ERROR)

# Create a scrubber
scrubber = Scrubber(
    rules=[
        Rule(
            path="request.headers",
            keys=["Auth-Token", "Cookie"],
            scrub="scrub",
        ),
        Rule(
            path="request",
            keys=["query_string"],
            scrub=build_scrub_query_string(params=["code", "state"]),
        ),
        Rule(
            path="exception.values.[].stacktrace.frames.[].vars",
            keys=["username", "password"],
            scrub="scrub",
        ),
    ]
)

# Set up Sentry with the scrubber and the default integrations which
# includes the LoggingIntegration which will capture messages with level
# logging.ERROR.
set_up_sentry(
    sentry_dsn="http://user@example.com/1",
    host_id="some host id",
    release="some release name",
    before_send=scrubber,
)


def kick_up_exception():
    username = "James"  # noqa
    try:
        raise Exception("internal exception")
    except Exception:
        logging.getLogger(__name__).exception("kick_up_exception exception")

Now you have a scrubber and you’ve set up the Sentry client to use it. How do you know it’s scrubbing the right stuff? How will you know if something changes and it’s no longer scrubbing the right stuff?

You can test it like this:

# examples/myapp/myapp/test_app.py
import unittest

from fillmore.test import SentryTestHelper

from myapp.app import kick_up_exception


class TestApp(unittest.TestCase):
    def test_scrubber(self):
        # Reuse the existing Sentry configuration and set up the helper
        # to capture Sentry events
        sentry_test_helper = SentryTestHelper()
        with sentry_test_helper.reuse() as sentry_client:
            kick_up_exception()

            (payload,) = sentry_client.envelope_payloads
            error = payload["exception"]["values"][0]
            self.assertEqual(error["type"], "Exception")
            self.assertEqual(error["value"], "internal exception")
            self.assertEqual(
                error["stacktrace"]["frames"][0]["vars"]["username"], "[Scrubbed]"
            )

This creates a Sentry client specific to this test and kicks up an exception in the test and captures it with Sentry.

Note that this is a contrived context using a Sentry client created for this test. You’ll want to write tests that use the Sentry client configured for your application and handling events kicked up from different points in your application to make sure that Sentry events are getting scrubbed correctly.

See Fillmore documentation for explanation and examples.

Why this? Why not other libraries?

Other libraries:

  • Have an awkward API that is hard to reason about.

    I’m not scrubbing Sentry events for fun. I need to be able to write scrubbing configuration that is exceptionally clear about what it is and isn’t doing.

  • Don’t covers large portions of the Sentry event structure.

    I need scrubbers that cover the entire event structure as well as some of the curious cases like the fact that cookie information shows up twice and can be encoded as a string.

  • Aren’t resilient.

    The scrubber is running in the context of Sentry reporting an error. If it also errors out, then you can end up in situations where you never see errors and have no signal that something is horribly wrong. We need scrubbing code to be extremely resilient and default to emitting a signal that it’s broken.

  • Don’t include testing infrastructure.

    I’m not scrubbing Sentry events for fun. I need to know that the scrubbing code is working correctly and that it continues to work as we upgrade Python, sentry_sdk, and other things.

    Having testing infrastructure for making this easier is really important.

Metadata

Release files for fillmore 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fillmore 2.2.0
File Size Uploaded
fillmore-2.2.0.tar.gz 38.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fillmore 2.2.0
File Interpreter ABI Platform
fillmore-2.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 56.4 kB

Release files / fillmore-2.2.0.tar.gz

Download URL fillmore-2.2.0.tar.gz
Size 38.1 kB
Tags Source
SHA-256 checksum
How to use checksums
87a0d60cfc0dab35f9ab42c5fe89079af5d26c4c61bac2fc989b64cc7fad1a82
BLAKE2b-256 checksum
How to use checksums
c595fdefe0896729ad93014e0adc165e24292f9dfff7bdff9e5715cd9a7212ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.14

Release files / fillmore-2.2.0-py3-none-any.whl

Download URL fillmore-2.2.0-py3-none-any.whl
Size 18.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2dc8912e335e4b23265d6d80fbfe50f090a32782a64624352bf92e43b5dbac02
BLAKE2b-256 checksum
How to use checksums
551dc07ecd17bdc988f77b416f69f1a7007a7860b1dff4dfcb9275f78100dd17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.14
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page