diff --git a/README.md b/README.md
index abde5298..976ce0ca 100644
--- a/README.md
+++ b/README.md
@@ -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).
diff --git a/docs/index.rst b/docs/index.rst
index 0c57ffb8..85285a2b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -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
----------------
@@ -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 `_.
+Breadcrumbs are a similar concept and Sentry's documentation covers them `here `_.
+
+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 `_.
+
+.. 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,
diff --git a/lib/sentry/context.ex b/lib/sentry/context.ex
index d0d2d426..7b1c9a19 100644
--- a/lib/sentry/context.ex
+++ b/lib/sentry/context.ex
@@ -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