tabs 0.6.1 → 0.6.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 CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  # Tabs
4
4
 
5
- Tabs is a redis-backed metrics tracker that supports counts, sums, averages, and min/max stats sliceable by the minute, hour, day, week, month, and year.
5
+ Tabs is a redis-backed metrics tracker that supports counts, sums,
6
+ averages, and min/max, and task based stats sliceable by the minute, hour, day, week, month, and year.
6
7
 
7
8
  ## Installation
8
9
 
9
10
  Add this line to your application's Gemfile:
10
11
 
11
- gem 'tabs'
12
+ gem 'tabs', '~> 0.6.1'
12
13
 
13
14
  And then execute:
14
15
 
@@ -28,7 +29,7 @@ type will only be available in v0.6.0 and above.
28
29
 
29
30
  ## Usage
30
31
 
31
- Metrics come in two flavors: counters and values.
32
+ Metrics come in three flavors: counters, values, and tasks.
32
33
 
33
34
  ### Counter Metrics
34
35
 
@@ -129,7 +130,7 @@ Tabs.complete_task("mobile-to-purchase", "2g4hj17787s")
129
130
  Retrieving stats for a task metric is just like the other types:
130
131
 
131
132
  ```ruby
132
- Tabs.get_stats("mobile-to-purchase", (Time.now - 6.hours)..Time.now), : minute)
133
+ Tabs.get_stats("mobile-to-purchase", (Time.now - 6.hours)..Time.now), :minute)
133
134
  ```
134
135
 
135
136
  This will return a hash like this:
@@ -139,7 +140,7 @@ This will return a hash like this:
139
140
  started: 3, #=> number of items started within the period
140
141
  completed: 2, #=> number of items completed within the period
141
142
  completed_within_period: 2, #=> number started AND completed within the period
142
- completion_rate: 0.18, #=> rate of completion
143
+ completion_rate: 0.18, #=> rate of completion in the specified resolution (e.g. :minute)
143
144
  average_completion_time: 1.5 #=> average completion time in the specified resolution
144
145
  }
