yam-ruby-metrics 0.8.6

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.
Files changed (49) hide show
  1. data/.bundle/config +2 -0
  2. data/.gitignore +4 -0
  3. data/.rvmrc +1 -0
  4. data/CHANGELOG.md +48 -0
  5. data/Gemfile +8 -0
  6. data/Gemfile.lock +36 -0
  7. data/LICENSE +21 -0
  8. data/README.md +86 -0
  9. data/Rakefile +19 -0
  10. data/autotest/discover.rb +3 -0
  11. data/examples/counter.rb +10 -0
  12. data/examples/gauge.rb +25 -0
  13. data/examples/histogram.rb +32 -0
  14. data/examples/integration/rack_endpoint.ru +24 -0
  15. data/examples/integration/rack_middleware.ru +21 -0
  16. data/examples/integration/webrick.rb +17 -0
  17. data/examples/meter.rb +25 -0
  18. data/examples/timer.rb +31 -0
  19. data/lib/ruby-metrics.rb +15 -0
  20. data/lib/ruby-metrics/agent.rb +62 -0
  21. data/lib/ruby-metrics/instruments/counter.rb +39 -0
  22. data/lib/ruby-metrics/instruments/gauge.rb +23 -0
  23. data/lib/ruby-metrics/instruments/histogram.rb +188 -0
  24. data/lib/ruby-metrics/instruments/meter.rb +99 -0
  25. data/lib/ruby-metrics/instruments/timer.rb +138 -0
  26. data/lib/ruby-metrics/integration.rb +11 -0
  27. data/lib/ruby-metrics/integration/rack_endpoint.rb +33 -0
  28. data/lib/ruby-metrics/integration/rack_middleware.rb +82 -0
  29. data/lib/ruby-metrics/integration/webrick.rb +47 -0
  30. data/lib/ruby-metrics/logging.rb +19 -0
  31. data/lib/ruby-metrics/statistics/exponential_sample.rb +91 -0
  32. data/lib/ruby-metrics/statistics/uniform_sample.rb +37 -0
  33. data/lib/ruby-metrics/time_units.rb +61 -0
  34. data/lib/ruby-metrics/version.rb +3 -0
  35. data/ruby-metrics.gemspec +27 -0
  36. data/spec/agent_spec.rb +48 -0
  37. data/spec/instruments/counter_spec.rb +79 -0
  38. data/spec/instruments/gauge_spec.rb +42 -0
  39. data/spec/instruments/histogram_spec.rb +115 -0
  40. data/spec/instruments/meter_spec.rb +99 -0
  41. data/spec/instruments/timer_spec.rb +146 -0
  42. data/spec/integration/rack_endpoint_spec.rb +60 -0
  43. data/spec/integration/rack_middleware_spec.rb +129 -0
  44. data/spec/integration/webrick_spec.rb +18 -0
  45. data/spec/spec_helper.rb +18 -0
  46. data/spec/statistics/exponential_sample_spec.rb +138 -0
  47. data/spec/statistics/uniform_sample_spec.rb +59 -0
  48. data/spec/time_units_spec.rb +13 -0
  49. metadata +184 -0
