Skip to content

Commit

Permalink
Merge pull request #401 from getsentry/use-logger-metadata-for-context
Browse files Browse the repository at this point in the history
Use logger metadata for context
  • Loading branch information
mitchellhenke authored Jun 18, 2020
2 parents 89ba002 + 8247f62 commit e9da4c6
Show file tree
Hide file tree
Showing 28 changed files with 677 additions and 600 deletions.
1 change: 1 addition & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[
import_deps: [:plug],
inputs: [
"lib/**/*.ex",
"config/*.exs",
Expand Down
15 changes: 2 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
language: elixir
elixir:
- 1.7
- 1.8
- 1.9
- 1.10
otp_release:
- 20.3
- 21.3
- 22.2
- 22.3
- 23.0
env:
- STRICT=true
- STRICT=false
matrix:
exclude:
- elixir: 1.7
env: STRICT=true
- elixir: 1.8
env: STRICT=true
- elixir: 1.9
env: STRICT=true
- elixir: 1.10
env: STRICT=false
- elixir: 1.10
otp_release: 20.3
notifications:
email:
- mitch@rokkincat.com
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
* Change default `included_environments` to only include `:prod` by default (#370)
* Change default event send type to :none instead of :async (#341)
* Make hackney an optional dependency, and simplify Sentry.HTTPClient behaviour (#400)
* Use Logger.metadata for Sentry.Context, no longer return metadata values on set_* functions, and rename `set_http_context` to `set_request_context`
* Move excluded exceptions from Sentry.Plug to Sentry.DefaultEventFilter
* Remove Sentry.Plug and Sentry.Phoenix.Endpoint in favor of Sentry.PlugContext and Sentry.PlugCapture
* Remove feedback form rendering and configuration

## 7.2.4 (2020-03-09)

Expand Down
73 changes: 53 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,10 @@

[![Build Status](https://img.shields.io/travis/getsentry/sentry-elixir.svg?style=flat)](https://travis-ci.org/getsentry/sentry-elixir)
[![hex.pm version](https://img.shields.io/hexpm/v/sentry.svg?style=flat)](https://hex.pm/packages/sentry)

The Official Sentry Client for Elixir which provides a simple API to capture exceptions, automatically handle Plug Exceptions and provides a backend for the Elixir Logger.

[Documentation](https://hexdocs.pm/sentry/readme.html)

## Note on upgrading from Sentry 6.x to 7.x

Elixir 1.7 and Erlang/OTP 21 significantly changed how errors are transmitted (See "Erlang/OTP logger integration" [here](https://elixir-lang.org/blog/2018/07/25/elixir-v1-7-0-released/)). Sentry integrated heavily with Erlang's `:error_logger` module, but it is no longer the suggested path towards handling errors.
The Official Sentry Client for Elixir which provides a simple API to capture exceptions, automatically handle Plug Exceptions and provides a backend for the Elixir Logger. This documentation represents unreleased features, for documentation on the current release, see [here](https://hexdocs.pm/sentry/readme.html).

Sentry 7.x requires Elixir 1.7 and Sentry 6.x will be maintained for applications running prior versions. Documentation for Sentry 6.x can be found [here](https://hexdocs.pm/sentry/6.4.2/readme.html).

If you would like to upgrade a project to use Sentry 7.x, see [here](https://gist.github.com/mitchellhenke/4ab6dd8d0ebeaaf9821fb625e0037a4d).

## Installation

Expand All @@ -30,26 +22,67 @@ defp deps do
end
```

### Setup with Plug or Phoenix
### Setup with Plug and Phoenix
Capturing errors in Plug applications is done with `Sentry.PlugContext` and `Sentry.PlugCapture`. `Sentry.PlugContext` adds contextual metadata from the current request which is then included in errors that are captured and reported by `Sentry.PlugCapture`.

In your Plug.Router or Phoenix.Router, add the following lines:
If you are using Phoenix, first add `Sentry.PlugCapture` above the `use Phoenix.Endpoint` line in your endpoint file. `Sentry.PlugContext` should be added below `Plug.Parsers`.

```diff
# lib/my_app_web/router.ex
defmodule MyAppWeb.Router do
use MyAppWeb, :router
+ use Plug.ErrorHandler
+ use Sentry.Plug
defmodule MyAppWeb.Endpoint
+ use Sentry.PlugCapture
use Phoenix.Endpoint, otp_app: :my_app
# ...
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Phoenix.json_library()

+ plug Sentry.PlugContext
```

If you are using Phoenix, you can also include [Sentry.Phoenix.Endpoint](https://hexdocs.pm/sentry/Sentry.Phoenix.Endpoint.html) in your Endpoint. This module captures errors occurring in the Phoenix pipeline before the request reaches the Router:
If you are in a non-Phoenix Plug application, add `Sentry.PlugCapture` at the top of your Plug application, and add `Sentry.PlugContext` below `Plug.Parsers` (if it is in your stack).

```diff
use Phoenix.Endpoint, otp_app: :my_app
+use Sentry.Phoenix.Endpoint
defmodule MyApp.Router do
+ use Sentry.PlugCapture
use Plug.Router
# ...
plug Plug.Parsers,
parsers: [:urlencoded, :multipart]
+ plug Sentry.PlugContext
```

More information on why this may be necessary can be found here: https://github.com/getsentry/sentry-elixir/issues/229 and https://github.com/phoenixframework/phoenix/issues/2791
#### Capturing User Feedback

If you would like to capture user feedback as described [here](https://docs.sentry.io/enriching-error-data/user-feedback), the `Sentry.get_last_event_id_and_source()` function can be used to see if Sentry has sent an event within the current Plug process, and the source of that event. `:plug` will be the source for events coming from `Sentry.PlugCapture`. The options described in the Sentry documentation linked above can be encoded into the response as well.

An example Phoenix application setup that wanted to display the user feedback form on 500 responses on requests accepting HTML could look like:

```elixir
defmodule MyAppWeb.ErrorView do
# ...
def render("500.html", _assigns) do
case Sentry.get_last_event_id_and_source() do
{event_id, :plug} when is_binary(event_id) ->
opts =
# can do %{eventId: event_id, title: "My custom title"}
%{eventId: event_id}
|> Jason.encode!()

~E"""
<script src="https://browser.sentry-cdn.com/5.9.1/bundle.min.js" integrity="sha384-/x1aHz0nKRd6zVUazsV6CbQvjJvr6zQL2CHbQZf3yoLkezyEtZUpqUNnOLW9Nt3v" crossorigin="anonymous"></script>
<script>
Sentry.init({ dsn: '<%= Sentry.Config.dsn() %>' });
Sentry.showReportDialog(<%= raw opts %>)
</script>
"""

_ ->
"Error"
end
# ...
end
```

### Capture Crashed Process Exceptions

Expand Down
2 changes: 2 additions & 0 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ config :sentry,

config :ex_unit,
assert_receive_timeout: 500

config :phoenix, :json_library, Jason
19 changes: 19 additions & 0 deletions lib/sentry.ex
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,25 @@ defmodule Sentry do
end
end

@doc """
Puts the last event ID sent to the server for the current process in
the process dictionary.
"""
@spec put_last_event_id_and_source(String.t()) :: {String.t(), atom() | nil} | nil
def put_last_event_id_and_source(event_id, source \\ nil) when is_binary(event_id) do
Process.put(:sentry_last_event_id_and_source, {event_id, source})
end

@doc """
Gets the last event ID sent to the server from the process dictionary.
Since it uses the process dictionary, it will only return the last event
ID sent within the current process.
"""
@spec get_last_event_id_and_source() :: {String.t(), atom() | nil} | nil
def get_last_event_id_and_source do
Process.get(:sentry_last_event_id_and_source)
end

@doc """
Reports a message to Sentry.
Expand Down
4 changes: 4 additions & 0 deletions lib/sentry/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ defmodule Sentry.Client do
maybe_log_result(result)
end

if match?({:ok, _}, result) do
Sentry.put_last_event_id_and_source(event.event_id, event.event_source)
end

result

{:error, error} ->
Expand Down
Loading

0 comments on commit e9da4c6

Please sign in to comment.