How to set up Sentry for Tornado applications

In this article, I'll show you how I set up Sentry for my Tornado projects.

Please install Sentry before proceeding.

Basic setup

This is a basic setup for quickly testing things out to ensure it works as expected.

However, ideally you will not want to run Sentry while you're developing your app in debug mode. See the next for running Sentry in production mode.

The code is full of comments which will, hopefully, explain things.

# app.py

def setup_sentry():
    """Function for setting up sentry.

    We keep all the sentry related imports local to this function
    so that they are only imported when we actually want to set up
    sentry such as in production mode.
    """
    import sentry_sdk
    from sentry_sdk.integrations.tornado import TornadoIntegration

    sentry_sdk.init(
        dsn='<your-sentry-dsn>',
        integrations=[TornadoIntegration()],
        ignore_errors=[KeyboardInterrupt], # don't report KeyboardInterrupt error 
                                           # (raised when stopping server with Ctrl+C)
        traces_sample_rate=0, # turn off performance monitoring
                              # set this option per your needs
        send_default_pii=True, # include personally identifiable information
                               # set this option per your needs
    )


if __name__ == '__main__':
    setup_sentry()

    # ...
    # rest of the code for running the app remains the same
    # ...
    # app.listen(888)
    # ioloop.IOLoop.current().start()

Sentry has a lot more options for error reporting. You should go through their docs to learn about them and configure them as per your project's requirements.

Setup for production mode

Ideally, you only want to run Sentry in production mode.

Tornado comes with a command line utility which can be used to create custom command line options for your application.

We'll define a debug option for our app. When this debug option is True (that means not in production mode), we will not set up Sentry.

When debug is False (that means running in production mode), we will set up Sentry.

# app.py

from tornado import options

# Define command line options
options.define('debug', default=True, help='Debug mode')


def setup_sentry():
    ...
    # same as in previous example
    ...


if __name__ == '__main__':
    options.parse_command_line() # parse command line options

    if options.options.debug == False:
        setup_sentry()

    # ...

Now to run your app in production mode, all you have to do is pass the debug option in the command:

$ python app.py --debug=False

Logging

Apart from automatic error reporting, you can also use Tornado's built-in loggers to log custom messages. Sentry will pick these up too and notify you as they happen.

You can do it like this:

from tornado.log import app_log

app_log.error("Something bad happened")

try:
    1/0
except:
    app_log.exception("Exception happened")

Bonus tips

Here are a few bonus tips about using command line options.

Tip #1: You can use the debug command line option to pass to your app's debug setting instead of hard-coding a value:

web.Application(
    r'/', IndexHandler,
    ...
    debug=options.options.debug,
)

Tip #2: You can also define an option for your app's port:

options.define('port', default=888, help='Port to listen on')


if __name__ == '__main__':
    ...
    app.listen(options.options.port)
    ...

Then you can pass a value of the port directly from the command line:

$ python app.py --port=9999

What do you think?

Did you like this article? Comment below and let me know your opinions. If you have any suggestions, better ideas or improvements, I'd love to know them.