@@ -0,0 +1,60 @@
1
+ require "rack/test"
2
+
3
+ describe Metrics::Integration::Rack::Endpoint do
4
+ include Rack::Test::Methods
5
+
6
+ def app(options = {})
7
+ @app ||= Metrics::Integration::Rack::Endpoint.new(options)
8
+ end
9
+ def agent
10
+ app.agent
11
+ end
12
+
13
+ it "should show stats" do
14
+ get "/"
15
+ last_response.should be_ok
16
+ last_response.body.should == agent.to_json
17
+ end
18
+
19
+ context "configuring" do
20
+
21
+ context "agent" do
22
+ it "should create an agent by default" do
23
+ app(:agent => nil)
24
+ agent.should be_a(Metrics::Agent)
25
+ end
26
+
27
+ it "should use an agent if provided" do
28
+ @agent = Metrics::Agent.new
29
+ app(:agent => @agent)
30
+ agent.should be_a(Metrics::Agent)
31
+ agent.should == @agent
32
+ end
33
+ end
34
+
35
+ context "show" do
36
+ it "should match a string to the PATH_INFO exactly" do
37
+ app(:show => "/foo")
38
+ get '/foo'
39
+ last_response.should be_ok
40
+ last_response.body.should == agent.to_json
41
+ end
42
+
43
+ it "should match a regular expression to the PATH_INFO" do
44
+ app(:show => /bar/)
45
+ get '/foobarbaz'
46
+ last_response.should be_ok
47
+ last_response.body.should == agent.to_json
48
+ end
49
+
50
+ it "should call `call` on the show option if it responds to it" do
51
+ app(:show => lambda{ |env| env['PATH_INFO'] == "/bing" })
52
+ get '/bing'
53
+ last_response.should be_ok
54
+ last_response.body.should == agent.to_json
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,129 @@
1
+ require "rack/test"
2
+
3
+ describe Metrics::Integration::Rack::Middleware do
4
+ include Rack::Test::Methods
5
+
6
+ def app(status = 200, body = ["Hello, World!"], headers = {})
7
+ @app ||= lambda{ |env| [status, {'Content-Type' => 'text/plain', 'Content-Length' => body.to_s.size.to_s}.merge(headers), body] }
8
+ end
9
+ alias_method :original_app, :app
10
+
11
+ describe "without integration" do
12
+ it "should work normally" do
13
+ get "/"
14
+
15
+ last_response.should be_ok
16
+ last_response.body.should == "Hello, World!"
17
+ end
18
+ end
19
+
20
+ describe "with integration" do
21
+ def app(options = {})
22
+ @integrated_app ||= Metrics::Integration::Rack::Middleware.new(original_app, options)
23
+ end
24
+ def agent
25
+ app.agent
26
+ end
27
+
28
+ it "should work normally" do
29
+ get "/"
30
+
31
+ last_response.should be_ok
32
+ last_response.body.should == "Hello, World!"
33
+ end
34
+
35
+ it "should show stats for default endpoint" do
36
+ get "/stats"
37
+ last_response.should be_ok
38
+ last_response.body.should == agent.to_json
39
+ end
40
+
41
+ it "should make 'metrics.agent' available to the upstream environment" do
42
+ @app = lambda do |env|
43
+ env['metrics.agent'].should be_a(Metrics::Agent)
44
+ env['metrics.agent'].should == agent
45
+ [200, {}, []]
46
+ end
47
+
48
+ get '/'
49
+ last_response.should be_ok
50
+ end
51
+
52
+ describe "integration metrics" do
53
+
54
+ it "should count all requests" do
55
+ lambda do
56
+ get '/'
57
+ end.should change{ app.requests.count }.by(1)
58
+ end
59
+
60
+ it "should count uncaught exceptions" do
61
+ @app = lambda{ |env| raise }
62
+ lambda do
63
+ lambda do
64
+ get '/'
65
+ end.should raise_error
66
+ end.should change{ app.uncaught_exceptions.to_i }.by(1)
67
+ end
68
+
69
+ it "should time request length" do
70
+ length = 0.1
71
+ @app = lambda{ |env| sleep(length); [200, {}, ['']] }
72
+ get '/'
73
+ app.requests.mean.should be_within(length / 10).of(length)
74
+ end
75
+
76
+ [ 200, 304, 404, 500].each do |status|
77
+ it "should count #{status} HTTP status code as #{status / 100}xx" do
78
+ @app = lambda{ |env| [status, {}, []] }
79
+ lambda do
80
+ get '/'
81
+ end.should change{ app.status_codes[status / 100].to_i }.by(1)
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ context "configuring" do
88
+
89
+ context "agent" do
90
+ it "should create an agent by default" do
91
+ app(:agent => nil)
92
+ agent.should be_a(Metrics::Agent)
93
+ end
94
+
95
+ it "should use an agent if provided" do
96
+ @agent = Metrics::Agent.new
97
+ app(:agent => @agent)
98
+ agent.should be_a(Metrics::Agent)
99
+ agent.should == @agent
100
+ end
101
+ end
102
+
103
+ context "show" do
104
+ it "should match a string to the PATH_INFO exactly" do
105
+ app(:show => "/foo")
106
+ get '/foo'
107
+ last_response.should be_ok
108
+ last_response.body.should == agent.to_json
109
+ end
110
+
111
+ it "should match a regular expression to the PATH_INFO" do
112
+ app(:show => /bar/)
113
+ get '/foobarbaz'
114
+ last_response.should be_ok
115
+ last_response.body.should == agent.to_json
116
+ end
117
+
118
+ it "should call `call` on the show option if it responds to it" do
119
+ app(:show => lambda{ |env| env['PATH_INFO'] == "/bing" })
120
+ get '/bing'
121
+ last_response.should be_ok
122
+ last_response.body.should == agent.to_json
123
+ end
124
+ end
125
+
126
+ end
127
+ end
128
+
129
+ end
@@ -0,0 +1,18 @@
1
+ require "rack/test"
2
+
3
+ describe Metrics::Integration::WEBrick do
4
+
5
+ it "should start the WEBrick thread" do
6
+ Thread.stub!(:new).and_return do |block|
7
+ block.call
8
+ end
9
+
10
+ mock_server = mock(WEBrick::HTTPServer)
11
+ WEBrick::HTTPServer.should_receive(:new).and_return mock_server
12
+ mock_server.should_receive(:mount)
13
+ mock_server.should_receive(:start)
14
+
15
+ Metrics::Integration::WEBrick.start
16
+ end
17
+
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start do
4
+ add_filter "/spec/"
5
+ add_group "Instruments", "metrics/instruments"
6
+ add_group "Statistical Samples", "metrics/statistics"
7
+ merge_timeout 3600
8
+ end
9
+
10
+ $:.unshift(File.expand_path('../../lib', __FILE__))
11
+ require 'ruby-metrics'
12
+
13
+ Metrics.logger = Logger.new(STDERR)
14
+ Metrics.logger.level = Logger::INFO
15
+
16
+ RSpec.configure do |config|
17
+ config.mock_with :rspec
18
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metrics::Statistics::ExponentialSample do
4
+ before(:each) do
5
+ end
6
+
7
+ it "should have a size equal 0 intially no matter to the initialization parameter" do
8
+ sample = Metrics::Statistics::ExponentialSample.new(100)
9
+ sample.size.should == 0
10
+
11
+ end
12
+
13
+ it "should have an empty backing hash initially" do
14
+ sample = Metrics::Statistics::ExponentialSample.new(100)
15
+ sample.values.length.should == 0
16
+ end
17
+
18
+
19
+ context "A sample of 100 out of 1000 elements" do
20
+ before(:each) do
21
+ @population = (0..99).to_a
22
+ @sample = Metrics::Statistics::ExponentialSample.new(1000, 0.99)
23
+ @population.each do |datum|
24
+ @sample.update(datum)
25
+ end
26
+ end
27
+
28
+ it "should have 100 elements" do
29
+ @sample.size.should == 100
30
+ @sample.values.length.should == 100
31
+ end
32
+
33
+ it "should only have elements from the population" do
34
+ values = @sample.values
35
+ @population.each do |datum|
36
+ values.should include datum
37
+ end
38
+ end
39
+ end
40
+
41
+ context "A heavily-biased sample of 100 out of 1000 elements" do
42
+ before(:each) do
43
+ @population = (0..99).to_a
44
+ @sample = Metrics::Statistics::ExponentialSample.new(1000, 0.01)
45
+ @population.each do |datum|
46
+ @sample.update(datum)
47
+ end
48
+ end
49
+
50
+ it "should have 100 elements" do
51
+ @sample.size.should == 100
52
+ @sample.values.length.should == 100
53
+ end
54
+
55
+ it "should only have elements from the population" do
56
+ values = @sample.values
57
+ @population.each do |datum|
58
+ values.should include datum
59
+ end
60
+ end
61
+
62
+ it "should add another element when updating" do
63
+ @sample.update(42)
64
+ @sample.size.should == 101
65
+ @sample.values.should include 42
66
+ end
67
+
68
+ it "should rescale when the clock is one hour in the future or more" do
69
+ future_time = Time.now + (60 * 60)
70
+ Time.stub(:now).and_return future_time
71
+ @sample.update(42)
72
+ @sample.size.should == 101
73
+
74
+ values = @sample.values
75
+
76
+ @population.each do |datum|
77
+ values.should include datum
78
+ end
79
+
80
+ values.should include 42
81
+ end
82
+ end
83
+
84
+ context "A heavily-biased sample of 1000 out of 1000 elements" do
85
+ before(:each) do
86
+ @population = (0..999).to_a
87
+ @sample = Metrics::Statistics::ExponentialSample.new(1000, 0.01)
88
+ @population.each do |datum|
89
+ @sample.update(datum)
90
+ end
91
+ end
92
+
93
+ it "should have 1000 elements" do
94
+ @sample.size.should == 1000
95
+ @sample.values.length.should == 1000
96
+ end
97
+
98
+ it "should only have elements from the population" do
99
+ values = @sample.values
100
+ @population.each do |datum|
101
+ values.should include datum
102
+ end
103
+ end
104
+
105
+ it "should replace an element when updating" do
106
+ @sample.update(4242)
107
+ @sample.size.should == 1000
108
+ @sample.values.should include 4242
109
+ end
110
+
111
+ it "should rescale so that newer events are higher in priority in the hash" do
112
+ future_time = Time.now + (60 * 60)
113
+ Time.stub(:now).and_return future_time
114
+
115
+ @sample.update(2121)
116
+
117
+
118
+ @sample.size.should == 1000
119
+
120
+ future_time = Time.now + (60 * 60 * 2)
121
+ Time.stub(:now).and_return future_time
122
+
123
+ @sample.update(4242)
124
+ @sample.size.should == 1000
125
+
126
+ values = @sample.values
127
+
128
+ values.length.should == 1000
129
+ values.should include 4242
130
+ values.should include 2121
131
+
132
+ # Most recently added values in time should be at the end with the highest priority
133
+ values[999].should == 4242
134
+ values[998].should == 2121
135
+ end
136
+ end
137
+
138
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metrics::Statistics::UniformSample do
4
+ before(:each) do
5
+ end
6
+
7
+ it "should have a size equal to the initialization parameter" do
8
+ sample = Metrics::Statistics::UniformSample.new(100)
9
+ sample.size.should == 100
10
+
11
+ end
12
+
13
+ it "should allocate an array of the requested size" do
14
+ sample = Metrics::Statistics::UniformSample.new(100)
15
+ sample.values.length.should == 100
16
+
17
+ sample.values.each do |value|
18
+ value.should == 0
19
+ end
20
+ end
21
+
22
+ it "should update at the end of the list" do
23
+ sample = Metrics::Statistics::UniformSample.new(100)
24
+ (1..100).each do |i|
25
+ sample.update(i)
26
+ end
27
+
28
+ values = sample.values
29
+
30
+ (0..99).each do |index|
31
+ values[index].should == (index + 1)
32
+ end
33
+ end
34
+
35
+ it "should update a random entry in the list when it's full" do
36
+
37
+ sample = Metrics::Statistics::UniformSample.new(100)
38
+ sample.should_receive(:rand).with(any_args()).and_return(50)
39
+
40
+ (1..101).each do |i|
41
+ sample.update(i)
42
+ end
43
+
44
+ values = sample.values
45
+
46
+ (0..49).each do |index|
47
+ values[index].should == (index + 1)
48
+ end
49
+
50
+ values[50].should == 101
51
+
52
+ (51..99).each do |index|
53
+ values[index].should == (index + 1)
54
+ end
55
+
56
+ end
57
+
58
+
59
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metrics::TimeUnit do
4
+ it "should raise NotImplementedError for #to_nsec" do
5
+ begin
6
+ Metrics::TimeUnit.to_nsec
7
+ rescue NotImplementedError
8
+ true
9
+ else
10
+ fail
11
+ end
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yam-ruby-metrics
3
+ version: !ruby/object:Gem::Version
4
+ hash: 51
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 8
9
+ - 6
10
+ version: 0.8.6
11
+ platform: ruby
12
+ authors:
13
+ - John Ewart
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-16 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: simplecov
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ - 3
61
+ - 8
62
+ version: 0.3.8
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rack-test
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
79
+ description: A Ruby implementation of metrics inspired by @coda's JVM metrics for those of us in Ruby land
80
+ email:
81
+ - john@johnewart.net
82
+ executables: []
83
+
84
+ extensions: []
85
+
86
+ extra_rdoc_files: []
87
+
88
+ files:
89
+ - .bundle/config
90
+ - .gitignore
91
+ - .rvmrc
92
+ - CHANGELOG.md
93
+ - Gemfile
94
+ - Gemfile.lock
95
+ - LICENSE
96
+ - README.md
97
+ - Rakefile
98
+ - autotest/discover.rb
99
+ - examples/counter.rb
100
+ - examples/gauge.rb
101
+ - examples/histogram.rb
102
+ - examples/integration/rack_endpoint.ru
103
+ - examples/integration/rack_middleware.ru
104
+ - examples/integration/webrick.rb
105
+ - examples/meter.rb
106
+ - examples/timer.rb
107
+ - lib/ruby-metrics.rb
108
+ - lib/ruby-metrics/agent.rb
109
+ - lib/ruby-metrics/instruments/counter.rb
110
+ - lib/ruby-metrics/instruments/gauge.rb
111
+ - lib/ruby-metrics/instruments/histogram.rb
112
+ - lib/ruby-metrics/instruments/meter.rb
113
+ - lib/ruby-metrics/instruments/timer.rb
114
+ - lib/ruby-metrics/integration.rb
115
+ - lib/ruby-metrics/integration/rack_endpoint.rb
116
+ - lib/ruby-metrics/integration/rack_middleware.rb
117
+ - lib/ruby-metrics/integration/webrick.rb
118
+ - lib/ruby-metrics/logging.rb
119
+ - lib/ruby-metrics/statistics/exponential_sample.rb
120
+ - lib/ruby-metrics/statistics/uniform_sample.rb
121
+ - lib/ruby-metrics/time_units.rb
122
+ - lib/ruby-metrics/version.rb
123
+ - ruby-metrics.gemspec
124
+ - spec/agent_spec.rb
125
+ - spec/instruments/counter_spec.rb
126
+ - spec/instruments/gauge_spec.rb
127
+ - spec/instruments/histogram_spec.rb
128
+ - spec/instruments/meter_spec.rb
129
+ - spec/instruments/timer_spec.rb
130
+ - spec/integration/rack_endpoint_spec.rb
131
+ - spec/integration/rack_middleware_spec.rb
132
+ - spec/integration/webrick_spec.rb
133
+ - spec/spec_helper.rb
134
+ - spec/statistics/exponential_sample_spec.rb
135
+ - spec/statistics/uniform_sample_spec.rb
136
+ - spec/time_units_spec.rb
137
+ has_rdoc: true
138
+ homepage: https://github.com/johnewart/ruby-metrics
139
+ licenses: []
140
+
141
+ post_install_message:
142
+ rdoc_options: []
143
+
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ hash: 3
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ hash: 3
161
+ segments:
162
+ - 0
163
+ version: "0"
164
+ requirements: []
165
+
166
+ rubyforge_project: yam-ruby-metrics
167
+ rubygems_version: 1.5.2
168
+ signing_key:
169
+ specification_version: 3
170
+ summary: Metrics for Ruby
171
+ test_files:
172
+ - spec/agent_spec.rb
173
+ - spec/instruments/counter_spec.rb
174
+ - spec/instruments/gauge_spec.rb
175
+ - spec/instruments/histogram_spec.rb
176
+ - spec/instruments/meter_spec.rb
177
+ - spec/instruments/timer_spec.rb
178
+ - spec/integration/rack_endpoint_spec.rb
179
+ - spec/integration/rack_middleware_spec.rb
180
+ - spec/integration/webrick_spec.rb
181
+ - spec/spec_helper.rb
182
+ - spec/statistics/exponential_sample_spec.rb
183
+ - spec/statistics/uniform_sample_spec.rb
184
+ - spec/time_units_spec.rb