Imported new docs
This commit is contained in:
parent
d13b3cf78c
commit
9e385c43b9
|
@ -13,8 +13,7 @@ pip-log.txt
|
||||||
/cover
|
/cover
|
||||||
/dist
|
/dist
|
||||||
/example_project/local_settings.py
|
/example_project/local_settings.py
|
||||||
/docs/html
|
/docs/_build
|
||||||
/docs/doctrees
|
|
||||||
/sentry_index/
|
/sentry_index/
|
||||||
/sentry_test_index
|
/sentry_test_index
|
||||||
/example_project/*.db
|
/example_project/*.db
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
SPHINXOPTS =
|
SPHINXOPTS =
|
||||||
SPHINXBUILD = sphinx-build
|
SPHINXBUILD = sphinx-build
|
||||||
PAPER =
|
PAPER =
|
||||||
BUILDDIR = ./
|
BUILDDIR = ./_build
|
||||||
|
|
||||||
# Internal variables.
|
# Internal variables.
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||||
|
|
|
@ -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.
|
|
@ -1,4 +0,0 @@
|
||||||
Changelog
|
|
||||||
=========
|
|
||||||
|
|
||||||
.. include:: ../../CHANGES
|
|
|
@ -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.
|
|
@ -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.
|
|
|
@ -1,68 +1,74 @@
|
||||||
raven-python
|
.. sentry:edition:: self
|
||||||
============
|
|
||||||
|
|
||||||
Raven is a standalone (and the official) Python client for `Sentry <http://www.getsentry.com/>`_.
|
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::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
:titlesonly:
|
||||||
|
|
||||||
install/index
|
installation
|
||||||
config/index
|
config
|
||||||
usage
|
usage
|
||||||
integrations/index
|
integrations/index
|
||||||
transports/index
|
transports
|
||||||
|
platform-support
|
||||||
|
api
|
||||||
|
|
||||||
Developers
|
.. sentry:edition:: self
|
||||||
----------
|
|
||||||
|
|
||||||
.. toctree::
|
For Developers
|
||||||
:maxdepth: 2
|
--------------
|
||||||
|
|
||||||
contributing/index
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:titlesonly:
|
||||||
|
|
||||||
Reference
|
contributing
|
||||||
---------
|
|
||||||
|
|
||||||
.. toctree::
|
Supported Platforms
|
||||||
:maxdepth: 1
|
-------------------
|
||||||
|
|
||||||
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
|
.. sentry:edition:: hosted, on-premise
|
||||||
- Python 2.7
|
|
||||||
- Python 3.2
|
|
||||||
- Python 3.3
|
|
||||||
- PyPy
|
|
||||||
- Google App Engine
|
|
||||||
|
|
||||||
About Sentry
|
Resources:
|
||||||
------------
|
|
||||||
|
|
||||||
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
|
|
||||||
---------
|
|
||||||
|
|
||||||
* `Documentation <http://raven.readthedocs.org/>`_
|
* `Documentation <http://raven.readthedocs.org/>`_
|
||||||
* `Bug Tracker <http://github.com/getsentry/raven-python/issues>`_
|
* `Bug Tracker <http://github.com/getsentry/raven-python/issues>`_
|
||||||
* `Code <http://github.com/getsentry/raven-python>`_
|
* `Code <http://github.com/getsentry/raven-python>`_
|
||||||
* `Mailing List <https://groups.google.com/group/getsentry>`_
|
* `Mailing List <https://groups.google.com/group/getsentry>`_
|
||||||
* `IRC <irc://irc.freenode.net/sentry>`_ (irc.freenode.net, #sentry)
|
* `IRC <irc://irc.freenode.net/sentry>`_ (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.
|
|
||||||
|
|
|
@ -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``
|
|
|
@ -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 <https://github.com/getsentry/raven-python>`_::
|
||||||
|
|
||||||
|
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.
|
|
@ -1,6 +1,9 @@
|
||||||
Bottle
|
Bottle
|
||||||
======
|
======
|
||||||
|
|
||||||
|
`Bottle <http://bottlepy.org/>`_ is a microframework for Python. Raven
|
||||||
|
supports this framework through the WSGI integration.
|
||||||
|
|
||||||
Setup
|
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 = bottle.app()
|
||||||
app.catchall = False
|
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
|
from raven.contrib.bottle import Sentry
|
||||||
|
client = Client('___DSN___')
|
||||||
app = Sentry(app, client)
|
app = Sentry(app, client)
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
|
@ -25,15 +31,16 @@ Once you've configured the Sentry application you need only call run with it::
|
||||||
|
|
||||||
run(app=app)
|
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``::
|
Capture an arbitrary exception by calling ``captureException``::
|
||||||
|
|
||||||
>>> try:
|
try:
|
||||||
>>> 1 / 0
|
1 / 0
|
||||||
>>> except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
>>> request.app.sentry.captureException()
|
request.app.sentry.captureException()
|
||||||
|
|
||||||
Log a generic message with ``captureMessage``::
|
Log a generic message with ``captureMessage``::
|
||||||
|
|
||||||
>>> request.app.sentry.captureMessage('hello, world!')
|
request.app.sentry.captureMessage('Hello, world!')
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
Celery
|
Celery
|
||||||
======
|
======
|
||||||
|
|
||||||
tl;dr register a couple of signals to hijack Celery error handling
|
`Celery <http://www.celeryproject.org/>`_ 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 import Client
|
||||||
from raven.contrib.celery import register_signal, register_logger_signal
|
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 a custom filter to filter out duplicate logs
|
||||||
register_logger_signal(client)
|
register_logger_signal(client)
|
||||||
|
@ -26,13 +29,13 @@ A more complex version to encapsulate behavior:
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import celery
|
import celery
|
||||||
|
import raven
|
||||||
|
from raven.contrib.celery import register_signal, register_logger_signal
|
||||||
|
|
||||||
class Celery(celery.Celery):
|
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 a custom filter to filter out duplicate logs
|
||||||
register_logger_signal(client)
|
register_logger_signal(client)
|
||||||
|
|
|
@ -1,27 +1,35 @@
|
||||||
Django
|
Django
|
||||||
======
|
======
|
||||||
|
|
||||||
Support
|
.. default-domain:: py
|
||||||
-------
|
|
||||||
|
|
||||||
While older versions of Django will likely work, officially only version 1.4 and newer are supported.
|
`Django <http://djangoproject.com/>`_ 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
|
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 = (
|
INSTALLED_APPS = (
|
||||||
'raven.contrib.django.raven_compat',
|
'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
|
import raven
|
||||||
|
|
||||||
RAVEN_CONFIG = {
|
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__)),
|
'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
|
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 %}
|
{% load raven %}
|
||||||
|
|
||||||
Inside your template, you can now use::
|
Inside your template, you can now use:
|
||||||
|
|
||||||
|
.. sourcecode:: html+django
|
||||||
|
|
||||||
<script>Raven.config('{% sentry_public_dsn %}').install()</script>
|
<script>Raven.config('{% sentry_public_dsn %}').install()</script>
|
||||||
|
|
||||||
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' %}
|
{% sentry_public_dsn 'https' %}
|
||||||
|
|
||||||
See `Raven.js documentation <http://raven-js.readthedocs.org/>`_ for more information.
|
.. sentry:edition:: hosted, on-premise
|
||||||
|
|
||||||
|
See the :doc:`Raven.js documentation <../../../clients/javascript/index>`
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
|
||||||
Integration with :mod:`logging`
|
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 = {
|
LOGGING = {
|
||||||
'version': 1,
|
'version': 1,
|
||||||
|
@ -71,7 +90,8 @@ To integrate with the standard library's :mod:`logging` module:
|
||||||
},
|
},
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'verbose': {
|
'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': {
|
'handlers': {
|
||||||
|
@ -136,8 +156,8 @@ Message References
|
||||||
|
|
||||||
Sentry supports sending a message ID to your clients so that they can be
|
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
|
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
|
information, the first is via the ``X-Sentry-ID`` HTTP response header.
|
||||||
this is as simple as appending a middleware to your stack::
|
Adding this is as simple as appending a middleware to your stack::
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + (
|
MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + (
|
||||||
# We recommend putting this as high in the chain as possible
|
# 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,
|
Another alternative method is rendering it within a template. By default,
|
||||||
Sentry will attach :attr:`request.sentry` when it catches a Django exception.
|
Sentry will attach :attr:`request.sentry` when it catches a Django
|
||||||
In our example, we will use this information to modify the default
|
exception. In our example, we will use this information to modify the
|
||||||
:file:`500.html` which is rendered, and show the user a case reference ID. The
|
default :file:`500.html` which is rendered, and show the user a case
|
||||||
first step in doing this is creating a custom :func:`handler500` in your
|
reference ID. The first step in doing this is creating a custom
|
||||||
:file:`urls.py` file::
|
:func:`handler500` in your :file:`urls.py` file::
|
||||||
|
|
||||||
from django.conf.urls.defaults import *
|
from django.conf.urls.defaults import *
|
||||||
|
|
||||||
from django.views.defaults import page_not_found, server_error
|
from django.views.defaults import page_not_found, server_error
|
||||||
|
from django.template import Context, loader
|
||||||
|
from django.http import HttpResponseServerError
|
||||||
|
|
||||||
def handler500(request):
|
def handler500(request):
|
||||||
"""
|
"""500 error handler which includes ``request`` in the context.
|
||||||
500 error handler which includes ``request`` in the context.
|
|
||||||
|
|
||||||
Templates: `500.html`
|
Templates: `500.html`
|
||||||
Context: None
|
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.
|
t = loader.get_template('500.html') # You need to create a 500.html template.
|
||||||
return HttpResponseServerError(t.render(Context({
|
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
|
Once we've successfully added the :data:`request` context variable, adding the
|
||||||
Sentry reference ID to our :file:`500.html` is simple:
|
Sentry reference ID to our :file:`500.html` is simple:
|
||||||
|
|
||||||
.. code-block:: django
|
.. sourcecode:: html+django
|
||||||
|
|
||||||
<p>You've encountered an error, oh noes!</p>
|
<p>You've encountered an error, oh noes!</p>
|
||||||
{% if request.sentry.id %}
|
{% if request.sentry.id %}
|
||||||
<p>If you need assistance, you may reference this error as <strong>{{ request.sentry.id }}</strong>.</p>
|
<p>If you need assistance, you may reference this error as
|
||||||
|
<strong>{{ request.sentry.id }}</strong>.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
WSGI Middleware
|
WSGI Middleware
|
||||||
|
@ -197,30 +217,31 @@ level of your Django application::
|
||||||
Additional Settings
|
Additional Settings
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
SENTRY_CLIENT
|
.. describe:: SENTRY_CLIENT
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
In some situations you may wish for a slightly different behavior to how Sentry
|
In some situations you may wish for a slightly different behavior to
|
||||||
communicates with your server. For this, Raven allows you to specify a custom
|
how Sentry communicates with your server. For this, Raven allows you
|
||||||
client::
|
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
|
If you are also using Celery, there is a handler being automatically
|
||||||
for you that captures the errors from workers. The default logging level for
|
registered for you that captures the errors from workers. The default
|
||||||
that handler is ``logging.ERROR`` and can be customized using this setting::
|
logging level for that handler is ``logging.ERROR`` and can be
|
||||||
|
customized using this setting::
|
||||||
|
|
||||||
SENTRY_CELERY_LOGLEVEL = logging.INFO
|
SENTRY_CELERY_LOGLEVEL = logging.INFO
|
||||||
RAVEN_CONFIG = {
|
RAVEN_CONFIG = {
|
||||||
'CELERY_LOGLEVEL': logging.INFO
|
'CELERY_LOGLEVEL': logging.INFO
|
||||||
}
|
}
|
||||||
|
|
||||||
Caveats
|
Caveats
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
The following things you should keep in mind when using Raven with Django.
|
||||||
|
|
||||||
Error Handling Middleware
|
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::
|
add something like the following::
|
||||||
|
|
||||||
from django.core.signals import got_request_exception
|
from django.core.signals import got_request_exception
|
||||||
|
|
||||||
class MyMiddleware(object):
|
class MyMiddleware(object):
|
||||||
def process_exception(self, request, exception):
|
def process_exception(self, request, exception):
|
||||||
# Make sure the exception signal is fired for Sentry
|
# Make sure the exception signal is fired for Sentry
|
||||||
|
@ -253,6 +275,7 @@ response codes.
|
||||||
Or, alternatively, you can just enable Sentry responses::
|
Or, alternatively, you can just enable Sentry responses::
|
||||||
|
|
||||||
from raven.contrib.django.raven_compat.models import sentry_exception_handler
|
from raven.contrib.django.raven_compat.models import sentry_exception_handler
|
||||||
|
|
||||||
class MyMiddleware(object):
|
class MyMiddleware(object):
|
||||||
def process_exception(self, request, exception):
|
def process_exception(self, request, exception):
|
||||||
# Make sure the exception signal is fired for Sentry
|
# Make sure the exception signal is fired for Sentry
|
||||||
|
@ -263,12 +286,14 @@ Or, alternatively, you can just enable Sentry responses::
|
||||||
Gunicorn
|
Gunicorn
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
If you are running Django with `gunicorn <http://gunicorn.org/>`_ and using the
|
If you are running Django with `gunicorn <http://gunicorn.org/>`_ and
|
||||||
``gunicorn`` executable, instead of the ``run_gunicorn`` management command, you
|
using the ``gunicorn`` executable, instead of the ``run_gunicorn``
|
||||||
will need to add a hook to gunicorn to activate Raven::
|
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):
|
def when_ready(server):
|
||||||
from django.core.management import call_command
|
|
||||||
call_command('validate')
|
call_command('validate')
|
||||||
|
|
||||||
Circus
|
Circus
|
||||||
|
@ -278,20 +303,22 @@ If you are running Django with `circus <http://circus.rtfd.org/>`_ and
|
||||||
`chaussette <http://chaussette.readthedocs.org/>`_ you will also need
|
`chaussette <http://chaussette.readthedocs.org/>`_ you will also need
|
||||||
to add a hook to circus to activate Raven::
|
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):
|
def run_raven(*args, **kwargs):
|
||||||
"""Set up raven for django by running a django command.
|
"""Set up raven for django by running a django command.
|
||||||
It is necessary because chaussette doesn't run 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:
|
if not settings.configured:
|
||||||
settings.configure()
|
settings.configure()
|
||||||
|
|
||||||
call_command('validate')
|
call_command('validate')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
And in your circus configuration::
|
And in your circus configuration:
|
||||||
|
|
||||||
|
.. sourcecode:: ini
|
||||||
|
|
||||||
[socket:dwebapp]
|
[socket:dwebapp]
|
||||||
host = 127.0.0.1
|
host = 127.0.0.1
|
||||||
|
@ -302,4 +329,3 @@ And in your circus configuration::
|
||||||
use_sockets = True
|
use_sockets = True
|
||||||
numprocesses = 2
|
numprocesses = 2
|
||||||
hooks.after_start = dproject.hooks.run_raven
|
hooks.after_start = dproject.hooks.run_raven
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
Flask
|
Flask
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
`Flask <http://flask.pocoo.org/>`_ 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
|
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]
|
pip install raven[flask]
|
||||||
|
|
||||||
|
@ -14,10 +18,13 @@ Setup
|
||||||
The first thing you'll need to do is to initialize Raven under your application::
|
The first thing you'll need to do is to initialize Raven under your application::
|
||||||
|
|
||||||
from raven.contrib.flask import Sentry
|
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
|
If you don't specify the ``dsn`` value, we will attempt to read it from
|
||||||
the ``SENTRY_DSN`` key.
|
your environment under the ``SENTRY_DSN`` key.
|
||||||
|
|
||||||
|
Extended Setup
|
||||||
|
--------------
|
||||||
|
|
||||||
You can optionally configure logging too::
|
You can optionally configure logging too::
|
||||||
|
|
||||||
|
@ -44,25 +51,36 @@ You can pass parameters in the ``init_app`` hook::
|
||||||
logging=True, level=logging.ERROR)
|
logging=True, level=logging.ERROR)
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
Settings
|
Settings
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Additional settings for the client can be configured using ``SENTRY_<setting name>`` in your application's configuration::
|
Additional settings for the client can be configured using
|
||||||
|
``SENTRY_<setting name>`` in your application's configuration::
|
||||||
|
|
||||||
class MyConfig(object):
|
class MyConfig(object):
|
||||||
SENTRY_DSN = 'http://public_key:secret_key@example.com/1'
|
SENTRY_DSN = '___DSN___'
|
||||||
SENTRY_INCLUDE_PATHS = ['myproject']
|
SENTRY_INCLUDE_PATHS = ['myproject']
|
||||||
|
|
||||||
If `Flask-Login <https://pypi.python.org/pypi/Flask-Login/>`_ is used by your application (including `Flask-Security <https://pypi.python.org/pypi/Flask-Security/>`_), user information will be captured when an exception or message is captured.
|
If `Flask-Login <https://pypi.python.org/pypi/Flask-Login/>`_ is used by
|
||||||
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``::
|
your application (including `Flask-Security
|
||||||
|
<https://pypi.python.org/pypi/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):
|
class MyConfig(object):
|
||||||
SENTRY_USER_ATTRS = ['username', 'first_name', 'last_name', 'email']
|
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):
|
class MyExceptionType(Exception):
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
|
@ -74,25 +92,28 @@ You can specify the types of exceptions that should not be reported by Sentry cl
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Once you've configured the Sentry application it will automatically capture uncaught exceptions within Flask. If you
|
Once you've configured the Sentry application it will automatically
|
||||||
want to send additional events, a couple of shortcuts are provided on the Sentry Flask middleware object.
|
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``::
|
Capture an arbitrary exception by calling ``captureException``::
|
||||||
|
|
||||||
>>> try:
|
try:
|
||||||
>>> 1 / 0
|
1 / 0
|
||||||
>>> except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
>>> sentry.captureException()
|
sentry.captureException()
|
||||||
|
|
||||||
Log a generic message with ``captureMessage``::
|
Log a generic message with ``captureMessage``::
|
||||||
|
|
||||||
>>> sentry.captureMessage('hello, world!')
|
sentry.captureMessage('hello, world!')
|
||||||
|
|
||||||
Getting the last event id
|
Getting the last event id
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
If possible, the last Sentry event ID is stored in the request context ``g.sentry_event_id`` variable.
|
If possible, the last Sentry event ID is stored in the request context
|
||||||
This allow to present the user an error ID if have done a custom error 500 page.
|
``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
|
.. 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
|
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.
|
When your Flask application is behind a proxy such as nginx, Sentry will
|
||||||
By using ``ProxyFix`` from `werkzeug.contrib.fixers <http://werkzeug.pocoo.org/docs/0.10/contrib/fixers/#werkzeug.contrib.fixers.ProxyFix>`_ the Flask ``.wsgi_app`` can be modified to send the actual ``REMOTE_ADDR`` along to Sentry. ::
|
use the remote address from the proxy, rather than from the actual
|
||||||
|
requesting computer. By using ``ProxyFix`` from `werkzeug.contrib.fixers
|
||||||
|
<http://werkzeug.pocoo.org/docs/0.10/contrib/fixers/#werkzeug.contrib.fixers.ProxyFix>`_
|
||||||
|
the Flask ``.wsgi_app`` can be modified to send the actual ``REMOTE_ADDR``
|
||||||
|
along to Sentry. ::
|
||||||
|
|
||||||
from werkzeug.contrib.fixers import ProxyFix
|
from werkzeug.contrib.fixers import ProxyFix
|
||||||
app.wsgi_app = ProxyFix(app.wsgi_app)
|
app.wsgi_app = ProxyFix(app.wsgi_app)
|
||||||
|
|
||||||
This may also require `changes <http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#proxy-setups>`_ to the proxy configuration to pass the right headers if it isn't doing so already.
|
This may also require `changes
|
||||||
|
<http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#proxy-setups>`_
|
||||||
|
to the proxy configuration to pass the right headers if it isn't doing so
|
||||||
|
already.
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
Integrations
|
Integrations
|
||||||
============
|
============
|
||||||
|
|
||||||
.. note:: Some integrations allow specifying these in a standard configuration, otherwise they are generally passed upon
|
The Raven Python module also comes with integration for some commonly used
|
||||||
instantiation of the Sentry client.
|
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::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 1
|
||||||
|
|
||||||
asyncio
|
|
||||||
bottle
|
bottle
|
||||||
celery
|
celery
|
||||||
django
|
django
|
||||||
|
@ -16,7 +21,8 @@ Integrations
|
||||||
logging
|
logging
|
||||||
pylons
|
pylons
|
||||||
pyramid
|
pyramid
|
||||||
|
rq
|
||||||
|
tornado
|
||||||
wsgi
|
wsgi
|
||||||
zerorpc
|
zerorpc
|
||||||
zope
|
zope
|
||||||
tornado
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ First you'll need to configure a handler::
|
||||||
You can also automatically configure the default client with a DSN::
|
You can also automatically configure the default client with a DSN::
|
||||||
|
|
||||||
# Configure the default client
|
# Configure the default client
|
||||||
handler = SentryHandler('http://public:secret@example.com/1')
|
handler = SentryHandler('___DSN___')
|
||||||
|
|
||||||
Finally, bind your handler to your context::
|
Finally, bind your handler to your context::
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
Logging
|
Logging
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Sentry supports the ability to directly tie into the :mod:`logging` module. To
|
.. default-domain:: py
|
||||||
use it simply add :class:`SentryHandler` to your logger.
|
|
||||||
|
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::
|
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::
|
You can also automatically configure the default client with a DSN::
|
||||||
|
|
||||||
# Configure the default client
|
# Configure the default client
|
||||||
handler = SentryHandler('http://public:secret@example.com/1')
|
handler = SentryHandler('___DSN___')
|
||||||
|
|
||||||
Finally, call the :func:`setup_logging` helper function::
|
Finally, call the :func:`setup_logging` helper function::
|
||||||
|
|
||||||
|
@ -31,7 +33,8 @@ Another option is to use :mod:`logging.config.dictConfig`::
|
||||||
|
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'console': {
|
'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',
|
'datefmt': '%H:%M:%S',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -45,7 +48,7 @@ Another option is to use :mod:`logging.config.dictConfig`::
|
||||||
'sentry': {
|
'sentry': {
|
||||||
'level': 'ERROR',
|
'level': 'ERROR',
|
||||||
'class': 'raven.handlers.logging.SentryHandler',
|
'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`
|
# If you're actually catching an exception, use `exc_info=True`
|
||||||
logger.error('There was an error, with a stacktrace!', 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={
|
logger.error('There was an error, with a stacktrace!', extra={
|
||||||
'stack': True,
|
'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)
|
client = Client(..., auto_log_stacks=True)
|
||||||
handler = SentryHandler(client)
|
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:: The ``url`` and ``view`` keys are used internally by Sentry
|
||||||
.. note:: Any key (in ``data``) prefixed with ``_`` will not automatically output on the Sentry details view.
|
within the extra data.
|
||||||
|
|
||||||
Sentry will intelligently group messages if you use proper string formatting. For example, the following messages would
|
.. note:: Any key (in ``data``) prefixed with ``_`` will not automatically
|
||||||
be seen as the same message within Sentry::
|
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', 'crazy')
|
||||||
logger.error('There was some %s error', 'fun')
|
logger.error('There was some %s error', 'fun')
|
||||||
logger.error('There was some %s error', 1)
|
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
|
|
||||||
<http://sentry.readthedocs.org/en/latest/developer/client/index.html>`_
|
|
||||||
documentation.
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Pylons
|
Pylons
|
||||||
======
|
======
|
||||||
|
|
||||||
|
Pylons is a framework for Python.
|
||||||
|
|
||||||
WSGI Middleware
|
WSGI Middleware
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -17,7 +19,7 @@ Configuration is handled via the sentry namespace:
|
||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
||||||
[sentry]
|
[sentry]
|
||||||
dsn=http://public:secret@example.com/1
|
dsn=___DSN___
|
||||||
include_paths=my.package,my.other.package,
|
include_paths=my.package,my.other.package,
|
||||||
exclude_paths=my.package.crud
|
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
|
datefmt = %H:%M:%S
|
||||||
|
|
||||||
.. note:: You may want to setup other loggers as well.
|
.. note:: You may want to setup other loggers as well.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,13 @@ Usage
|
||||||
|
|
||||||
The simplest way is passing your ``SENTRY_DSN`` through ``rqworker``::
|
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
|
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/
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Tornado
|
Tornado
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
Tornado is an async web framework for Python.
|
||||||
|
|
||||||
Setup
|
Setup
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -8,7 +10,6 @@ The first thing you'll need to do is to initialize sentry client under
|
||||||
your application
|
your application
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 2,11,12,13
|
|
||||||
|
|
||||||
import tornado.web
|
import tornado.web
|
||||||
from raven.contrib.tornado import AsyncSentryClient
|
from raven.contrib.tornado import AsyncSentryClient
|
||||||
|
@ -21,7 +22,7 @@ your application
|
||||||
(r"/", MainHandler),
|
(r"/", MainHandler),
|
||||||
])
|
])
|
||||||
application.sentry_client = AsyncSentryClient(
|
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
|
import tornado.web
|
||||||
from raven.contrib.tornado import SentryMixin
|
from raven.contrib.tornado import SentryMixin
|
||||||
|
|
||||||
class UncaughtExceptionExampleHandler(SentryMixin, tornado.web.RequestHandler):
|
class UncaughtExceptionExampleHandler(
|
||||||
|
SentryMixin, tornado.web.RequestHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
1/0
|
1/0
|
||||||
|
|
||||||
|
@ -79,7 +81,7 @@ Asynchronous
|
||||||
|
|
||||||
.. tip::
|
.. tip::
|
||||||
|
|
||||||
The value returned by the yield is a HTTPResponse obejct.
|
The value returned by the yield is a ``HTTPResponse`` object.
|
||||||
|
|
||||||
|
|
||||||
Synchronous
|
Synchronous
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
ZeroRPC
|
ZeroRPC
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
ZeroRPC is a light-weight, reliable and language-agnostic library for
|
||||||
|
distributed communication between server-side processes.
|
||||||
|
|
||||||
Setup
|
Setup
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -12,25 +15,17 @@ registered into ZeroRPC's context manager::
|
||||||
|
|
||||||
from raven.contrib.zerorpc import SentryMiddleware
|
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)
|
zerorpc.Context.get_instance().register_middleware(sentry)
|
||||||
|
|
||||||
By default, the middleware will hide internal frames from ZeroRPC when it
|
By default, the middleware will hide internal frames from ZeroRPC when it
|
||||||
submits exceptions to Sentry. This behavior can be disabled by passing the
|
submits exceptions to Sentry. This behavior can be disabled by passing the
|
||||||
``hide_zerorpc_frames`` parameter to the middleware::
|
``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
|
Compatibility
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
- ZeroRPC-Python < 0.4.0 is compatible with Raven <= 3.1.0;
|
- ZeroRPC-Python < 0.4.0 is compatible with Raven <= 3.1.0;
|
||||||
- ZeroRPC-Python >= 0.4.0 requires 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.
|
|
||||||
|
|
|
@ -18,17 +18,18 @@ A basic setup for logging looks like that:
|
||||||
|
|
||||||
%import raven.contrib.zope
|
%import raven.contrib.zope
|
||||||
<sentry>
|
<sentry>
|
||||||
dsn YOUR_DSN
|
dsn ___DSN___
|
||||||
level ERROR
|
level ERROR
|
||||||
</sentry>
|
</sentry>
|
||||||
</eventlog>
|
</eventlog>
|
||||||
|
|
||||||
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.
|
Nobody writes zope.conf files these days, instead buildout recipe does
|
||||||
To add the equivalent configuration, you would do this:
|
that. To add the equivalent configuration, you would do this:
|
||||||
|
|
||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
||||||
|
@ -42,6 +43,6 @@ To add the equivalent configuration, you would do this:
|
||||||
level INFO
|
level INFO
|
||||||
</logfile>
|
</logfile>
|
||||||
<sentry>
|
<sentry>
|
||||||
dsn YOUR_DSN
|
dsn ___DSN___
|
||||||
level ERROR
|
level ERROR
|
||||||
</sentry>
|
</sentry>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
Supported Platforms
|
||||||
|
===================
|
||||||
|
|
||||||
|
- Python 2.6
|
||||||
|
- Python 2.7
|
||||||
|
- Python 3.2
|
||||||
|
- Python 3.3
|
||||||
|
- PyPy
|
||||||
|
- Google App Engine
|
|
@ -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___'
|
|
@ -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 <https://github.com/getsentry/raven-aiohttp>`_
|
|
|
@ -1,78 +1,79 @@
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
This gives a basic overview of how to use the raven client with Python
|
||||||
|
directly.
|
||||||
|
|
||||||
Capture an Error
|
Capture an Error
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
::
|
The most basic use for raven is to record one specific error that occurs::
|
||||||
|
|
||||||
from raven import Client
|
from raven import Client
|
||||||
|
|
||||||
client = Client('http://dd2c825ff9b1417d88a99573903ebf80:91631495b10b45f8a1cdbc492088da6a@localhost:9000/1')
|
client = Client('___DSN___')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
1 / 0
|
1 / 0
|
||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
client.captureException()
|
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
|
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.
|
def handle_request(request):
|
||||||
class DjangoUserContext(object):
|
client.context.merge({'user': {
|
||||||
def process_request(self, request):
|
'email': request.user.email
|
||||||
client.user_context({
|
}})
|
||||||
'email': request.user.email,
|
try:
|
||||||
})
|
...
|
||||||
|
finally:
|
||||||
def process_response(self, request):
|
|
||||||
client.context.clear()
|
client.context.clear()
|
||||||
|
|
||||||
|
|
||||||
See also:
|
|
||||||
|
|
||||||
- Client.extra_context
|
|
||||||
- Client.http_context
|
|
||||||
- Client.tags_context
|
|
||||||
|
|
||||||
|
|
||||||
Testing the Client
|
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 <DSN value>
|
raven test ___DSN___
|
||||||
|
|
||||||
If you've configured your environment to have SENTRY_DSN available, you can simply drop
|
If you've configured your environment to have ``SENTRY_DSN`` available, you
|
||||||
the optional DSN argument::
|
can simply drop the optional DSN argument::
|
||||||
|
|
||||||
raven test
|
raven test
|
||||||
|
|
||||||
You should get something like the following, assuming you're configured everything correctly::
|
You should get something like the following, assuming you're configured everything correctly::
|
||||||
|
|
||||||
$ raven test http://dd2c825ff9b1417d88a99573903ebf80:91631495b10b45f8a1cdbc492088da6a@localhost:9000/1
|
$ raven test sync+___DSN___
|
||||||
Using DSN configuration:
|
Using DSN configuration:
|
||||||
http://dd2c825ff9b1417d88a99573903ebf80:91631495b10b45f8a1cdbc492088da6a@localhost:9000/1
|
sync+___DSN___
|
||||||
|
|
||||||
Client configuration:
|
Client configuration:
|
||||||
servers : ['http://localhost:9000/api/store/']
|
servers : ['___API_URL___/api/store/']
|
||||||
project : 1
|
project : ___PROJECT_ID___
|
||||||
public_key : dd2c825ff9b1417d88a99573903ebf80
|
public_key : ___PUBLIC_KEY___
|
||||||
secret_key : 91631495b10b45f8a1cdbc492088da6a
|
secret_key : ___SECRET_KEY___
|
||||||
|
|
||||||
Sending a test message... success!
|
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:
|
|
||||||
|
|
|
@ -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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue