rubycut-metriks 0.9.9.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +14 -0
- data/LICENSE +21 -0
- data/README.md +405 -0
- data/Rakefile +150 -0
- data/benchmark/samplers.rb +92 -0
- data/lib/metriks/counter.rb +44 -0
- data/lib/metriks/ewma.rb +63 -0
- data/lib/metriks/exponentially_decaying_sample.rb +102 -0
- data/lib/metriks/histogram.rb +112 -0
- data/lib/metriks/meter.rb +85 -0
- data/lib/metriks/registry.rb +207 -0
- data/lib/metriks/reporter/graphite.rb +119 -0
- data/lib/metriks/reporter/librato_metrics.rb +185 -0
- data/lib/metriks/reporter/logger.rb +129 -0
- data/lib/metriks/reporter/proc_title.rb +65 -0
- data/lib/metriks/reporter/riemann.rb +119 -0
- data/lib/metriks/simple_moving_average.rb +60 -0
- data/lib/metriks/snapshot.rb +59 -0
- data/lib/metriks/time_tracker.rb +26 -0
- data/lib/metriks/timer.rb +101 -0
- data/lib/metriks/uniform_sample.rb +40 -0
- data/lib/metriks/utilization_timer.rb +43 -0
- data/lib/metriks.rb +35 -0
- data/metriks.gemspec +100 -0
- data/test/counter_test.rb +39 -0
- data/test/graphite_reporter_test.rb +41 -0
- data/test/histogram_test.rb +199 -0
- data/test/librato_metrics_reporter_test.rb +35 -0
- data/test/logger_reporter_test.rb +49 -0
- data/test/meter_test.rb +38 -0
- data/test/metriks_test.rb +31 -0
- data/test/proc_title_reporter_test.rb +25 -0
- data/test/registry_test.rb +49 -0
- data/test/riemann_reporter_test.rb +88 -0
- data/test/test_helper.rb +33 -0
- data/test/thread_error_handling_tests.rb +20 -0
- data/test/timer_test.rb +32 -0
- data/test/utilization_timer_test.rb +25 -0
- metadata +161 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
module Metriks
|
2
|
+
class Snapshot
|
3
|
+
MEDIAN_Q = 0.5
|
4
|
+
P75_Q = 0.75
|
5
|
+
P95_Q = 0.95
|
6
|
+
P98_Q = 0.98
|
7
|
+
P99_Q = 0.99
|
8
|
+
P999_Q = 0.999
|
9
|
+
|
10
|
+
attr_reader :values
|
11
|
+
|
12
|
+
def initialize(values)
|
13
|
+
@values = values.sort
|
14
|
+
end
|
15
|
+
|
16
|
+
def value(quantile)
|
17
|
+
raise ArgumentError, "quantile must be between 0.0 and 1.0" if quantile < 0.0 || quantile > 1.0
|
18
|
+
|
19
|
+
return 0.0 if @values.empty?
|
20
|
+
|
21
|
+
pos = quantile * (@values.length + 1)
|
22
|
+
|
23
|
+
return @values.first if pos < 1
|
24
|
+
return @values.last if pos >= @values.length
|
25
|
+
|
26
|
+
lower = @values[pos.to_i - 1]
|
27
|
+
upper = @values[pos.to_i]
|
28
|
+
lower + (pos - pos.floor) * (upper - lower)
|
29
|
+
end
|
30
|
+
|
31
|
+
def size
|
32
|
+
@values.length
|
33
|
+
end
|
34
|
+
|
35
|
+
def median
|
36
|
+
value(MEDIAN_Q)
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_75th_percentile
|
40
|
+
value(P75_Q)
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_95th_percentile
|
44
|
+
value(P95_Q)
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_98th_percentile
|
48
|
+
value(P98_Q)
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_99th_percentile
|
52
|
+
value(P99_Q)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_999th_percentile
|
56
|
+
value(P999_Q)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Metriks
|
2
|
+
class TimeTracker
|
3
|
+
def initialize(interval)
|
4
|
+
@interval = interval
|
5
|
+
@next_time = Time.now.to_f
|
6
|
+
end
|
7
|
+
|
8
|
+
def sleep
|
9
|
+
sleep_time = next_time - Time.now.to_f
|
10
|
+
if sleep_time > 0
|
11
|
+
Kernel.sleep(sleep_time)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def now_floored
|
16
|
+
time = Time.now.to_i
|
17
|
+
time - (time % @interval)
|
18
|
+
end
|
19
|
+
|
20
|
+
def next_time
|
21
|
+
now = Time.now.to_f
|
22
|
+
@next_time = now if @next_time <= now
|
23
|
+
@next_time += @interval - (@next_time % @interval)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'atomic'
|
2
|
+
require 'hitimes'
|
3
|
+
|
4
|
+
require 'metriks/meter'
|
5
|
+
require 'metriks/histogram'
|
6
|
+
|
7
|
+
module Metriks
|
8
|
+
class Timer
|
9
|
+
class Context
|
10
|
+
def initialize(timer)
|
11
|
+
@timer = timer
|
12
|
+
@interval = Hitimes::Interval.now
|
13
|
+
end
|
14
|
+
|
15
|
+
def restart
|
16
|
+
@interval = Hitimes::Interval.now
|
17
|
+
end
|
18
|
+
|
19
|
+
def stop
|
20
|
+
@interval.stop
|
21
|
+
@timer.update(@interval.duration)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(histogram = Metriks::Histogram.new_exponentially_decaying)
|
26
|
+
@meter = Metriks::Meter.new
|
27
|
+
@histogram = histogram
|
28
|
+
end
|
29
|
+
|
30
|
+
def clear
|
31
|
+
@meter.clear
|
32
|
+
@histogram.clear
|
33
|
+
end
|
34
|
+
|
35
|
+
def update(duration)
|
36
|
+
if duration >= 0
|
37
|
+
@meter.mark
|
38
|
+
@histogram.update(duration)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def time(callable = nil, &block)
|
43
|
+
callable ||= block
|
44
|
+
context = Context.new(self)
|
45
|
+
|
46
|
+
if callable.nil?
|
47
|
+
return context
|
48
|
+
end
|
49
|
+
|
50
|
+
begin
|
51
|
+
return callable.call
|
52
|
+
ensure
|
53
|
+
context.stop
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def snapshot
|
58
|
+
@histogram.snapshot
|
59
|
+
end
|
60
|
+
|
61
|
+
def count
|
62
|
+
@histogram.count
|
63
|
+
end
|
64
|
+
|
65
|
+
def one_minute_rate
|
66
|
+
@meter.one_minute_rate
|
67
|
+
end
|
68
|
+
|
69
|
+
def five_minute_rate
|
70
|
+
@meter.five_minute_rate
|
71
|
+
end
|
72
|
+
|
73
|
+
def fifteen_minute_rate
|
74
|
+
@meter.fifteen_minute_rate
|
75
|
+
end
|
76
|
+
|
77
|
+
def mean_rate
|
78
|
+
@meter.mean_rate
|
79
|
+
end
|
80
|
+
|
81
|
+
def min
|
82
|
+
@histogram.min
|
83
|
+
end
|
84
|
+
|
85
|
+
def max
|
86
|
+
@histogram.max
|
87
|
+
end
|
88
|
+
|
89
|
+
def mean
|
90
|
+
@histogram.mean
|
91
|
+
end
|
92
|
+
|
93
|
+
def stddev
|
94
|
+
@histogram.stddev
|
95
|
+
end
|
96
|
+
|
97
|
+
def stop
|
98
|
+
@meter.stop
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'atomic'
|
2
|
+
require 'metriks/snapshot'
|
3
|
+
|
4
|
+
module Metriks
|
5
|
+
class UniformSample
|
6
|
+
def initialize(reservoir_size)
|
7
|
+
@values = Array.new(reservoir_size, 0)
|
8
|
+
@count = Atomic.new(0)
|
9
|
+
end
|
10
|
+
|
11
|
+
def clear
|
12
|
+
@values.length.times do |idx|
|
13
|
+
@values[idx] = 0
|
14
|
+
end
|
15
|
+
@count.value = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def size
|
19
|
+
count = @count.value
|
20
|
+
count > @values.length ? @values.length : count
|
21
|
+
end
|
22
|
+
|
23
|
+
def snapshot
|
24
|
+
Snapshot.new(@values.slice(0, size))
|
25
|
+
end
|
26
|
+
|
27
|
+
def update(value)
|
28
|
+
new_count = @count.update { |v| v + 1 }
|
29
|
+
|
30
|
+
if new_count <= @values.length
|
31
|
+
@values[new_count - 1] = value
|
32
|
+
else
|
33
|
+
idx = rand(new_count)
|
34
|
+
if idx < @values.length
|
35
|
+
@values[idx] = value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'metriks/timer'
|
2
|
+
|
3
|
+
module Metriks
|
4
|
+
class UtilizationTimer < Metriks::Timer
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@duration_meter = Metriks::Meter.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def clear
|
11
|
+
super
|
12
|
+
@duration_meter.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
def update(duration)
|
16
|
+
super
|
17
|
+
if duration >= 0
|
18
|
+
@duration_meter.mark(duration)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def one_minute_utilization
|
23
|
+
@duration_meter.one_minute_rate
|
24
|
+
end
|
25
|
+
|
26
|
+
def five_minute_utilization
|
27
|
+
@duration_meter.five_minute_rate
|
28
|
+
end
|
29
|
+
|
30
|
+
def fifteen_minute_utilization
|
31
|
+
@duration_meter.fifteen_minute_rate
|
32
|
+
end
|
33
|
+
|
34
|
+
def mean_utilization
|
35
|
+
@duration_meter.mean_rate
|
36
|
+
end
|
37
|
+
|
38
|
+
def stop
|
39
|
+
super
|
40
|
+
@duration_meter.stop
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/metriks.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
module Metriks
|
3
|
+
VERSION = '0.9.9.4'
|
4
|
+
|
5
|
+
def self.get(name)
|
6
|
+
Metriks::Registry.default.get(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.counter(name)
|
10
|
+
Metriks::Registry.default.counter(name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.gauge(name, callable = nil, &block)
|
14
|
+
Metriks::Registry.default.gauge(name, callable, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.timer(name)
|
18
|
+
Metriks::Registry.default.timer(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.utilization_timer(name)
|
22
|
+
Metriks::Registry.default.utilization_timer(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.meter(name)
|
26
|
+
Metriks::Registry.default.meter(name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.histogram(name)
|
30
|
+
Metriks::Registry.default.histogram(name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'metriks/registry'
|
35
|
+
require 'metriks/reporter/proc_title'
|
data/metriks.gemspec
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
## This is the rakegem gemspec template. Make sure you read and understand
|
2
|
+
## all of the comments. Some sections require modification, and others can
|
3
|
+
## be deleted if you don't need them. Once you understand the contents of
|
4
|
+
## this file, feel free to delete any comments that begin with two hash marks.
|
5
|
+
## You can find comprehensive Gem::Specification documentation, at
|
6
|
+
## http://docs.rubygems.org/read/chapter/20
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
9
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
10
|
+
s.rubygems_version = '1.3.5'
|
11
|
+
|
12
|
+
## Leave these as is they will be modified for you by the rake gemspec task.
|
13
|
+
## If your rubyforge_project name is different, then edit it and comment out
|
14
|
+
## the sub! line in the Rakefile
|
15
|
+
s.name = 'rubycut-metriks'
|
16
|
+
s.version = '0.9.9.4'
|
17
|
+
s.date = '2013-02-22'
|
18
|
+
|
19
|
+
## Make sure your summary is short. The description may be as long
|
20
|
+
## as you like.
|
21
|
+
s.summary = "An experimental metrics client"
|
22
|
+
s.description = "An experimental metrics client."
|
23
|
+
|
24
|
+
## List the primary authors. If there are a bunch of authors, it's probably
|
25
|
+
## better to set the email to an email list or something. If you don't have
|
26
|
+
## a custom homepage, consider using your GitHub URL or the like.
|
27
|
+
s.authors = ["Eric Lindvall"]
|
28
|
+
s.email = 'eric@sevenscale.com'
|
29
|
+
s.homepage = 'https://github.com/eric/metriks'
|
30
|
+
|
31
|
+
## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
|
32
|
+
## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
|
33
|
+
s.require_paths = %w[lib]
|
34
|
+
|
35
|
+
## Specify any RDoc options here. You'll want to add your README and
|
36
|
+
## LICENSE files to the extra_rdoc_files list.
|
37
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
38
|
+
s.extra_rdoc_files = %w[README.md LICENSE]
|
39
|
+
|
40
|
+
## List your runtime dependencies here. Runtime dependencies are those
|
41
|
+
## that are needed for an end user to actually USE your code.
|
42
|
+
s.add_dependency('atomic', ["~> 1.0"])
|
43
|
+
s.add_dependency('hitimes', [ "~> 1.1"])
|
44
|
+
s.add_dependency('avl_tree', [ "~> 1.1.2" ])
|
45
|
+
|
46
|
+
## List your development dependencies here. Development dependencies are
|
47
|
+
## those that are only needed during development
|
48
|
+
# s.add_development_dependency('tomdoc', ["~> 0.2"])
|
49
|
+
s.add_development_dependency('mocha', ['~> 0.10'])
|
50
|
+
|
51
|
+
## Leave this section as-is. It will be automatically generated from the
|
52
|
+
## contents of your Git repository via the gemspec task. DO NOT REMOVE
|
53
|
+
## THE MANIFEST COMMENTS, they are used as delimiters by the task.
|
54
|
+
# = MANIFEST =
|
55
|
+
s.files = %w[
|
56
|
+
Gemfile
|
57
|
+
LICENSE
|
58
|
+
README.md
|
59
|
+
Rakefile
|
60
|
+
benchmark/samplers.rb
|
61
|
+
lib/metriks.rb
|
62
|
+
lib/metriks/counter.rb
|
63
|
+
lib/metriks/ewma.rb
|
64
|
+
lib/metriks/exponentially_decaying_sample.rb
|
65
|
+
lib/metriks/histogram.rb
|
66
|
+
lib/metriks/meter.rb
|
67
|
+
lib/metriks/registry.rb
|
68
|
+
lib/metriks/reporter/graphite.rb
|
69
|
+
lib/metriks/reporter/librato_metrics.rb
|
70
|
+
lib/metriks/reporter/logger.rb
|
71
|
+
lib/metriks/reporter/proc_title.rb
|
72
|
+
lib/metriks/reporter/riemann.rb
|
73
|
+
lib/metriks/simple_moving_average.rb
|
74
|
+
lib/metriks/snapshot.rb
|
75
|
+
lib/metriks/time_tracker.rb
|
76
|
+
lib/metriks/timer.rb
|
77
|
+
lib/metriks/uniform_sample.rb
|
78
|
+
lib/metriks/utilization_timer.rb
|
79
|
+
metriks.gemspec
|
80
|
+
test/counter_test.rb
|
81
|
+
test/graphite_reporter_test.rb
|
82
|
+
test/histogram_test.rb
|
83
|
+
test/librato_metrics_reporter_test.rb
|
84
|
+
test/logger_reporter_test.rb
|
85
|
+
test/meter_test.rb
|
86
|
+
test/metriks_test.rb
|
87
|
+
test/proc_title_reporter_test.rb
|
88
|
+
test/registry_test.rb
|
89
|
+
test/riemann_reporter_test.rb
|
90
|
+
test/test_helper.rb
|
91
|
+
test/thread_error_handling_tests.rb
|
92
|
+
test/timer_test.rb
|
93
|
+
test/utilization_timer_test.rb
|
94
|
+
]
|
95
|
+
# = MANIFEST =
|
96
|
+
|
97
|
+
## Test files will be grabbed from the file list. Make sure the path glob
|
98
|
+
## matches what you actually use.
|
99
|
+
s.test_files = s.files.select { |path| path =~ /^test\/.*_test\.rb/ }
|
100
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'metriks/counter'
|
4
|
+
|
5
|
+
class CounterTest < Test::Unit::TestCase
|
6
|
+
include ThreadHelper
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@counter = Metriks::Counter.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_increment
|
13
|
+
@counter.increment
|
14
|
+
|
15
|
+
assert_equal 1, @counter.count
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_increment_threaded
|
19
|
+
thread 10, :n => 100 do
|
20
|
+
@counter.increment
|
21
|
+
end
|
22
|
+
|
23
|
+
assert_equal 1000, @counter.count
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_increment_by_more
|
27
|
+
@counter.increment 10
|
28
|
+
|
29
|
+
assert_equal 10, @counter.count
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_increment_by_more_threaded
|
33
|
+
thread 10, :n => 100 do
|
34
|
+
@counter.increment 10
|
35
|
+
end
|
36
|
+
|
37
|
+
assert_equal 10000, @counter.count
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'thread_error_handling_tests'
|
3
|
+
|
4
|
+
require 'metriks/reporter/graphite'
|
5
|
+
|
6
|
+
class GraphiteReporterTest < Test::Unit::TestCase
|
7
|
+
include ThreadErrorHandlingTests
|
8
|
+
|
9
|
+
def build_reporter(options={})
|
10
|
+
Metriks::Reporter::Graphite.new('localhost', 3333, { :registry => @registry }.merge(options))
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@registry = Metriks::Registry.new
|
15
|
+
@reporter = build_reporter
|
16
|
+
@stringio = StringIO.new
|
17
|
+
|
18
|
+
@reporter.stubs(:socket).returns(@stringio)
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
@reporter.stop
|
23
|
+
@registry.stop
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_write
|
27
|
+
@registry.meter('meter.testing').mark
|
28
|
+
@registry.counter('counter.testing').increment
|
29
|
+
@registry.timer('timer.testing').update(1.5)
|
30
|
+
@registry.histogram('histogram.testing').update(1.5)
|
31
|
+
@registry.utilization_timer('utilization_timer.testing').update(1.5)
|
32
|
+
@registry.gauge('gauge.testing').set(123)
|
33
|
+
@registry.gauge('gauge.testing.block') { 456 }
|
34
|
+
|
35
|
+
@reporter.write
|
36
|
+
|
37
|
+
assert_match /timer.testing.median \d/, @stringio.string
|
38
|
+
assert_match /gauge.testing.value 123/, @stringio.string
|
39
|
+
assert_match /gauge.testing.block.value 456/, @stringio.string
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'metriks/histogram'
|
4
|
+
|
5
|
+
class HistogramTest < Test::Unit::TestCase
|
6
|
+
include ThreadHelper
|
7
|
+
|
8
|
+
def setup
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_uniform_sample_min
|
12
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
13
|
+
|
14
|
+
@histogram.update(5)
|
15
|
+
@histogram.update(10)
|
16
|
+
|
17
|
+
assert_equal 5, @histogram.min
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_uniform_sample_max
|
21
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
22
|
+
|
23
|
+
@histogram.update(5)
|
24
|
+
@histogram.update(10)
|
25
|
+
|
26
|
+
assert_equal 10, @histogram.max
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_uniform_sample_mean
|
30
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
31
|
+
|
32
|
+
@histogram.update(5)
|
33
|
+
@histogram.update(10)
|
34
|
+
|
35
|
+
assert_equal 7, @histogram.mean
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_uniform_sample_mean_threaded
|
39
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
40
|
+
|
41
|
+
thread 10, :n => 100 do
|
42
|
+
@histogram.update(5)
|
43
|
+
@histogram.update(10)
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_equal 7, @histogram.mean
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_uniform_sample_2000
|
50
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
51
|
+
|
52
|
+
2000.times do |idx|
|
53
|
+
@histogram.update(idx)
|
54
|
+
end
|
55
|
+
|
56
|
+
assert_equal 1999, @histogram.max
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_uniform_sample_2000_threaded
|
60
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
61
|
+
|
62
|
+
t = 10
|
63
|
+
thread t do |i|
|
64
|
+
2000.times do |x|
|
65
|
+
if (x % t) == i
|
66
|
+
@histogram.update x
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
assert_equal 1999, @histogram.max
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_uniform_sample_snashot
|
75
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
76
|
+
|
77
|
+
100.times do |idx|
|
78
|
+
@histogram.update(idx)
|
79
|
+
end
|
80
|
+
|
81
|
+
snapshot = @histogram.snapshot
|
82
|
+
|
83
|
+
assert_equal 49.5, snapshot.median
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_uniform_sample_snapshot_threaded
|
87
|
+
@histogram = Metriks::Histogram.new(Metriks::UniformSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE))
|
88
|
+
|
89
|
+
thread 10 do
|
90
|
+
100.times do |idx|
|
91
|
+
@histogram.update(idx)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
snapshot = @histogram.snapshot
|
96
|
+
|
97
|
+
assert_equal 49.5, snapshot.median
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_exponential_sample_min
|
101
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
102
|
+
|
103
|
+
@histogram.update(5)
|
104
|
+
@histogram.update(10)
|
105
|
+
|
106
|
+
assert_equal 5, @histogram.min
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_exponential_sample_max
|
110
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
111
|
+
|
112
|
+
@histogram.update(5)
|
113
|
+
@histogram.update(10)
|
114
|
+
|
115
|
+
assert_equal 10, @histogram.max
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_exponential_sample_mean
|
119
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
120
|
+
|
121
|
+
@histogram.update(5)
|
122
|
+
@histogram.update(10)
|
123
|
+
|
124
|
+
assert_equal 7, @histogram.mean
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_exponential_sample_mean_threaded
|
128
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
129
|
+
|
130
|
+
thread 10, :n => 100 do
|
131
|
+
@histogram.update(5)
|
132
|
+
@histogram.update(10)
|
133
|
+
end
|
134
|
+
|
135
|
+
assert_equal 7, @histogram.mean
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_exponential_sample_2000
|
139
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
140
|
+
|
141
|
+
2000.times do |idx|
|
142
|
+
@histogram.update(idx)
|
143
|
+
end
|
144
|
+
|
145
|
+
assert_equal 1999, @histogram.max
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_exponential_sample_2000_threaded
|
149
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
150
|
+
|
151
|
+
t = 10
|
152
|
+
thread t do |i|
|
153
|
+
2000.times do |idx|
|
154
|
+
if (idx % t) == i
|
155
|
+
@histogram.update(idx)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
assert_equal 1999, @histogram.max
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_exponential_sample_snashot
|
164
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
165
|
+
|
166
|
+
100.times do |idx|
|
167
|
+
@histogram.update(idx)
|
168
|
+
end
|
169
|
+
|
170
|
+
snapshot = @histogram.snapshot
|
171
|
+
|
172
|
+
assert_equal 49.5, snapshot.median
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_exponential_sample_snapshot_threaded
|
176
|
+
@histogram = Metriks::Histogram.new(Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA))
|
177
|
+
|
178
|
+
thread 10 do
|
179
|
+
100.times do |idx|
|
180
|
+
@histogram.update(idx)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
snapshot = @histogram.snapshot
|
185
|
+
|
186
|
+
assert_equal 49.5, snapshot.median
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_long_idle_sample
|
190
|
+
Time.stubs(:now).returns(Time.at(2000))
|
191
|
+
sample = Metriks::ExponentiallyDecayingSample.new(Metriks::Histogram::DEFAULT_SAMPLE_SIZE, Metriks::Histogram::DEFAULT_ALPHA)
|
192
|
+
Time.unstub(:now)
|
193
|
+
@histogram = Metriks::Histogram.new(sample)
|
194
|
+
|
195
|
+
@histogram.update(5)
|
196
|
+
|
197
|
+
assert_equal 5, @histogram.min
|
198
|
+
end
|
199
|
+
end
|