Honeybadger-Extensions

Honeybadger extension that can log exceptions raised by Flask or Celery, adding more context than the original honeybadger python library.


License
MIT
Install
pip install Honeybadger-Extensions==0.1.2

Documentation

Honeybadger-Extensions

CircleCI

Honeybadger-Extensions extend current Honeybadger Python library to better support Celery & Flask. It offers:

  • Improved reporting, including details for component, action etc.
  • Easier Honeybadger via Flask's or Celery's configuration object.
  • (Optional) Automatic reporting of errors detected by Celery or Flask.

Installation

The easiest way to install it is using pip from PyPI

pip install Honeybadger-Extensions

Celery Usage

Honeybadger-Extensions provides the install_celery_handler() function which can be used to initialize both Honeybadger & the Celery extensions. The arguments to this function are:

  • config: a dict-like object to use for configuring Honeybadger.
  • context_generators: allows adding dynamically context on each call to honeybadger.notify. It should be a dictionary, with key the name of the context variable to use and value a lambda or callable that generates the value.
  • report_exceptions: boolean, whether to report exceptions raised by tasks. False by default. Uses task_failure signal to detect failures.

Hint: You can reuse configuration properties from celery's configuration object.

Hint: It's a good idea to initialize honeybadger as soon as possible in order to catch errors while initializing celery

The following conventions are used for reporting:

  • component: The module that the task is defined in is used.
  • action: The name of the task is used.
  • params: A dictionary containing args and kwargs passed to the task.
  • cgi_data: Task ID, current retry and max retries are added as values.

Example: Setup Honeybadger and automatically report exceptions

The following example will setup Honeybadger and automatically report exceptions raised by the tasks.

It will also add component, action, params, cgi_data and context (as generated by context generators) to all errors sent using honeybadger.notify().

from celery import Celery
from honeybadger_extensions import install_celery_handler

celery = Celery(__name__)
celery.config_from_object({
    'HONEYBADGER_API_KEY': '<your key>',
    'HONEYBADGER_ENVIRONMENT': 'development'
})

install_celery_handler(config=celery.conf, report_exceptions=True)

[...]

@celery.task
def mytask():
    [...]
    try:
        # Do something dangerous
        [...]
    except Exception as e:
        honeybadger.notify(e) # Additional info will be added!

Flask usage

A Flask extension is available for initializing and configuring Honeybadger: honeybadger_extensions.HoneybadgerFlask. The extensions add the following information:

  • url: The URL the request was sent to.
  • component: The module that the view is defined at. If the view is a class-based view, then the name of the class is also added.
  • action: The name of the function called. If the action is defined within a blueprint, then the action name will have the name of the blueprint prefixed.
  • params: A dictionary containing query parameters and form data. If a variable is defined in both, then the form data are stored. Params are filtered (see Configuration).
  • session: Session data, filtered (see Configuration).
  • cgi_data: Request headers, filtered (see Configuration).

Let's see it in action with an example:

Example 1: Setup Honeybadger and automatically report exceptions

    from flask import Flask, jsonify
    from honeybadger_extensions import HoneybadgerFlask

    app = Flask(__name__)
    app.config['HONEYBADGER_ENVIRONMENT'] = 'development'
    app.config['HONEYBADGER_API_KEY'] = '<your key>'
    app.config['HONEYBADGER_EXCLUDE_HEADERS'] = 'Authorization, Proxy-Authorization, X-Custom-Key'
    app.config['HONEYBADGER_PARAMS_FILTERS'] = 'password, secret, credit-card'
    HoneybadgerFlask(app, report_exceptions=True)

    @app.route('/')
    def index():
        a = int(request.args.get('a'))
        b = int(request.args.get('b'))

        logger.info('Dividing two numbers {} {}'.format(a, b))
        return jsonify({'result': a / b})

[...]

The code above will:

  • Initialize honeybadger using provided configuration.
  • Listen for exceptions.
  • Log unhandled exceptions to Honeybadger.
  • It will also add url, component, action, params, cgi_data and context (as generated by context generators) to all errors send using honeybadger.notify().

You can get an error by passing 0 as argument b. The logged action will be index.

Note: Using report_exceptions=True will result in recording all exceptions thrown by your view functions, including HTTPError's raised by calls to abort methods.

Note: HoneybadgerFlask uses got_request_exception signal to detect errors. If you don't see some errors, check if an errorhandler handles it before raising an error.

Example 2: Setup Honeybadger with dynamic context

from flask import Flask
from flask.views import MethodView
from honeybadger_extensions import HoneybadgerFlask

app = Flask(__name__)
app.config['HONEYBADGER_ENVIRONMENT'] = 'development'
app.config['HONEYBADGER_API_KEY'] = '<your key>'
app.config['HONEYBADGER_EXCLUDE_HEADERS'] = 'Authorization, Proxy-Authorization, X-Custom-Key'
app.config['HONEYBADGER_PARAMS_FILTERS'] = 'password, secret, credit-card'
HoneybadgerFlask(app, context_generators={
    'request-id': lambda: request.headers.get('X-Request-ID')
})

[...]

Application app will:

  • Initialize honeybadger using provided configuration.
  • It will NOT listen for exceptions
  • Everything logged to Honeybadger will contain request-id in the context, with value the value of HTTP header X-Request-ID

More examples

You can find more examples under examples directory.

Configuration

The following parameters can be configured through Flask's configuration system:

Configuration Name Description
HONEYBADGER_API_KEY Honeybadger's API key. If it's not present, honeybadger won't be initialized.
HONEYBADGER_ENVIRONMENT The name of the environment to use in honeybadger.
HONEYBADGER_EXCLUDE_HEADERS Flask only! Headers to exclude from logging. If this variable is not configured, then Authorization and Proxy-Authorization headers are the default.
HONEYBADGER_PARAMS_FILTERS Flask only! Parameters from query string, form post or session to exclude. Replaces them with string [FILTERED].

License

See the LICENSE file for license rights and limitations (MIT).