yam-ruby-metrics 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.bundle/config +2 -0
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/CHANGELOG.md +48 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +36 -0
- data/LICENSE +21 -0
- data/README.md +86 -0
- data/Rakefile +19 -0
- data/autotest/discover.rb +3 -0
- data/examples/counter.rb +10 -0
- data/examples/gauge.rb +25 -0
- data/examples/histogram.rb +32 -0
- data/examples/integration/rack_endpoint.ru +24 -0
- data/examples/integration/rack_middleware.ru +21 -0
- data/examples/integration/webrick.rb +17 -0
- data/examples/meter.rb +25 -0
- data/examples/timer.rb +31 -0
- data/lib/ruby-metrics.rb +15 -0
- data/lib/ruby-metrics/agent.rb +62 -0
- data/lib/ruby-metrics/instruments/counter.rb +39 -0
- data/lib/ruby-metrics/instruments/gauge.rb +23 -0
- data/lib/ruby-metrics/instruments/histogram.rb +188 -0
- data/lib/ruby-metrics/instruments/meter.rb +99 -0
- data/lib/ruby-metrics/instruments/timer.rb +138 -0
- data/lib/ruby-metrics/integration.rb +11 -0
- data/lib/ruby-metrics/integration/rack_endpoint.rb +33 -0
- data/lib/ruby-metrics/integration/rack_middleware.rb +82 -0
- data/lib/ruby-metrics/integration/webrick.rb +47 -0
- data/lib/ruby-metrics/logging.rb +19 -0
- data/lib/ruby-metrics/statistics/exponential_sample.rb +91 -0
- data/lib/ruby-metrics/statistics/uniform_sample.rb +37 -0
- data/lib/ruby-metrics/time_units.rb +61 -0
- data/lib/ruby-metrics/version.rb +3 -0
- data/ruby-metrics.gemspec +27 -0
- data/spec/agent_spec.rb +48 -0
- data/spec/instruments/counter_spec.rb +79 -0
- data/spec/instruments/gauge_spec.rb +42 -0
- data/spec/instruments/histogram_spec.rb +115 -0
- data/spec/instruments/meter_spec.rb +99 -0
- data/spec/instruments/timer_spec.rb +146 -0
- data/spec/integration/rack_endpoint_spec.rb +60 -0
- data/spec/integration/rack_middleware_spec.rb +129 -0
- data/spec/integration/webrick_spec.rb +18 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/statistics/exponential_sample_spec.rb +138 -0
- data/spec/statistics/uniform_sample_spec.rb +59 -0
- data/spec/time_units_spec.rb +13 -0
- metadata +184 -0
data/.bundle/config
ADDED
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.2@metrics
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
v0.8.6 -- June 2, 2011
|
2
|
+
======================
|
3
|
+
|
4
|
+
* Updated tests for JSON serialization of instruments
|
5
|
+
* Fixed JSON serialization of some instruments
|
6
|
+
|
7
|
+
v0.8.5 -- May 11, 2011
|
8
|
+
======================
|
9
|
+
|
10
|
+
* Removed dependency on quantity gem -- conflicted with ActiveSupport
|
11
|
+
* Updated code to compute some unit conversions manually instead of depending on quantity
|
12
|
+
|
13
|
+
|
14
|
+
v0.8.0 -- April 26, 2011
|
15
|
+
========================
|
16
|
+
|
17
|
+
* Added timer example
|
18
|
+
* Changes to timer initialization
|
19
|
+
* Added register_with_options to support timers with different units or options
|
20
|
+
* Integrated Matt's changes for integration to modularize webrick and rack export options
|
21
|
+
|
22
|
+
v0.7.0 -- April 18, 2011
|
23
|
+
========================
|
24
|
+
|
25
|
+
* Replaced ruby-units with quantity
|
26
|
+
* Added time unit conversion internally
|
27
|
+
* Initial implementation of Timer instrument
|
28
|
+
* More spec tests to increase coverage
|
29
|
+
|
30
|
+
|
31
|
+
v0.6.0 -- April 15, 2011
|
32
|
+
========================
|
33
|
+
|
34
|
+
* Exponentially decaying samples for histograms
|
35
|
+
* Updates to Meter to use exponentially decaying samples
|
36
|
+
* Ability to override WEBrick port in constructor
|
37
|
+
* Updates to README
|
38
|
+
|
39
|
+
v0.5.0 -- April 13, 2011
|
40
|
+
========================
|
41
|
+
|
42
|
+
* Initial gem packaging (courtesy of @richardiux)
|
43
|
+
* Histograms
|
44
|
+
* Sampling classes for histograms
|
45
|
+
* Updates to weighted average calculations
|
46
|
+
* Tests, tests, tests!
|
47
|
+
* Mumblety-peg....
|
48
|
+
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ruby-metrics (0.8.6)
|
5
|
+
json
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.1.2)
|
11
|
+
json (1.5.1)
|
12
|
+
rack (1.2.2)
|
13
|
+
rack-test (0.5.7)
|
14
|
+
rack (>= 1.0)
|
15
|
+
rake (0.8.7)
|
16
|
+
rspec (2.5.0)
|
17
|
+
rspec-core (~> 2.5.0)
|
18
|
+
rspec-expectations (~> 2.5.0)
|
19
|
+
rspec-mocks (~> 2.5.0)
|
20
|
+
rspec-core (2.5.1)
|
21
|
+
rspec-expectations (2.5.0)
|
22
|
+
diff-lcs (~> 1.1.2)
|
23
|
+
rspec-mocks (2.5.0)
|
24
|
+
simplecov (0.4.0)
|
25
|
+
simplecov-html (~> 0.4.0)
|
26
|
+
simplecov-html (0.4.3)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
rack-test
|
33
|
+
rake
|
34
|
+
rspec
|
35
|
+
ruby-metrics!
|
36
|
+
simplecov (>= 0.3.8)
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2011 John Ewart
|
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.
|
21
|
+
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
|
2
|
+
## What is this?
|
3
|
+
|
4
|
+
This is a Ruby version of performance metrics inspired by [metrics][metrics] developed by Coda Hale at Yammer. Currently this is under *heavy* development -- it needs Gem packaging, more features, validation of metrics, more functional testing, and a little better test coverage. Pull requests happily accepted, please include docs and tests where possible!
|
5
|
+
|
6
|
+
## What needs to be done?
|
7
|
+
|
8
|
+
Among other important things, this needs to be made more thread-safe. I'm currently looking at Mr. Nutter's ruby-atomic gem for making this less tedious but any suggestions are welcome!
|
9
|
+
|
10
|
+
## What's in this?
|
11
|
+
|
12
|
+
Right now, I have:
|
13
|
+
|
14
|
+
* Counters
|
15
|
+
* Meters
|
16
|
+
* Gauges
|
17
|
+
* Histograms w/ uniform sampling
|
18
|
+
* Histograms w/ exponentially decaying sampling
|
19
|
+
* Timers
|
20
|
+
|
21
|
+
## Getting Started
|
22
|
+
|
23
|
+
The goal of ruby-metrics is to get up and running quickly. You start an agent, register some instruments, and they're exported over HTTP via JSON. For example, getting started with a counter would look like this:
|
24
|
+
|
25
|
+
@metrics = Metrics::Agent.new
|
26
|
+
|
27
|
+
counter = @metrics.counter :my_counter
|
28
|
+
counter.incr
|
29
|
+
counter.incr
|
30
|
+
|
31
|
+
puts @metrics.to_json
|
32
|
+
#=> {"my_counter":"2"}
|
33
|
+
|
34
|
+
|
35
|
+
## Integration
|
36
|
+
|
37
|
+
Integrating ruby-metrics into existing applications is entirely up to your needs. Provided options include:
|
38
|
+
|
39
|
+
* Embedded WEBrick listener:
|
40
|
+
|
41
|
+
This runs a background thread and enables HTTP access to a local port (8001 by default) for a JSON representation of the current metrics.
|
42
|
+
|
43
|
+
``` ruby
|
44
|
+
require 'ruby-metrics/integration/webrick'
|
45
|
+
@agent = Metrics::Agent.new
|
46
|
+
@agent.start(:port => 8081)
|
47
|
+
```
|
48
|
+
|
49
|
+
* Rack Middleware:
|
50
|
+
|
51
|
+
This will add metrics such as `requests` (a timer) as well as counters for each class of HTTP status code (1xx, 2xx, etc). Also counts uncaught exceptions before reraising.
|
52
|
+
Provides a configurable path option (`:show`) to trigger the return of the metrics (as JSON) when the request path matches exactly (a string), as a regular expression, or as any object that responds to `call` for custom logic (passed the whole `env`).
|
53
|
+
|
54
|
+
``` ruby
|
55
|
+
require 'ruby-metrics'
|
56
|
+
@agent = Metrics::Agent.new
|
57
|
+
|
58
|
+
use Metrics::Integration::Rack::Middleware, :agent => @agent, :show => '/stats'
|
59
|
+
|
60
|
+
run app
|
61
|
+
```
|
62
|
+
|
63
|
+
* Rack Endpoint:
|
64
|
+
|
65
|
+
Use this to expose an endpoint for external consumption for your metrics.
|
66
|
+
Works best when used with a URLMap or mounted in addition to other routes, like Rails' `mount` route matcher.
|
67
|
+
|
68
|
+
``` ruby
|
69
|
+
require 'ruby-metrics'
|
70
|
+
@agent = Metrics::Agent.new
|
71
|
+
|
72
|
+
run Metrics::Integration::Rack::Endpoint.new(:agent => @agent)
|
73
|
+
```
|
74
|
+
|
75
|
+
or
|
76
|
+
|
77
|
+
``` ruby
|
78
|
+
# in config/router.rb
|
79
|
+
mount Metrics::Integration::Rack::Endpoint.new(:agent => @agent)
|
80
|
+
```
|
81
|
+
|
82
|
+
[metrics]: https://github.com/codahale/metrics
|
83
|
+
|
84
|
+
## License
|
85
|
+
|
86
|
+
Copyright 2011 John Ewart <john@johnewart.net>. Released under the MIT license. See the file LICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler"
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec::Core::RakeTask.new do |t|
|
15
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
16
|
+
t.pattern = 'spec/**/*_spec.rb'
|
17
|
+
end
|
18
|
+
|
19
|
+
task :default => :spec
|
data/examples/counter.rb
ADDED
data/examples/gauge.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require '../lib/ruby-metrics'
|
3
|
+
|
4
|
+
@metrics = Metrics::Agent.new
|
5
|
+
|
6
|
+
hit_count = 42
|
7
|
+
http_requests = 53
|
8
|
+
|
9
|
+
gauge = @metrics.gauge :my_gauge do
|
10
|
+
{
|
11
|
+
:hit_count => hit_count,
|
12
|
+
:http_requests => http_requests
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
puts "Gauge: #{gauge.to_s}"
|
17
|
+
|
18
|
+
hit_count = 65
|
19
|
+
http_requests = 99
|
20
|
+
|
21
|
+
puts "Gauge: #{gauge.to_s}"
|
22
|
+
|
23
|
+
result = gauge.get
|
24
|
+
|
25
|
+
puts "Result: #{result}"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require '../lib/ruby-metrics/integration/webrick'
|
3
|
+
|
4
|
+
@metrics = Metrics::Agent.new
|
5
|
+
@metrics.start
|
6
|
+
|
7
|
+
exponential_histogram = @metrics.exponential_histogram :exponential_histogram
|
8
|
+
uniform_histogram = @metrics.uniform_histogram :uniform_histogram
|
9
|
+
|
10
|
+
data = %w(3.600 1.800 3.333 2.283 4.533 2.883 4.700 3.600 1.950 4.350 1.833 3.917 4.200 1.750 4.700 2.167 1.750 4.800 1.600 4.250 1.800 1.750 3.450 3.067 4.533 3.600 1.967 4.083 3.850 4.433 4.300 4.467 3.367 4.033 3.833 2.017 1.867 4.833 1.833 4.783 4.350 1.883 4.567 1.750 4.533 3.317 3.833 2.100 4.633 2.000 4.800 4.716 1.833 4.833 1.733 4.883 3.717 1.667 4.567 4.317 2.233 4.500 1.750 4.800 1.817 4.400 4.167 4.700 2.067 4.700 4.033 1.967 4.500 4.000 1.983 5.067 2.017 4.567 3.883 3.600 4.133 4.333 4.100 2.633 4.067 4.933 3.950 4.517 2.167 4.000 2.200 4.333 1.867 4.817 1.833 4.300 4.667 3.750 1.867 4.900 2.483 4.367 2.100 4.500 4.050 1.867 4.700 1.783 4.850 3.683 4.733 2.300 4.900 4.417 1.700 4.633 2.317 4.600 1.817 4.417 2.617 4.067 4.250 1.967 4.600 3.767 1.917 4.500 2.267 4.650 1.867 4.167 2.800 4.333 1.833 4.383 1.883 4.933 2.033 3.733 4.233 2.233 4.533 4.817 4.333 1.983 4.633 2.017 5.100 1.800 5.033 4.000 2.400 4.600 3.567 4.000 4.500 4.083 1.800 3.967 2.200 4.150 2.000 3.833 3.500 4.583 2.367 5.000 1.933 4.617 1.917 2.083 4.583 3.333 4.167 4.333 4.500 2.417 4.000 4.167 1.883 4.583 4.250 3.767 2.033 4.433 4.083 1.833 4.417 2.183 4.800 1.833 4.800 4.100 3.966 4.233 3.500 4.366 2.250 4.667 2.100 4.350 4.133 1.867 4.600 1.783 4.367 3.850 1.933 4.500 2.383 4.700 1.867 3.833 3.417 4.233 2.400 4.800 2.000 4.150 1.867 4.267 1.750 4.483 4.000 4.117 4.083 4.267 3.917 4.550 4.083 2.417 4.183 2.217 4.450 1.883 1.850 4.283 3.950 2.333 4.150 2.350 4.933 2.900 4.583 3.833 2.083 4.367 2.133 4.350 2.200 4.450 3.567 4.500 4.150 3.817 3.917 4.450 2.000 4.283 4.767 4.533 1.850 4.250 1.983 2.250 4.750 4.117 2.150 4.417 1.817 4.467)
|
11
|
+
data.each do |point|
|
12
|
+
exponential_histogram.update(point.to_f)
|
13
|
+
uniform_histogram.update(point.to_f)
|
14
|
+
end
|
15
|
+
|
16
|
+
step = 0
|
17
|
+
|
18
|
+
# This is here so that we will run indefinitely so you can hit the
|
19
|
+
# status page on localhost:8001/stats
|
20
|
+
loop do
|
21
|
+
sleep 1
|
22
|
+
|
23
|
+
modifier = rand(500).to_i / 100
|
24
|
+
step += 1
|
25
|
+
|
26
|
+
if (step % 2)
|
27
|
+
modifier *= -1
|
28
|
+
end
|
29
|
+
|
30
|
+
uniform_histogram.update((2 + modifier).to_f)
|
31
|
+
exponential_histogram.update((2 + modifier).to_f)
|
32
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
# Ran with:
|
4
|
+
# rackup -p 8000 ./examples/integration/rack_endpoint.ru
|
5
|
+
#
|
6
|
+
# Make requests to: http://localhost:8000/
|
7
|
+
# See stats at : http://localhost:8000/stats
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ruby-metrics')
|
10
|
+
@agent = Metrics::Agent.new
|
11
|
+
|
12
|
+
counter = @agent.counter(:my_counter)
|
13
|
+
|
14
|
+
app = proc do |env|
|
15
|
+
counter.incr
|
16
|
+
[200, {'Content-Type' => 'text/plain'}, ["Counted!"]]
|
17
|
+
end
|
18
|
+
|
19
|
+
map = Rack::URLMap.new({
|
20
|
+
'/stats' => Metrics::Integration::Rack::Endpoint.new(:agent => @app),
|
21
|
+
'/' => app
|
22
|
+
})
|
23
|
+
|
24
|
+
run map
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
# Ran with:
|
4
|
+
# rackup -p 8000 ./examples/integration/rack_middleware.ru
|
5
|
+
#
|
6
|
+
# Make requests to: http://localhost:8000/
|
7
|
+
# See stats at : http://localhost:8000/stats
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ruby-metrics')
|
10
|
+
@agent = Metrics::Agent.new
|
11
|
+
|
12
|
+
counter = @agent.counter(:my_counter)
|
13
|
+
|
14
|
+
use Metrics::Integration::Rack::Middleware, :agent => @agent
|
15
|
+
|
16
|
+
app = proc do |env|
|
17
|
+
counter.incr
|
18
|
+
[200, {'Content-Type' => 'text/plain'}, ["Counted!"]]
|
19
|
+
end
|
20
|
+
|
21
|
+
run app
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ruby-metrics'))
|
3
|
+
|
4
|
+
# Run with:
|
5
|
+
# ruby examples/integration/webrick.rb
|
6
|
+
|
7
|
+
@agent = Metrics::Agent.new
|
8
|
+
|
9
|
+
counter = @agent.counter(:my_counter)
|
10
|
+
counter.incr
|
11
|
+
counter.incr
|
12
|
+
|
13
|
+
Metrics::Integration::WEBrick.start(:port => 8001,
|
14
|
+
:agent => @agent)
|
15
|
+
|
16
|
+
sleep
|
17
|
+
# Now navigate to: http://localhost:8001/stats
|
data/examples/meter.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require '../lib/ruby-metrics/integration/webrick'
|
3
|
+
|
4
|
+
@metrics = Metrics::Agent.new
|
5
|
+
@metrics.start :port => 8081 # optional
|
6
|
+
|
7
|
+
timer = @metrics.meter :my_meter
|
8
|
+
timer.mark(500)
|
9
|
+
|
10
|
+
step = 0
|
11
|
+
|
12
|
+
# This is here so that we will run indefinitely so you can hit the
|
13
|
+
# status page on localhost:8081/stats
|
14
|
+
loop do
|
15
|
+
sleep 1
|
16
|
+
|
17
|
+
modifier = rand(200).to_i
|
18
|
+
step += 1
|
19
|
+
|
20
|
+
if (step % 2)
|
21
|
+
modifier *= -1
|
22
|
+
end
|
23
|
+
|
24
|
+
timer.mark(500 + modifier)
|
25
|
+
end
|
data/examples/timer.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require '../lib/ruby-metrics/integration/webrick'
|
3
|
+
|
4
|
+
@metrics = Metrics::Agent.new
|
5
|
+
@metrics.start :port => 8081 # optional
|
6
|
+
|
7
|
+
timer = @metrics.timer :my_timer
|
8
|
+
timer.update(500, :milliseconds)
|
9
|
+
timer.update(5, :seconds)
|
10
|
+
timer.update(4242, :nanoseconds)
|
11
|
+
|
12
|
+
msec_timer = @metrics.timer :msec_timer, {:duration_unit => :microseconds, :rate_unit => :seconds}
|
13
|
+
|
14
|
+
step = 0
|
15
|
+
|
16
|
+
# This is here so that we will run indefinitely so you can hit the
|
17
|
+
# status page on localhost:8081/stats
|
18
|
+
loop do
|
19
|
+
sleep 1
|
20
|
+
|
21
|
+
modifier = rand(200).to_i
|
22
|
+
step += 1
|
23
|
+
|
24
|
+
if (step % 2)
|
25
|
+
modifier *= -1
|
26
|
+
end
|
27
|
+
|
28
|
+
timer.update(500 + modifier, :microseconds)
|
29
|
+
msec_timer.update(500 + modifier, :microseconds)
|
30
|
+
|
31
|
+
end
|