heartbeat_rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7d34ba3323b944cc84d98bac468998098441293d
4
+ data.tar.gz: 81ecafb6e37febc1eba5cac95db8c3872ca19bf5
5
+ SHA512:
6
+ metadata.gz: e94bec3bd78da48a92be99a24813aa289b00acb09284128f256090f891a2a2392864a933fab2dd70f1eaa9ee5fc739246e3f3ddf73069c87abb7cfd4f724673f
7
+ data.tar.gz: 7ca76e51131d34d0e06b861fad398d9b16da4cf38da66b7ad09f77bd6d0552f1410b9b6b501ab8d49ab709cdc2eeb900c3f501f8310f210b74e0efd167e66ba2
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ spec/dummy/db/*.sqlite3
5
+ spec/dummy/log/*.log
6
+ spec/dummy/tmp/
7
+ spec/dummy/.sass-cache
8
+ /coverage/
9
+ Gemfile.lock
10
+ /*.gem
11
+
12
+ # RSpec failed examples
13
+ spec/examples.txt
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require rails_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ # Use containers for fast builds
3
+ sudo: false
4
+ rvm:
5
+ - 2.2.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,46 @@
1
+ # CHANGELOG for heartbeat_rails
2
+
3
+ This file is used to list changes made in each version of heartbeat_rails.
4
+
5
+ ## 1.0.0: (2015-12-02)
6
+
7
+ * Removed unused files/modules/views etc.
8
+ * Automatically mount the engine at `heartbeat` endpoint (`status` is too common as word).
9
+ * Configurable endpoint, one can change the endpoint, append it, prepend it or disable automounting using configuration methods.
10
+ * Simplified routes, only `/heartbeat` and `/heartbeat/health` available (removed the `ping` suffix).
11
+ * Added a `newrelic_ignore` call in the `HealthController`, heartbeat checks should not be reported as newrelic transactions
12
+ otherwise they improve your apdex with no reason to do that.
13
+ * Changed the default database check to use [default active record implementation](https://github.com/rails/rails/blob/3e36db4406beea32772b1db1e9a16cc1e8aea14c/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L72)
14
+ which perform better and save some resources on busiest MySQL servers.That method is defined for each supported AR adapter.
15
+
16
+ ## 0.1.2: (2014-02-03)
17
+
18
+ Features:
19
+
20
+ * Updated rails dependency to allow 4.0 (now >= 3.2)
21
+ * Now also tested on ruby 2.1
22
+
23
+ ## 0.1.1: (2013-08-26)
24
+
25
+ Bugfixes:
26
+
27
+ * Fix initialization with nested hashes in configuration (unused so far)
28
+
29
+ Features:
30
+
31
+ * Removed dependency on `newrelic_rpm` gem
32
+ * Now with 100% code coverage!
33
+
34
+ ## 0.1.0: (2013-01-24)
35
+
36
+ * Initial release of new\_relic\_ping
37
+
38
+ Supported features:
39
+ * ping action
40
+ * health action with configurable monitoring code blocks
41
+ * ActiveRecord database monitoring default check
42
+
43
+ - - -
44
+ Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown.
45
+
46
+ The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Declare your gem's dependencies in new_relic_ping.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ group :development, :test do
9
+ gem 'pry'
10
+ # for CRuby, Rubinius, including Windows and RubyInstaller
11
+ gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
12
+ end
13
+
14
+ # jquery-rails is used by the dummy application
15
+ gem 'jquery-rails'
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Jeremy Olliver
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ HeartbeatRails
2
+ ============
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/heartbeat_rails.png)](http://badge.fury.io/rb/heartbeat_rails)
5
+ [![Build Status](https://travis-ci.org/fabn/heartbeat_rails.png?branch=master)](https://travis-ci.org/fabn/heartbeat_rails)
6
+
7
+ Add a URL to your rails application to respond to ping requests from NewRelic (and other services).
8
+ This is something that we've found we often implement. While you can often simply call the root URL
9
+ when monitoring, that isn't always possible if the homepage is protected by a login screen which
10
+ returns a 403 status. Adding this gem keeps the ping URL's out of your main application space, and
11
+ as a bonus, makes additional support for data stores or other services in your heartbeat a breeze.
12
+
13
+ Usage
14
+ -----
15
+
16
+ Add this to your Gemfile
17
+
18
+ ```ruby
19
+ gem 'heartbeat_rails'
20
+ ```
21
+
22
+ This enables two URL's (they are automatically appended in the existing routeset)
23
+
24
+ ```
25
+ /heartbeat
26
+ /heartbeat/health
27
+ ```
28
+
29
+ heartbeat will respond with the text OK, and status 200 when your rails server is available.
30
+ The health action is to allow more deep monitoring of the health of your service. You can configure
31
+ additional checks to run when this controller action is hit, this allows you to keep tabs on things
32
+ like response times for services or data stores your app is dependent on.
33
+
34
+ Routes handling
35
+ -----------------------------
36
+
37
+ By default this gem appends the above routes in your current routeset, if you need to customize them you can use
38
+ the following methods available via configuration methods (for instance in an initializer)
39
+
40
+ ```ruby
41
+ # config/initializers/heartbeat.rb
42
+ HeartbeatRails.configure do |c|
43
+ # Customize where the engine is mounted, default is `/heartbeat`
44
+ c.mount_on '/whatever'
45
+ # Customize where the route is mounted
46
+ c.append_route! # default if not specified
47
+ c.prepend_route! # to prepend the engine route
48
+ c.dont_mount! # if you want to manually mount the route in whatever position
49
+ end
50
+ ```
51
+
52
+ In the latter case you have to mount the route by yourself by using a line like this in your app `routes.rb`
53
+
54
+ ```ruby
55
+ mount HeartbeatRails::Engine => '/whatever-path-you-want'
56
+ ```
57
+
58
+ This can be useful if you need to apply some route constraint or if you want to protect the route in some way.
59
+
60
+ Configuring monitoring checks
61
+ -----------------------------
62
+
63
+ Configure a block to run checks monitoring services you are dependent on, e.g.:
64
+
65
+ ```ruby
66
+ # in config/initializers/heartbeat.rb
67
+ HeartbeatRails.configure do |c|
68
+ # This database check is defined for you by default if you're using ActiveRecord
69
+ # though you can override it by redefining it in your configuration
70
+ c.monitor('database') do
71
+ ActiveRecord::Base.connection.execute("select count(*) from schema_migrations")
72
+ end
73
+ c.monitor('redis') do
74
+ # Block return value is ignored, you must raise to fail a check
75
+ raise 'Redis ping failed' unless 'PONG' == Redis.client.ping
76
+ end
77
+ end
78
+ ```
79
+
80
+ These blocks will be executed when the /health action is called, and the additional information set in the HTTP headers of the request.
81
+ `X-{service}-Response` will be set to the return value of the block, `X-{Service}-Time` will show the execution time of the given block: "X.XXXXXX seconds".
82
+
83
+ The return value of the monitoring blocks does not determine success or failure conditions, an HTTP error status will only be returned
84
+ if the block raises an exception.
85
+
86
+ You can now configure any monitoring/alerting tools that you use, such as pingdom, or new relic to 'ping' this url,
87
+ checking if your application is alive.
88
+
89
+ ```
90
+ curl -v http://localhost:3000/heartbeat
91
+ curl -v http://localhost:3000/heartbeat/health
92
+ ```
93
+
94
+ Contributing to HeartbeatRails
95
+ ------------------------------
96
+
97
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
98
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
99
+ * Fork the project
100
+ * Start a feature/bugfix branch
101
+ * Commit and push until you are happy with your contribution
102
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
103
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
104
+
105
+ Credits
106
+ -------
107
+
108
+ This is a fork of the original work made by [Jeremy Olliver](https://github.com/jeremyolliver/new_relic_ping).
109
+
110
+ - - -
111
+ Copyright (c) 2013 Jeremy Olliver, (c) 2015 Fabio Napoleoni. Released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,42 @@
1
+ module HeartbeatRails
2
+ class HealthController < ApplicationController
3
+
4
+ # Don't include these actions as transactions in newrelic reports
5
+ newrelic_ignore if respond_to?(:newrelic_ignore)
6
+
7
+ # Return an okay if the Application Server is alive
8
+ def ping
9
+ send_response(:ok)
10
+ end
11
+
12
+ # Run the configured monitoring blocks
13
+ # Set the response times (return values) as HTTP headers
14
+ # return either ok or error status (error sent only if the configured block raises an exception)
15
+ def health
16
+ send_response(*configuration.status_check)
17
+ end
18
+
19
+ protected
20
+
21
+ def send_response(status_msg, meta_info = {})
22
+ write_headers(meta_info)
23
+ render :text => status_msg.to_s, :status => status_msg, :content_type => Mime::TEXT
24
+ end
25
+
26
+ def write_headers(values = {})
27
+ values.each do |name, value|
28
+ response.headers[header_name_for(name)] = value
29
+ end
30
+ end
31
+
32
+ # Transform :database_response => 'X-Database-Response'
33
+ def header_name_for(name)
34
+ 'X' + name.to_s.camelize.gsub(/([A-Z])/) { "-#{$1}"}
35
+ end
36
+
37
+ def configuration
38
+ HeartbeatRails.config
39
+ end
40
+
41
+ end
42
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ HeartbeatRails::Engine.routes.draw do
2
+ get '/' => 'health#ping'
3
+ get '/health' => 'health#health'
4
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'heartbeat_rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'heartbeat_rails'
8
+ spec.version = HeartbeatRails::VERSION
9
+ spec.authors = ['Jeremy Olliver', 'Fabio Napoleoni']
10
+ spec.email = %w(jeremy.olliver@gmail.com f.napoleoni@gmail.com)
11
+
12
+ spec.summary = %q{Rails endpoint for NewRelic HTTP ping monitoring}
13
+ spec.description = %q{Provides endpoints for NewRelic (or any other uptime service monitor) HTTP ping monitoring for Rails applications}
14
+ spec.homepage = 'https://github.com/fabn/heartbeat_rails'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ # Relaxed version constraint, we don't want to be a barrier to upgrading
23
+ spec.add_dependency 'rails', '>= 3.2'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.10'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'rspec'
28
+ spec.add_development_dependency 'rspec-rails'
29
+ end
@@ -0,0 +1,113 @@
1
+ require 'benchmark'
2
+
3
+ module HeartbeatRails
4
+ class Configuration
5
+
6
+ # Default mountpoint for engine
7
+ DEFAULT_MOUNTPOINT = '/heartbeat'
8
+ # used in railtie to read where to mount the engine
9
+ attr_reader :mountpoint
10
+
11
+ attr_accessor :monitors
12
+
13
+ def initialize(data={})
14
+ @data = {}
15
+ @monitors = {}
16
+ @mountpoint = DEFAULT_MOUNTPOINT
17
+ @mount_mode = :append
18
+ update!(data)
19
+ load_default_monitors
20
+ end
21
+
22
+ def update!(data)
23
+ data.each do |key, value|
24
+ self[key] = value
25
+ end
26
+ end
27
+
28
+ def [](key)
29
+ @data[key.to_sym]
30
+ end
31
+
32
+ def []=(key, value)
33
+ @data[key.to_sym] = value
34
+ end
35
+
36
+ def method_missing(sym, *args)
37
+ if sym.to_s =~ /(.+)=$/
38
+ self[$1] = args.first
39
+ else
40
+ self[sym]
41
+ end
42
+ end
43
+
44
+ def monitor(label, &block)
45
+ @monitors[label.to_s] = block
46
+ end
47
+
48
+ # Configure where the engine should be mounted
49
+ def mount_at(mountpoint)
50
+ @mountpoint = mountpoint
51
+ end
52
+
53
+ def automount?
54
+ !!@mount_mode
55
+ end
56
+
57
+ def route_method
58
+ @mount_mode
59
+ end
60
+
61
+ def append_route!
62
+ @mount_mode = :append
63
+ end
64
+
65
+ def prepend_route!
66
+ @mount_mode = :prepend
67
+ end
68
+
69
+ def dont_mount!
70
+ @mount_mode = nil
71
+ end
72
+
73
+ def load_default_monitors
74
+ if defined?(ActiveRecord::Base)
75
+ monitor('database') do
76
+ # Delegate activeness check to actual AR implementation
77
+ # in MySQL it would call mysql.ping in postgres it fallback to SELECT 1
78
+ ActiveRecord::Base.connection.active?
79
+ end
80
+ end
81
+ end
82
+
83
+ def status_check
84
+ responses = {}
85
+ begin
86
+ @monitors.each do |label, mon|
87
+ time = ::Benchmark.realtime do
88
+ responses["#{label}_response"] = (mon.call).to_s
89
+ end
90
+ responses["#{label}_time"] = "#{time.inspect} seconds"
91
+ end
92
+ return :ok, responses
93
+ rescue => e
94
+ responses['error_message'] = e.message
95
+ return :error, responses
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+ class << self
102
+ attr_accessor :config_instance
103
+
104
+ def config
105
+ self.config_instance ||= Configuration.new
106
+ end
107
+
108
+ def configure
109
+ yield config
110
+ end
111
+ end
112
+
113
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails'
2
+
3
+ module HeartbeatRails
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace HeartbeatRails
6
+
7
+ initializer 'heartbeat_rails.add_routes' do
8
+ if HeartbeatRails.config.automount?
9
+ Rails.logger.debug do
10
+ "Mounting HeartbeatRails::Engine at #{HeartbeatRails.config.mountpoint} with mode #{HeartbeatRails.config.route_method}"
11
+ end
12
+ Rails.application.routes.public_send(HeartbeatRails.config.route_method) do
13
+ mount HeartbeatRails::Engine => HeartbeatRails.config.mountpoint
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module HeartbeatRails
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,6 @@
1
+ require 'heartbeat_rails/engine'
2
+ require 'heartbeat_rails/configuration'
3
+ require 'heartbeat_rails/version'
4
+
5
+ module HeartbeatRails
6
+ end
data/script/rails ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/heartbeat_rails/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heartbeat_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Olliver
8
+ - Fabio Napoleoni
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '3.2'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '3.2'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.10'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.10'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec-rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description: Provides endpoints for NewRelic (or any other uptime service monitor)
85
+ HTTP ping monitoring for Rails applications
86
+ email:
87
+ - jeremy.olliver@gmail.com
88
+ - f.napoleoni@gmail.com
89
+ executables: []
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - ".gitignore"
94
+ - ".rspec"
95
+ - ".travis.yml"
96
+ - CHANGELOG.md
97
+ - Gemfile
98
+ - LICENSE
99
+ - README.md
100
+ - Rakefile
101
+ - app/controllers/heartbeat_rails/health_controller.rb
102
+ - config/routes.rb
103
+ - heartbeat_rails.gemspec
104
+ - lib/heartbeat_rails.rb
105
+ - lib/heartbeat_rails/configuration.rb
106
+ - lib/heartbeat_rails/engine.rb
107
+ - lib/heartbeat_rails/version.rb
108
+ - script/rails
109
+ homepage: https://github.com/fabn/heartbeat_rails
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.4.3
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Rails endpoint for NewRelic HTTP ping monitoring
133
+ test_files: []