Python

Documentation - Raygun4Python - Python Error Tracking & Reporting

The Raygun4py provider can send uncaught exceptions by creating a handler and attaching it to sys.excepthook, or automatically by adding the built-in logger. It also supports manual sending from except blocks. It only takes a few minutes to set up so you can start real time error monitoring and crash reporting from your Python applications quickly and easily.

Contents

Setup Instructions

Requirements

Raygun4py is known to work with Python 2.6-2.7, Python 3.1+ and PyPy environments.

It requires the socket module to be build with SSL support.

Installation

Grab the module with pip:

pip install raygun4py

Then include and instantiate it:

from raygun4py import raygunprovider

client = raygunprovider.RaygunSender('your_apikey')

Test the installation

From the command line, run:

$ raygun4py test your_apikey

Replace your_apikey with the one listed on your Raygun dashboard. This will cause a test exception to be generated and sent.

Usage

Automatically send the current exception like this:

try:
    raise Exception("foo")
except:
    client.send_exception()

See sending functions for more ways to send.

Uncaught exception handler

To automatically pick up unhandled exceptions with custom logic, you can provide a callback function to sys.excepthook:

def handle_exception(exc_type, exc_value, exc_traceback):
    sender = raygunprovider.RaygunSender("your_apikey")
    sender.send_exception(exc_info=(exc_type, exc_value, exc_traceback))

sys.excepthook = handle_exception

Logging

You can also send exceptions using a logger:

logger = logging.getLogger("mylogger")
rgHandler = raygunprovider.RaygunHandler("your_apikey")
logger.addHandler(rgHandler)

def log_exception(exc_type, exc_value, exc_traceback):
    logger.error("An exception occurred", exc_info = (exc_type, exc_value, exc_traceback))

sys.excepthook = log_exception

This uses the built-in RaygunHandler. You can provide your own handler implementation based on that class if you need custom sending behavior.

Web frameworks

Raygun4py includes dedicated middleware implementations for Django and Flask, as well as generic WSGI frameworks (Tornado, Bottle, Ginkgo etc). These are available for both Python 2.6/2.7 and Python 3+.

Django

To configure Django to automatically send all exceptions that are raised in views to Raygun:

settings.py

MIDDLEWARE_CLASSES = (
    'raygun4py.middleware.django.Provider'
)

RAYGUN4PY_CONFIG = {
    'api_key': 'paste_your_api_key_here'
}

The above configuration is the minimal required setup. The full set of options supported by the provider can be declared in the same way:

RAYGUN4PY_CONFIG = {
    'api_key': 'paste_your_api_key_here',
    'http_timeout': 10.0,
    'proxy': None,
    'before_send_callback': None,
    'grouping_key_callback': None,
    'filtered_keys': [],
    'ignored_exceptions': [],
    'transmit_global_variables': True,
    'transmit_local_variables': True,
    'userversion': "Not defined",
    'user': None
}

Flask

from flask import Flask, current_app
from raygun4py.middleware import flask

app = Flask(__name__)

flask.Provider(app, 'your_apikey').attach()

WSGI

An example using Tornado, which will pick up exceptions that occur in the WSGI pipeline:

from raygun4py.middleware import wsgi

class MainHandler(tornado.web.RequestHandler):

  def initialize(self):
      raise Exception('init')

def main():
  settings = {
      'default_handler_class': MainHandler
  }

  application = tornado.web.Application([
      (r"/", MainHandler),
  ], **settings)

  wsgiapp = tornado.wsgi.WSGIAdapter(application)
  raygun_wrapped_app = wsgi.Provider(wsgiapp, 'your_apikey')
  server = wsgiref.simple_server.make_server('', 8888, raygun_wrapped_app)
  server.serve_forever()

Note that many frameworks (tornado, pryramid, gevent et al) will swallow exceptions that occur within their domain.

Attaching raw HTTP request data

