-
-
Notifications
You must be signed in to change notification settings - Fork 199
/
Copy pathhttp_client.ex
129 lines (95 loc) · 3.92 KB
/
http_client.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
defmodule Sentry.HTTPClient do
@moduledoc """
A behaviour for HTTP clients that Sentry can use.
The default HTTP client is `Sentry.HackneyClient`.
To configure a different HTTP client, implement the `Sentry.HTTPClient` behaviour and
change the `:client` configuration:
config :sentry,
client: MyHTTPClient
## Child Spec
The `c:child_spec/0` callback is a callback that should be used when you want Sentry
to start the HTTP client *under its supervision tree*. If you want to start your own
HTTP client under your application's supervision tree, just don't implement the callback
and Sentry won't do anything to start the client.
> #### Optional Since v9.0.0 {: .warning}
>
> The `c:child_spec/0` callback is optional only since v9.0.0 of Sentry, and was required
> before.
## Alternative Clients
Let's look at an example of using an alternative HTTP client. In this example, we'll
use [Finch](https://github.com/sneako/finch), a lightweight HTTP client for Elixir.
First, we need to add Finch to our dependencies:
# In mix.exs
defp deps do
[
# ...
{:finch, "~> 0.16"}
]
end
Then, we need to define a module that implements the `Sentry.HTTPClient` behaviour:
defmodule MyApp.SentryFinchHTTPClient do
@behaviour Sentry.HTTPClient
@impl true
def child_spec do
Supervisor.child_spec({Finch, name: __MODULE__}, id: __MODULE__)
end
@impl true
def post(url, headers, body) do
request = Finch.build(:post, url, headers, body)
case Finch.request(request, __MODULE__) do
{:ok, %Finch.Response{status: status, headers: headers, body: body}} ->
{:ok, status, headers, body}
{:error, error} ->
{:error, error}
end
end
end
Last, we need to configure Sentry to use our new HTTP client:
config :sentry,
client: MyApp.SentryFinchHTTPClient
### Umbrella Apps
The HTTP client for Sentry is configured globally for the `:sentry` application. In an
umbrella setup, this means that all applications must configure Sentry to use the same
HTTP client.
If you want to use an alternative Sentry HTTP client in your umbrella application, we
recommend to do this:
1. Create a new application in the umbrella (we'll call it `sentry_http_client`).
1. Add `:sentry` as a dependency of the new application.
1. Add a new module to the new application (such as `SentryHTTPClient`) which implements
the desired `Sentry.HTTPClient` behaviour.
1. Configure `:sentry` to use the "shared" HTTP client. This works because configuration
in umbrella apps is generally shared by all apps within the umbrella (and it's in
`config/config.exs` at the root of the umbrella).
config :sentry,
# ...
client: SentryHTTPClient
"""
@typedoc """
The response status for an HTTP request.
"""
@typedoc since: "9.0.0"
@type status :: 100..599
@typedoc """
HTTP request or response headers.
"""
@type headers :: [{String.t(), String.t()}]
@typedoc """
HTTP request or response body.
"""
@typedoc since: "9.0.0"
@type body :: binary()
@doc """
Should return a **child specification** to start the HTTP client.
For example, this can start a pool of HTTP connections dedicated to Sentry.
If not provided, Sentry won't do anything to start your HTTP client. See
[the module documentation](#module-child-spec) for more info.
"""
@callback child_spec() :: :supervisor.child_spec()
@doc """
Should make an HTTP `POST` request to `url` with the given `headers` and `body`.
"""
@callback post(url :: String.t(), request_headers :: headers(), request_body :: body()) ::
{:ok, status(), response_headers :: headers(), response_body :: body()}
| {:error, term()}
@optional_callbacks [child_spec: 0]
end