heartcheck 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 30402737433dacfa08875ade181a6fb9570b6b0a
4
+ data.tar.gz: d6747a981694289118544f929e70cb254153bdf4
5
+ SHA512:
6
+ metadata.gz: 3be0e45e564098d82e130030a69aaaca7c9858de1021629178745afd803db934f4ed439d9b9c580d67454519b950db42c082220b919992f8e08ae7336a6f73e7
7
+ data.tar.gz: d4129a1cf932d1ae0e3d724231dc03a0f7a02f158632318d372ee1c29f27cdc581c15983e1fdeafbe209711118769e29301b6a1ae131d9850b81a24991a319ab
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ $LOAD_PATH.push File.expand_path('../../lib', __FILE__)
6
+ require 'heartcheck'
7
+
8
+ optparse = OptionParser.new do |opts|
9
+ opts.banner = "Usage: heartcheck (rails|padrino|sinatra)\n\nYou can use flags as such:"
10
+
11
+ opts.on('-h', '--help', 'Display this screen') do
12
+ puts opts
13
+ exit
14
+ end
15
+
16
+ if ARGV.size != 1 || !%w(rails sinatra padrino).include?(ARGV[0])
17
+ puts opts
18
+ exit
19
+ end
20
+ end
21
+
22
+ begin
23
+ optparse.parse!
24
+ rescue OptionParser::InvalidOption => e
25
+ puts e
26
+ exit
27
+ end
28
+
29
+ Heartcheck::Generator.new(ARGV).invoke_all
@@ -0,0 +1,63 @@
1
+ require 'thor/group'
2
+
3
+ module Heartcheck
4
+ class Generator < Thor::Group
5
+ include Thor::Actions
6
+
7
+ desc 'generate default files and instructions to use the Heartcheck'
8
+
9
+ argument :framework
10
+
11
+ def self.source_root
12
+ File.join(File.dirname(__FILE__), 'templates')
13
+ end
14
+
15
+ def show_framework
16
+ box framework.capitalize, :green
17
+ end
18
+
19
+ def generate_initializer
20
+ template('config.rb', initializer_path)
21
+ end
22
+
23
+ def generate_route
24
+ case framework
25
+ when 'rails'
26
+ instructions(
27
+ 'config/routes.rb',
28
+ 'mount Heartcheck::App.new, at: "/monitoring"'
29
+ )
30
+ when 'padrino', 'sinatra'
31
+ instructions(
32
+ 'config.ru', %(require "heartcheck"
33
+ map "/monitoring" do
34
+ use Heartcheck::App
35
+ end)
36
+ )
37
+ end
38
+ end
39
+
40
+ def include_empty_lines
41
+ puts "\n\n"
42
+ end
43
+
44
+ private
45
+
46
+ def instructions(file_name, file_content)
47
+ box "Include the following content to file #{file_name}"
48
+ say file_content, :blue
49
+ end
50
+
51
+ def box(content, color = :red)
52
+ size = content.size
53
+ say "#{'=' * (size + 2)}\n #{content}\n#{'=' * (size + 2)}\n", color
54
+ end
55
+
56
+ def initializer_path
57
+ case framework
58
+ when 'rails' then 'config/initializers/heartcheck.rb'
59
+ when 'padrino', 'sinatra' then 'app/app.rb'
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,67 @@
1
+ Heartcheck.setup do |monitor|
2
+ # monitor has a default logger but you can use yours
3
+ # default value: Logger.new(STDOUT)
4
+ # monitor.logger = Rails.logger
5
+
6
+ # Services
7
+ # For each service you can set the folling options
8
+ # name: String => root name to show in report page (default: class.name)
9
+ # functional: Boolean => options to set if this service is optional (default: false)
10
+ # on_error: Block => to customize the errors (default: nil)
11
+ # to_validate: Block => to validate the sevices (default: nil)
12
+ #
13
+ # See the exemple bellow to undertand how you can configure it.
14
+ #
15
+ # monitor.add :base do |c|
16
+ # c.name = "filesystem"
17
+ # c.functional = true
18
+ # c.add_service(name: "my_file", path: "/var/www/my_project/my_file")
19
+ #
20
+ # c.on_error do |sevices|
21
+ # errors << "Custom error message for #{service[:name]}"
22
+ # end
23
+ #
24
+ # c.to_validate do |services, errors|
25
+ # services.each do |service|
26
+ # errors << "erro message" unless if File.exists?(service[:path])
27
+ # end
28
+ # end
29
+ # end
30
+
31
+ # Firewall
32
+ # check with telnet if the firewall is open to conect to the service
33
+ monitor.add :firewall do |c|
34
+ # you can add service wth (host and port) or (url)
35
+ c.add_service(host: 'lala.com', port: 80)
36
+ c.add_service(url: 'http://lalal.com')
37
+
38
+ # add dynamic services when you need it run after initializer
39
+ c.register_dynamic_services do
40
+ Pmta.all.map { |p| { host: p.host, port: 25 } }
41
+ end
42
+
43
+ # to customize default error message, the default is:
44
+ # "connection refused on: #{service.host}:#{service.port}"
45
+ # params
46
+ # errors: Array => errors to show on page
47
+ # service: FirewallService => object that respond to :host and :port
48
+ c.on_error do |_errors, service|
49
+ erros << "Custom error message for #{service.host}"
50
+ end
51
+ end
52
+
53
+ # Redis
54
+ # check if you redis conection is working
55
+ # you need to send a redis conection as a service
56
+ monitor.add :redis do |c|
57
+ c.add_service(name: 'Redis', connection: Resque.redis)
58
+ end
59
+
60
+ # Cache
61
+ # check if your cache is working
62
+ # you can pass any kind of cache, but this need to respond to
63
+ # set, get and delete
64
+ monitor.add :cache do |c|
65
+ c.add_service(name: 'memcached', connection: Rails.cache.instance_variable_get('@data'))
66
+ end
67
+ end
@@ -0,0 +1,111 @@
1
+ module Heartcheck
2
+ require 'logger'
3
+ require 'heartcheck/app'
4
+ require 'heartcheck/checks'
5
+ require 'heartcheck/errors'
6
+ require 'heartcheck/services'
7
+ require 'heartcheck/logger'
8
+
9
+ @checks = []
10
+
11
+ class << self
12
+ # @attr [Array<Checks>] the checks to use when checking
13
+ attr_accessor :checks
14
+ # @attr_writer [Object] change the default logger
15
+ attr_writer :logger
16
+
17
+ # Is used to log some messages when checking if the logger
18
+ # is not set it's returns de default_logger.
19
+ #
20
+ # @return [Object] the logger object
21
+ def logger
22
+ @logger ||= default_logger
23
+ end
24
+
25
+ # @abstract
26
+ # Is used to configure.
27
+ #
28
+ # @yield A bock that recieve the class
29
+ # @example
30
+ # Heartcheck.setup do |c|
31
+ # puts c
32
+ # end
33
+ # @return [void]
34
+ def setup
35
+ yield(self)
36
+ end
37
+
38
+ # It's used to add an instance of a check
39
+ # to the check list
40
+ #
41
+ # @param [String] name to identify in the result page
42
+ # @param [Hash] options the options to create an instance of a check.
43
+ # @option options [String] :class The class name to get an instance
44
+ # @yield a block to config the instance
45
+ # @example
46
+ # Heartcheck.add(:base) do |c|
47
+ # c.name = 'Base check'
48
+ # end
49
+ # @return [void]
50
+ def add(name, options = {}, &block)
51
+ class_name = options.fetch(:class) { constantize(name) }
52
+ instance = Checks.const_get(class_name).new
53
+
54
+ if block_given?
55
+ checks << instance.tap(&block)
56
+ else
57
+ checks << instance
58
+ end
59
+ end
60
+
61
+ # filter checks that are essential
62
+ #
63
+ # @return [Array<Check>] checks that are essential
64
+ def essential_checks
65
+ checks.select { |ctx| !ctx.functional? && !ctx.dev? }
66
+ end
67
+
68
+ # filter checks that are functional
69
+ #
70
+ # @return [Array<Check>] checks that are functional
71
+ def functional_checks
72
+ checks.select(&:functional?)
73
+ end
74
+
75
+ # filter checks that are not functional
76
+ #
77
+ # @return [Array<Check>] checks that are not functional
78
+ def dev_checks
79
+ checks.select { |ctx| !ctx.functional? }
80
+ end
81
+
82
+ # filter checks that has some information
83
+ #
84
+ # @return [Array<Check>] checks that respond to :info
85
+ def info_checks
86
+ checks.select { |ctx| ctx.respond_to?(:info) }
87
+ end
88
+
89
+ private
90
+
91
+ # if no logger is setted we create an instance
92
+ # of ruby logger with STDOUT
93
+ #
94
+ # @return [Logger] a ruby logger to STDOUT and info level
95
+ def default_logger
96
+ log = ::Logger.new(STDOUT)
97
+ log.level = ::Logger::INFO
98
+ log
99
+ end
100
+
101
+ # helper method to get a constant
102
+ #
103
+ # @example
104
+ # contantize('my_check') => 'MyCheck'
105
+ # @param [String] name of class
106
+ # @return [String]
107
+ def constantize(name)
108
+ name.to_s.split('_').map(&:capitalize).join
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,65 @@
1
+ require 'rack'
2
+ require 'heartcheck/controllers/base'
3
+
4
+ Dir.glob(File.expand_path('../controllers/*.rb', __FILE__))
5
+ .each { |x| require x }
6
+
7
+ # A web app that's use rack
8
+ module Heartcheck
9
+ class App
10
+ # A hash with paths as keys and controllers
11
+ # as values we use it in #dispath_action
12
+ # to routes the requests
13
+ ROUTE_TO_CONTROLLER = {
14
+ '/' => Controllers::Essential,
15
+ '' => Controllers::Essential,
16
+ '/functional' => Controllers::Functional,
17
+ '/dev' => Controllers::Dev,
18
+ '/info' => Controllers::Info,
19
+ '/health_check' => Controllers::HealthCheck
20
+ }
21
+
22
+ # Sets up the rack application.
23
+ #
24
+ # @param app [RackApp] is a rack app where
25
+ # heartcheck is included.
26
+ # @return [void]
27
+ def initialize(app = nil)
28
+ @app = app
29
+ end
30
+
31
+ # Sets up the rack application.
32
+ #
33
+ # @param env [Hash] is an instance of Hash
34
+ # that includes CGI-like headers.
35
+ # @return [Array] must be an array that contains
36
+ # - The HTTP response code
37
+ # - A Hash of headers
38
+ # - The response body, which must respond to each
39
+ def call(env)
40
+ req = Rack::Request.new(env)
41
+
42
+ [200, { 'Content-Type' => 'application/json' }, [dispatch_action(req)]]
43
+ rescue Heartcheck::Errors::RoutingError
44
+ [404, { 'Content-Type' => 'application/json' }, ['Not found']]
45
+ end
46
+
47
+ private
48
+
49
+ # Find a controller to espefic path
50
+ # and call the index method
51
+ #
52
+ # @param req [Rack::Request] an instance of request
53
+ # @return [String] a response body
54
+ def dispatch_action(req)
55
+ controller = ROUTE_TO_CONTROLLER[req.path_info]
56
+ fail Heartcheck::Errors::RoutingError if controller.nil?
57
+
58
+ Logger.info "Start [#{controller}] from #{req.ip} at #{Time.now}"
59
+
60
+ controller.new.index.tap do |_|
61
+ Logger.info "End [#{controller}]\n"
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ require 'heartcheck/checks/base'
2
+ require 'heartcheck/checks/firewall'
3
+ require 'heartcheck/checks/process'
@@ -0,0 +1,101 @@
1
+ module Heartcheck
2
+ module Checks
3
+ class Base
4
+ attr_accessor :functional, :dev, :name, :timeout
5
+
6
+ alias_method :functional?, :functional
7
+ alias_method :dev?, :dev
8
+
9
+ # call in Heartcheck.set
10
+ def initialize
11
+ @dynamic_services = nil
12
+ @error_proc = nil
13
+ @errors = []
14
+ @functional = false
15
+ @dev = false
16
+ @name = self.class.name.split('::').last.downcase
17
+ @services = []
18
+ @timeout = 0
19
+ @validate_proc = nil
20
+ end
21
+
22
+ def on_error(&block)
23
+ @error_proc = block if block_given?
24
+ end
25
+
26
+ def to_validate(&block)
27
+ @validate_proc = block if block_given?
28
+ end
29
+
30
+ def register_dynamic_services(&block)
31
+ @dynamic_services = block if block_given?
32
+ end
33
+
34
+ def add_service(service)
35
+ @services << service
36
+ end
37
+
38
+ def services
39
+ if @dynamic_services
40
+ @services + @dynamic_services.call
41
+ else
42
+ @services
43
+ end
44
+ end
45
+
46
+ def check
47
+ validation
48
+ hash = { name => { 'status' => (@errors.empty? ? 'ok' : 'error') } }
49
+ hash[name]['message'] = error_message unless @errors.empty?
50
+
51
+ Logger.info Oj.dump(hash)
52
+ hash
53
+ end
54
+
55
+ def informations
56
+ info
57
+ rescue => e
58
+ { 'error' => e.message }
59
+ end
60
+
61
+ private
62
+
63
+ def append_error(*args)
64
+ if @error_proc
65
+ @error_proc.call(@errors, *args)
66
+ else
67
+ custom_error(*args)
68
+ end
69
+ end
70
+
71
+ def validation
72
+ @errors = []
73
+ begin
74
+ Timeout.timeout(timeout, Heartcheck::Errors::Warning) do
75
+ if @validate_proc
76
+ @validate_proc.call(services, @errors)
77
+ else
78
+ validate
79
+ end
80
+ end
81
+ rescue Heartcheck::Errors::Warning => w
82
+ @errors = [{ type: 'warning', message: w.message }]
83
+ rescue => e
84
+ @errors = [e.message]
85
+ end
86
+ @errors
87
+ end
88
+
89
+ def error_message
90
+ @errors.map(&format_error)
91
+ end
92
+
93
+ def format_error
94
+ lambda do |error|
95
+ error.is_a?(Hash) ? error : { type: 'error', message: error }
96
+ end
97
+ end
98
+
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,26 @@
1
+ module Heartcheck
2
+ module Checks
3
+ class Firewall < Base
4
+ def services
5
+ super.map { |opts| Services::Firewall.new(opts) }
6
+ end
7
+
8
+ def validate
9
+ services.each do |service|
10
+ begin
11
+ Net::Telnet.new(service.params)
12
+ rescue Errno::ECONNREFUSED; nil
13
+ rescue
14
+ append_error(service)
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def custom_error(service)
22
+ @errors << "connection refused on: #{service.host}:#{service.port}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module Heartcheck
2
+ module Checks
3
+ class Process < Base
4
+ def validate
5
+ services.each do |service|
6
+ begin
7
+ pid = get_pid(service)
8
+ ::Process.kill(0, pid)
9
+ rescue Errno::ESRCH
10
+ append_error(service, pid)
11
+ end
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def custom_error(service, pid)
18
+ @errors << "The process of #{service[:name]} is not run with pid #{pid}"
19
+ end
20
+
21
+ def get_pid(service)
22
+ if service[:pid]
23
+ service[:pid]
24
+ else
25
+ File.read(service[:file]).to_i
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ require 'rack'
2
+ require 'oj'
3
+
4
+ Oj.default_options = { mode: :compat }
5
+
6
+ module Heartcheck
7
+ module Controllers
8
+ class Base
9
+ def index
10
+ fail NotImplementError
11
+ end
12
+
13
+ protected
14
+
15
+ def check(who)
16
+ Oj.dump(Heartcheck
17
+ .send("#{who}_checks")
18
+ .map(&:check))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ module Heartcheck
2
+ module Controllers
3
+ class Dev < Base
4
+ def index
5
+ results = []
6
+
7
+ total_execution_time = time_diff do
8
+ checks = Heartcheck.dev_checks
9
+
10
+ results += checks.reduce([]) do |acc, elem|
11
+ context_result = {}
12
+
13
+ context_result['execution_time'] = time_diff do
14
+ context_result.merge!(elem.check)
15
+ end
16
+
17
+ acc << context_result
18
+ end
19
+ end
20
+
21
+ results << { 'total_execution_time' => total_execution_time }
22
+ Oj.dump(results)
23
+ end
24
+
25
+ private
26
+
27
+ def time_diff
28
+ start_time = Time.now
29
+ yield
30
+ '%.2f ms' % ((Time.now - start_time) * 1_000)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ module Heartcheck
2
+ module Controllers
3
+ class Essential < Base
4
+ def index
5
+ check(:essential)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Heartcheck
2
+ module Controllers
3
+ class Functional < Base
4
+ def index
5
+ check(:functional)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Heartcheck
2
+ module Controllers
3
+ class HealthCheck < Base
4
+ def index
5
+ Oj.dump({ status: 'ok' })
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Heartcheck
2
+ module Controllers
3
+ class Info < Base
4
+ def index
5
+ Oj.dump(Heartcheck
6
+ .info_checks
7
+ .map(&:informations))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ require 'heartcheck/errors/routing_error'
2
+ require 'heartcheck/errors/warning'
@@ -0,0 +1,6 @@
1
+ module Heartcheck
2
+ module Errors
3
+ class RoutingError < RuntimeError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Heartcheck
2
+ module Errors
3
+ class Warning < RuntimeError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,53 @@
1
+ module Heartcheck
2
+ # A simple Interface to log messages
3
+ class Logger
4
+ # log message with debug level
5
+ #
6
+ # @param message [String] message to log
7
+ # @return [void]
8
+ def self.debug(message)
9
+ logger(:debug, message)
10
+ end
11
+
12
+ # log message with info level
13
+ #
14
+ # @param message [String] message to log
15
+ #
16
+ # @return [void]
17
+ def self.info(message)
18
+ logger(:info, message)
19
+ end
20
+
21
+ # log message with warn level
22
+ #
23
+ # @param message [String] message to log
24
+ #
25
+ # @return [void]
26
+ def self.warn(message)
27
+ logger(:warn, message)
28
+ end
29
+
30
+ # log message with error level
31
+ #
32
+ # @param message [String] message to log
33
+ #
34
+ # @return [void]
35
+ def self.error(message)
36
+ logger(:error, message)
37
+ end
38
+
39
+ private
40
+
41
+ # Sent the message to Heartcheck logger
42
+ # that you can configure
43
+ #
44
+ # @see Heartcheck.logger
45
+ # @param level [Symbol] the level log
46
+ # @param message [String] message to log
47
+ #
48
+ # @return [void]
49
+ def self.logger(level, message)
50
+ Heartcheck.logger.send(level, "[Heartcheck] #{message}")
51
+ end
52
+ end
53
+ end
@@ -0,0 +1 @@
1
+ require 'heartcheck/services/firewall'
@@ -0,0 +1,72 @@
1
+ require 'net/telnet'
2
+
3
+ module Heartcheck
4
+ module Services
5
+ # A service to check with a simple telnet
6
+ # if the route to a host is working.
7
+ class Firewall
8
+ attr_reader :uri, :proxy
9
+
10
+ # Sets up the options to firewall.
11
+ #
12
+ # @param params [Hash] a hash with the configurations.
13
+ # @option params [String] :host The domain/Ip
14
+ # @option params [Integer] :port Number of port to check
15
+ # @option params [String] :proxy The uri of your proxy if is required
16
+ # @option params [integer] :timeout (defaults to: 2) Number in seconds
17
+ # @option params [string] :uri You can pass a URI instead a host and port
18
+ #
19
+ # @example
20
+ # Firewall.new(host: 'domain.com', port: 80)
21
+ # Firewall.new(host: 'domain.com', port: 80, timeout: 5)
22
+ # Firewall.new(uri: 'https://domain.com')
23
+ # Firewall.new(uri: 'https://domain.com', proxy: 'http://proxy.domain.com')
24
+ #
25
+ # @return [void]
26
+ def initialize(params)
27
+ @host = params[:host]
28
+ @port = params[:port]
29
+ @proxy = params[:proxy]
30
+ @timeout = params[:timeout] || 2
31
+ @uri = URI(params[:url].to_s)
32
+ end
33
+
34
+ # format params to use in Telnet
35
+ #
36
+ # @return [Hash] with the config
37
+ # - Host
38
+ # - Port
39
+ # - Timeout
40
+ # - Proxy - if is seted return a Net::Telnet object
41
+ def params
42
+ params = { 'Host' => host, 'Port' => port, 'Timeout' => @timeout }
43
+ params['Proxy'] = proxy_uri if proxy
44
+ params
45
+ end
46
+
47
+ # to get the host or stract from @uri
48
+ #
49
+ # @return [String] the host that is configured
50
+ def host
51
+ @host || uri.host
52
+ end
53
+
54
+ # to get the port or stract from @uri
55
+ #
56
+ # @return [Integre] the port that is configured
57
+ def port
58
+ @port || uri.port
59
+ end
60
+
61
+ private
62
+
63
+ # to get the configured proxy
64
+ #
65
+ # @return [Net::Telnet] an instance with configured proxy
66
+ def proxy_uri
67
+ uri_proxy = URI(proxy)
68
+ ::Net::Telnet.new('Host' => uri_proxy.host, 'Port' => uri_proxy.port, 'Timeout' => @timeout)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,3 @@
1
+ module Heartcheck
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,248 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heartcheck
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Locaweb
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.6.0
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.6.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 1.6.0
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.6.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: oj
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 2.11.0
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.11.4
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 2.11.0
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.11.4
53
+ - !ruby/object:Gem::Dependency
54
+ name: pry-nav
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 0.2.0
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.2.4
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 0.2.0
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.2.4
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: 3.1.0
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.1.0
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.1.0
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 3.1.0
93
+ - !ruby/object:Gem::Dependency
94
+ name: rubocop
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: 0.27.0
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 0.27.1
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.27.0
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 0.27.1
113
+ - !ruby/object:Gem::Dependency
114
+ name: thor
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: 0.19.0
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 0.19.1
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: 0.19.0
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 0.19.1
133
+ - !ruby/object:Gem::Dependency
134
+ name: rack-test
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: 0.6.0
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: 0.6.3
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: 0.6.0
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: 0.6.3
153
+ - !ruby/object:Gem::Dependency
154
+ name: yard
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.8.0
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 0.8.7
163
+ type: :development
164
+ prerelease: false
165
+ version_requirements: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - "~>"
168
+ - !ruby/object:Gem::Version
169
+ version: 0.8.0
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 0.8.7
173
+ - !ruby/object:Gem::Dependency
174
+ name: redcarpet
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: 3.2.0
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: 3.2.2
183
+ type: :development
184
+ prerelease: false
185
+ version_requirements: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - "~>"
188
+ - !ruby/object:Gem::Version
189
+ version: 3.2.0
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: 3.2.2
193
+ description: A simple way to check your app heart.
194
+ email:
195
+ - desenvolvedores@locaweb.com.br
196
+ executables:
197
+ - heartcheck
198
+ extensions: []
199
+ extra_rdoc_files: []
200
+ files:
201
+ - bin/heartcheck
202
+ - lib/generators/generator.rb
203
+ - lib/generators/templates/config.rb
204
+ - lib/heartcheck.rb
205
+ - lib/heartcheck/app.rb
206
+ - lib/heartcheck/checks.rb
207
+ - lib/heartcheck/checks/base.rb
208
+ - lib/heartcheck/checks/firewall.rb
209
+ - lib/heartcheck/checks/process.rb
210
+ - lib/heartcheck/controllers/base.rb
211
+ - lib/heartcheck/controllers/dev.rb
212
+ - lib/heartcheck/controllers/essential.rb
213
+ - lib/heartcheck/controllers/functional.rb
214
+ - lib/heartcheck/controllers/health_check.rb
215
+ - lib/heartcheck/controllers/info.rb
216
+ - lib/heartcheck/errors.rb
217
+ - lib/heartcheck/errors/routing_error.rb
218
+ - lib/heartcheck/errors/warning.rb
219
+ - lib/heartcheck/logger.rb
220
+ - lib/heartcheck/services.rb
221
+ - lib/heartcheck/services/firewall.rb
222
+ - lib/heartcheck/version.rb
223
+ homepage: http://developer.locaweb.com.br
224
+ licenses:
225
+ - MIT
226
+ metadata: {}
227
+ post_install_message:
228
+ rdoc_options: []
229
+ require_paths:
230
+ - lib
231
+ required_ruby_version: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ required_rubygems_version: !ruby/object:Gem::Requirement
237
+ requirements:
238
+ - - ">="
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ requirements: []
242
+ rubyforge_project:
243
+ rubygems_version: 2.4.5
244
+ signing_key:
245
+ specification_version: 4
246
+ summary: A simple way to check if your app is runnig like as expected.
247
+ test_files: []
248
+ has_rdoc: