Skip to content

Commit ece3fcf

Browse files
authored
Merge pull request #445 from binaryseed/add-bandit
Add Bandit HTTP server support
2 parents 2d1830a + e186642 commit ece3fcf

File tree

10 files changed

+239
-123
lines changed

10 files changed

+239
-123
lines changed

.github/workflows/elixir.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ jobs:
139139

140140
- name: Start integration test dependencies
141141
run: |
142-
docker-compose up -d
142+
docker compose up -d
143143
until pg_isready -h localhost; do sleep 1; done;
144144
until mysqladmin --protocol tcp ping; do sleep 1; done;
145145

examples/apps/phx_example/config/config.exs

+10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ config :phx_example, PhxExampleWeb.Endpoint,
1010
live_view: [signing_salt: "dB7qn7EQ"],
1111
secret_key_base: "A+gtEDayUNx4ZyfHvUKETwRC4RjxK0FDlrLjuRhaBnr3Ll3ynfu5RlSSGe5E7zbW"
1212

13+
config :phx_example, PhxExampleWeb.BanditEndpoint,
14+
url: [host: "localhost"],
15+
render_errors: [formats: [html: PhxExampleWeb.ErrorHTML], layout: false],
16+
http: [port: 4005],
17+
server: true,
18+
adapter: Bandit.PhoenixAdapter,
19+
pubsub_server: PhxExample.PubSub,
20+
live_view: [signing_salt: "dB7qn7EQ"],
21+
secret_key_base: "A+gtEDayUNx4ZyfHvUKETwRC4RjxK0FDlrLjuRhaBnr3Ll3ynfu5RlSSGe5E7zbW"
22+
1323
config :logger, level: :warning
1424

1525
config :phoenix, :json_library, Jason

examples/apps/phx_example/lib/phx_example/application.ex

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ defmodule PhxExample.Application do
66
def start(_type, _args) do
77
children = [
88
{Phoenix.PubSub, name: PhxExample.PubSub},
9-
PhxExampleWeb.Endpoint
9+
PhxExampleWeb.Endpoint,
10+
PhxExampleWeb.BanditEndpoint
1011
]
1112

1213
opts = [strategy: :one_for_one, name: PhxExample.Supervisor]
@@ -15,6 +16,7 @@ defmodule PhxExample.Application do
1516

1617
def config_change(changed, _new, removed) do
1718
PhxExampleWeb.Endpoint.config_change(changed, removed)
19+
PhxExampleWeb.BanditEndpoint.config_change(changed, removed)
1820
:ok
1921
end
2022
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
defmodule PhxExampleWeb.BanditEndpoint do
2+
use Phoenix.Endpoint, otp_app: :phx_example
3+
4+
@session_options [
5+
store: :cookie,
6+
key: "_phx_example_key",
7+
signing_salt: "F6n7gjjvL6I61gUB",
8+
same_site: "Lax"
9+
]
10+
11+
socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]
12+
13+
plug Plug.Static,
14+
at: "/",
15+
from: :phx_example,
16+
gzip: false,
17+
only: PhxExampleWeb.static_paths()
18+
19+
plug Plug.RequestId
20+
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
21+
22+
plug Plug.Parsers,
23+
parsers: [:urlencoded, :multipart, :json],
24+
pass: ["*/*"],
25+
json_decoder: Phoenix.json_library()
26+
27+
plug Plug.MethodOverride
28+
plug Plug.Head
29+
plug Plug.Session, @session_options
30+
plug PhxExampleWeb.Router
31+
end

examples/apps/phx_example/mix.exs

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ defmodule PhxExample.MixProject do
3131
{:phoenix_view, "~> 2.0"},
3232
{:phoenix_live_view, "~> 0.20"},
3333
{:jason, "~> 1.0"},
34-
{:plug_cowboy, "~> 2.0"}
34+
{:plug_cowboy, "~> 2.0"},
35+
{:bandit, "~> 1.0"}
3536
]
3637
end
3738
end

examples/apps/phx_example/test/phx_example_test.exs

+105-93
Original file line numberDiff line numberDiff line change
@@ -5,133 +5,145 @@ defmodule PhxExampleTest do
55

66
setup_all context, do: TestSupport.simulate_agent_enabled(context)
77

8-
test "Phoenix metrics generated" do
9-
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
10-
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
8+
for server <- [:cowboy, :bandit] do
9+
describe "Testing #{server}:" do
10+
test "Phoenix metrics generated" do
11+
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
12+
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
1113

12-
{:ok, %{body: body}} = request("/phx/bar")
13-
assert body =~ "Welcome to Phoenix"
14+
{:ok, %{body: body}} = request("/phx/bar", unquote(server))
15+
assert body =~ "Welcome to Phoenix"
1416

15-
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
17+
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
1618

17-
assert TestSupport.find_metric(
18-
metrics,
19-
"WebTransaction/Phoenix/PhxExampleWeb.PageController/index"
20-
)
19+
assert TestSupport.find_metric(
20+
metrics,
21+
"WebTransaction/Phoenix/PhxExampleWeb.PageController/index"
22+
)
2123

22-
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
24+
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
2325

24-
assert event[:"phoenix.endpoint"] == "PhxExampleWeb.Endpoint"
25-
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
26-
assert event[:"phoenix.controller"] == "PhxExampleWeb.PageController"
27-
assert event[:"phoenix.action"] == "index"
28-
assert event[:status] == 200
29-
end
26+
assert event[:"phoenix.endpoint"] =~ "PhxExampleWeb"
27+
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
28+
assert event[:"phoenix.controller"] == "PhxExampleWeb.PageController"
29+
assert event[:"phoenix.action"] == "index"
30+
assert event[:status] == 200
31+
end
3032

31-
test "Phoenix metrics generated for LiveView" do
32-
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
33-
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
33+
test "Phoenix metrics generated for LiveView" do
34+
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
35+
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
3436

35-
{:ok, %{body: body}} = request("/phx/home")
36-
assert body =~ "Some content"
37+
{:ok, %{body: body}} = request("/phx/home", unquote(server))
38+
assert body =~ "Some content"
3739

38-
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
40+
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
3941

40-
assert TestSupport.find_metric(
41-
metrics,
42-
"WebTransaction/Phoenix/PhxExampleWeb.HomeLive/index"
43-
)
42+
assert TestSupport.find_metric(
43+
metrics,
44+
"WebTransaction/Phoenix/PhxExampleWeb.HomeLive/index"
45+
)
4446

45-
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
47+
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
4648

47-
assert event[:"phoenix.endpoint"] == "PhxExampleWeb.Endpoint"
48-
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
49-
assert event[:"phoenix.controller"] == "Phoenix.LiveView.Plug"
50-
assert event[:"phoenix.action"] == "index"
51-
assert event[:status] == 200
52-
end
49+
assert event[:"phoenix.endpoint"] =~ "PhxExampleWeb"
50+
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
51+
assert event[:"phoenix.controller"] == "Phoenix.LiveView.Plug"
52+
assert event[:"phoenix.action"] == "index"
53+
assert event[:status] == 200
54+
end
5355

54-
@tag :capture_log
55-
test "Phoenix error" do
56-
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
57-
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
56+
@tag :capture_log
57+
test "Phoenix error" do
58+
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
59+
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
5860

59-
{:ok, %{body: body, status_code: 500}} = request("/phx/error")
61+
{:ok, %{body: body, status_code: 500}} = request("/phx/error", unquote(server))
6062

61-
assert body =~ "Oops, Internal Server Error"
63+
assert body =~ "Oops, Internal Server Error"
6264

63-
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
65+
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
6466

65-
assert TestSupport.find_metric(
66-
metrics,
67-
"WebTransaction/Phoenix/PhxExampleWeb.PageController/error"
68-
)
67+
assert TestSupport.find_metric(
68+
metrics,
69+
"WebTransaction/Phoenix/PhxExampleWeb.PageController/error"
70+
)
6971

70-
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
72+
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
7173

