diff --git a/lib/nerve/prometheus_metrics.rb b/lib/nerve/prometheus_metrics.rb index 6bf2a8a..b8c8279 100644 --- a/lib/nerve/prometheus_metrics.rb +++ b/lib/nerve/prometheus_metrics.rb @@ -170,6 +170,9 @@ def start_server(bind, port) end Thread.new { @@prom_server.start } + rescue Errno::EADDRINUSE, Errno::EACCES => e + log.error "nerve: prometheus metrics failed to bind to #{bind}:#{port} (#{e.class}: #{e.message})" + raise end end diff --git a/spec/lib/nerve/prometheus_metrics_spec.rb b/spec/lib/nerve/prometheus_metrics_spec.rb index c5c561d..7821941 100644 --- a/spec/lib/nerve/prometheus_metrics_spec.rb +++ b/spec/lib/nerve/prometheus_metrics_spec.rb @@ -169,15 +169,37 @@ def configure_without_server(opts = {}) describe "HTTP server" do it "serves /metrics endpoint" do - Nerve::PrometheusMetrics.configure({"enabled" => true, "port" => 19297}) + Nerve::PrometheusMetrics.configure({ + "enabled" => true, + "bind" => "127.0.0.1", + "port" => 0 + }) sleep 0.2 + server = Nerve::PrometheusMetrics.class_variable_get(:@@prom_server) + port = server.listeners.first.addr[1] + require "net/http" - response = Net::HTTP.get_response("127.0.0.1", "/metrics", 19297) + response = Net::HTTP.get_response("127.0.0.1", "/metrics", port) expect(response.code).to eq("200") expect(response["content-type"]).to include("text/plain") expect(response.body).to include("nerve_build_info") end + + it "fails fast when the port is already in use" do + server = TCPServer.new("127.0.0.1", 0) + port = server.addr[1] + + expect { + Nerve::PrometheusMetrics.configure({ + "enabled" => true, + "bind" => "127.0.0.1", + "port" => port + }) + }.to raise_error(Errno::EADDRINUSE) + ensure + server&.close + end end describe ".stop_server" do