From 04b2f101cc52c14b9ac8b69703a0ac6aab5b90f3 Mon Sep 17 00:00:00 2001 From: Steven Harman Date: Wed, 8 May 2024 09:29:21 -0400 Subject: [PATCH] Warn when enabling socket_telemetry on unsupported platform The structs we depend on for collecting socket telemetry (`SOL_TCP` and `TCP_INFO`) don't exist on all platforms. In such cases, these constants won't be defined, and so we should WARN users and not enabled the `socket_telemetry` option. NOTE: On macOS, similar structs do exist: `Socket::IPPROTO_TCP` and `Socket::TCP_CONNECTION_INFO`, respectively, but I couldn't figure out the binary layout of the data, so couldn't unpack it. Maybe someone else knows more about those details and can dig in at some point. --- lib/puma/plugin/telemetry/config.rb | 9 ++++++++- spec/integration/plugin_spec.rb | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/puma/plugin/telemetry/config.rb b/lib/puma/plugin/telemetry/config.rb index 1f26718..526e42f 100644 --- a/lib/puma/plugin/telemetry/config.rb +++ b/lib/puma/plugin/telemetry/config.rb @@ -91,7 +91,14 @@ def enabled? end def socket_telemetry! - @socket_telemetry = true + # These structs are platform specific, and not available on macOS, + # for example. If they're undefined, then we cannot capture socket + # telemetry. We'll warn in that case. + if defined?(Socket::SOL_TCP) && defined?(Socket::TCP_INFO) + @socket_telemetry = true + else + warn("Cannot capture socket telemetry on this platform (#{RUBY_PLATFORM}); socket_telemetry is disabled.") + end end def socket_telemetry? diff --git a/spec/integration/plugin_spec.rb b/spec/integration/plugin_spec.rb index 81628c3..1436663 100644 --- a/spec/integration/plugin_spec.rb +++ b/spec/integration/plugin_spec.rb @@ -105,6 +105,10 @@ def make_request end it 'logs socket telemetry' do + unless defined?(Socket::SOL_TCP) && defined?(Socket::TCP_INFO) + skip("Socket::SOL_TCP not defined on #{RUBY_PLATFORM}") + end + threads = Array.new(2) { make_request } sleep 0.1 @@ -123,7 +127,7 @@ def make_request possible_lines = ['queue.backlog=1 sockets.backlog=5', 'queue.backlog=0 sockets.backlog=6'] - expect(possible_lines.include?(line)).to eq(true) + expect(possible_lines).to include(line) total = line.split.sum { |kv| kv.split('=').last.to_i } expect(total).to eq 6