diff --git a/.gitignore b/.gitignore index 01c9c77d..267294f0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,8 +13,7 @@ pip-log.txt /cover /dist /example_project/local_settings.py -/docs/html -/docs/doctrees +/docs/_build /sentry_index/ /sentry_test_index /example_project/*.db diff --git a/docs/Makefile b/docs/Makefile index ed016ccb..1db8f3cd 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -5,7 +5,7 @@ SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = -BUILDDIR = ./ +BUILDDIR = ./_build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 00000000..8b3fabb5 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,122 @@ +API Reference +============= + +.. default-domain:: py + +This gives you an overview of the public API that raven-python exposes. + + +Client +------ + +.. py:class:: raven.Client(dsn=None, **kwargs) + + The client needs to be instanciated once and can then be used for + submitting events to the Sentry server. For information about the + configuration of that client and which parameters are accepted see + :ref:`python-client-config`. + + .. py:method:: capture(event_type, data=None, date=None, \ + time_spent=None, extra=None, stack=False, tags=None, **kwargs) + + This method is the low-level method for reporting events to + Sentry. It captures and processes an event and pipes it via the + configured transport to Sentry. + + Example:: + + capture('raven.events.Message', message='foo', data={ + 'request': { + 'url': '...', + 'data': {}, + 'query_string': '...', + 'method': 'POST', + }, + 'logger': 'logger.name', + }, extra={ + 'key': 'value', + }) + + :param event_type: the module path to the Event class. Builtins can + use shorthand class notation and exclude the + full module path. + :param data: the data base, useful for specifying structured data + interfaces. Any key which contains a '.' will be + assumed to be a data interface. + :param date: the datetime of this event. If not supplied the + current timestamp is used. + :param time_spent: a integer value representing the duration of the + event (in milliseconds) + :param extra: a dictionary of additional standard metadata. + :param stack: If set to `True` a stack frame is recorded together + with the event. + :param tags: list of extra tags + :param kwargs: extra keyword arguments are handled specific to the + reported event type. + :return: a tuple with a 32-length string identifying this event + + .. py:method:: captureMessage(message, **kwargs) + + This is a shorthand to reporting a message via :meth:`capture`. + It passes ``'raven.events.Message'`` as `event_type` and the + message along. All other keyword arguments are regularly + forwarded. + + Example:: + + client.captureMessage('This just happened!') + + .. py:method:: captureException(message, exc_info=None, **kwargs) + + This is a shorthand to reporting an exception via :meth:`capture`. + It passes ``'raven.events.Exception'`` as `event_type` and the + traceback along. All other keyword arguments are regularly + forwarded. + + If exc_info is not provided, or is set to True, then this method + will perform the ``exc_info = sys.exc_info()`` and the requisite + clean-up for you. + + Example:: + + try: + 1 / 0 + except Exception: + client.captureException() + + .. py:method:: send(**data) + + Accepts all data parameters and serializes them, then sends then + onwards via the transport to Sentry. This can be used as to send + low-level protocol data to the server. + + .. py:attribute:: context + + Returns a reference to the thread local context object. See + :py:class:`raven.context.Context` for more information. + +Context +------- + +.. py:class:: raven.context.Context() + + The context object works similar to a dictionary and is used to record + information that should be submitted with events automatically. It is + available through :py:attr:`raven.Client.context` and is thread local. + This means that you can modify this object over time to feed it with + more appropriate information. + + .. py:method:: merge(data) + + Performs a merge of the current data in the context and the new + data provided. + + .. py:method:: clear() + + Clears the context. It's important that you make sure to call + this when you reuse the thread for something else. For instance + for web frameworks it's generally a good idea to call this at the + end of the HTTP request. + + Otherwise you run at risk of seeing incorrect information after + the first use of the thread. diff --git a/docs/changelog/index.rst b/docs/changelog/index.rst deleted file mode 100644 index f8b67d62..00000000 --- a/docs/changelog/index.rst +++ /dev/null @@ -1,4 +0,0 @@ -Changelog -========= - -.. include:: ../../CHANGES diff --git a/docs/config.rst b/docs/config.rst new file mode 100644 index 00000000..27975e18 --- /dev/null +++ b/docs/config.rst @@ -0,0 +1,204 @@ +Configuration +============= + +.. default-domain:: py + +This document describes configuration options available to the Raven +client for the use with Sentry. It also covers some other important parts +about configuring the environment. + + +.. _python-client-config: + +Configuring the Client +---------------------- + +Settings are specified as part of the initialization of the client. The +client is a class that can be instanciated with a specific configuration +and all reporting can then happen from the instance of that object. +Typically an instance is created somewhere globally and then imported as +necessary. + +As of Raven 1.2.0, you can now configure all clients through a standard DSN +string. This can be specified as a default using the ``SENTRY_DSN`` environment +variable, as well as passed to all clients by using the ``dsn`` argument. + +.. code-block:: python + + from raven import Client + + # Read configuration from the environment + client = Client() + + # Manually specify a DSN + client = Client('___DSN___') + + +A reasonably configured client should generally include a few additional +settings: + +.. code-block:: python + + import raven + + client = raven.Client( + dsn='___DSN___' + + # inform the client which parts of code are yours + # include_paths=['my.app'] + include_paths=[__name__.split('.', 1)[0]], + + # pass along the version of your application + # release='1.0.0' + # release=raven.fetch_package_version('my-app') + release=raven.fetch_git_sha(os.path.dirname(__file__)), + ) + +.. versionadded:: 5.2.0 + The *fetch_package_version* and *fetch_git_sha* helpers. + + +The Sentry DSN +-------------- + +.. sentry:edition:: hosted, on-premise + + The most important information is the Sentry DSN. For information + about it see :ref:`configure-the-dsn` in the general Sentry docs. + +The Python client supports one additional modification to the regular DSN +values which is the choice of the transport. To select a specific +transport, the DSN needs to be prepended with the name of the transport. +For instance to select the ``gevent`` transport, the following DSN would +be used:: + + 'gevent+___DSN___' + +For more information see :doc:`transports`. + +Client Arguments +---------------- + +The following are valid arguments which may be passed to the Raven client: + +.. describe:: dsn + + A Sentry compatible DSN as mentioned before:: + + dsn = '___DSN___' + +.. describe:: site + + An optional, arbitrary string to identify this client installation:: + + site = 'my site name' + +.. describe:: name + + This will override the ``server_name`` value for this installation. + Defaults to ``socket.gethostname()``:: + + name = 'sentry_rocks_' + socket.gethostname() + +.. describe:: release + + The version of your application. This will map up into a Release in + Sentry:: + + release = '1.0.3' + +.. describe:: exclude_paths + + Extending this allow you to ignore module prefixes when we attempt to + discover which function an error comes from (typically a view):: + + exclude_paths = [ + 'django', + 'sentry', + 'raven', + 'lxml.objectify', + ] + +.. describe:: include_paths + + For example, in Django this defaults to your list of ``INSTALLED_APPS``, + and is used for drilling down where an exception is located:: + + include_paths = [ + 'django', + 'sentry', + 'raven', + 'lxml.objectify', + ] + +.. describe:: max_list_length + + The maximum number of items a list-like container should store. + + If an iterable is longer than the specified length, the left-most + elements up to length will be kept. + + .. note:: This affects sets as well, which are unordered. + + :: + + list_max_length = 50 + +.. describe:: string_max_length + + The maximum characters of a string that should be stored. + + If a string is longer than the given length, it will be truncated down + to the specified size:: + + string_max_length = 200 + +.. describe:: auto_log_stacks + + Should Raven automatically log frame stacks (including locals) for all + calls as it would for exceptions:: + + auto_log_stacks = True + +.. describe:: processors + + A list of processors to apply to events before sending them to the + Sentry server. Useful for sending additional global state data or + sanitizing data that you want to keep off of the server:: + + processors = ( + 'raven.processors.SanitizePasswordsProcessor', + ) + +Sanitizing Data +--------------- + +Several processors are included with Raven to assist in data +sanitiziation. These are configured with the ``processors`` value. + +.. data:: raven.processors.SanitizePasswordsProcessor + :noindex: + + Removes all keys which resemble ``password``, ``secret``, or + ``api_key`` within stacktrace contexts, HTTP bits (such as cookies, + POST data, the querystring, and environment), and extra data. + +.. data:: raven.processors.RemoveStackLocalsProcessor + :noindex: + + Removes all stacktrace context variables. This will cripple the + functionality of Sentry, as you'll only get raw tracebacks, but it will + ensure no local scoped information is available to the server. + +.. data:: raven.processors.RemovePostDataProcessor + :noindex: + + Removes the ``body`` of all HTTP data. + + +A Note on uWSGI +--------------- + +If you're using uWSGI you will need to add ``enable-threads`` to the +default invocation, or you will need to switch off of the threaded default +transport. diff --git a/docs/config/index.rst b/docs/config/index.rst deleted file mode 100644 index f71538dd..00000000 --- a/docs/config/index.rst +++ /dev/null @@ -1,247 +0,0 @@ -Configuration -============= - -This document describes configuration options available to Sentry. - - -Configuring the Client ----------------------- - -Settings are specified as part of the initialization of the client. - -As of Raven 1.2.0, you can now configure all clients through a standard DSN -string. This can be specified as a default using the ``SENTRY_DSN`` environment -variable, as well as passed to all clients by using the ``dsn`` argument. - -.. code-block:: python - - from raven import Client - - # Read configuration from the environment - client = Client() - - # Manually specify a DSN - client = Client('http://public:secret@example.com/1') - - -A reasonably configured client should generally include a few additional settings: - -.. code-block:: python - - import raven - - client = raven.Client( - dsn='http://public:secret@example.com/1' - - # inform the client which parts of code are yours - # include_paths=['my.app'] - include_paths=[__name__.split('.', 1)[0]], - - # pass along the version of your application - # release='1.0.0' - # release=raven.fetch_package_version('my-app') - release=raven.fetch_git_sha(os.path.dirname(__file__)), - ) - -.. versionadded:: 5.2.0 - The *fetch_package_version* and *fetch_git_sha* helpers. - - -The Sentry DSN --------------- - -The DSN can be found in Sentry by navigation to Account -> Projects -> [Project Name] -> [Member Name]. Its template resembles the following:: - - '{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}/{PATH}{PROJECT_ID}' - -It is composed of six important pieces: - -* The Protocol used. This can be one of the following: http or https. - -* The public and secret keys to authenticate the client. - -* The hostname of the Sentry server. - -* An optional path if Sentry is not located at the webserver root. This is specific to HTTP requests. - -* The project ID which the authenticated user is bound to. - - -Client Arguments ----------------- - -The following are valid arguments which may be passed to the Raven client: - -dsn -~~~ - -A sentry compatible DSN. - -:: - - dsn = 'http://public:secret@example.com/1' - -project -~~~~~~~ - -Set this to your Sentry project ID. The default value for installations is ``1``. - -:: - - project = 1 - - -public_key -~~~~~~~~~~ - -Set this to the public key of the project member which will authenticate as the -client. You can find this information on the member details page of your project -within Sentry. - -:: - - public_key = 'fb9f9e31ea4f40d48855c603f15a2aa4' - - -secret_key -~~~~~~~~~~ - -Set this to the secret key of the project member which will authenticate as the -client. You can find this information on the member details page of your project -within Sentry. - -:: - - secret_key = '6e968b3d8ba240fcb50072ad9cba0810' - -site -~~~~ - -An optional, arbitrary string to identify this client installation. - -:: - - site = 'my site name' - - -name -~~~~ - -This will override the ``server_name`` value for this installation. Defaults to ``socket.gethostname()``. - -:: - - name = 'sentry_rocks_' + socket.gethostname() - - -release -~~~~~~~~ - -The version of your application. This will map up into a Release in Sentry. - -:: - - release = '1.0.3' - - -exclude_paths -~~~~~~~~~~~~~ - -Extending this allow you to ignore module prefixes when we attempt to discover which function an error comes from (typically a view) - -:: - - exclude_paths = [ - 'django', - 'sentry', - 'raven', - 'lxml.objectify', - ] - -include_paths -~~~~~~~~~~~~~ - -For example, in Django this defaults to your list of ``INSTALLED_APPS``, and is used for drilling down where an exception is located - -:: - - include_paths = [ - 'django', - 'sentry', - 'raven', - 'lxml.objectify', - ] - -list_max_length -~~~~~~~~~~~~~~~ - -The maximum number of items a list-like container should store. - -If an iterable is longer than the specified length, the left-most elements up to length will be kept. - -.. note:: This affects sets as well, which are unordered. - -:: - - list_max_length = 50 - -string_max_length -~~~~~~~~~~~~~~~~~ - -The maximum characters of a string that should be stored. - -If a string is longer than the given length, it will be truncated down to the specified size. - -:: - - string_max_length = 200 - -auto_log_stacks -~~~~~~~~~~~~~~~ - -Should Raven automatically log frame stacks (including locals) for all calls as -it would for exceptions. - -:: - - auto_log_stacks = True - - -processors -~~~~~~~~~~ - -A list of processors to apply to events before sending them to the Sentry server. Useful for sending -additional global state data or sanitizing data that you want to keep off of the server. - -:: - - processors = ( - 'raven.processors.SanitizePasswordsProcessor', - ) - -Sanitizing Data ---------------- - -Several processors are included with Raven to assist in data sanitiziation. These are configured with the -``processors`` value. - -.. data:: raven.processors.SanitizePasswordsProcessor - - Removes all keys which resemble ``password``, ``secret``, or ``api_key`` - within stacktrace contexts, HTTP bits (such as cookies, POST data, - the querystring, and environment), and extra data. - -.. data:: raven.processors.RemoveStackLocalsProcessor - - Removes all stacktrace context variables. This will cripple the functionality of Sentry, as you'll only - get raw tracebacks, but it will ensure no local scoped information is available to the server. - -.. data:: raven.processors.RemovePostDataProcessor - - Removes the ``body`` of all HTTP data. - - -A Note on uWSGI ---------------- - -If you're using uWSGI you will need to add ``enable-threads`` to the default invocation, or you will need to switch off of the threaded transport. diff --git a/docs/contributing/index.rst b/docs/contributing.rst similarity index 100% rename from docs/contributing/index.rst rename to docs/contributing.rst diff --git a/docs/index.rst b/docs/index.rst index 21b7648a..19bb2c29 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,68 +1,74 @@ -raven-python -============ +.. sentry:edition:: self -Raven is a standalone (and the official) Python client for `Sentry `_. + Raven Python + ============ -This version of Raven requires Sentry 7.0 or newer. +.. sentry:edition:: hosted, on-premise -Users Guide ------------ + .. class:: platform-python + + Python + ====== + +Raven for Python (raven-python) is the official standalone Python client +for Sentry. It can be used with any modern Python interpreter be it +CPython 2.x or 3.x, PyPy or Jython. It's an Open Source project and +available under a very liberal BSD license. + +.. sentry:edition:: self + + Users Guide + ----------- .. toctree:: :maxdepth: 2 + :titlesonly: - install/index - config/index + installation + config usage integrations/index - transports/index + transports + platform-support + api -Developers ----------- +.. sentry:edition:: self -.. toctree:: - :maxdepth: 2 + For Developers + -------------- - contributing/index + .. toctree:: + :maxdepth: 2 + :titlesonly: -Reference ---------- + contributing -.. toctree:: - :maxdepth: 1 + Supported Platforms + ------------------- - changelog/index + - Python 2.6 + - Python 2.7 + - Python 3.2 + - Python 3.3 + - PyPy + - Google App Engine -Supported Platforms -------------------- + Deprecation Notes + ----------------- + + Milestones releases are 1.3 or 1.4, and our deprecation policy is to a two + version step. For example, a feature will be deprecated in 1.3, and + completely removed in 1.4. + + Resources + --------- -- Python 2.6 -- Python 2.7 -- Python 3.2 -- Python 3.3 -- PyPy -- Google App Engine +.. sentry:edition:: hosted, on-premise -About Sentry ------------- - -Sentry provides you with a generic interface to view and interact with your error logs. With this -it allows you to interact and view near real-time information to discover issues and more -easily trace them in your application. - -More information about Sentry can be found at http://www.getsentry.com/ - -Resources ---------- + Resources: * `Documentation `_ * `Bug Tracker `_ * `Code `_ * `Mailing List `_ * `IRC `_ (irc.freenode.net, #sentry) - -Deprecation Notes ------------------ - -Milestones releases are 1.3 or 1.4, and our deprecation policy is to a two version step. For example, -a feature will be deprecated in 1.3, and completely removed in 1.4. diff --git a/docs/install/index.rst b/docs/install/index.rst deleted file mode 100644 index b6af50a7..00000000 --- a/docs/install/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -Install -======= - -If you haven't already, start by downloading Raven. The easiest way is with **pip**:: - - pip install raven --upgrade - -Or with *setuptools*:: - - easy_install -U raven - -Requirements ------------- - -If you installed using pip or setuptools you shouldn't need to worry about requirements. Otherwise -you will need to install the following packages in your environment: - - - ``simplejson`` diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 00000000..d0449709 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,25 @@ +Installation +============ + +If you haven't already, start by downloading Raven. The easiest way is +with *pip*:: + + pip install raven --upgrade + +Or alternatively with *setuptools*:: + + easy_install -U raven + +If you want to use the latest git version you can get it from `the github +repository `_:: + + git clone https://github.com/getsentry/raven-python + pip install raven-python + +Certain additional features can be installed by defining the feature when +``pip`` installing it. For instance to install all dependencies needed to +use the Flask integration, you can depend on ``raven[flask]``:: + + pip install raven[flask] + +For more information refer to the individual integration documentation. diff --git a/docs/integrations/bottle.rst b/docs/integrations/bottle.rst index ae1fd50b..3b1a4871 100644 --- a/docs/integrations/bottle.rst +++ b/docs/integrations/bottle.rst @@ -1,6 +1,9 @@ Bottle ====== +`Bottle `_ is a microframework for Python. Raven +supports this framework through the WSGI integration. + Setup ----- @@ -11,11 +14,14 @@ The first thing you'll need to do is to disable catchall in your Bottle app:: app = bottle.app() app.catchall = False -.. note:: Bottle will not propagate exceptions to the underlying WSGI middleware by default. Setting catchall to False disables that. +.. note:: Bottle will not propagate exceptions to the underlying WSGI + middleware by default. Setting catchall to False disables that. -Sentry will act as Middleware:: +Sentry will then act as Middleware:: + from raven import Client from raven.contrib.bottle import Sentry + client = Client('___DSN___') app = Sentry(app, client) Usage @@ -25,15 +31,16 @@ Once you've configured the Sentry application you need only call run with it:: run(app=app) -If you want to send additional events, a couple of shortcuts are provided on the Bottle request app object. +If you want to send additional events, a couple of shortcuts are provided +on the Bottle request app object. Capture an arbitrary exception by calling ``captureException``:: - >>> try: - >>> 1 / 0 - >>> except ZeroDivisionError: - >>> request.app.sentry.captureException() + try: + 1 / 0 + except ZeroDivisionError: + request.app.sentry.captureException() Log a generic message with ``captureMessage``:: - >>> request.app.sentry.captureMessage('hello, world!') + request.app.sentry.captureMessage('Hello, world!') diff --git a/docs/integrations/celery.rst b/docs/integrations/celery.rst index c6865e43..052d34a6 100644 --- a/docs/integrations/celery.rst +++ b/docs/integrations/celery.rst @@ -1,14 +1,17 @@ Celery ====== -tl;dr register a couple of signals to hijack Celery error handling +`Celery `_ is a distributed task queue +system for Python built on AMQP principles. For Celery built-in support +by Raven is provided but it requires some manual configuraiton. -.. code-block:: python +To capture errors, you need to register a couple of signals to hijack +Celery error handling:: from raven import Client from raven.contrib.celery import register_signal, register_logger_signal - client = Client() + client = Client('___DSN___') # register a custom filter to filter out duplicate logs register_logger_signal(client) @@ -26,13 +29,13 @@ A more complex version to encapsulate behavior: .. code-block:: python import celery + import raven + from raven.contrib.celery import register_signal, register_logger_signal class Celery(celery.Celery): - def on_configure(self): - import raven - from raven.contrib.celery import register_signal, register_logger_signal - client = raven.Client() + def on_configure(self): + client = raven.Client('___DSN___') # register a custom filter to filter out duplicate logs register_logger_signal(client) diff --git a/docs/integrations/django.rst b/docs/integrations/django.rst index 96ea0e81..55baf35c 100644 --- a/docs/integrations/django.rst +++ b/docs/integrations/django.rst @@ -1,27 +1,35 @@ Django ====== -Support -------- +.. default-domain:: py -While older versions of Django will likely work, officially only version 1.4 and newer are supported. +`Django `_ is one of (if not the) Python's most +popular web frameworks. Support is built into Raven but needs some +configuration. While older versions of Django will likely work, +officially only version 1.4 and newer are supported. Setup ----- -Using the Django integration is as simple as adding :mod:`raven.contrib.django.raven_compat` to your installed apps:: +Using the Django integration is as simple as adding +:mod:`raven.contrib.django.raven_compat` to your installed apps:: INSTALLED_APPS = ( 'raven.contrib.django.raven_compat', ) -.. note:: This causes Raven to install a hook in Django that will automatically report uncaught exceptions. +.. note:: This causes Raven to install a hook in Django that will + automatically report uncaught exceptions. -Additional settings for the client are configured using the ``RAVEN_CONFIG`` dictionary:: +Additional settings for the client are configured using the +``RAVEN_CONFIG`` dictionary:: import raven + RAVEN_CONFIG = { - 'dsn': 'http://public:secret@example.com/1', + 'dsn': '___DSN___', + # If you are using git, you can also automatically configure the + # release based on the git info. 'release': raven.fetch_git_sha(os.path.dirname(__file__)), } @@ -40,27 +48,38 @@ You'll be referencing the client slightly differently in Django as well:: Using with Raven.js ------------------- -A Django template tag is provided to render a proper public DSN inside your templates, you must first load ``raven``:: +A Django template tag is provided to render a proper public DSN inside +your templates, you must first load ``raven``: + +.. sourcecode:: django {% load raven %} -Inside your template, you can now use:: +Inside your template, you can now use: + +.. sourcecode:: html+django -By default, the DSN is generated in a protocol relative fashion, e.g. ``//public@example.com/1``. If you need a specific protocol, you can override:: +By default, the DSN is generated in a protocol relative fashion, e.g. +``//public@example.com/1``. If you need a specific protocol, you can +override: + +.. sourcecode:: html+django {% sentry_public_dsn 'https' %} -See `Raven.js documentation `_ for more information. +.. sentry:edition:: hosted, on-premise + + See the :doc:`Raven.js documentation <../../../clients/javascript/index>` + for more information. Integration with :mod:`logging` ------------------------------- -To integrate with the standard library's :mod:`logging` module: - -:: +To integrate with the standard library's :mod:`logging` module the +following config can be used:: LOGGING = { 'version': 1, @@ -71,7 +90,8 @@ To integrate with the standard library's :mod:`logging` module: }, 'formatters': { 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' + 'format': '%(levelname)s %(asctime)s %(module)s ' + '%(process)d %(thread)d %(message)s' }, }, 'handlers': { @@ -136,8 +156,8 @@ Message References Sentry supports sending a message ID to your clients so that they can be tracked easily by your development team. There are two ways to access this -information, the first is via the ``X-Sentry-ID`` HTTP response header. Adding -this is as simple as appending a middleware to your stack:: +information, the first is via the ``X-Sentry-ID`` HTTP response header. +Adding this is as simple as appending a middleware to your stack:: MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ( # We recommend putting this as high in the chain as possible @@ -146,25 +166,24 @@ this is as simple as appending a middleware to your stack:: ) Another alternative method is rendering it within a template. By default, -Sentry will attach :attr:`request.sentry` when it catches a Django exception. -In our example, we will use this information to modify the default -:file:`500.html` which is rendered, and show the user a case reference ID. The -first step in doing this is creating a custom :func:`handler500` in your -:file:`urls.py` file:: +Sentry will attach :attr:`request.sentry` when it catches a Django +exception. In our example, we will use this information to modify the +default :file:`500.html` which is rendered, and show the user a case +reference ID. The first step in doing this is creating a custom +:func:`handler500` in your :file:`urls.py` file:: from django.conf.urls.defaults import * from django.views.defaults import page_not_found, server_error + from django.template import Context, loader + from django.http import HttpResponseServerError def handler500(request): - """ - 500 error handler which includes ``request`` in the context. + """500 error handler which includes ``request`` in the context. Templates: `500.html` Context: None """ - from django.template import Context, loader - from django.http import HttpResponseServerError t = loader.get_template('500.html') # You need to create a 500.html template. return HttpResponseServerError(t.render(Context({ @@ -174,11 +193,12 @@ first step in doing this is creating a custom :func:`handler500` in your Once we've successfully added the :data:`request` context variable, adding the Sentry reference ID to our :file:`500.html` is simple: -.. code-block:: django +.. sourcecode:: html+django

You've encountered an error, oh noes!

{% if request.sentry.id %} -

If you need assistance, you may reference this error as {{ request.sentry.id }}.

+

If you need assistance, you may reference this error as + {{ request.sentry.id }}.

{% endif %} WSGI Middleware @@ -197,30 +217,31 @@ level of your Django application:: Additional Settings ------------------- -SENTRY_CLIENT -~~~~~~~~~~~~~~ +.. describe:: SENTRY_CLIENT -In some situations you may wish for a slightly different behavior to how Sentry -communicates with your server. For this, Raven allows you to specify a custom -client:: + In some situations you may wish for a slightly different behavior to + how Sentry communicates with your server. For this, Raven allows you + to specify a custom client:: - SENTRY_CLIENT = 'raven.contrib.django.raven_compat.DjangoClient' + SENTRY_CLIENT = 'raven.contrib.django.raven_compat.DjangoClient' -SENTRY_CELERY_LOGLEVEL -~~~~~~~~~~~~~~~~~~~~~~ +.. describe:: SENTRY_CELERY_LOGLEVEL -If you are also using Celery, there is a handler being automatically registered -for you that captures the errors from workers. The default logging level for -that handler is ``logging.ERROR`` and can be customized using this setting:: + If you are also using Celery, there is a handler being automatically + registered for you that captures the errors from workers. The default + logging level for that handler is ``logging.ERROR`` and can be + customized using this setting:: - SENTRY_CELERY_LOGLEVEL = logging.INFO - RAVEN_CONFIG = { - 'CELERY_LOGLEVEL': logging.INFO - } + SENTRY_CELERY_LOGLEVEL = logging.INFO + RAVEN_CONFIG = { + 'CELERY_LOGLEVEL': logging.INFO + } Caveats ------- +The following things you should keep in mind when using Raven with Django. + Error Handling Middleware ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -238,6 +259,7 @@ To work around this, you can either disable your error handling middleware, or add something like the following:: from django.core.signals import got_request_exception + class MyMiddleware(object): def process_exception(self, request, exception): # Make sure the exception signal is fired for Sentry @@ -253,6 +275,7 @@ response codes. Or, alternatively, you can just enable Sentry responses:: from raven.contrib.django.raven_compat.models import sentry_exception_handler + class MyMiddleware(object): def process_exception(self, request, exception): # Make sure the exception signal is fired for Sentry @@ -263,12 +286,14 @@ Or, alternatively, you can just enable Sentry responses:: Gunicorn ~~~~~~~~ -If you are running Django with `gunicorn `_ and using the -``gunicorn`` executable, instead of the ``run_gunicorn`` management command, you -will need to add a hook to gunicorn to activate Raven:: +If you are running Django with `gunicorn `_ and +using the ``gunicorn`` executable, instead of the ``run_gunicorn`` +management command, you will need to add a hook to gunicorn to activate +Raven:: + + from django.core.management import call_command def when_ready(server): - from django.core.management import call_command call_command('validate') Circus @@ -278,20 +303,22 @@ If you are running Django with `circus `_ and `chaussette `_ you will also need to add a hook to circus to activate Raven:: + from django.conf import settings + from django.core.management import call_command + def run_raven(*args, **kwargs): """Set up raven for django by running a django command. It is necessary because chaussette doesn't run a django command. - """ - from django.conf import settings - from django.core.management import call_command if not settings.configured: settings.configure() call_command('validate') return True -And in your circus configuration:: +And in your circus configuration: + +.. sourcecode:: ini [socket:dwebapp] host = 127.0.0.1 @@ -302,4 +329,3 @@ And in your circus configuration:: use_sockets = True numprocesses = 2 hooks.after_start = dproject.hooks.run_raven - diff --git a/docs/integrations/flask.rst b/docs/integrations/flask.rst index 1fab91d7..b2c95e19 100644 --- a/docs/integrations/flask.rst +++ b/docs/integrations/flask.rst @@ -1,10 +1,14 @@ Flask ===== +`Flask `_ is a popular Python micro webframework. +Support for Flask is provided by Raven directly but for some dependencies +you need to install raven with the flask feature set. + Installation ------------ -If you haven't already, install raven with its explicit Flask dependencies: +If you haven't already, install raven with its explicit Flask dependencies:: pip install raven[flask] @@ -14,10 +18,13 @@ Setup The first thing you'll need to do is to initialize Raven under your application:: from raven.contrib.flask import Sentry - sentry = Sentry(app, dsn='http://public_key:secret_key@example.com/1') + sentry = Sentry(app, dsn='___DSN___') -If you don't specify the ``dsn`` value, we will attempt to read it from your environment under -the ``SENTRY_DSN`` key. +If you don't specify the ``dsn`` value, we will attempt to read it from +your environment under the ``SENTRY_DSN`` key. + +Extended Setup +-------------- You can optionally configure logging too:: @@ -44,25 +51,36 @@ You can pass parameters in the ``init_app`` hook:: logging=True, level=logging.ERROR) return app - Settings -------- -Additional settings for the client can be configured using ``SENTRY_`` in your application's configuration:: +Additional settings for the client can be configured using +``SENTRY_`` in your application's configuration:: class MyConfig(object): - SENTRY_DSN = 'http://public_key:secret_key@example.com/1' + SENTRY_DSN = '___DSN___' SENTRY_INCLUDE_PATHS = ['myproject'] -If `Flask-Login `_ is used by your application (including `Flask-Security `_), user information will be captured when an exception or message is captured. -By default, only the ``id`` (current_user.get_id()), ``is_authenticated``, and ``is_anonymous`` is captured for the user. If you would like additional attributes on the ``current_user`` to be captured, you can configure them using ``SENTRY_USER_ATTRS``:: +If `Flask-Login `_ is used by +your application (including `Flask-Security +`_), user information will +be captured when an exception or message is captured. By default, only +the ``id`` (current_user.get_id()), ``is_authenticated``, and +``is_anonymous`` is captured for the user. If you would like additional +attributes on the ``current_user`` to be captured, you can configure them +using ``SENTRY_USER_ATTRS``:: class MyConfig(object): SENTRY_USER_ATTRS = ['username', 'first_name', 'last_name', 'email'] -``email`` will be captured as ``sentry.interfaces.User.email``, and any additionl attributes will be available under ``sentry.interfaces.User.data`` +``email`` will be captured as ``sentry.interfaces.User.email``, and any +additionl attributes will be available under +``sentry.interfaces.User.data`` -You can specify the types of exceptions that should not be reported by Sentry client in your application by setting the ``RAVEN_IGNORE_EXCEPTIONS`` configuration value on your Flask app configuration:: +You can specify the types of exceptions that should not be reported by +Sentry client in your application by setting the +``RAVEN_IGNORE_EXCEPTIONS`` configuration value on your Flask app +configuration:: class MyExceptionType(Exception): def __init__(self, message): @@ -74,25 +92,28 @@ You can specify the types of exceptions that should not be reported by Sentry cl Usage ----- -Once you've configured the Sentry application it will automatically capture uncaught exceptions within Flask. If you -want to send additional events, a couple of shortcuts are provided on the Sentry Flask middleware object. +Once you've configured the Sentry application it will automatically +capture uncaught exceptions within Flask. If you want to send additional +events, a couple of shortcuts are provided on the Sentry Flask middleware +object. Capture an arbitrary exception by calling ``captureException``:: - >>> try: - >>> 1 / 0 - >>> except ZeroDivisionError: - >>> sentry.captureException() + try: + 1 / 0 + except ZeroDivisionError: + sentry.captureException() Log a generic message with ``captureMessage``:: - >>> sentry.captureMessage('hello, world!') + sentry.captureMessage('hello, world!') Getting the last event id ------------------------- -If possible, the last Sentry event ID is stored in the request context ``g.sentry_event_id`` variable. -This allow to present the user an error ID if have done a custom error 500 page. +If possible, the last Sentry event ID is stored in the request context +``g.sentry_event_id`` variable. This allow to present the user an error +ID if have done a custom error 500 page. .. code-block:: html+jinja @@ -104,10 +125,17 @@ This allow to present the user an error ID if have done a custom error 500 page. Dealing with proxies -------------------- -When your Flask application is behind a proxy such as nginx, Sentry will use the remote address from the proxy, rather than from the actual requesting computer. -By using ``ProxyFix`` from `werkzeug.contrib.fixers `_ the Flask ``.wsgi_app`` can be modified to send the actual ``REMOTE_ADDR`` along to Sentry. :: +When your Flask application is behind a proxy such as nginx, Sentry will +use the remote address from the proxy, rather than from the actual +requesting computer. By using ``ProxyFix`` from `werkzeug.contrib.fixers +`_ +the Flask ``.wsgi_app`` can be modified to send the actual ``REMOTE_ADDR`` +along to Sentry. :: from werkzeug.contrib.fixers import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app) -This may also require `changes `_ to the proxy configuration to pass the right headers if it isn't doing so already. +This may also require `changes +`_ +to the proxy configuration to pass the right headers if it isn't doing so +already. diff --git a/docs/integrations/index.rst b/docs/integrations/index.rst index bfdefe7a..b9365385 100644 --- a/docs/integrations/index.rst +++ b/docs/integrations/index.rst @@ -1,13 +1,18 @@ Integrations ============ -.. note:: Some integrations allow specifying these in a standard configuration, otherwise they are generally passed upon - instantiation of the Sentry client. +The Raven Python module also comes with integration for some commonly used +libraries to automatically capture errors from common environments. This +means that once you have such an integration configured you typically do +not need to report errors manually. + +Some integrations allow specifying these in a standard configuration, +otherwise they are generally passed upon instantiation of the Sentry +client. .. toctree:: - :maxdepth: 2 + :maxdepth: 1 - asyncio bottle celery django @@ -16,7 +21,8 @@ Integrations logging pylons pyramid + rq + tornado wsgi zerorpc zope - tornado diff --git a/docs/integrations/logbook.rst b/docs/integrations/logbook.rst index 26f4ef11..d42311b5 100644 --- a/docs/integrations/logbook.rst +++ b/docs/integrations/logbook.rst @@ -15,7 +15,7 @@ First you'll need to configure a handler:: You can also automatically configure the default client with a DSN:: # Configure the default client - handler = SentryHandler('http://public:secret@example.com/1') + handler = SentryHandler('___DSN___') Finally, bind your handler to your context:: diff --git a/docs/integrations/logging.rst b/docs/integrations/logging.rst index 1eef8bc9..602f13c6 100644 --- a/docs/integrations/logging.rst +++ b/docs/integrations/logging.rst @@ -1,8 +1,10 @@ Logging ======= -Sentry supports the ability to directly tie into the :mod:`logging` module. To -use it simply add :class:`SentryHandler` to your logger. +.. default-domain:: py + +Sentry supports the ability to directly tie into the :mod:`logging` +module. To use it simply add :class:`SentryHandler` to your logger. First you'll need to configure a handler:: @@ -15,7 +17,7 @@ First you'll need to configure a handler:: You can also automatically configure the default client with a DSN:: # Configure the default client - handler = SentryHandler('http://public:secret@example.com/1') + handler = SentryHandler('___DSN___') Finally, call the :func:`setup_logging` helper function:: @@ -31,7 +33,8 @@ Another option is to use :mod:`logging.config.dictConfig`:: 'formatters': { 'console': { - 'format': '[%(asctime)s][%(levelname)s] %(name)s %(filename)s:%(funcName)s:%(lineno)d | %(message)s', + 'format': '[%(asctime)s][%(levelname)s] %(name)s ' + '%(filename)s:%(funcName)s:%(lineno)d | %(message)s', 'datefmt': '%H:%M:%S', }, }, @@ -45,7 +48,7 @@ Another option is to use :mod:`logging.config.dictConfig`:: 'sentry': { 'level': 'ERROR', 'class': 'raven.handlers.logging.SentryHandler', - 'dsn': 'http://public:secret@example.com/1', + 'dsn': '___DSN___', }, }, @@ -79,14 +82,21 @@ Sentry to render it based on that information:: # If you're actually catching an exception, use `exc_info=True` logger.error('There was an error, with a stacktrace!', exc_info=True) - # If you don't have an exception, but still want to capture a stacktrace, use the `stack` arg + # If you don't have an exception, but still want to capture a + # stacktrace, use the `stack` arg logger.error('There was an error, with a stacktrace!', extra={ 'stack': True, }) -.. note:: Depending on the version of Python you're using, ``extra`` might not be an acceptable keyword argument for a logger's ``.exception()`` method (``.debug()``, ``.info()``, ``.warning()``, ``.error()`` and ``.critical()`` should work fine regardless of Python version). This should be fixed as of Python 3.2. Official issue here: http://bugs.python.org/issue15541. +.. note:: Depending on the version of Python you're using, ``extra`` might + not be an acceptable keyword argument for a logger's ``.exception()`` + method (``.debug()``, ``.info()``, ``.warning()``, ``.error()`` and + ``.critical()`` should work fine regardless of Python version). This + should be fixed as of Python 3.2. Official issue here: + http://bugs.python.org/issue15541. -While we don't recommend this, you can also enable implicit stack capturing for all messages:: +While we don't recommend this, you can also enable implicit stack +capturing for all messages:: client = Client(..., auto_log_stacks=True) handler = SentryHandler(client) @@ -108,20 +118,16 @@ within your ``extra`` clause:: } }) -.. note:: The ``url`` and ``view`` keys are used internally by Sentry within the extra data. -.. note:: Any key (in ``data``) prefixed with ``_`` will not automatically output on the Sentry details view. +.. note:: The ``url`` and ``view`` keys are used internally by Sentry + within the extra data. -Sentry will intelligently group messages if you use proper string formatting. For example, the following messages would -be seen as the same message within Sentry:: +.. note:: Any key (in ``data``) prefixed with ``_`` will not automatically + output on the Sentry details view. + +Sentry will intelligently group messages if you use proper string +formatting. For example, the following messages would be seen as the same +message within Sentry:: logger.error('There was some %s error', 'crazy') logger.error('There was some %s error', 'fun') logger.error('There was some %s error', 1) - -.. note:: - - Other languages that provide a logging package that is comparable to the - python :mod:`logging` package may define a Sentry handler. Check the - `Extending Sentry - `_ - documentation. diff --git a/docs/integrations/pylons.rst b/docs/integrations/pylons.rst index f220fd31..f03c022e 100644 --- a/docs/integrations/pylons.rst +++ b/docs/integrations/pylons.rst @@ -1,6 +1,8 @@ Pylons ====== +Pylons is a framework for Python. + WSGI Middleware --------------- @@ -17,7 +19,7 @@ Configuration is handled via the sentry namespace: .. code-block:: ini [sentry] - dsn=http://public:secret@example.com/1 + dsn=___DSN___ include_paths=my.package,my.other.package, exclude_paths=my.package.crud @@ -65,5 +67,3 @@ Add the following lines to your project's `.ini` file to setup `SentryHandler`: datefmt = %H:%M:%S .. note:: You may want to setup other loggers as well. - - diff --git a/docs/integrations/rq.rst b/docs/integrations/rq.rst index 1a42e555..d52d758f 100644 --- a/docs/integrations/rq.rst +++ b/docs/integrations/rq.rst @@ -8,11 +8,13 @@ Usage The simplest way is passing your ``SENTRY_DSN`` through ``rqworker``:: - $ rqworker --sentry-dsn="http://public:secret@example.com/1" + $ rqworker --sentry-dsn="___DSN___" Custom Client ------------- -It's possible to use a custom ``Client`` object and use your own worker process as an alternative to ``rqworker``. +It's possible to use a custom ``Client`` object and use your own worker +process as an alternative to ``rqworker``. -Please see ``rq``'s documentation for more information: http://python-rq.org/patterns/sentry/ +Please see ``rq``'s documentation for more information: +http://python-rq.org/patterns/sentry/ diff --git a/docs/integrations/tornado.rst b/docs/integrations/tornado.rst index 481bb3bb..4dab1dc1 100644 --- a/docs/integrations/tornado.rst +++ b/docs/integrations/tornado.rst @@ -1,6 +1,8 @@ Tornado ======= +Tornado is an async web framework for Python. + Setup ----- @@ -8,7 +10,6 @@ The first thing you'll need to do is to initialize sentry client under your application .. code-block:: python - :emphasize-lines: 2,11,12,13 import tornado.web from raven.contrib.tornado import AsyncSentryClient @@ -21,7 +22,7 @@ your application (r"/", MainHandler), ]) application.sentry_client = AsyncSentryClient( - 'http://public_key:secret_key@host:port/project' + '___DSN___' ) @@ -36,7 +37,8 @@ can automatically capture uncaught exceptions by inheriting the `SentryMixin` cl import tornado.web from raven.contrib.tornado import SentryMixin - class UncaughtExceptionExampleHandler(SentryMixin, tornado.web.RequestHandler): + class UncaughtExceptionExampleHandler( + SentryMixin, tornado.web.RequestHandler): def get(self): 1/0 @@ -79,7 +81,7 @@ Asynchronous .. tip:: - The value returned by the yield is a HTTPResponse obejct. + The value returned by the yield is a ``HTTPResponse`` object. Synchronous diff --git a/docs/integrations/zerorpc.rst b/docs/integrations/zerorpc.rst index f4cd412b..2326821f 100644 --- a/docs/integrations/zerorpc.rst +++ b/docs/integrations/zerorpc.rst @@ -1,6 +1,9 @@ ZeroRPC ======= +ZeroRPC is a light-weight, reliable and language-agnostic library for +distributed communication between server-side processes. + Setup ----- @@ -12,25 +15,17 @@ registered into ZeroRPC's context manager:: from raven.contrib.zerorpc import SentryMiddleware - sentry = SentryMiddleware(dsn='udp://public_key:secret_key@example.com:4242/1') + sentry = SentryMiddleware(dsn='___DSN___') zerorpc.Context.get_instance().register_middleware(sentry) By default, the middleware will hide internal frames from ZeroRPC when it submits exceptions to Sentry. This behavior can be disabled by passing the ``hide_zerorpc_frames`` parameter to the middleware:: - sentry = SentryMiddleware(hide_zerorpc_frames=False, dsn='udp://public_key:secret_key@example.com:4242/1') + sentry = SentryMiddleware(hide_zerorpc_frames=False, dsn='___DSN___') Compatibility ------------- - ZeroRPC-Python < 0.4.0 is compatible with Raven <= 3.1.0; - ZeroRPC-Python >= 0.4.0 requires Raven > 3.1.0. - -Caveats -------- - -Since sending an exception to Sentry will basically block your RPC call, you are -*strongly* advised to use the UDP server of Sentry. In any cases, a cleaner and -long term solution would be to make Raven requests to the Sentry server -asynchronous. diff --git a/docs/integrations/zope.rst b/docs/integrations/zope.rst index 572ff65b..c6de3925 100644 --- a/docs/integrations/zope.rst +++ b/docs/integrations/zope.rst @@ -18,17 +18,18 @@ A basic setup for logging looks like that: %import raven.contrib.zope - dsn YOUR_DSN + dsn ___DSN___ level ERROR -This configuration keeps the regular logging to a logfile, but adds logging to sentry for ERRORs. +This configuration keeps the regular logging to a logfile, but adds +logging to sentry for ERRORs. -All options of :py:class:`raven.base.Client` are supported. See :ref:`usage-label` +All options of :py:class:`raven.base.Client` are supported. -Nobody writes zope.conf files these days, instead buildout recipe does that. -To add the equivalent configuration, you would do this: +Nobody writes zope.conf files these days, instead buildout recipe does +that. To add the equivalent configuration, you would do this: .. code-block:: ini @@ -42,6 +43,6 @@ To add the equivalent configuration, you would do this: level INFO - dsn YOUR_DSN + dsn ___DSN___ level ERROR diff --git a/docs/platform-support.rst b/docs/platform-support.rst new file mode 100644 index 00000000..9e372744 --- /dev/null +++ b/docs/platform-support.rst @@ -0,0 +1,9 @@ +Supported Platforms +=================== + +- Python 2.6 +- Python 2.7 +- Python 3.2 +- Python 3.3 +- PyPy +- Google App Engine diff --git a/docs/transports.rst b/docs/transports.rst new file mode 100644 index 00000000..1db40ade --- /dev/null +++ b/docs/transports.rst @@ -0,0 +1,107 @@ +Transports +========== + +A transport is the mechanism in which Raven sends the HTTP request to the +Sentry server. By default, Raven uses a threaded asynchronous transport, +but you can easily adjust this by modifying your ``SENTRY_DSN`` value. + +Transport registration is done via the URL prefix, so for example, a +synchronous transport is as simple as prefixing your ``SENTRY_DSN`` with +the ``sync+`` value. + +Options are passed to transports via the querystring. + +All transports should support at least the following options: + +``timeout = 1`` + The time to wait for a response from the server, in seconds. + +``verify_ssl = 1`` + If the connection is HTTPS, validate the certificate and hostname. + +``ca_certs = [raven]/data/cacert.pem`` + A certificate bundle to use when validating SSL connections. + +For example, to increase the timeout and to disable SSL verification:: + + SENTRY_DSN = '___DSN___?timeout=5&verify_ssl=0' + + +aiohttp +------- + +Should only be used within a :pep:`3156` compatible event loops +(*asyncio* itself and others). + +:: + + SENTRY_DSN = 'aiohttp+___DSN___' + +Eventlet +-------- + +Should only be used within an Eventlet IO loop. + +:: + + SENTRY_DSN = 'eventlet+___DSN___' + + +Gevent +------ + +Should only be used within a Gevent IO loop. + +:: + + SENTRY_DSN = 'gevent+___DSN___' + + +Requests +-------- + +Requires the ``requests`` library. Synchronous. + +:: + + SENTRY_DSN = 'requests+___DSN___' + + +Sync +---- + +A synchronous blocking transport. + +:: + + SENTRY_DSN = 'sync+___DSN___' + + +Threaded (Default) +------------------ + +Spawns an async worker for processing messages. + +:: + + SENTRY_DSN = 'threaded+___DSN___' + + +Tornado +------- + +Should only be used within a Tornado IO loop. + +:: + + SENTRY_DSN = 'tornado+___DSN___' + + +Twisted +------- + +Should only be used within a Twisted event loop. + +:: + + SENTRY_DSN = 'twisted+___DSN___' diff --git a/docs/transports/index.rst b/docs/transports/index.rst deleted file mode 100644 index 44a9d3e0..00000000 --- a/docs/transports/index.rst +++ /dev/null @@ -1,68 +0,0 @@ -Transports -========== - -A transport is the mechanism in which Raven sends the HTTP request to the Sentry server. By default, Raven uses a threaded asynchronous transport, but you can easily adjust this by modifying your ``SENTRY_DSN`` value. - -Transport registration is done as part of the Client configuration: - -.. code-block:: python - - # Use the synchronous HTTP transport - client = Client('http://public:secret@example.com/1', transport=HTTPTransport) - -Options are passed to transports via the querystring. - -All transports should support at least the following options: - -``timeout = 1`` - The time to wait for a response from the server, in seconds. - -``verify_ssl = 1`` - If the connection is HTTPS, validate the certificate and hostname. - -``ca_certs = [raven]/data/cacert.pem`` - A certificate bundle to use when validating SSL connections. - -For example, to increase the timeout and to disable SSL verification: - -:: - - SENTRY_DSN = 'http://public:secret@example.com/1?timeout=5&verify_ssl=0' - - -Builtin Transports ------------------- - -.. data:: raven.transport.threaded.ThreadedHTTPTransport - - The default transport. Manages a threaded worker for processing messages asynchronously. - -.. data:: raven.transport.http.HTTPTransport - - A synchronous blocking transport. - -.. data:: raven.transport.eventlet.EventletHTTPTransport - - Should only be used within an Eventlet IO loop. - -.. data:: raven.transport.gevent.GeventedHTTPTransport - - Should only be used within a Gevent IO loop. - -.. data:: raven.transport.requests.RequestsHTTPTransport - - A synchronous transport which relies on the ``requests`` library. - -.. data:: raven.transport.tornado.TornadoHTTPTransport - - Should only be used within a Tornado IO loop. - -.. data:: raven.transport.twisted.TwistedHTTPTransport - - Should only be used within a Twisted event loop. - - -Other Transports ----------------- - -- `aiohttp `_ diff --git a/docs/usage.rst b/docs/usage.rst index e5384c63..287bbf90 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -1,78 +1,79 @@ Usage ===== +This gives a basic overview of how to use the raven client with Python +directly. + Capture an Error ---------------- -:: +The most basic use for raven is to record one specific error that occurs:: from raven import Client - client = Client('http://dd2c825ff9b1417d88a99573903ebf80:91631495b10b45f8a1cdbc492088da6a@localhost:9000/1') + client = Client('___DSN___') try: 1 / 0 except ZeroDivisionError: client.captureException() +Reporting an Event +------------------ + +To report an arbitrary event you can use the +:py:meth:`~raven.Client.capture` method. This is the most low-level +method available. In most cases you would want to use the +:py:meth:`~raven.Client.captureMessage` method instead however which +directly reports a message:: + + client.captureMessage('Something went fundamentally wrong') + Adding Context -------------- -A few helpers exist for adding context to a request. These are most useful within a middleware, or some kind of context wrapper. +The raven client internally keeps a thread local mapping that can carry +additional information. Whenever a message is submitted to Sentry that +additional data will be passed along. -:: +For instance if you use a web framework, you can use this to inject +additional information into the context. The basic primitive for this is +the :py:attr:`~raven.Client.context` attribute. It provides a `merge()` +and `clear()` function that can be used:: - # If you're using the Django client, we already deal with this for you. - class DjangoUserContext(object): - def process_request(self, request): - client.user_context({ - 'email': request.user.email, - }) - - def process_response(self, request): + def handle_request(request): + client.context.merge({'user': { + 'email': request.user.email + }}) + try: + ... + finally: client.context.clear() - -See also: - -- Client.extra_context -- Client.http_context -- Client.tags_context - - Testing the Client ------------------ -Once you've got your server configured, you can test the Raven client by using its CLI:: +Once you've got your server configured, you can test the Raven client by +using its CLI:: - raven test + raven test ___DSN___ -If you've configured your environment to have SENTRY_DSN available, you can simply drop -the optional DSN argument:: +If you've configured your environment to have ``SENTRY_DSN`` available, you +can simply drop the optional DSN argument:: - raven test + raven test You should get something like the following, assuming you're configured everything correctly:: - $ raven test http://dd2c825ff9b1417d88a99573903ebf80:91631495b10b45f8a1cdbc492088da6a@localhost:9000/1 - Using DSN configuration: - http://dd2c825ff9b1417d88a99573903ebf80:91631495b10b45f8a1cdbc492088da6a@localhost:9000/1 + $ raven test sync+___DSN___ + Using DSN configuration: + sync+___DSN___ - Client configuration: - servers : ['http://localhost:9000/api/store/'] - project : 1 - public_key : dd2c825ff9b1417d88a99573903ebf80 - secret_key : 91631495b10b45f8a1cdbc492088da6a + Client configuration: + servers : ['___API_URL___/api/store/'] + project : ___PROJECT_ID___ + public_key : ___PUBLIC_KEY___ + secret_key : ___SECRET_KEY___ - Sending a test message... success! - - The test message can be viewed at the following URL: - http://localhost:9000/1/search/?q=c988bf5cb7db4653825c92f6864e7206$b8a6fbd29cc9113a149ad62cf7e0ddd5 - - -Client API ----------- - -.. autoclass:: raven.base.Client - :members: + Sending a test message... success! diff --git a/docs/wizards.json b/docs/wizards.json new file mode 100644 index 00000000..e673af1a --- /dev/null +++ b/docs/wizards.json @@ -0,0 +1,83 @@ +{ + "configurations": { + "python": { + "name": "Python", + "client_lib": "raven-python", + "is_framework": false, + "doc_link": "installation", + "snippets": [ + "installation#installation", + "usage#capture-an-error", + "usage#reporting-an-event" + ] + }, + "python-flask": { + "name": "Flask", + "client_lib": "raven-python", + "is_framework": true, + "doc_link": "integrations/flask", + "snippets": [ + "integrations/flask#installation", + "integrations/flask#setup" + ] + }, + "python-bottle": { + "name": "Bottle", + "client_lib": "raven-python", + "is_framework": true, + "doc_link": "integrations/bottle", + "snippets": [ + "integrations/bottle#setup", + "integrations/bottle#usage" + ] + }, + "python-celery": { + "name": "Celery", + "client_lib": "raven-python", + "is_framework": true, + "doc_link": "integrations/celery", + "snippets": [ + "integrations/celery" + ] + }, + "python-django": { + "name": "Django", + "client_lib": "raven-python", + "is_framework": true, + "doc_link": "integrations/django", + "snippets": [ + "integrations/django#setup" + ] + }, + "python-pylons": { + "name": "Pylons", + "client_lib": "raven-python", + "is_framework": true, + "doc_link": "integrations/pylons", + "snippets": [ + "integrations/pylons#wsgi-middleware", + "integrations/pylons#logger-setup" + ] + }, + "python-pyramid": { + "name": "Pyramid", + "client_lib": "raven-python", + "is_framework": true, + "doc_link": "integrations/pyramid", + "snippets": [ + "integrations/pyramid#pastedeploy-filter", + "integrations/pyramid#logger-setup" + ] + }, + "python-tornado": { + "name": "Tornado", + "client_lib": "raven-python", + "is_framework": true, + "doc_link": "integrations/tornado", + "snippets": [ + "integrations/tornado#setup", + "integrations/tornado#usage" + ] + } + } +}