72-
assert event[:status] == 500
73-
assert event[:"phoenix.endpoint"] == "PhxExampleWeb.Endpoint"
74-
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
75-
assert event[:"phoenix.controller"] == "PhxExampleWeb.PageController"
76-
assert event[:"phoenix.action"] == "error"
77-
assert event[:error]
78-
end
74+
assert event[:status] == 500
75+
assert event[:"phoenix.endpoint"] =~ "PhxExampleWeb"
76+
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
77+
assert event[:"phoenix.controller"] == "PhxExampleWeb.PageController"
78+
assert event[:"phoenix.action"] == "error"
79+
assert event[:error]
80+
end
7981

80-
@tag :capture_log
81-
test "Phoenix LiveView error" do
82-
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
83-
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
82+
@tag :capture_log
83+
test "Phoenix LiveView error" do
84+
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
85+
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
8486

85-
{:ok, %{body: body, status_code: 500}} = request("/phx/live_error")
87+
{:ok, %{body: body, status_code: 500}} = request("/phx/live_error", unquote(server))
8688

87-
assert body =~ "Oops, Internal Server Error"
89+
assert body =~ "Oops, Internal Server Error"
8890

89-
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
91+
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
9092

91-
assert TestSupport.find_metric(
92-
metrics,
93-
"WebTransaction/Phoenix/PhxExampleWeb.ErrorLive/index"
94-
)
93+
assert TestSupport.find_metric(
94+
metrics,
95+
"WebTransaction/Phoenix/PhxExampleWeb.ErrorLive/index"
96+
)
9597

96-
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
98+
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
9799

98-
assert event[:status] == 500
99-
assert event[:"phoenix.endpoint"] == "PhxExampleWeb.Endpoint"
100-
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
101-
assert event[:"phoenix.controller"] == "Phoenix.LiveView.Plug"
102-
assert event[:"phoenix.action"] == "index"
103-
assert event[:error]
104-
end
100+
assert event[:status] == 500
101+
assert event[:"phoenix.endpoint"] =~ "PhxExampleWeb"
102+
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
103+
assert event[:"phoenix.controller"] == "Phoenix.LiveView.Plug"
104+
assert event[:"phoenix.action"] == "index"
105+
assert event[:error]
106+
end
107+
108+
test "Phoenix route not found" do
109+
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
110+
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
111+
TestSupport.restart_harvest_cycle(Collector.ErrorTrace.HarvestCycle)
105112

106-
test "Phoenix route not found" do
107-
TestSupport.restart_harvest_cycle(Collector.Metric.HarvestCycle)
108-
TestSupport.restart_harvest_cycle(Collector.TransactionEvent.HarvestCycle)
109-
TestSupport.restart_harvest_cycle(Collector.ErrorTrace.HarvestCycle)
113+
{:ok, %{body: body, status_code: 404}} = request("/not_found", unquote(server))
114+
assert body =~ "Not Found"
110115

111-
{:ok, %{body: body, status_code: 404}} = request("/not_found")
112-
assert body =~ "Not Found"
116+
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
113117

114-
metrics = TestSupport.gather_harvest(Collector.Metric.Harvester)
118+
metric =
119+
case unquote(server) do
120+
:cowboy -> "WebTransaction/Phoenix/PhxExampleWeb.Endpoint/GET"
121+
:bandit -> "WebTransaction/Phoenix/PhxExampleWeb.BanditEndpoint/GET"
122+
end
115123

116-
assert TestSupport.find_metric(
117-
metrics,
118-
"WebTransaction/Phoenix/PhxExampleWeb.Endpoint/GET"
119-
)
124+
assert TestSupport.find_metric(metrics, metric)
120125

121-
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
126+
[[_, event]] = TestSupport.gather_harvest(Collector.TransactionEvent.Harvester)
122127

123-
assert event[:status] == 404
124-
assert event[:"phoenix.endpoint"] == "PhxExampleWeb.Endpoint"
125-
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
126-
refute event[:"phoenix.controller"]
127-
refute event[:error]
128+
assert event[:status] == 404
129+
assert event[:"phoenix.endpoint"] =~ "PhxExampleWeb"
130+
assert event[:"phoenix.router"] == "PhxExampleWeb.Router"
131+
refute event[:"phoenix.controller"]
132+
refute event[:error]
128133

