tabs 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
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=