From 9023518b14520efd1c684fad19d4dcac2e5ea9f7 Mon Sep 17 00:00:00 2001 From: Johan van den Dorpe Date: Wed, 2 Jan 2019 17:55:01 +0100 Subject: [PATCH 1/5] Allow setting open_timeout and read_timeout. Capture Net::HTTP errors for these timeouts. --- CHANGELOG.md | 2 ++ bin/check-http.rb | 22 +++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7375c72..1960834 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md) ## [Unreleased] +### Changed +- `check-http.rb`: Add options to set open-timeout and read-timeout for Net:HTTP. Improve output on what Net::HTTP timeout was encountered. ## [4.0.0] - 2018-12-17 ### Breaking Changes diff --git a/bin/check-http.rb b/bin/check-http.rb index 0533c3b..2d931ba 100755 --- a/bin/check-http.rb +++ b/bin/check-http.rb @@ -165,7 +165,19 @@ class CheckHttp < Sensu::Plugin::Check::CLI short: '-t SECS', long: '--timeout SECS', proc: proc(&:to_i), - description: 'Set the timeout', + description: 'Set the total execution timeout in seconds', + default: 15 + + option :open_timeout, + long: '--open-timeout SECS', + proc: proc(&:to_i), + description: 'Number of seconds to wait for the connection to open', + default: 15 + + option :read_timeout, + long: '--read-timeout SECS', + proc: proc(&:to_i), + description: 'Number of seconds to wait for one block to be read', default: 15 option :redirectok, @@ -254,6 +266,10 @@ def run Timeout.timeout(config[:timeout]) do acquire_resource end + rescue Net::OpenTimeout + critical 'Request timed out opening connection' + rescue Net::ReadTimeout + critical 'Request timed out reading data' rescue Timeout::Error critical 'Request timed out' rescue StandardError => e @@ -279,8 +295,8 @@ def acquire_resource else http = Net::HTTP.new(config[:host], config[:port]) end - http.read_timeout = config[:timeout] - http.open_timeout = config[:timeout] + http.read_timeout = config[:read_timeout] + http.open_timeout = config[:open_timeout] http.ssl_timeout = config[:timeout] http.continue_timeout = config[:timeout] http.keep_alive_timeout = config[:timeout] From b025c62429437405d49ddb1f5b257065aab45066 Mon Sep 17 00:00:00 2001 From: Johan van den Dorpe Date: Mon, 14 Jan 2019 12:32:31 +0000 Subject: [PATCH 2/5] Add vendor/ to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 39840db..28603dd 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ mkmf.log #Intellij files *.iml *.idea + +vendor/ From e56904eeff076f8cd15d405c8d944b8a9c6697be Mon Sep 17 00:00:00 2001 From: Johan van den Dorpe Date: Mon, 14 Jan 2019 12:46:16 +0000 Subject: [PATCH 3/5] Use ruby DNS resolver and set DNS resolution timeout --- CHANGELOG.md | 1 + bin/check-http.rb | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1960834..44ec071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins ## [Unreleased] ### Changed - `check-http.rb`: Add options to set open-timeout and read-timeout for Net:HTTP. Improve output on what Net::HTTP timeout was encountered. +- `check-http.rb`: Use ruby DNS resolver, and set DNS resolution timeout. ## [4.0.0] - 2018-12-17 ### Breaking Changes diff --git a/bin/check-http.rb b/bin/check-http.rb index 2d931ba..cda472b 100755 --- a/bin/check-http.rb +++ b/bin/check-http.rb @@ -59,6 +59,7 @@ require 'net/http' require 'net/https' require 'digest' +require 'resolv-replace' # # Check HTTP @@ -262,6 +263,11 @@ def run config[:port] ||= config[:ssl] ? 443 : 80 end + # Use Ruby DNS Resolver and set DNS resolution timeout to 800ms + dns_resolver = Resolv::DNS.new + dns_resolver.timeouts = 0.8 + Resolv::DefaultResolver.replace_resolvers([dns_resolver]) + begin Timeout.timeout(config[:timeout]) do acquire_resource From 36dd33506bedb423f5a0c68073fba2295d5cefdb Mon Sep 17 00:00:00 2001 From: Johan van den Dorpe Date: Tue, 15 Jan 2019 17:21:40 +0000 Subject: [PATCH 4/5] Add hosts resolver, and add test for DNS timeouts --- bin/check-http.rb | 13 ++++++++++--- .../helpers/serverspec/check-http-shared_spec.rb | 12 +++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/bin/check-http.rb b/bin/check-http.rb index cda472b..b63abcb 100755 --- a/bin/check-http.rb +++ b/bin/check-http.rb @@ -181,6 +181,12 @@ class CheckHttp < Sensu::Plugin::Check::CLI description: 'Number of seconds to wait for one block to be read', default: 15 + option :dns_timeout, + long: '--dns-timeout SECS', + proc: proc(&:to_f), + description: 'Number of seconds to allow for DNS resolution. Accepts decimal number.', + default: 0.8 + option :redirectok, short: '-r', boolean: true, @@ -263,10 +269,11 @@ def run config[:port] ||= config[:ssl] ? 443 : 80 end - # Use Ruby DNS Resolver and set DNS resolution timeout to 800ms + # Use Ruby DNS Resolver and set DNS resolution timeout to dns_timeout value + hosts_resolver = Resolv::Hosts.new dns_resolver = Resolv::DNS.new - dns_resolver.timeouts = 0.8 - Resolv::DefaultResolver.replace_resolvers([dns_resolver]) + dns_resolver.timeouts = config[:dns_timeout] + Resolv::DefaultResolver.replace_resolvers([hosts_resolver, dns_resolver]) begin Timeout.timeout(config[:timeout]) do diff --git a/test/integration/helpers/serverspec/check-http-shared_spec.rb b/test/integration/helpers/serverspec/check-http-shared_spec.rb index 32bd93a..78ce371 100644 --- a/test/integration/helpers/serverspec/check-http-shared_spec.rb +++ b/test/integration/helpers/serverspec/check-http-shared_spec.rb @@ -6,7 +6,7 @@ gem_path = '/usr/local/bin' check_name = 'check-http.rb' check = "#{gem_path}/#{check_name}" -domain = 'localhost' +domain = '127.0.0.1' describe 'ruby environment' do it_behaves_like 'ruby checks', check @@ -40,8 +40,14 @@ describe command("#{check} --url https://#{domain}/okay") do its(:exit_status) { should eq 2 } if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0') - its(:stdout) { should match(/CheckHttp CRITICAL: Request error: Failed to open TCP connection to localhost:443/) } + its(:stdout) { should match(/CheckHttp CRITICAL: Request error: Failed to open TCP connection to 127.0.0.1:443/) } else - its(:stdout) { should match(/CheckHttp CRITICAL: Request error: Cannot assign requested address - connect\(2\) for "localhost" port 443/) } + its(:stdout) { should match(/CheckHttp CRITICAL: Request error: Cannot assign requested address - connect\(2\) for "127.0.0.1" port 443/) } end end + +# DNS timeout +describe command("#{check} --url http://blackhole.webpagetest.org/okay --dns-timeout 0.00001") do + its(:exit_status) { should eq 2 } + its(:stdout) { should match(/CheckHttp CRITICAL: Request error: Failed to open TCP connection to blackhole.webpagetest.org/) } +end From bb7ad2dc80f54b58969f6e057965e39423d12eaa Mon Sep 17 00:00:00 2001 From: Johan van den Dorpe Date: Thu, 17 Jan 2019 13:03:38 +0000 Subject: [PATCH 5/5] Update Changelog --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44ec071..0162661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md) ## [Unreleased] +### Added +- `check-http.rb`: Add options to set `--open-timeout` and `--read-timeout` for Net:HTTP. Additionally rescue `Net::OpenTimeout` and `Net::ReadTimeout` exception classes (@johanek) +- `check-http.rb`: exposed `--dns-timeout` for Ruby DNS Resolver. (@johanek) + ### Changed -- `check-http.rb`: Add options to set open-timeout and read-timeout for Net:HTTP. Improve output on what Net::HTTP timeout was encountered. -- `check-http.rb`: Use ruby DNS resolver, and set DNS resolution timeout. +- `check-http.rb`: switched to using rubies DNS resolver to allow catching DNS failures when Net::HTTP establishes connection. (@johanek) ## [4.0.0] - 2018-12-17 ### Breaking Changes