129-
errors = TestSupport.gather_harvest(Collector.ErrorTrace.Harvester)
130-
assert errors == []
134+
errors = TestSupport.gather_harvest(Collector.ErrorTrace.Harvester)
135+
assert errors == []
136+
end
137+
end
131138
end
132139

133-
defp request(path) do
134-
config = Application.get_env(:phx_example, PhxExampleWeb.Endpoint)
140+
defp request(path, server) do
141+
config =
142+
case server do
143+
:cowboy -> Application.get_env(:phx_example, PhxExampleWeb.Endpoint)
144+
:bandit -> Application.get_env(:phx_example, PhxExampleWeb.BanditEndpoint)
145+
end
146+
135147
NewRelic.Util.HTTP.get("http://localhost:#{config[:http][:port]}#{path}")
136148
end
137149
end

examples/apps/test_support/lib/test_support.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ defmodule TestSupport do
66

77
def gather_harvest(harvester) do
88
Process.sleep(300)
9-
harvester.gather_harvest
9+
harvester.gather_harvest()
1010
end
1111

1212
def restart_harvest_cycle(harvest_cycle) do

examples/mix.lock

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
%{
2+
"bandit": {:hex, :bandit, "1.5.7", "6856b1e1df4f2b0cb3df1377eab7891bec2da6a7fd69dc78594ad3e152363a50", [:mix], [{:hpax, "~> 1.0.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "f2dd92ae87d2cbea2fa9aa1652db157b6cba6c405cb44d4f6dd87abba41371cd"},
23
"castore": {:hex, :castore, "0.1.9", "eb08a94c12ebff92a92d844c6ccd90728dc7662aab9bdc8b3b785ba653c499d5", [:mix], [], "hexpm", "99c3a38ad9c0bab03fee1418c98390da1a31f3b85e317db5840d51a1443d26c8"},
34
"cc_precompiler": {:hex, :cc_precompiler, "0.1.9", "e8d3364f310da6ce6463c3dd20cf90ae7bbecbf6c5203b98bf9b48035592649b", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "9dcab3d0f3038621f1601f13539e7a9ee99843862e66ad62827b0c42b2f58a54"},
45
"certifi": {:hex, :certifi, "2.5.3", "70bdd7e7188c804f3a30ee0e7c99655bc35d8ac41c23e12325f36ab449b70651", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "ed516acb3929b101208a9d700062d520f3953da3b6b918d866106ffa980e1c10"},
@@ -13,6 +14,7 @@
1314
"elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"},
1415
"exqlite": {:hex, :exqlite, "0.17.0", "865ab503debde7913ffa02b58838ab92885165978f4c88d8169ee8688c655d1e", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "719fa7986fed242839629a907d60f774000c1d2dc03ba6ba05fcd30579f2ab45"},
1516
"hackney": {:hex, :hackney, "1.17.0", "717ea195fd2f898d9fe9f1ce0afcc2621a41ecfe137fae57e7fe6e9484b9aa99", [:rebar3], [{:certifi, "~>2.5", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "64c22225f1ea8855f584720c0e5b3cd14095703af1c9fbc845ba042811dc671c"},
17+
"hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
1618
"httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"},
1719
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
1820
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
@@ -35,6 +37,7 @@
3537
"redix": {:hex, :redix, "1.0.0", "4f310341744ffceab3031394450a4e603d4d1001a697c3f18ae57ae776cbd3fb", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8c8d9b33b5491737adcd5bb9e0f43b85212a384ac0042f64c156113518266ecb"},
3638
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
3739
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
40+
"thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
3841
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
3942
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
4043
"websock_adapter": {:hex, :websock_adapter, "0.5.5", "9dfeee8269b27e958a65b3e235b7e447769f66b5b5925385f5a569269164a210", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b977ba4a01918acbf77045ff88de7f6972c2a009213c515a445c48f224ffce9"},

lib/new_relic/sampler/beam.ex

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ defmodule NewRelic.Sampler.Beam do
104104
safe_div(active, total)
105105
end
106106

107-
defp safe_div(_, 0.0), do: 0.0
107+
defp safe_div(_, +0.0), do: 0.0
108+
defp safe_div(_, -0.0), do: 0.0
108109
defp safe_div(a, b), do: a / b
109110
end

0 commit comments

Comments
 (0)