health_check 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.travis.yml +150 -11
- data/CHANGELOG +21 -0
- data/README.rdoc +78 -21
- data/Rakefile +1 -1
- data/Vagrantfile +13 -1
- data/config/routes.rb +1 -1
- data/health_check.gemspec +4 -4
- data/lib/health_check.rb +45 -5
- data/lib/health_check/elasticsearch_health_check.rb +15 -0
- data/lib/health_check/health_check_controller.rb +32 -21
- data/lib/health_check/health_check_routes.rb +1 -1
- data/lib/health_check/middleware_health_check.rb +6 -1
- data/lib/health_check/rabbitmq_health_check.rb +16 -0
- data/lib/health_check/redis_health_check.rb +20 -7
- data/lib/health_check/s3_health_check.rb +9 -14
- data/lib/health_check/utils.rb +44 -30
- data/lib/health_check/version.rb +1 -1
- data/test/fake_smtp_server +143 -24
- data/test/init_variables +19 -1
- data/test/migrate/twelve/012_create_users.rb +1 -1
- data/test/provision_vagrant +55 -13
- data/test/rails_5.0.gemfile +8 -7
- data/test/rails_5.1.gemfile +7 -8
- data/test/rails_5.2.gemfile +34 -0
- data/test/rails_6.0.gemfile +30 -0
- data/test/rails_6.1.gemfile +29 -0
- data/test/rails_6.2.gemfile +30 -0
- data/test/rails_edge.gemfile +37 -0
- data/test/setup_railsapp +138 -54
- data/test/test_with_railsapp +137 -44
- data/test/testurl +9 -0
- metadata +24 -12
data/Rakefile
CHANGED
data/Vagrantfile
CHANGED
@@ -5,7 +5,7 @@ Vagrant.configure("2") do |config|
|
|
5
5
|
# For a complete reference, please see the online documentation at
|
6
6
|
# https://docs.vagrantup.com.
|
7
7
|
|
8
|
-
config.vm.box = "ubuntu/
|
8
|
+
config.vm.box = "ubuntu/focal64"
|
9
9
|
|
10
10
|
# set auto_update to false, if you do NOT want to check the correct
|
11
11
|
# additions version when booting this machine
|
@@ -17,4 +17,16 @@ Vagrant.configure("2") do |config|
|
|
17
17
|
# provision with a shell script.
|
18
18
|
config.vm.provision "shell", path: "./test/provision_vagrant"
|
19
19
|
|
20
|
+
config.vm.provider "virtualbox" do |v|
|
21
|
+
# travis allocates 7.5 GB, but this is sufficient
|
22
|
+
v.memory = 2048
|
23
|
+
v.cpus = 2
|
24
|
+
end
|
25
|
+
|
26
|
+
# if File.file?('.git') && IO.read('.git') =~ %r{\Agitdir: (.+)/.git/worktrees.*}
|
27
|
+
# # Handle git worktrees ...
|
28
|
+
# path = $1
|
29
|
+
# config.vm.synced_folder path, path
|
30
|
+
# end
|
31
|
+
|
20
32
|
end
|
data/config/routes.rb
CHANGED
data/health_check.gemspec
CHANGED
@@ -9,14 +9,14 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.required_rubygems_version = Gem::Requirement.new(">= 0") if gem.respond_to? :required_rubygems_version=
|
10
10
|
gem.authors = ["Ian Heggie"]
|
11
11
|
gem.email = ["ian@heggie.biz"]
|
12
|
-
gem.summary = %q{Simple health check of Rails app for uptime monitoring with Pingdom, NewRelic, EngineYard
|
12
|
+
gem.summary = %q{Simple health check of Rails app for uptime monitoring with Pingdom, NewRelic, EngineYard etc.}
|
13
13
|
gem.description = <<-EOF
|
14
|
-
Simple health check of Rails app for uptime monitoring with Pingdom, NewRelic, EngineYard
|
14
|
+
Simple health check of Rails app for uptime monitoring with Pingdom, NewRelic, EngineYard etc.
|
15
15
|
EOF
|
16
16
|
gem.homepage = "https://github.com/ianheggie/health_check"
|
17
|
+
gem.license = "MIT"
|
17
18
|
|
18
19
|
gem.files = `git ls-files`.split($/)
|
19
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
20
20
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
21
21
|
gem.extra_rdoc_files = [ "README.rdoc" ]
|
22
22
|
gem.require_paths = ["lib"]
|
@@ -25,5 +25,5 @@ Gem::Specification.new do |gem|
|
|
25
25
|
gem.add_development_dependency(%q<smarter_bundler>, [">= 0.1.0"])
|
26
26
|
gem.add_development_dependency(%q<rake>, [">= 0.8.3"])
|
27
27
|
gem.add_development_dependency(%q<shoulda>, ["~> 2.11.0"])
|
28
|
-
gem.add_development_dependency(%q<bundler>, ["
|
28
|
+
gem.add_development_dependency(%q<bundler>, [">= 1.2"])
|
29
29
|
end
|
data/lib/health_check.rb
CHANGED
@@ -3,14 +3,22 @@
|
|
3
3
|
|
4
4
|
module HealthCheck
|
5
5
|
|
6
|
-
class Engine < Rails::Engine
|
7
|
-
cattr_accessor :routes_explicitly_defined
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
cattr_accessor :routes_explicitly_defined
|
8
8
|
end
|
9
9
|
|
10
|
+
# Log level
|
11
|
+
mattr_accessor :log_level
|
12
|
+
self.log_level = 'info'
|
13
|
+
|
10
14
|
# Text output upon success
|
11
15
|
mattr_accessor :success
|
12
16
|
self.success = "success"
|
13
17
|
|
18
|
+
# Text output upon failure
|
19
|
+
mattr_accessor :failure
|
20
|
+
self.failure = "health_check failed"
|
21
|
+
|
14
22
|
# Timeout in seconds used when checking smtp server
|
15
23
|
mattr_accessor :smtp_timeout
|
16
24
|
self.smtp_timeout = 30.0
|
@@ -27,6 +35,10 @@ module HealthCheck
|
|
27
35
|
mattr_accessor :http_status_for_ip_whitelist_error
|
28
36
|
self.http_status_for_ip_whitelist_error = 403
|
29
37
|
|
38
|
+
# check remote_ip rather than ip for ip whitelist
|
39
|
+
mattr_accessor :accept_proxied_requests
|
40
|
+
self.accept_proxied_requests = false
|
41
|
+
|
30
42
|
# ips allowed to perform requests
|
31
43
|
mattr_accessor :origin_ip_whitelist
|
32
44
|
self.origin_ip_whitelist = []
|
@@ -40,6 +52,10 @@ module HealthCheck
|
|
40
52
|
mattr_accessor :buckets
|
41
53
|
self.buckets = {}
|
42
54
|
|
55
|
+
# rabbitmq
|
56
|
+
mattr_accessor :rabbitmq_config
|
57
|
+
self.rabbitmq_config = {}
|
58
|
+
|
43
59
|
# health check uri path
|
44
60
|
mattr_accessor :uri
|
45
61
|
self.uri = 'health_check'
|
@@ -54,7 +70,7 @@ module HealthCheck
|
|
54
70
|
mattr_accessor :full_checks
|
55
71
|
mattr_accessor :standard_checks
|
56
72
|
self.custom_checks = { }
|
57
|
-
self.full_checks = ['database', 'migrations', 'custom', 'email', 'cache', 'redis-if-present', 'sidekiq-redis-if-present', 'resque-redis-if-present', 's3-if-present']
|
73
|
+
self.full_checks = ['database', 'migrations', 'custom', 'email', 'cache', 'redis-if-present', 'sidekiq-redis-if-present', 'resque-redis-if-present', 's3-if-present', 'elasticsearch-if-present']
|
58
74
|
self.standard_checks = [ 'database', 'migrations', 'custom', 'emailconf' ]
|
59
75
|
|
60
76
|
# Middleware based checks
|
@@ -63,15 +79,37 @@ module HealthCheck
|
|
63
79
|
|
64
80
|
mattr_accessor :installed_as_middleware
|
65
81
|
|
66
|
-
# Allow non-standard redis url
|
82
|
+
# Allow non-standard redis url and password
|
67
83
|
mattr_accessor :redis_url
|
68
|
-
self.redis_url =
|
84
|
+
self.redis_url = ENV['REDIS_URL']
|
85
|
+
|
86
|
+
mattr_accessor :redis_password
|
87
|
+
self.redis_password = 'some-password'
|
88
|
+
|
89
|
+
# Include the error in the response body.
|
90
|
+
# You should only do this where your /health_check endpoint is NOT open to the public internet
|
91
|
+
mattr_accessor :include_error_in_response_body
|
92
|
+
self.include_error_in_response_body = false
|
93
|
+
|
94
|
+
# used for on_failure and on_success
|
95
|
+
mattr_accessor :success_callbacks
|
96
|
+
mattr_accessor :failure_callbacks
|
69
97
|
|
70
98
|
def self.add_custom_check(name = 'custom', &block)
|
71
99
|
custom_checks[name] ||= [ ]
|
72
100
|
custom_checks[name] << block
|
73
101
|
end
|
74
102
|
|
103
|
+
def self.on_success(&block)
|
104
|
+
success_callbacks ||= [ ]
|
105
|
+
success_callbacks << block
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.on_failure(&block)
|
109
|
+
failure_callbacks ||= [ ]
|
110
|
+
failure_callbacks << block
|
111
|
+
end
|
112
|
+
|
75
113
|
def self.setup
|
76
114
|
yield self
|
77
115
|
end
|
@@ -83,10 +121,12 @@ require 'health_check/base_health_check'
|
|
83
121
|
require 'health_check/resque_health_check'
|
84
122
|
require 'health_check/s3_health_check'
|
85
123
|
require 'health_check/redis_health_check'
|
124
|
+
require 'health_check/elasticsearch_health_check'
|
86
125
|
require 'health_check/sidekiq_health_check'
|
87
126
|
require 'health_check/utils'
|
88
127
|
require 'health_check/health_check_controller'
|
89
128
|
require 'health_check/health_check_routes'
|
90
129
|
require 'health_check/middleware_health_check'
|
130
|
+
require 'health_check/rabbitmq_health_check'
|
91
131
|
|
92
132
|
# vi: sw=2 sm ai:
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module HealthCheck
|
2
|
+
class ElasticsearchHealthCheck
|
3
|
+
extend BaseHealthCheck
|
4
|
+
|
5
|
+
def self.check
|
6
|
+
unless defined?(::Elasticsearch)
|
7
|
+
raise "Wrong configuration. Missing 'elasticsearch' gem"
|
8
|
+
end
|
9
|
+
res = ::Elasticsearch::Client.new.ping
|
10
|
+
res == true ? '' : "Elasticsearch returned #{res.inspect} instead of true"
|
11
|
+
rescue Exception => e
|
12
|
+
create_error 'elasticsearch', e.message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2021 Ian Heggie, released under the MIT license.
|
2
2
|
# See MIT-LICENSE for details.
|
3
|
+
require "ipaddr"
|
3
4
|
|
4
5
|
module HealthCheck
|
5
6
|
class HealthCheckController < ActionController::Base
|
@@ -14,8 +15,8 @@ module HealthCheck
|
|
14
15
|
if max_age > 1
|
15
16
|
last_modified = Time.at((last_modified.to_f / max_age).floor * max_age).utc
|
16
17
|
end
|
17
|
-
|
18
|
-
if stale?(:
|
18
|
+
is_public = (max_age > 1) && ! HealthCheck.basic_auth_username
|
19
|
+
if stale?(last_modified: last_modified, public: is_public)
|
19
20
|
checks = params[:checks] ? params[:checks].split('_') : ['standard']
|
20
21
|
checks -= HealthCheck.middleware_checks if HealthCheck.installed_as_middleware
|
21
22
|
begin
|
@@ -23,15 +24,25 @@ module HealthCheck
|
|
23
24
|
rescue Exception => e
|
24
25
|
errors = e.message.blank? ? e.class.to_s : e.message.to_s
|
25
26
|
end
|
26
|
-
response.headers['Cache-
|
27
|
+
response.headers['Cache-Control'] = "must-revalidate, max-age=#{max_age}"
|
27
28
|
if errors.blank?
|
28
|
-
send_response nil, :ok, :ok
|
29
|
+
send_response true, nil, :ok, :ok
|
30
|
+
if HealthCheck.success_callbacks
|
31
|
+
HealthCheck.success_callbacks.each do |callback|
|
32
|
+
callback.call(checks)
|
33
|
+
end
|
34
|
+
end
|
29
35
|
else
|
30
|
-
msg = "
|
31
|
-
send_response msg, HealthCheck.http_status_for_error_text, HealthCheck.http_status_for_error_object
|
36
|
+
msg = HealthCheck.include_error_in_response_body ? "#{HealthCheck.failure}: #{errors}" : nil
|
37
|
+
send_response false, msg, HealthCheck.http_status_for_error_text, HealthCheck.http_status_for_error_object
|
38
|
+
|
32
39
|
# Log a single line as some uptime checkers only record that it failed, not the text returned
|
33
|
-
|
34
|
-
|
40
|
+
msg = "#{HealthCheck.failure}: #{errors}"
|
41
|
+
logger.send(HealthCheck.log_level, msg) if logger && HealthCheck.log_level
|
42
|
+
if HealthCheck.failure_callbacks
|
43
|
+
HealthCheck.failure_callbacks.each do |callback|
|
44
|
+
callback.call(checks, msg)
|
45
|
+
end
|
35
46
|
end
|
36
47
|
end
|
37
48
|
end
|
@@ -39,15 +50,14 @@ module HealthCheck
|
|
39
50
|
|
40
51
|
protected
|
41
52
|
|
42
|
-
def send_response(msg, text_status, obj_status)
|
43
|
-
healthy
|
44
|
-
|
45
|
-
obj = { :healthy => healthy, :message => msg}
|
53
|
+
def send_response(healthy, msg, text_status, obj_status)
|
54
|
+
msg ||= healthy ? HealthCheck.success : HealthCheck.failure
|
55
|
+
obj = { healthy: healthy, message: msg}
|
46
56
|
respond_to do |format|
|
47
|
-
format.html { render :
|
48
|
-
format.json { render :
|
49
|
-
format.xml { render :
|
50
|
-
format.any { render :
|
57
|
+
format.html { render plain: msg, status: text_status, content_type: 'text/plain' }
|
58
|
+
format.json { render json: obj, status: obj_status }
|
59
|
+
format.xml { render xml: obj, status: obj_status }
|
60
|
+
format.any { render plain: msg, status: text_status, content_type: 'text/plain' }
|
51
61
|
end
|
52
62
|
end
|
53
63
|
|
@@ -59,11 +69,12 @@ module HealthCheck
|
|
59
69
|
end
|
60
70
|
|
61
71
|
def check_origin_ip
|
72
|
+
request_ipaddr = IPAddr.new(HealthCheck.accept_proxied_requests ? request.remote_ip : request.ip)
|
62
73
|
unless HealthCheck.origin_ip_whitelist.blank? ||
|
63
|
-
HealthCheck.origin_ip_whitelist.
|
64
|
-
render :
|
65
|
-
:
|
66
|
-
:
|
74
|
+
HealthCheck.origin_ip_whitelist.any? { |addr| IPAddr.new(addr).include? request_ipaddr }
|
75
|
+
render plain: 'Health check is not allowed for the requesting IP',
|
76
|
+
status: HealthCheck.http_status_for_ip_whitelist_error,
|
77
|
+
content_type: 'text/plain'
|
67
78
|
end
|
68
79
|
end
|
69
80
|
|
@@ -8,7 +8,7 @@ module ActionDispatch::Routing
|
|
8
8
|
|
9
9
|
def add_health_check_routes(prefix = nil)
|
10
10
|
HealthCheck.uri = prefix if prefix
|
11
|
-
match "#{HealthCheck.uri}(/:checks)(.:format)", :
|
11
|
+
match "#{HealthCheck.uri}(/:checks)(.:format)", controller: 'health_check/health_check', action: :index, via: [:get, :post], defaults: { format: 'txt' }
|
12
12
|
end
|
13
13
|
|
14
14
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# Copyright (c) 2010-2021 Ian Heggie, released under the MIT license.
|
2
|
+
# See MIT-LICENSE for details.
|
3
|
+
require 'ipaddr'
|
4
|
+
|
1
5
|
module HealthCheck
|
2
6
|
class MiddlewareHealthcheck
|
3
7
|
|
@@ -59,7 +63,8 @@ module HealthCheck
|
|
59
63
|
def ip_blocked(env)
|
60
64
|
return false if HealthCheck.origin_ip_whitelist.blank?
|
61
65
|
req = Rack::Request.new(env)
|
62
|
-
|
66
|
+
request_ipaddr = IPAddr.new(req.ip)
|
67
|
+
unless HealthCheck.origin_ip_whitelist.any? { |addr| IPAddr.new(addr).include? request_ipaddr }
|
63
68
|
[ HealthCheck.http_status_for_ip_whitelist_error,
|
64
69
|
{ 'Content-Type' => 'text/plain' },
|
65
70
|
[ 'Health check is not allowed for the requesting IP' ]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module HealthCheck
|
2
|
+
class RabbitMQHealthCheck
|
3
|
+
extend BaseHealthCheck
|
4
|
+
def self.check
|
5
|
+
unless defined?(::Bunny)
|
6
|
+
raise "Wrong configuration. Missing 'bunny' gem"
|
7
|
+
end
|
8
|
+
connection = Bunny.new(HealthCheck.rabbitmq_config)
|
9
|
+
connection.start
|
10
|
+
connection.close
|
11
|
+
''
|
12
|
+
rescue Exception => e
|
13
|
+
create_error 'rabbitmq', e.message
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,15 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HealthCheck
|
2
4
|
class RedisHealthCheck
|
3
5
|
extend BaseHealthCheck
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
raise "Wrong configuration. Missing 'redis' gem"
|
7
|
+
class << self
|
8
|
+
def check
|
9
|
+
raise "Wrong configuration. Missing 'redis' gem" unless defined?(::Redis)
|
10
|
+
|
11
|
+
client.ping == 'PONG' ? '' : "Redis.ping returned #{res.inspect} instead of PONG"
|
12
|
+
rescue Exception => err
|
13
|
+
create_error 'redis', err.message
|
14
|
+
ensure
|
15
|
+
client.close if client.connected?
|
16
|
+
end
|
17
|
+
|
18
|
+
def client
|
19
|
+
@client ||= Redis.new(
|
20
|
+
{
|
21
|
+
url: HealthCheck.redis_url,
|
22
|
+
password: HealthCheck.redis_password
|
23
|
+
}.reject { |k, v| v.nil? }
|
24
|
+
)
|
8
25
|
end
|
9
|
-
res = ::Redis.new(url: HealthCheck.redis_url).ping
|
10
|
-
res == 'PONG' ? '' : "Redis.ping returned #{res.inspect} instead of PONG"
|
11
|
-
rescue Exception => e
|
12
|
-
create_error 'redis', e.message
|
13
26
|
end
|
14
27
|
end
|
15
28
|
end
|
@@ -5,7 +5,7 @@ module HealthCheck
|
|
5
5
|
class << self
|
6
6
|
def check
|
7
7
|
unless defined?(::Aws)
|
8
|
-
raise "Wrong configuration. Missing 'aws-sdk' gem"
|
8
|
+
raise "Wrong configuration. Missing 'aws-sdk' or 'aws-sdk-s3' gem"
|
9
9
|
end
|
10
10
|
return create_error 's3', 'Could not connect to aws' if aws_s3_client.nil?
|
11
11
|
HealthCheck.buckets.each do |bucket_name, permissions|
|
@@ -27,19 +27,14 @@ module HealthCheck
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
+
# We already assume you are using Rails. Let's also assume you have an initializer
|
31
|
+
# created for your Aws config. We will set the region here so you can use an
|
32
|
+
# instance profile and simply set the region in your environment.
|
30
33
|
def configure_client
|
31
|
-
|
34
|
+
::Aws.config[:s3] = { force_path_style: true }
|
35
|
+
::Aws.config[:region] ||= ENV['AWS_REGION'] || ENV['DEFAULT_AWS_REGION']
|
32
36
|
|
33
|
-
|
34
|
-
region: Rails.application.secrets.aws_default_region,
|
35
|
-
credentials: ::Aws::Credentials.new(
|
36
|
-
Rails.application.secrets.aws_access_key_id,
|
37
|
-
Rails.application.secrets.aws_secret_access_key
|
38
|
-
),
|
39
|
-
force_path_style: true
|
40
|
-
}
|
41
|
-
|
42
|
-
::Aws::S3::Client.new aws_configuration
|
37
|
+
::Aws::S3::Client.new
|
43
38
|
end
|
44
39
|
|
45
40
|
def aws_s3_client
|
@@ -52,13 +47,13 @@ module HealthCheck
|
|
52
47
|
|
53
48
|
def W(bucket)
|
54
49
|
aws_s3_client.put_object(bucket: bucket,
|
55
|
-
key: "healthcheck_#{Rails.application.class.parent_name}",
|
50
|
+
key: "healthcheck_#{::Rails.application.class.parent_name}",
|
56
51
|
body: Time.new.to_s)
|
57
52
|
end
|
58
53
|
|
59
54
|
def D(bucket)
|
60
55
|
aws_s3_client.delete_object(bucket: bucket,
|
61
|
-
key: "healthcheck_#{Rails.application.class.parent_name}")
|
56
|
+
key: "healthcheck_#{::Rails.application.class.parent_name}")
|
62
57
|
end
|
63
58
|
end
|
64
59
|
end
|
data/lib/health_check/utils.rb
CHANGED
@@ -6,13 +6,13 @@ module HealthCheck
|
|
6
6
|
|
7
7
|
@@default_smtp_settings =
|
8
8
|
{
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
9
|
+
address: "localhost",
|
10
|
+
port: 25,
|
11
|
+
domain: 'localhost.localdomain',
|
12
|
+
user_name: nil,
|
13
|
+
password: nil,
|
14
|
+
authentication: nil,
|
15
|
+
enable_starttls_auto: true
|
16
16
|
}
|
17
17
|
|
18
18
|
cattr_accessor :default_smtp_settings
|
@@ -55,6 +55,8 @@ module HealthCheck
|
|
55
55
|
errors << HealthCheck::RedisHealthCheck.check if defined?(::Redis)
|
56
56
|
when 's3-if-present'
|
57
57
|
errors << HealthCheck::S3HealthCheck.check if defined?(::Aws)
|
58
|
+
when 'elasticsearch-if-present'
|
59
|
+
errors << HealthCheck::ElasticsearchHealthCheck.check if defined?(::Elasticsearch)
|
58
60
|
when 'resque-redis'
|
59
61
|
errors << HealthCheck::ResqueHealthCheck.check
|
60
62
|
when 'sidekiq-redis'
|
@@ -63,6 +65,10 @@ module HealthCheck
|
|
63
65
|
errors << HealthCheck::RedisHealthCheck.check
|
64
66
|
when 's3'
|
65
67
|
errors << HealthCheck::S3HealthCheck.check
|
68
|
+
when 'elasticsearch'
|
69
|
+
errors << HealthCheck::ElasticsearchHealthCheck.check
|
70
|
+
when 'rabbitmq'
|
71
|
+
errors << HealthCheck::RabbitMQHealthCheck.check
|
66
72
|
when "standard"
|
67
73
|
errors << HealthCheck::Utils.process_checks(HealthCheck.standard_checks, called_from_middleware)
|
68
74
|
when "middleware"
|
@@ -84,15 +90,16 @@ module HealthCheck
|
|
84
90
|
return "invalid argument to health_test."
|
85
91
|
end
|
86
92
|
end
|
93
|
+
errors << '. ' unless errors == '' || errors.end_with?('. ')
|
87
94
|
end
|
88
|
-
return errors
|
95
|
+
return errors.strip
|
89
96
|
rescue => e
|
90
97
|
return e.message
|
91
98
|
end
|
92
99
|
|
93
100
|
def self.db_migrate_path
|
94
101
|
# Lazy initialisation so Rails.root will be defined
|
95
|
-
@@db_migrate_path ||= File.join(Rails.root, 'db', 'migrate')
|
102
|
+
@@db_migrate_path ||= File.join(::Rails.root, 'db', 'migrate')
|
96
103
|
end
|
97
104
|
|
98
105
|
def self.db_migrate_path=(value)
|
@@ -135,36 +142,43 @@ module HealthCheck
|
|
135
142
|
status = ''
|
136
143
|
begin
|
137
144
|
if @skip_external_checks
|
138
|
-
status = '
|
145
|
+
status = '250'
|
139
146
|
else
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
147
|
-
t.puts "HELO #{settings[:domain]}\r"
|
148
|
-
while status != nil && status !~ /^250/
|
149
|
-
status = t.gets
|
150
|
-
end
|
151
|
-
t.puts "QUIT\r"
|
152
|
-
status = t.gets
|
153
|
-
ensure
|
154
|
-
t.close
|
155
|
-
end
|
147
|
+
smtp = Net::SMTP.new(settings[:address], settings[:port])
|
148
|
+
smtp.enable_starttls if settings[:enable_starttls_auto]
|
149
|
+
smtp.open_timeout = timeout
|
150
|
+
smtp.read_timeout = timeout
|
151
|
+
smtp.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication]) do
|
152
|
+
status = smtp.helo(settings[:domain]).status
|
156
153
|
end
|
157
154
|
end
|
158
|
-
rescue Errno::EBADF => ex
|
159
|
-
status = "Unable to connect to service"
|
160
155
|
rescue Exception => ex
|
161
156
|
status = ex.to_s
|
162
157
|
end
|
163
|
-
(status =~ /^
|
158
|
+
(status =~ /^250/) ? '' : "SMTP: #{status || 'unexpected error'}. "
|
164
159
|
end
|
165
160
|
|
166
161
|
def self.check_cache
|
167
|
-
|
162
|
+
t = Time.now.to_i
|
163
|
+
value = "ok #{t}"
|
164
|
+
ret = ::Rails.cache.read('__health_check_cache_test__')
|
165
|
+
if ret.to_s =~ /^ok (\d+)$/
|
166
|
+
diff = ($1.to_i - t).abs
|
167
|
+
return('Cache expiry is broken. ') if diff > 30
|
168
|
+
elsif ret
|
169
|
+
return 'Cache is returning garbage. '
|
170
|
+
end
|
171
|
+
if ::Rails.cache.write('__health_check_cache_test__', value, expires_in: 2.seconds)
|
172
|
+
ret = ::Rails.cache.read('__health_check_cache_test__')
|
173
|
+
if ret =~ /^ok (\d+)$/
|
174
|
+
diff = ($1.to_i - t).abs
|
175
|
+
(diff < 2 ? '' : 'Out of date cache or time is skewed. ')
|
176
|
+
else
|
177
|
+
'Unable to read from cache. '
|
178
|
+
end
|
179
|
+
else
|
180
|
+
'Unable to write to cache. '
|
181
|
+
end
|
168
182
|
end
|
169
183
|
|
170
184
|
end
|