drone 1.0.5 → 1.0.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.
- data/.travis.yml +2 -0
- data/README.md +4 -5
- data/lib/drone/metrics/histogram.rb +116 -115
- data/lib/drone/utils/exponentially_decaying_sample.rb +4 -4
- data/lib/drone/version.rb +1 -1
- data/specs/metrics/histogram_spec.rb +2 -2
- metadata +8 -7
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -16,7 +16,7 @@ The example will output the collected statistics directly on the console every s
|
|
16
16
|
|
17
17
|
# Supported Runtimes
|
18
18
|
|
19
|
-
- MRI 1.
|
19
|
+
- MRI 1.9.2+
|
20
20
|
- Rubinius 1.2.2+
|
21
21
|
|
22
22
|
|
@@ -29,8 +29,7 @@ The example will output the collected statistics directly on the console every s
|
|
29
29
|
|
30
30
|
- Good test coverage
|
31
31
|
|
32
|
-
The gem was created for a specific need and is currently used in
|
33
|
-
no major bugs until now.
|
32
|
+
The gem was created for a specific need and is currently used in production environment.
|
34
33
|
|
35
34
|
|
36
35
|
# How is it done
|
@@ -154,9 +153,9 @@ gem to limit the core's dependencies so the only one in core is:
|
|
154
153
|
|
155
154
|
The specs are written with bacon, mocha and em-spec, they can be ran with:
|
156
155
|
|
157
|
-
rake
|
156
|
+
bundle exec rake
|
158
157
|
|
159
158
|
## Build the doc
|
160
159
|
You will need the gems: yard and bluecloth and then run:
|
161
160
|
|
162
|
-
rake doc
|
161
|
+
bundle exec rake doc
|
@@ -3,152 +3,153 @@ require File.expand_path('../../utils/exponentially_decaying_sample', __FILE__)
|
|
3
3
|
require File.expand_path('../metric', __FILE__)
|
4
4
|
|
5
5
|
module Drone
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
6
|
+
module Metrics
|
7
|
+
##
|
8
|
+
# An Histogram store a list of values (1028) and can
|
9
|
+
# compute on demand statistics on those values:
|
10
|
+
# - min/max
|
11
|
+
# - mean
|
12
|
+
# - stddev
|
13
|
+
# - percentiles
|
14
|
+
#
|
15
|
+
class Histogram < Metric
|
16
|
+
MIN = (-(2**63)).freeze
|
17
|
+
MAX = ((2**64) - 1).freeze
|
18
|
+
|
19
|
+
def initialize(name, sample_or_type = :uniform)
|
20
|
+
super(name)
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
if sample_or_type.is_a?(Symbol)
|
23
|
+
case sample_or_type
|
24
|
+
when :uniform then @sample = UniformSample.new("#{name}:sample", 1028)
|
25
|
+
when :biased then @sample = ExponentiallyDecayingSample.new("#{name}:sample", 1028, 0.015)
|
26
|
+
else
|
27
|
+
raise ArgumentError, "unknown type: #{sample_or_type}"
|
28
|
+
end
|
26
29
|
else
|
27
|
-
|
30
|
+
@sample = sample_or_type
|
28
31
|
end
|
29
|
-
else
|
30
|
-
@sample = sample_or_type
|
31
|
-
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
@count = Drone::request_number("#{name}:count", 0)
|
34
|
+
@_min = Drone::request_number("#{name}:min", MAX)
|
35
|
+
@_max = Drone::request_number("#{name}:max", MIN)
|
36
|
+
@_sum = Drone::request_number("#{name}:max", 0)
|
37
|
+
@varianceM = Drone::request_number("#{name}:varianceM", -1)
|
38
|
+
@varianceS = Drone::request_number("#{name}:varianceS", 0)
|
39
39
|
|
40
|
-
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
def clear
|
43
|
+
@sample.clear()
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
@count = Drone::request_number("#{name}:count", 0)
|
46
|
+
@_min = Drone::request_number("#{name}:min", MAX)
|
47
|
+
@_max = Drone::request_number("#{name}:max", MIN)
|
48
|
+
@_sum = Drone::request_number("#{name}:max", 0)
|
49
|
+
@varianceM = Drone::request_number("#{name}:varianceM", -1)
|
50
|
+
@varianceS = Drone::request_number("#{name}:varianceS", 0)
|
51
|
+
end
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
53
|
+
def update(val)
|
54
|
+
@count.inc
|
55
|
+
@sample.update(val)
|
56
|
+
set_max(val);
|
57
|
+
set_min(val);
|
58
|
+
@_sum.inc(val)
|
59
|
+
update_variance(val)
|
60
|
+
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
def count
|
63
|
+
@count.get
|
64
|
+
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
def max
|
67
|
+
(@count.get > 0) ? @_max.get : 0.0
|
68
|
+
end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
def min
|
71
|
+
(@count.get > 0) ? @_min.get : 0.0
|
72
|
+
end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
def mean
|
75
|
+
(@count.get > 0) ? @_sum.get.to_f / @count.get : 0.0
|
76
|
+
end
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
def stdDev
|
79
|
+
(@count.get > 0) ? Math.sqrt( variance() ) : 0.0
|
80
|
+
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
82
|
+
def percentiles(*percentiles)
|
83
|
+
scores = Array.new(percentiles.size, 0)
|
84
|
+
if @count.get > 0
|
85
|
+
values = @sample.values.sort
|
86
|
+
percentiles.each.with_index do |p, i|
|
87
|
+
pos = p * (values.size + 1)
|
88
|
+
if pos < 1
|
89
|
+
scores[i] = values[0]
|
90
|
+
elsif pos >= values.size
|
91
|
+
scores[i] = values[-1]
|
92
|
+
else
|
93
|
+
lower = values[pos - 1]
|
94
|
+
upper = values[pos]
|
95
|
+
scores[i] = lower + (pos - pos.floor) * (upper - lower)
|
96
|
+
end
|
96
97
|
end
|
97
98
|
end
|
98
|
-
end
|
99
99
|
|
100
|
-
|
101
|
-
|
100
|
+
scores
|
101
|
+
end
|
102
102
|
|
103
|
-
|
104
|
-
|
105
|
-
|
103
|
+
def values
|
104
|
+
@sample.values
|
105
|
+
end
|
106
106
|
|
107
|
-
|
107
|
+
private
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
def doubleToLongBits(n)
|
110
|
+
[n].pack('D').unpack('q')[0]
|
111
|
+
end
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
def longBitsToDouble(n)
|
114
|
+
[n].pack('q').unpack('D')[0]
|
115
|
+
end
|
116
116
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
117
|
+
def update_variance(val)
|
118
|
+
if @varianceM.get == -1
|
119
|
+
@varianceM.set( doubleToLongBits(val) )
|
120
|
+
else
|
121
|
+
oldMCas = @varianceM.get
|
122
|
+
oldM = longBitsToDouble(oldMCas)
|
123
|
+
newM = oldM + ((val - oldM) / count())
|
124
124
|
|
125
|
-
|
126
|
-
|
127
|
-
|
125
|
+
oldSCas = @varianceS.get
|
126
|
+
oldS = longBitsToDouble(oldSCas)
|
127
|
+
newS = oldS + ((val - oldM) * (val - newM))
|
128
128
|
|
129
|
-
|
130
|
-
|
129
|
+
@varianceM.set( doubleToLongBits(newM) )
|
130
|
+
@varianceS.set( doubleToLongBits(newS) )
|
131
|
+
end
|
131
132
|
end
|
132
|
-
end
|
133
133
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
134
|
+
def variance
|
135
|
+
count = @count.get
|
136
|
+
if count <= 1
|
137
|
+
0.0
|
138
|
+
else
|
139
|
+
longBitsToDouble(@varianceS.get) / (count - 1)
|
140
|
+
end
|
140
141
|
end
|
141
|
-
end
|
142
142
|
|
143
|
-
|
144
|
-
|
145
|
-
|
143
|
+
def set_max(val)
|
144
|
+
(@_max.get >= val) || @_max.set(val)
|
145
|
+
end
|
146
146
|
|
147
|
-
|
148
|
-
|
149
|
-
|
147
|
+
def set_min(val)
|
148
|
+
(@_min.get <= val) || @_min.set(val)
|
149
|
+
end
|
150
150
|
|
151
151
|
|
152
152
|
|
153
|
+
end
|
153
154
|
end
|
154
155
|
end
|
@@ -12,9 +12,9 @@ module Drone
|
|
12
12
|
|
13
13
|
##
|
14
14
|
# Create a new dataset, if the decay factor is too big
|
15
|
-
# the flt ruby library
|
16
|
-
# to allow greater precision, the
|
17
|
-
#
|
15
|
+
# the flt ruby library is used for internal computations
|
16
|
+
# to allow greater precision, the performance impact should be
|
17
|
+
# minimal.
|
18
18
|
#
|
19
19
|
# @param [String] id A unique id representing this
|
20
20
|
# dataset.
|
@@ -94,7 +94,7 @@ module Drone
|
|
94
94
|
private
|
95
95
|
|
96
96
|
def use_flt?
|
97
|
-
|
97
|
+
true
|
98
98
|
end
|
99
99
|
|
100
100
|
def math_exp(n)
|
data/lib/drone/version.rb
CHANGED
@@ -11,7 +11,7 @@ describe 'Histogram' do
|
|
11
11
|
|
12
12
|
describe "A histogram with zero recorded values" do
|
13
13
|
before do
|
14
|
-
@histogram = Histogram.new("id1", UniformSample.new("id1:sample", 100))
|
14
|
+
@histogram = Metrics::Histogram.new("id1", UniformSample.new("id1:sample", 100))
|
15
15
|
end
|
16
16
|
|
17
17
|
should "have a count of 0" do
|
@@ -54,7 +54,7 @@ describe 'Histogram' do
|
|
54
54
|
|
55
55
|
describe "A histogram of the numbers 1 through 10000" do
|
56
56
|
before do
|
57
|
-
@histogram = Histogram.new("id1", UniformSample.new("id1:sample", 100000) )
|
57
|
+
@histogram = Metrics::Histogram.new("id1", UniformSample.new("id1:sample", 100000) )
|
58
58
|
(1..10000).each{|n| @histogram.update(n) }
|
59
59
|
end
|
60
60
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-11-06 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement: &
|
16
|
+
requirement: &70350261467800 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.12.10
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70350261467800
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: flt
|
27
|
-
requirement: &
|
27
|
+
requirement: &70350261463160 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 1.3.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70350261463160
|
36
36
|
description: Drone is a monitoring library based on the metrics java library
|
37
37
|
email: []
|
38
38
|
executables: []
|
@@ -41,6 +41,7 @@ extra_rdoc_files: []
|
|
41
41
|
files:
|
42
42
|
- .gitignore
|
43
43
|
- .rvmrc
|
44
|
+
- .travis.yml
|
44
45
|
- .yardopts
|
45
46
|
- Gemfile
|
46
47
|
- Guardfile
|
@@ -118,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
119
|
version: '0'
|
119
120
|
segments:
|
120
121
|
- 0
|
121
|
-
hash: -
|
122
|
+
hash: -2466968706053759942
|
122
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
124
|
none: false
|
124
125
|
requirements:
|
@@ -127,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
128
|
version: '0'
|
128
129
|
segments:
|
129
130
|
- 0
|
130
|
-
hash: -
|
131
|
+
hash: -2466968706053759942
|
131
132
|
requirements: []
|
132
133
|
rubyforge_project: drone
|
133
134
|
rubygems_version: 1.8.11
|