145
146
  ```
@@ -31,7 +31,11 @@ module Tabs
31
31
  end
32
32
 
33
33
  def total
34
- get("stat:counter:#{key}:total").to_i
34
+ (get("stat:counter:#{key}:total") || 0).to_i
35
+ end
36
+
37
+ def drop!
38
+ del_by_prefix("stat:counter:#{key}")
35
39
  end
36
40
 
37
41
  private
@@ -39,6 +39,10 @@ module Tabs
39
39
  }
40
40
  end
41
41
 
42
+ def drop!
43
+ del_by_prefix("stat:task:#{key}")
44
+ end
45
+
42
46
  private
43
47
 
44
48
  def tokens_for_period(range, resolution, type)
@@ -32,6 +32,10 @@ module Tabs
32
32
  filtered_pairs.map { |p| Hash[[p]] }
33
33
  end
34
34
 
35
+ def drop!
36
+ del_by_prefix("stat:value:#{key}")
37
+ end
38
+
35
39
  private
36
40
 
37
41
  def update_values(stat_key, value)
@@ -24,10 +24,17 @@ module Tabs
24
24
  end
25
25
 
26
26
  def del(*keys)
27
+ return 0 if keys.empty?
27
28
  prefixed_keys = keys.map { |k| "tabs:#{k}" }
28
29
  redis.del(*prefixed_keys)
29
30
  end
30
31
 
32
+ def del_by_prefix(pattern)
33
+ keys = redis.keys("tabs:#{pattern}*")
34
+ return 0 if keys.empty?
35
+ redis.del(*keys)
36
+ end
37
+
31
38
  def incr(key)
32
39
  redis.incr("tabs:#{key}")
33
40
  end
@@ -86,13 +86,9 @@ module Tabs
86
86
 
87
87
  def drop_metric(key)
88
88
  raise UnknownMetricError.new("Unknown metric: #{key}") unless metric_exists?(key)
89
+ metric = get_metric(key)
90
+ metric.drop!
89
91
  hdel "metrics", key
90
- Tabs::RESOLUTIONS.each do |resolution|
91
- stat_key = "stat:keys:#{key}:#{resolution}"
92
- keys = smembers(stat_key)
93
- del(keys)
94
- del stat_key
95
- end
96
92
  end
97
93
 
98
94
  private
@@ -1,3 +1,3 @@
1
1
  module Tabs
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.2"
3
3
  end
@@ -2,6 +2,8 @@ require "spec_helper"
2
2
 
3
3
  describe Tabs::Metrics::Counter do
4
4
 
5
+ include Tabs::Storage
6
+
5
7
  let(:metric) { Tabs.create_metric("foo", "counter") }
6
8
  let(:now) { Time.utc(2000, 1, 1, 0, 0) }
7
9
 
@@ -111,4 +113,33 @@ describe Tabs::Metrics::Counter do
111
113
 
112
114
  end
113
115
 
116
+ describe ".drop!" do
117
+
118
+ before do
119
+ 3.times { metric.increment }
120
+ expect(exists("stat:counter:foo:total")).to be_true
121
+ @count_keys = (Tabs::RESOLUTIONS.map do |res|
122
+ smembers("stat:counter:foo:keys:#{res}")
123
+ end).flatten
124
+ metric.drop!
125
+ end
126
+
127
+ it "deletes the counter total key" do
128
+ expect(exists("stat:counter:foo:total")).to be_false
129
+ end
130
+
131
+ it "deletes all resolution count keys" do
132
+ @count_keys.each do |key|
133
+ expect(exists(key)).to be_false
134
+ end
135
+ end
136
+
137
+ it "deletes all resolution key collection keys" do
138
+ Tabs::RESOLUTIONS.each do |res|
139
+ expect(exists("stat:counter:foo:keys:#{res}")).to be_false
140
+ end
141
+ end
142
+
143
+ end
144
+
114
145
  end
@@ -2,6 +2,8 @@ require "spec_helper"
2
2
 
3
3
  describe Tabs::Metrics::Value do
4
4
 
5
+ include Tabs::Storage
6
+
5
7
  let(:metric) { Tabs.create_metric("foo", "value") }
6
8
  let(:now) { Time.utc(2000, 1, 1, 0, 0) }
7
9
 
@@ -82,4 +84,28 @@ describe Tabs::Metrics::Value do
82
84
 
83
85
  end
84
86
 
87
+ describe ".drop!" do
88
+
89
+ before do
90
+ 3.times { metric.record(rand(30)) }
91
+ @count_keys = (Tabs::RESOLUTIONS.map do |res|
92
+ smembers("stat:value:foo:keys:#{res}")
93
+ end).flatten
94
+ metric.drop!
95
+ end
96
+
97
+ it "deletes all resolution count keys" do
98
+ @count_keys.each do |key|
99
+ expect(exists(key)).to be_false
100
+ end
101
+ end
102
+
103
+ it "deletes all resolution key collection keys" do
104
+ Tabs::RESOLUTIONS.each do |res|
105
+ expect(exists("stat:value:foo:keys:#{res}")).to be_false
106
+ end
107
+ end
108
+
109
+ end
110
+
85
111
  end
@@ -74,15 +74,18 @@ describe Tabs do
74
74
  it "removes the metric from the list_metrics" do
75
75
  Tabs.drop_metric("foo")
76
76
  expect(Tabs.list_metrics).to_not include("foo")
77
+ end
78
+
79
+ it "results in metric_exists? returning false" do
80
+ Tabs.drop_metric("foo")
77
81
  expect(Tabs.metric_exists?("foo")).to be_false
78
82
  end
79
83
 
80
- it "removes the metrics values from redis" do
81
- Tabs.increment_counter("foo")
82
- keys = smembers("tabs:stat:keys:foo:hour")
83
- expect(redis.keys).to include("tabs:stat:counter:foo:keys:hour")
84
+ it "calls drop! on the metric" do
85
+ metric = stub(:metric)
86
+ Tabs.stub(get_metric: metric)
87
+ metric.should_receive(:drop!)
84
88
  Tabs.drop_metric("foo")
85
- expect(redis.keys).to_not include(keys[0])
86
89
  end
87
90
 
88
91
  end
@@ -144,13 +147,21 @@ describe Tabs do
144
147
 
145
148
  describe "#metric_type" do
146
149
 
147
- it "returns the type of a given metric" do
150
+ it "returns the type of a counter metric" do
148
151
  Tabs.create_metric("foo", "counter")
149
- Tabs.create_metric("bar", "value")
150
152
  expect(Tabs.metric_type("foo")).to eq("counter")
153
+ end
154
+
155
+ it "returns the type of a value metric" do
156
+ Tabs.create_metric("bar", "value")
151
157
  expect(Tabs.metric_type("bar")).to eq("value")
152
158
  end
153
159
 
160
+ it "returns the type of a task metric" do
161
+ Tabs.create_metric("baz", "task")
162
+ expect(Tabs.metric_type("baz")).to eq("task")
163
+ end
164
+
154
165
  end
155
166
 
156
167
  end
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tabs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - JC Grubbs
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-03-17 00:00:00.000000000 Z
12
+ date: 2013-03-24 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activesupport
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ! '>='
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - ! '>='
25
28
  - !ruby/object:Gem::Version
@@ -27,6 +30,7 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: json
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - ~>
32
36
  - !ruby/object:Gem::Version
@@ -34,6 +38,7 @@ dependencies:
34
38
  type: :runtime
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - ~>
39
44
  - !ruby/object:Gem::Version
@@ -41,6 +46,7 @@ dependencies:
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: redis
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
51
  - - ~>
46
52
  - !ruby/object:Gem::Version
@@ -48,6 +54,7 @@ dependencies:
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
59
  - - ~>
53
60
  - !ruby/object:Gem::Version
@@ -55,6 +62,7 @@ dependencies:
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: fakeredis
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
67
  - - ! '>='
60
68
  - !ruby/object:Gem::Version
@@ -62,6 +70,7 @@ dependencies:
62
70
  type: :development
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
75
  - - ! '>='
67
76
  - !ruby/object:Gem::Version
@@ -69,6 +78,7 @@ dependencies:
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: pry
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
83
  - - ! '>='
74
84
  - !ruby/object:Gem::Version
@@ -76,6 +86,7 @@ dependencies:
76
86
  type: :development
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
91
  - - ! '>='
81
92
  - !ruby/object:Gem::Version
@@ -83,6 +94,7 @@ dependencies:
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: rake
85
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
86
98
  requirements:
87
99
  - - ! '>='
88
100
  - !ruby/object:Gem::Version
@@ -90,6 +102,7 @@ dependencies:
90
102
  type: :development
91
103
  prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
93
106
  requirements:
94
107
  - - ! '>='
95
108
  - !ruby/object:Gem::Version
@@ -97,6 +110,7 @@ dependencies:
97
110
  - !ruby/object:Gem::Dependency
98
111
  name: rspec
99
112
  requirement: !ruby/object:Gem::Requirement
113
+ none: false
100
114
  requirements:
101
115
  - - ! '>='
102
116
  - !ruby/object:Gem::Version
@@ -104,6 +118,7 @@ dependencies:
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
107
122
  requirements:
108
123
  - - ! '>='
109
124
  - !ruby/object:Gem::Version
@@ -111,6 +126,7 @@ dependencies:
111
126
  - !ruby/object:Gem::Dependency
112
127
  name: timecop
113
128
  requirement: !ruby/object:Gem::Requirement
129
+ none: false
114
130
  requirements:
115
131
  - - ! '>='
116
132
  - !ruby/object:Gem::Version
@@ -118,6 +134,7 @@ dependencies:
118
134
  type: :development
119
135
  prerelease: false
120
136
  version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
121
138
  requirements:
122
139
  - - ! '>='
123
140
  - !ruby/object:Gem::Version
@@ -162,7 +179,6 @@ files:
162
179
  - tabs.gemspec
163
180
  homepage: https://github.com/thegrubbsian/tabs
164
181
  licenses: []
165
- metadata: {}
166
182
  post_install_message: ! '**** NOTICE ****
167
183
 
168
184
  Please note there are breaking changes in this version of tabs!
@@ -176,20 +192,22 @@ rdoc_options: []
176
192
  require_paths:
177
193
  - lib
178
194
  required_ruby_version: !ruby/object:Gem::Requirement
195
+ none: false
179
196
  requirements:
180
197
  - - ! '>='
181
198
  - !ruby/object:Gem::Version
182
199
  version: '0'
183
200
  required_rubygems_version: !ruby/object:Gem::Requirement
201
+ none: false
184
202
  requirements:
185
203
  - - ! '>='
186
204
  - !ruby/object:Gem::Version
187
205
  version: '0'
188
206
  requirements: []
189
207
  rubyforge_project:
190
- rubygems_version: 2.0.3
208
+ rubygems_version: 1.8.23
191
209
  signing_key:
192
- specification_version: 4
210
+ specification_version: 3
193
211
  summary: A redis-backed metrics tracker for keeping tabs on pretty much anything ;)
194
212
  test_files:
195
213
  - spec/lib/tabs/metrics/counter_spec.rb
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZGVkZDU2ZjE2NzVjMDFiNjRjZDVmZWQyODQzNmE0MzZmMWE3MzRkZA==
5
- data.tar.gz: !binary |-
6
- ZThhYTI3ODI5ZGNhM2M5ZmU2MWE4YTg0YzljOTQ3NDIyNDg1Njc4YQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MDJjNzY3YzM5MTAyYmJkOWUyYWMwYmNhYmU0YWY2YjcwYWJmMjQ2ZWRiZGZj
10
- MDU0MjU2MzJiMTE5NzNlMDcwMzY0YmI2MTJmNzg5YzdmMmIyMjdkMjg5NjAz
11
- ZDJiMjExMjNhNGI2YjY3MWJmNjg0ODJjODk3Mjc0ZjJhM2QxYjc=
12
- data.tar.gz: !binary |-
13
- M2U3MDczNmZhNjJhYzE5MDA2NzlkMzliYjQ0MzBmOWUxNmVmNDU0Zjc0MWRk
14
- ZWNiNDVmOTEzNDdjMzQ3YWRlMzRkNGI2ZTk3MWYyNmYwYTk5MjMyYzVkNDQ3
15
- OTRlZjA1ZTIzYzY0ZjQ5ZTljNjQ2MGZiYTkwMTkwYmVhNzZmMDg=