From 0a194105d32359dab23c8f1fd40975a7d7c8a21b Mon Sep 17 00:00:00 2001 From: Leonid Beder Date: Mon, 20 Apr 2015 15:58:02 +0300 Subject: [PATCH] Added support for custom providers. --- README.md | 22 ++++++++ lib/health_monitor/configuration.rb | 24 +++++++-- lib/health_monitor/monitor.rb | 2 +- lib/health_monitor/version.rb | 2 +- spec/lib/health_monitor/configuration_spec.rb | 52 +++++++++++++++---- spec/lib/health_monitor/monitor_spec.rb | 10 ++-- 6 files changed, 92 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index b65c701..bf52812 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,28 @@ The currently supported settings are: * `latency`: the latency (in seconds) of a queue (now - when the oldest job was enqueued) which is considered unhealthy (the default is 30 seconds, but larger processing queue should have a larger latency value). +### Adding a custom provider +It's also possible to add custom health check providers suited for your needs (of course, it's highly appreciated and encouraged if you'd contribute useful providers to the project). + +In order to add a custom provider, you'd need to: + +* Implement the `HealthMonitor::Providers::Base` class and its `check!` method (a check is considered as failed if it raises an exception): + +```ruby +class CustomProvider < HealthMonitor::Providers::Base + def check! + raise 'Oh oh!' + end +end +``` +* Add its class to the configuration: + +```ruby +HealthMonitor.configure do |config| + config.add_custom_provider(CustomProvider) +end +``` + ### Adding a custom error callback If you need to perform any additional error handling (for example, for additional error reporting), you can configure a custom error callback: diff --git a/lib/health_monitor/configuration.rb b/lib/health_monitor/configuration.rb index 8bb6284..c480b0f 100644 --- a/lib/health_monitor/configuration.rb +++ b/lib/health_monitor/configuration.rb @@ -9,14 +9,28 @@ def initialize database end - PROVIDERS.each do |provider| - define_method provider do |&block| - require "health_monitor/providers/#{provider}" + PROVIDERS.each do |provider_name| + define_method provider_name do |&block| + require "health_monitor/providers/#{provider_name}" - (@providers ||= Set.new) << provider + add_provider("HealthMonitor::Providers::#{provider_name.capitalize}".constantize) + end + end - "HealthMonitor::Providers::#{provider.capitalize}".constantize + def add_custom_provider(custom_provider_class) + unless custom_provider_class < HealthMonitor::Providers::Base + raise ArgumentError.new('custom provider class must implement HealthMonitor::Providers::Base') end + + add_provider(custom_provider_class) + end + + private + + def add_provider(provider_class) + (@providers ||= Set.new) << provider_class + + provider_class end end end diff --git a/lib/health_monitor/monitor.rb b/lib/health_monitor/monitor.rb index cd785c3..32cbe71 100644 --- a/lib/health_monitor/monitor.rb +++ b/lib/health_monitor/monitor.rb @@ -13,7 +13,7 @@ def configure def check!(request: nil) configuration.providers.each do |provider| - monitor = "HealthMonitor::Providers::#{provider.capitalize}".constantize.new(request: request) + monitor = provider.new(request: request) monitor.check! end rescue Exception => e diff --git a/lib/health_monitor/version.rb b/lib/health_monitor/version.rb index dbe3c00..dfdc377 100644 --- a/lib/health_monitor/version.rb +++ b/lib/health_monitor/version.rb @@ -1,3 +1,3 @@ module HealthMonitor - VERSION = '2.0.2'.freeze + VERSION = '2.1.0'.freeze end diff --git a/spec/lib/health_monitor/configuration_spec.rb b/spec/lib/health_monitor/configuration_spec.rb index 0c2087b..64e8f8f 100644 --- a/spec/lib/health_monitor/configuration_spec.rb +++ b/spec/lib/health_monitor/configuration_spec.rb @@ -2,31 +2,63 @@ describe HealthMonitor::Configuration do describe 'defaults' do - it { expect(subject.providers).to eq(Set.new([:database])) } + it { expect(subject.providers).to eq(Set.new([HealthMonitor::Providers::Database])) } it { expect(subject.error_callback).to be_nil } it { expect(subject.basic_auth_credentials).to be_nil } end describe 'providers' do - HealthMonitor::Configuration::PROVIDERS.each do |provider| + HealthMonitor::Configuration::PROVIDERS.each do |provider_name| before do subject.instance_variable_set('@providers', Set.new) - stub_const("HealthMonitor::Providers::#{provider.capitalize}", Class.new) + stub_const("HealthMonitor::Providers::#{provider_name.capitalize}", Class.new) end - it "responds to #{provider}" do - expect(subject).to respond_to(provider) + it "responds to #{provider_name}" do + expect(subject).to respond_to(provider_name) end - it "configures #{provider}" do + it "configures #{provider_name}" do expect { - subject.send(provider) - }.to change { subject.providers }.to(Set.new([provider])) + subject.send(provider_name) + }.to change { subject.providers }.to(Set.new(["HealthMonitor::Providers::#{provider_name.capitalize}".constantize])) end - it "returns #{provider}'s class" do - expect(subject.send(provider)).to eq("HealthMonitor::Providers::#{provider.capitalize}".constantize) + it "returns #{provider_name}'s class" do + expect(subject.send(provider_name)).to eq("HealthMonitor::Providers::#{provider_name.capitalize}".constantize) + end + end + end + + describe '#add_custom_provider' do + before do + subject.instance_variable_set('@providers', Set.new) + end + + context 'inherits' do + class CustomProvider < HealthMonitor::Providers::Base + end + + it 'accepts' do + expect { + subject.add_custom_provider(CustomProvider) + }.to change { subject.providers }.to(Set.new([CustomProvider])) + end + + it "returns CustomProvider class" do + expect(subject.add_custom_provider(CustomProvider)).to eq(CustomProvider) + end + end + + context 'does not inherit' do + class TestClass + end + + it 'does not accept' do + expect { + subject.add_custom_provider(TestClass) + }.to raise_error(ArgumentError) end end end diff --git a/spec/lib/health_monitor/monitor_spec.rb b/spec/lib/health_monitor/monitor_spec.rb index 46231a0..acb822c 100644 --- a/spec/lib/health_monitor/monitor_spec.rb +++ b/spec/lib/health_monitor/monitor_spec.rb @@ -14,7 +14,8 @@ subject.configure do |config| config.redis end - }.to change { HealthMonitor.configuration.providers }.to(Set.new([:database, :redis])) + }.to change { HealthMonitor.configuration.providers }. + to(Set.new([HealthMonitor::Providers::Database, HealthMonitor::Providers::Redis])) end it 'configures a multiple providers' do @@ -23,7 +24,9 @@ config.redis config.sidekiq end - }.to change { HealthMonitor.configuration.providers }.to(Set.new([:database, :redis, :sidekiq])) + }.to change { HealthMonitor.configuration.providers }. + to(Set.new([HealthMonitor::Providers::Database, HealthMonitor::Providers::Redis, + HealthMonitor::Providers::Sidekiq])) end it 'appends new providers' do @@ -31,7 +34,8 @@ subject.configure do |config| config.resque end - }.to change { HealthMonitor.configuration.providers }.to(Set.new([:database, :resque])) + }.to change { HealthMonitor.configuration.providers }. + to(Set.new([HealthMonitor::Providers::Database, HealthMonitor::Providers::Resque])) end end