Skip to content

Commit 4dfdeb5

Browse files
committed
separate hackney pool
1 parent a3674ac commit 4dfdeb5

File tree

5 files changed

+37
-3
lines changed

5 files changed

+37
-3
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ config :sentry,
6868
| `server_name` | False | None | |
6969
| `use_error_logger` | False | False | |
7070
| hackney_opts | False | [] | |
71+
| hackney_pool_max_connections | False | 50 | |
72+
| hackney_pool_timeout | False | 5000 | |
7173

7274
An example production config might look like this:
7375

@@ -113,7 +115,7 @@ Now, on our servers, we can set the environment variable appropriately. On
113115
our local development machines, exceptions will never be sent, because the
114116
default value is not in the list of `included_environments`.
115117

116-
Sentry uses the [hackney HTTP client](https://github.com/benoitc/hackney) for HTTP requests. If you need to set [hackney configurations](https://github.com/benoitc/hackney/blob/master/doc/hackney.md#request5) for things like a proxy or different pool, the `hackney_opts` configuration is passed directly to hackney.
118+
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.
117119

118120
## Testing Your Configuration
119121

config/test.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ use Mix.Config
22

33
config :sentry,
44
environment_name: :test,
5-
client: Sentry.TestClient
5+
client: Sentry.TestClient,
6+
hackney_opts: [recv_timeout: 50]

lib/sentry.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,13 @@ defmodule Sentry do
9494
@client Application.get_env(:sentry, :client, Sentry.Client)
9595
@use_error_logger Application.get_env(:sentry, :use_error_logger, false)
9696
@default_environment_name Mix.env
97+
@max_hackney_connections Application.get_env(:sentry, :hackney_pool_max_connections, 50)
98+
@hackney_timeout Application.get_env(:sentry, :hackney_pool_timeout, 5000)
9799

98100
def start(_type, _opts) do
99101
children = [
100102
supervisor(Task.Supervisor, [[name: Sentry.TaskSupervisor]]),
103+
:hackney_pool.child_spec(Sentry.Client.hackney_pool_name(), [timeout: @hackney_timeout, max_connections: @max_hackney_connections])
101104
]
102105
opts = [strategy: :one_for_one, name: Sentry.Supervisor]
103106

lib/sentry/client.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ defmodule Sentry.Client do
44
@type get_dsn :: {String.t, String.t, Integer.t}
55
@sentry_version 5
66
@max_attempts 4
7+
@hackney_pool_name :sentry_pool
78

89
quote do
910
unquote(@sentry_client "sentry-elixir/#{Mix.Project.config[:version]}")
@@ -55,6 +56,7 @@ defmodule Sentry.Client do
5556
"""
5657
def request(method, url, headers, body) do
5758
hackney_opts = Application.get_env(:sentry, :hackney_opts, [])
59+
|> Keyword.put_new(:pool, @hackney_pool_name)
5860
case :hackney.request(method, url, headers, body, hackney_opts) do
5961
{:ok, 200, _headers, client} ->
6062
case :hackney.body(client) do
@@ -108,6 +110,10 @@ defmodule Sentry.Client do
108110
{endpoint, public_key, secret_key}
109111
end
110112

113+
def hackney_pool_name do
114+
@hackney_pool_name
115+
end
116+
111117
defp fetch_dsn do
112118
case Application.fetch_env!(:sentry, :dsn) do
113119
{:system, env_var} -> System.get_env(env_var)
@@ -117,7 +123,7 @@ defmodule Sentry.Client do
117123

118124
defp log_api_error(body) do
119125
Logger.warn(fn ->
120-
["Failed to send sentry event.", ?\n, body]
126+
["Failed to send Sentry event.", ?\n, body]
121127
end)
122128
end
123129

test/sentry_test.exs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule SentryTest do
22
use ExUnit.Case
3+
import ExUnit.CaptureLog
34

45
test "excludes events properly" do
56
Application.put_env(:sentry, :filter, Sentry.TestFilter)
@@ -22,4 +23,25 @@ defmodule SentryTest do
2223
assert :excluded = Sentry.capture_exception(%ArithmeticError{message: "error"}, [event_source: :plug])
2324
assert {:ok, _} = Sentry.capture_message("RuntimeError: error", [event_source: :plug])
2425
end
26+
27+
test "errors when taking too long to receive response" do
28+
Application.put_env(:sentry, :filter, Sentry.TestFilter)
29+
30+
bypass = Bypass.open
31+
Bypass.expect bypass, fn conn ->
32+
:timer.sleep(100)
33+
assert conn.request_path == "/api/1/store/"
34+
assert conn.method == "POST"
35+
Plug.Conn.send_resp(conn, 200, ~s<{"id": "340"}>)
36+
end
37+
Bypass.pass(bypass)
38+
39+
Application.put_env(:sentry, :dsn, "http://public:secret@localhost:#{bypass.port}/1")
40+
Application.put_env(:sentry, :included_environments, [:test])
41+
Application.put_env(:sentry, :environment_name, :test)
42+
43+
assert capture_log(fn ->
44+
assert :error = Sentry.capture_message("error", [])
45+
end) =~ "Failed to send Sentry event"
46+
end
2547
end

0 commit comments

Comments
 (0)