Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,30 @@ default value is not in the list of `included_environments`.

Sentry uses the [hackney HTTP client](https://github.com/benoitc/hackney) for HTTP requests. Sentry starts its own hackney pool named `:sentry_pool` with a default connection pool of 50, and a connection timeout of 5000 milliseconds. The pool can be configured with the `hackney_pool_max_connections` and `hackney_pool_timeout` configuration keys. If you need to set other [hackney configurations](https://github.com/benoitc/hackney/blob/master/doc/hackney.md#request5) for things like a proxy, using your own pool or response timeouts, the `hackney_opts` configuration is passed directly to hackney for each request.

### Context and Breadcrumbs

Sentry has multiple options for including contextual information. They are organized into "Tags", "User", and "Extra", and Sentry's documentation on them is [here](https://docs.sentry.io/learn/context/). Breadcrumbs are a similar concept and Sentry's documentation covers them [here](https://docs.sentry.io/learn/breadcrumbs/).

In Elixir this can be complicated due to processes being isolated from one another. Tags context can be set globally through configuration, and all contexts can be set within a process, and on individual events. If an event is sent within a process that has some context configured it will include that context in the event. Examples of each are below, and for more information see the documentation of [Sentry.Context](https://hexdocs.pm/sentry/Sentry.html#module-filtering-exceptions).

```elixir
# Global Tags context via configuration:

config :sentry,
tags: %{my_app_version: "14.30.10"}
# ...

# Process-based Context
Sentry.Context.set_extra_context(%{day_of_week: "Friday"})
Sentry.Context.set_user_context(%{id: 24, username: "user_username", has_subscription: true})
Sentry.Context.set_tags_context(%{locale: "en-us"})
Sentry.Context.add_breadcrumb(%{category: "web.request"})

# Event-based Context
Sentry.capture_exception(exception, [tags: %{locale: "en-us", }, user: %{id: 34},
extra: %{day_of_week: "Friday"}, breadcrumbs: [%{timestamp: 1461185753845, category: "web.request"}]]
```

### Fingerprinting

By default, Sentry aggregates reported events according to the attributes of the event, but users may need to override this functionality via [fingerprinting](https://docs.sentry.io/learn/rollups/#customize-grouping-with-fingerprints).
Expand Down
51 changes: 30 additions & 21 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,6 @@ If using an environment with Plug or Phoenix add the following to your router:
use Sentry.Plug


Adding Context
--------------

Sentry allows a user to provide context to all error reports, Elixir being multi-process makes this a special
case. When setting a context we store that context in the process dictionary, which means if you spin up a
new process and it fails you might lose your context. That said using the context is simple:

.. code-block:: elixir

# sets the logged in user
Sentry.Context.set_user_context(%{email: "foo@example.com"})

# sets the tag of interesting
Sentry.Context.set_tags_context(%{interesting: "yes"})

# sends any additional context
Sentry.Context.set_extra_context(%{my: "context"})

# adds an breadcrumb to the request to help debug
Sentry.Context.add_breadcrumb(%{my: "crumb"})

Filtering Events
----------------

Expand Down Expand Up @@ -137,6 +116,36 @@ allows other exceptions to be sent.
included_environments: ~w(production staging),
environment_name: System.get_env("RELEASE_LEVEL") || "development"

Context and Breadcrumbs
----------------

Sentry has multiple options for including contextual information. They are organized into
"Tags", "User", and "Extra", and Sentry's documentation on them is `here <https://docs.sentry.io/learn/context/>`_.
Breadcrumbs are a similar concept and Sentry's documentation covers them `here <https://docs.sentry.io/learn/breadcrumbs/>`_.

In Elixir this can be complicated due to processes being isolated from one another. Tags
context can be set globally through configuration, and all contexts can be set within a
process, and on individual events. If an event is sent within a process that has some context
configured it will include that context in the event. Examples of each are below,
and for more information see the documentation of `Sentry.Context <https://hexdocs.pm/sentry/Sentry.html#module-filtering-exceptions>`_.

.. code-block:: elixir
# Global Tags context via configuration:

config :sentry,
tags: %{my_app_version: "14.30.10"}
# ...

# Process-based Context
Sentry.Context.set_extra_context(%{day_of_week: "Friday"})
Sentry.Context.set_user_context(%{id: 24, username: "user_username", has_subscription: true})
Sentry.Context.set_tags_context(%{locale: "en-us"})
Sentry.Context.add_breadcrumb(%{category: "web.request"})

# Event-based Context
Sentry.capture_exception(exception, [tags: %{locale: "en-us", }, user: %{id: 34},
extra: %{day_of_week: "Friday"}, breadcrumbs: [%{timestamp: 1461185753845, category: "web.request"}]]

Fingerprinting
----------------
By default, Sentry aggregates reported events according to the attributes of the event,
Expand Down
24 changes: 17 additions & 7 deletions lib/sentry/context.ex
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
defmodule Sentry.Context do
@moduledoc """
Provides a method to store user, tags, and extra context when an
event is reported. The contexts will be fetched and merged into
the event.
Provides functionality to store user, tags, extra, and breadcrumbs context when an
event is reported. The contexts will be fetched and merged into the event when it is sent.

Sentry.Context uses the Process Dictionary to store this state.
This imposes some limitations. The state will only exist within
When calling Sentry.Context, the Process Dictionary is used to store this state.
This imposes some limitations. The state will only exist within
the current process, and the context will die with the process.

For example, if you add context inside your controller and an
error happens in a Task the context won't send.
For example, if you add context inside your controller and an
error happens in a Task, that context will not be included.

A common use-case is to set context within Plug or Phoenix applications, as each
request is its own process, and so any stored context will be included should an
error be reported within that request process. Example:

# post_controller.ex
def index(conn, _params) do
Sentry.Context.set_user_context(%{id: conn.assigns.user_id})
posts = Blog.list_posts()
render(conn, "index.html", posts: posts)
end
"""
@process_dictionary_key :sentry_context
@user_key :user
Expand Down