tabs 0.8.1 → 0.8.2
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/README.md +14 -0
- data/lib/tabs/helpers.rb +5 -0
- data/lib/tabs/metrics/value.rb +22 -21
- data/lib/tabs/storage.rb +8 -0
- data/lib/tabs/version.rb +1 -1
- data/spec/lib/tabs/metrics/value_spec.rb +7 -7
- data/tabs.gemspec +18 -4
- metadata +33 -6
data/README.md
CHANGED
@@ -276,6 +276,20 @@ enumerable and most existing code utilizing tabs should continue to
|
|
276
276
|
function. However, please review the docs for more information if you
|
277
277
|
encounter issues when upgrading.
|
278
278
|
|
279
|
+
### Breaking Changes in v0.8.2
|
280
|
+
|
281
|
+
In version 0.8.2 and higher the storage keys for value metrics have been
|
282
|
+
changed. Originally the various pieces (avg, sum, count, etc) were
|
283
|
+
stored in a JSON serialized string in a single key. The intent was that
|
284
|
+
this would comprise a poor-mans transaction of sorts. The downside
|
285
|
+
however was a major hit on performance when doing a lot of writes or
|
286
|
+
reading stats for a large date range. In v0.8.2 these component values
|
287
|
+
are stored in a real Redis hash and updated atomically when a value is
|
288
|
+
recorded. In future versions this will be changed to use a MULTI
|
289
|
+
statement to simulate a transaction. Value data that was recorded prior
|
290
|
+
to v0.8.2 will not be accessible in this or future versions so please
|
291
|
+
continue to use v0.8.1 or lower if that is an issue.
|
292
|
+
|
279
293
|
## Contributing
|
280
294
|
|
281
295
|
1. Fork it
|
data/lib/tabs/helpers.rb
CHANGED
data/lib/tabs/metrics/value.rb
CHANGED
@@ -23,11 +23,13 @@ module Tabs
|
|
23
23
|
def stats(period, resolution)
|
24
24
|
timestamps = timestamp_range period, resolution
|
25
25
|
keys = timestamps.map do |ts|
|
26
|
-
|
26
|
+
formatted_time = Tabs::Resolution.serialize(resolution, ts)
|
27
|
+
"stat:value:#{key}:data:#{formatted_time}"
|
27
28
|
end
|
28
29
|
|
29
30
|
values = mget(*keys).map do |v|
|
30
|
-
value = v.nil? ? default_value(0) :
|
31
|
+
value = v.nil? ? default_value(0) : v
|
32
|
+
value = Hash[value.map { |k, i| [k, to_numeric(i)] }]
|
31
33
|
value["timestamp"] = timestamps.shift
|
32
34
|
value.with_indifferent_access
|
33
35
|
end
|
@@ -42,35 +44,34 @@ module Tabs
|
|
42
44
|
private
|
43
45
|
|
44
46
|
def update_values(stat_key, value)
|
45
|
-
|
46
|
-
|
47
|
-
update_min(
|
48
|
-
update_max(
|
49
|
-
update_avg(
|
50
|
-
set(stat_key, JSON.generate(hash))
|
47
|
+
count = update_count(stat_key)
|
48
|
+
sum = update_sum(stat_key, value)
|
49
|
+
update_min(stat_key, value)
|
50
|
+
update_max(stat_key, value)
|
51
|
+
update_avg(stat_key, sum, count)
|
51
52
|
end
|
52
53
|
|
53
|
-
def
|
54
|
-
|
55
|
-
return JSON.parse(hash) if hash
|
56
|
-
default_value
|
54
|
+
def update_count(stat_key)
|
55
|
+
hincrby(stat_key, "count", 1)
|
57
56
|
end
|
58
57
|
|
59
|
-
def
|
60
|
-
|
61
|
-
hash["sum"] += value
|
58
|
+
def update_sum(stat_key, value)
|
59
|
+
hincrby(stat_key, "sum", value)
|
62
60
|
end
|
63
61
|
|
64
|
-
def update_min(
|
65
|
-
|
62
|
+
def update_min(stat_key, value)
|
63
|
+
min = (hget(stat_key, "min") || 0).to_i
|
64
|
+
hset(stat_key, "min", value) if value < min || min == 0
|
66
65
|
end
|
67
66
|
|
68
|
-
def update_max(
|
69
|
-
|
67
|
+
def update_max(stat_key, value)
|
68
|
+
max = (hget(stat_key, "max") || 0).to_i
|
69
|
+
hset(stat_key, "max", value) if value > max || max == 0
|
70
70
|
end
|
71
71
|
|
72
|
-
def update_avg(
|
73
|
-
|
72
|
+
def update_avg(stat_key, sum, count)
|
73
|
+
avg = sum.to_f / count.to_f
|
74
|
+
hset(stat_key, "avg", avg)
|
74
75
|
end
|
75
76
|
|
76
77
|
def default_value(nil_value=nil)
|
data/lib/tabs/storage.rb
CHANGED
data/lib/tabs/version.rb
CHANGED
@@ -16,7 +16,7 @@ describe Tabs::Metrics::Value do
|
|
16
16
|
metric.record(42)
|
17
17
|
time = Time.utc(now.year, now.month, now.day, now.hour)
|
18
18
|
stats = metric.stats(((now - 2.hours)..(now + 4.hours)), :hour)
|
19
|
-
expect(stats).to include({ "timestamp"=>time, "count"=>2, "min"=>17, "max"=>42, "sum"=>59, "avg"=>29})
|
19
|
+
expect(stats).to include({ "timestamp"=>time, "count"=>2, "min"=>17, "max"=>42, "sum"=>59, "avg"=>29.5})
|
20
20
|
end
|
21
21
|
|
22
22
|
it "applys the value to the specified timestamp if one is supplied" do
|
@@ -58,42 +58,42 @@ describe Tabs::Metrics::Value do
|
|
58
58
|
create_span(:minutes)
|
59
59
|
stats = metric.stats(now..(now + 7.minutes), :minute)
|
60
60
|
expect(stats).to include({ "timestamp" => (now + 3.minutes), "count"=>1, "min"=>10, "max"=>10, "sum"=>10, "avg"=>10})
|
61
|
-
expect(stats).to include({ "timestamp" => (now + 6.minutes), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17})
|
61
|
+
expect(stats).to include({ "timestamp" => (now + 6.minutes), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17.5})
|
62
62
|
end
|
63
63
|
|
64
64
|
it "returns the expected results for an hourly metric" do
|
65
65
|
create_span(:hours)
|
66
66
|
stats = metric.stats(now..(now + 7.hours), :hour)
|
67
67
|
expect(stats).to include({ "timestamp" => (now + 3.hours), "count"=>1, "min"=>10, "max"=>10, "sum"=>10, "avg"=>10})
|
68
|
-
expect(stats).to include({ "timestamp" => (now + 6.hours), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17})
|
68
|
+
expect(stats).to include({ "timestamp" => (now + 6.hours), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17.5})
|
69
69
|
end
|
70
70
|
|
71
71
|
it "returns the expected results for a daily metric" do
|
72
72
|
create_span(:days)
|
73
73
|
stats = metric.stats(now..(now + 7.days), :day)
|
74
74
|
expect(stats).to include({ "timestamp" => (now + 3.days), "count"=>1, "min"=>10, "max"=>10, "sum"=>10, "avg"=>10})
|
75
|
-
expect(stats).to include({ "timestamp" => (now + 6.days), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17})
|
75
|
+
expect(stats).to include({ "timestamp" => (now + 6.days), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17.5})
|
76
76
|
end
|
77
77
|
|
78
78
|
it "returns the expected results for a weekly metric" do
|
79
79
|
create_span(:weeks)
|
80
80
|
stats = metric.stats(now..(now + 7.weeks), :week)
|
81
81
|
expect(stats).to include({ "timestamp" => (now + 3.weeks).beginning_of_week, "count"=>1, "min"=>10, "max"=>10, "sum"=>10, "avg"=>10})
|
82
|
-
expect(stats).to include({ "timestamp" => (now + 6.weeks).beginning_of_week, "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17})
|
82
|
+
expect(stats).to include({ "timestamp" => (now + 6.weeks).beginning_of_week, "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17.5})
|
83
83
|
end
|
84
84
|
|
85
85
|
it "returns the expected results for a monthly metric" do
|
86
86
|
create_span(:months)
|
87
87
|
stats = metric.stats(now..(now + 7.months), :month)
|
88
88
|
expect(stats).to include({ "timestamp" => (now + 3.months), "count"=>1, "min"=>10, "max"=>10, "sum"=>10, "avg"=>10})
|
89
|
-
expect(stats).to include({ "timestamp" => (now + 6.months), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17})
|
89
|
+
expect(stats).to include({ "timestamp" => (now + 6.months), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17.5})
|
90
90
|
end
|
91
91
|
|
92
92
|
it "returns the expected results for a yearly metric" do
|
93
93
|
create_span(:years)
|
94
94
|
stats = metric.stats(now..(now + 7.years), :year)
|
95
95
|
expect(stats).to include({ "timestamp" => (now + 3.years), "count"=>1, "min"=>10, "max"=>10, "sum"=>10, "avg"=>10})
|
96
|
-
expect(stats).to include({ "timestamp" => (now + 6.years), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17})
|
96
|
+
expect(stats).to include({ "timestamp" => (now + 6.years), "count"=>2, "min"=>15, "max"=>20, "sum"=>35, "avg"=>17.5})
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
data/tabs.gemspec
CHANGED
@@ -20,11 +20,25 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.post_install_message = <<EOS
|
22
22
|
Tabs v0.8.0 - BREAKING CHANGES:
|
23
|
-
|
24
|
-
an array of hashes.
|
25
|
-
|
26
|
-
|
23
|
+
In version 0.8.0 and higher the get_stats method returns a more robust
|
24
|
+
object instead of just an array of hashes. These stats objects are
|
25
|
+
enumerable and most existing code utilizing tabs should continue to
|
26
|
+
function. However, please review the docs for more information if you
|
27
|
+
encounter issues when upgrading. Please review the README if installing
|
27
28
|
v0.8.0 or higher.
|
29
|
+
|
30
|
+
Tabs v0.8.2 - BREAKING CHANGES:
|
31
|
+
In version 0.8.2 and higher the storage keys for value metrics have been
|
32
|
+
changed. Originally the various pieces (avg, sum, count, etc) were
|
33
|
+
stored in a JSON serialized string in a single key. The intent was that
|
34
|
+
this would comprise a poor-mans transaction of sorts. The downside
|
35
|
+
however was a major hit on performance when doing a lot of writes or
|
36
|
+
reading stats for a large date range. In v0.8.2 these component values
|
37
|
+
are stored in a real Redis hash and updated atomically when a value is
|
38
|
+
recorded. In future versions this will be changed to use a MULTI
|
39
|
+
statement to simulate a transaction. Value data that was recorded prior
|
40
|
+
to v0.8.2 will not be accessible in this or future versions so please
|
41
|
+
continue to use v0.8.1 or lower if that is an issue.
|
28
42
|
EOS
|
29
43
|
|
30
44
|
gem.add_dependency "activesupport", ">= 3.2"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tabs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -186,16 +186,43 @@ homepage: https://github.com/thegrubbsian/tabs
|
|
186
186
|
licenses: []
|
187
187
|
post_install_message: ! 'Tabs v0.8.0 - BREAKING CHANGES:
|
188
188
|
|
189
|
-
|
189
|
+
In version 0.8.0 and higher the get_stats method returns a more robust
|
190
190
|
|
191
|
-
an array of hashes.
|
191
|
+
object instead of just an array of hashes. These stats objects are
|
192
192
|
|
193
|
-
|
193
|
+
enumerable and most existing code utilizing tabs should continue to
|
194
194
|
|
195
|
-
|
195
|
+
function. However, please review the docs for more information if you
|
196
|
+
|
197
|
+
encounter issues when upgrading. Please review the README if installing
|
196
198
|
|
197
199
|
v0.8.0 or higher.
|
198
200
|
|
201
|
+
|
202
|
+
Tabs v0.8.2 - BREAKING CHANGES:
|
203
|
+
|
204
|
+
In version 0.8.2 and higher the storage keys for value metrics have been
|
205
|
+
|
206
|
+
changed. Originally the various pieces (avg, sum, count, etc) were
|
207
|
+
|
208
|
+
stored in a JSON serialized string in a single key. The intent was that
|
209
|
+
|
210
|
+
this would comprise a poor-mans transaction of sorts. The downside
|
211
|
+
|
212
|
+
however was a major hit on performance when doing a lot of writes or
|
213
|
+
|
214
|
+
reading stats for a large date range. In v0.8.2 these component values
|
215
|
+
|
216
|
+
are stored in a real Redis hash and updated atomically when a value is
|
217
|
+
|
218
|
+
recorded. In future versions this will be changed to use a MULTI
|
219
|
+
|
220
|
+
statement to simulate a transaction. Value data that was recorded prior
|
221
|
+
|
222
|
+
to v0.8.2 will not be accessible in this or future versions so please
|
223
|
+
|
224
|
+
continue to use v0.8.1 or lower if that is an issue.
|
225
|
+
|
199
226
|
'
|
200
227
|
rdoc_options: []
|
201
228
|
require_paths:
|