If you are in a web server environment and have HTTP request details available, you can pass these and the headers through in a dictionary (see sample.py in the GitHub repository). Code running on Google App Engine is supported - this requires a paid account due to required SSL support.

API

Initialization options

RaygunSender accepts a dict which is used to set options on the provider:

from raygun4py import raygunprovider

client = raygunprovider.RaygunSender('your_apikey', config={
    'http_timeout': 10.0,
    'proxy': None,
    'before_send_callback': None,
    'grouping_key_callback': None,
    'filtered_keys': [],
    'ignored_exceptions': [],
    'transmit_global_variables': True,
    'transmit_local_variables': True,
    'userversion': "Not defined",
    'user': None
})

For the local/global variables, if their options are set to False the corresponding variables will not be sent with exception payloads. http_timeout controls the maximum time the HTTP request can take when POSTing to the Raygun API, and is of type 'float'.

Sending functions

View the available public functions and their overloads to configure and interact with the provider:

Sending functions

  • send_exception - call this function to send an exception. Can automatically use the current exception in scope, or be provided with several overloads to manually send an Exception object. It can also accept extra data as arguments; the full signature is:
client.send_exception(exception=e, tags=[], userCustomData={}, request={})

where e is an Exception object, tags is an array of strings/numbers, userCustomData is a Dict with values of strings/numbers/dates, and request is a Dict for HTTP data.

Configuration and data functions

  • set_version - sets the version of your Python application (used for deployments and filtering in the Raygun dashboard)
  • set_user - sets the current logged-in end user (used to view who was affected by what exceptions, and to contact them in the Raygun dashboard)
  • filter_keys - remove sensitive data from the payload before it is transmitted to Raygun by providing a list of keys to filter by
  • ignore_exceptions - blacklist certain Exception types from being sent
  • on_before_send - you can provide a callback function here to mutate the candidate payload however you like immediately before it is sent
  • on_grouping_key - pass a callback function to this method to configure custom grouping logic. The callback should take one parameter, an instance of RaygunMessage, and return a string between 1 and 100 characters in length (see 'Custom Grouping Logic' below for more details).
  • set_proxy - tunnel the connection to the Raygun API through a proxy

Features

Custom grouping logic

You can create custom exception grouping logic that overrides the automatic Raygun grouping by passing in a function that accepts one parameter using this function. The callback's one parameter is an instance of RaygunMessage (python[2/3]/raygunmsgs.py), and the callback should return a string. The RaygunMessage instance contains all the error and state data that is about to be sent to the Raygun API. In your callback you can inspect this RaygunMessage, hash together the fields you want to group by, then return a string which is the grouping key.

This string needs to be between 1 and 100 characters long. If the callback is not set or the string isn't valid, the default automatic grouping will be used. By example:

class MyClass(object):

    def my_callback(self, raygun_message):
        return raygun_message.get_error().message[:100] # Use naive message-based grouping only

    def create_raygun_and_bind_callback(self):
        sender = raygunprovider.RaygunSender('api_key')
        sender.on_grouping_key(self.my_callback)

The RaygunSender above will use the my_callback to execute custom grouping logic when an exception is raised. The above logic will use the exception message only - you'll want to use a more sophisticated approach, usually involving sanitizing or ignoring data.

Chained exceptions

For Python 3, chained exceptions are now supported and automatically sent along with their traceback.

This occurs when an exception is raised while handling another exception - see tests_functional.py for an example.

Local, global and environment variables

Raygun4py can automatically send the names of all variables that are in scope and their values if these options are set. Local variables will send the variable state for each stack frame, and global variables will transmit the state of all variables in global scope. System environment variables are also sent. See Initialization Options above if you wish to disable this.

Raygun4py GitHub Repository

Visit the raygun4py GitHub repository to view the code. Like all our providers, it is available under the MIT license.

Documentation missing?

If we don't have documentation about your desired topic, send us a message and we'll create it for you.