healthyr 0.5
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 +15 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +8 -0
- data/healthyr.gemspec +23 -0
- data/lib/healthyr.rb +36 -0
- data/lib/healthyr/event.rb +43 -0
- data/lib/healthyr/event_agent.rb +49 -0
- data/lib/healthyr/event_handler.rb +15 -0
- data/lib/healthyr/event_pool.rb +26 -0
- data/lib/healthyr/railtie.rb +7 -0
- data/spec/event_agent_spec.rb +39 -0
- data/spec/event_handler_spec.rb +29 -0
- data/spec/event_pool_spec.rb +26 -0
- data/spec/event_spec.rb +39 -0
- data/spec/spec_helper.rb +1 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MTIzOWNmZTllNTRjYmZmNGRhODAyNDIwZWIyNDE5MGM2OWEzOTgyMw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YWU1NGI2NDBiZTExMDNhN2I2MzI3ZGYxMGViMjE3ZjFmMTc0NGZhYQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDBiNTE0ZGNhMGZlY2E3OGY0MTQ2ZDQ0MWU0NzY0MDk1Nzc5ZmE4NjhhYTdi
|
10
|
+
M2RmNmVhNjFmNjVhMTA4M2E0YTg4ZjU2MTRlYWNmYTQwNTI2YjlmZTBjNGRk
|
11
|
+
OGQ3MDRhMWIzMzIxMTc5NzVhNzRiOGJlYjJjMGFlNWE5ZTUzYzU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Mzk1NDhkODBlNDI0OGJjNjhjNmRiNWFiYjExOTBiZDM5ZDI5ZDhhYTM2MjFj
|
14
|
+
MGNjMTExZDgyZTcxZmNjY2FiY2MwMDQ5NGUzNzgwNmZiZDUxZmFhODczZmYw
|
15
|
+
OWY5N2QwZWFjMjM1MzIxYTFmMzBlYjJkNjM2MmY4OWUzNjNhMjg=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 elvio
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Healthyr
|
2
|
+
Healthyr is a performance monitor for Ruby on Rails applications. It takes advantage of [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) instruments to help you find slow parts of your app.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
* Add healthyr to your Rails Gemfile:
|
7
|
+
|
8
|
+
gem 'healthyr'
|
9
|
+
|
10
|
+
* Clone the application monitor
|
11
|
+
|
12
|
+
git clone https://github.com/elvio/healthyr\_monitor
|
13
|
+
|
14
|
+
* Start the monitor
|
15
|
+
|
16
|
+
$ rackup config.ru --port=[PORT]
|
17
|
+
|
18
|
+
* Start your Rails app with HEALTHYR\_MONITOR\_URL environment variable pointing to the monitor you have started
|
19
|
+
|
20
|
+
$ HEALTHYR\_MONITOR\_URL="http://[SERVER]:[PORT]" rails s
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
* Access the monitor URL to have access to charts and data about the slowest parts of your application (database, view and controller)
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/healthyr.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "healthyr"
|
7
|
+
spec.version = "0.5"
|
8
|
+
spec.authors = ["elvio"]
|
9
|
+
spec.email = ["elvio@elviovicosa.com"]
|
10
|
+
spec.description = %q{Healthyr is a simple Ruby on Rails app performance monitor. It takes advantage of ActiveSupport::Notifications instruments to help you find slow portions of your app.}
|
11
|
+
spec.summary = %q{Healthyr is a simple Ruby on Rails app performance monitor.}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
end
|
data/lib/healthyr.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'net/http'
|
3
|
+
require 'healthyr/event'
|
4
|
+
require 'healthyr/event_handler'
|
5
|
+
require 'healthyr/event_agent'
|
6
|
+
require 'healthyr/event_pool'
|
7
|
+
|
8
|
+
module Healthyr
|
9
|
+
def self.boot(app)
|
10
|
+
start_event_handler
|
11
|
+
start_event_agent
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.start_event_handler
|
15
|
+
EventHandler.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.start_event_agent
|
19
|
+
EventAgent.new(monitor_url, update_interval)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.monitor_url
|
23
|
+
if ENV['HEALTHYR_MONITOR_URL']
|
24
|
+
URI.parse(ENV['HEALTHYR_MONITOR_URL'] + "/events")
|
25
|
+
else
|
26
|
+
raise ArgumentError.new "Healthyr could not find environment variable: HEALTHYR_MONITOR_URL"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.update_interval
|
31
|
+
interval = ENV['HEALTHYR_UPDATE_INTERVAL'].to_i
|
32
|
+
interval < 5 ? 5 : interval
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'healthyr/railtie'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Healthyr
|
2
|
+
class Event
|
3
|
+
attr_accessor :event
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
@event = ActiveSupport::Notifications::Event.new(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash
|
10
|
+
{reported_at: Time.at(event.time), time: {total: event.duration}}.tap do |hash|
|
11
|
+
if database?
|
12
|
+
hash[:name] = 'database'
|
13
|
+
hash[:value] = payload[:sql]
|
14
|
+
elsif view?
|
15
|
+
hash[:name] = 'view'
|
16
|
+
hash[:value] = payload[:virtual_path]
|
17
|
+
elsif controller?
|
18
|
+
hash[:name] = 'controller'
|
19
|
+
hash[:value] = "#{payload[:controller]}##{payload[:action]}"
|
20
|
+
hash[:time][:view] = payload[:view_runtime]
|
21
|
+
hash[:time][:db] = payload[:db_runtime]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def payload
|
28
|
+
@payload ||= event.payload
|
29
|
+
end
|
30
|
+
|
31
|
+
def database?
|
32
|
+
event.name == 'sql.active_record'
|
33
|
+
end
|
34
|
+
|
35
|
+
def view?
|
36
|
+
event.name == '!render_template.action_view'
|
37
|
+
end
|
38
|
+
|
39
|
+
def controller?
|
40
|
+
event.name == 'process_action.action_controller'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Healthyr
|
2
|
+
class EventAgent
|
3
|
+
|
4
|
+
def initialize(monitor_url, update_interval)
|
5
|
+
AgentThread.new(update_interval) do
|
6
|
+
events = EventPool.flush
|
7
|
+
envelope = Envelope.new(events)
|
8
|
+
|
9
|
+
begin
|
10
|
+
response = Net::HTTP.post_form(monitor_url, {data: envelope.content})
|
11
|
+
if response.code != 200
|
12
|
+
Rails.logger.error "Healthyr failed to send data to monitor"
|
13
|
+
end
|
14
|
+
rescue Errno::ECONNREFUSED
|
15
|
+
Rails.logger.error "Healthyr could not connect to '#{monitor_url}'"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
class Envelope
|
23
|
+
def initialize(events)
|
24
|
+
@events = events
|
25
|
+
end
|
26
|
+
|
27
|
+
def content
|
28
|
+
Hash[from: instance_id, events: @events.map(&:to_hash)].to_json
|
29
|
+
end
|
30
|
+
|
31
|
+
def instance_id
|
32
|
+
"#{Socket.gethostname}-#{$$}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class AgentThread
|
37
|
+
def initialize(duration, &block)
|
38
|
+
Thread.abort_on_exception = true
|
39
|
+
Thread.new do
|
40
|
+
while true
|
41
|
+
sleep duration
|
42
|
+
block.call
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Healthyr
|
2
|
+
class EventHandler
|
3
|
+
EVENT_NAMES = /sql\.active_record|!render_template\.action_view|process_action\.action_controller/
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
ActiveSupport::Notifications.subscribe(EVENT_NAMES) do |*args|
|
7
|
+
event_received(Event.new(*args))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def event_received(event)
|
12
|
+
EventPool.add(event)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Healthyr
|
2
|
+
class EventPool
|
3
|
+
@@elements = []
|
4
|
+
@@mutex = Mutex.new
|
5
|
+
|
6
|
+
def self.add(element)
|
7
|
+
@@mutex.synchronize do
|
8
|
+
@@elements << element
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.flush
|
13
|
+
_elements = []
|
14
|
+
@@mutex.synchronize do
|
15
|
+
_elements = @@elements.dup
|
16
|
+
@@elements = []
|
17
|
+
end
|
18
|
+
|
19
|
+
_elements
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.elements
|
23
|
+
@@elements
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Healthyr
|
5
|
+
describe EventAgent do
|
6
|
+
class EventAgent::AgentThread
|
7
|
+
def initialize(duration, &block)
|
8
|
+
block.call
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class EventAgent::Envelope
|
13
|
+
def instance_id
|
14
|
+
"test-10"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:monitor_url) { "http://monitor-url" }
|
19
|
+
let(:update_interval) { 10 }
|
20
|
+
|
21
|
+
|
22
|
+
describe "#initialize" do
|
23
|
+
let(:event1) { stub("Event1", to_hash: Hash[name: "event1"]) }
|
24
|
+
let(:event2) { stub("Event2", to_hash: Hash[name: "event2"]) }
|
25
|
+
let(:data) { {from: 'test-10', events: [event1.to_hash, event2.to_hash]}.to_json }
|
26
|
+
let(:response) { stub("Response", code: 200) }
|
27
|
+
|
28
|
+
before do
|
29
|
+
EventPool.add(event1)
|
30
|
+
EventPool.add(event2)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sends the events data to monitor" do
|
34
|
+
Net::HTTP.should_receive(:post_form).with(monitor_url, {data: data}).and_return(response)
|
35
|
+
EventAgent.new(monitor_url, update_interval)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Healthyr
|
4
|
+
describe EventHandler do
|
5
|
+
describe ".start" do
|
6
|
+
it "subscribes to ActiveSupport::Notifications" do
|
7
|
+
ActiveSupport::Notifications.should_receive(:subscribe).with(EventHandler::EVENT_NAMES)
|
8
|
+
described_class.new
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".event_received" do
|
13
|
+
let(:event) { stub("Event") }
|
14
|
+
|
15
|
+
before do
|
16
|
+
ActiveSupport::Notifications.stub(:subscribe)
|
17
|
+
end
|
18
|
+
|
19
|
+
subject do
|
20
|
+
described_class.new
|
21
|
+
end
|
22
|
+
|
23
|
+
it "adds a new event to the event pool" do
|
24
|
+
EventPool.should_receive(:add).with(event)
|
25
|
+
subject.event_received(event)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Healthyr
|
2
|
+
describe EventPool do
|
3
|
+
let(:event1) { stub("Event1") }
|
4
|
+
let(:event2) { stub("Event2") }
|
5
|
+
|
6
|
+
before do
|
7
|
+
EventPool.flush
|
8
|
+
EventPool.add(event1)
|
9
|
+
EventPool.add(event2)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.add' do
|
13
|
+
it 'adds a new element to the pool' do
|
14
|
+
EventPool.elements.should == [event1, event2]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.flush' do
|
19
|
+
it 'cleans the pool and return the elements' do
|
20
|
+
flushed = EventPool.flush
|
21
|
+
flushed.should == [event1, event2]
|
22
|
+
EventPool.elements.should == []
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/event_spec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Healthyr
|
4
|
+
describe Event do
|
5
|
+
let(:transaction_id) { "38bb3fae1c76bbfb5c1c" }
|
6
|
+
let(:starts) { 1363158057 }
|
7
|
+
let(:ends) { 1363158067 }
|
8
|
+
let(:event_time) { Time.at(starts) }
|
9
|
+
let(:args) { [event_type, starts, ends, transaction_id, payload] }
|
10
|
+
let(:duration) { 10000.0 }
|
11
|
+
|
12
|
+
subject { Event.new(*args).to_hash }
|
13
|
+
|
14
|
+
context 'database event' do
|
15
|
+
let(:sql_query) { %q{SELECT "users".* FROM "users"} }
|
16
|
+
let(:event_type) { "sql.active_record" }
|
17
|
+
let(:payload) { Hash[sql: sql_query] }
|
18
|
+
|
19
|
+
it { should == Hash[name: 'database', value: sql_query, time: {total: duration}, reported_at: event_time]}
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'view event' do
|
23
|
+
let(:event_type) { '!render_template.action_view' }
|
24
|
+
let(:view_path) { 'users/index' }
|
25
|
+
let(:payload) { Hash[virtual_path: view_path] }
|
26
|
+
|
27
|
+
it { should == Hash[name: 'view', value: view_path, time: {total: duration}, reported_at: event_time]}
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'controller event' do
|
31
|
+
let(:event_type) { 'process_action.action_controller' }
|
32
|
+
let(:view_runtime) { 10.4 }
|
33
|
+
let(:db_runtime) { 1.98 }
|
34
|
+
let(:payload) { Hash[controller: 'UsersController', action: 'index', view_runtime: view_runtime, db_runtime: db_runtime] }
|
35
|
+
|
36
|
+
it { should == Hash[name: 'controller', value: 'UsersController#index', time: {total: duration, view: view_runtime, db: db_runtime}, reported_at: event_time] }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'healthyr'
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: healthyr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.5'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- elvio
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Healthyr is a simple Ruby on Rails app performance monitor. It takes
|
56
|
+
advantage of ActiveSupport::Notifications instruments to help you find slow portions
|
57
|
+
of your app.
|
58
|
+
email:
|
59
|
+
- elvio@elviovicosa.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- .gitignore
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- healthyr.gemspec
|
70
|
+
- lib/healthyr.rb
|
71
|
+
- lib/healthyr/event.rb
|
72
|
+
- lib/healthyr/event_agent.rb
|
73
|
+
- lib/healthyr/event_handler.rb
|
74
|
+
- lib/healthyr/event_pool.rb
|
75
|
+
- lib/healthyr/railtie.rb
|
76
|
+
- spec/event_agent_spec.rb
|
77
|
+
- spec/event_handler_spec.rb
|
78
|
+
- spec/event_pool_spec.rb
|
79
|
+
- spec/event_spec.rb
|
80
|
+
- spec/spec_helper.rb
|
81
|
+
homepage: ''
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.0.0
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Healthyr is a simple Ruby on Rails app performance monitor.
|
105
|
+
test_files:
|
106
|
+
- spec/event_agent_spec.rb
|
107
|
+
- spec/event_handler_spec.rb
|
108
|
+
- spec/event_pool_spec.rb
|
109
|
+
- spec/event_spec.rb
|
110
|
+
- spec/spec_helper.rb
|