tabs 0.6.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -9,7 +9,7 @@ averages, and min/max, and task based stats sliceable by the minute, hour, day,
9
9
 
10
10
  Add this line to your application's Gemfile:
11
11
 
12
- gem 'tabs', '~> 0.6.3'
12
+ gem 'tabs', '~> 0.6.2'
13
13
 
14
14
  And then execute:
15
15
 
@@ -10,8 +10,8 @@ module Tabs
10
10
  @key = key
11
11
  end
12
12
 
13
- def increment
14
- timestamp = Time.now.utc
13
+ def increment(timestamp=Time.now)
14
+ timestamp.utc
15
15
  Tabs::RESOLUTIONS.each do |resolution|
16
16
  increment_resolution(resolution, timestamp)
17
17
  end
@@ -12,13 +12,13 @@ module Tabs
12
12
  @key = key
13
13
  end
14
14
 
15
- def start(token)
16
- Token.new(token, key).start
15
+ def start(token, timestamp=Time.now)
16
+ Token.new(token, key).start(timestamp)
17
17
  true
18
18
  end
19
19
 
20
- def complete(token)
21
- Token.new(token, key).complete
20
+ def complete(token, timestamp=Time.now)
21
+ Token.new(token, key).complete(timestamp)
22
22
  true
23
23
  end
24
24
 
@@ -46,10 +46,17 @@ module Tabs
46
46
  private
47
47
 
48
48
  def tokens_for_period(range, resolution, type)
49
- keys = Task::Token.keys_for_range(key, range, resolution, type)
49
+ keys = keys_for_range(range, resolution, type)
50
50
  mget(*keys).compact.map(&:to_a).flatten.map { |t| Token.new(t, key) }
51
51
  end
52
52
 
53
+ def keys_for_range(range, resolution, type)
54
+ range.map do |date|
55
+ formatted_time = Tabs::Resolution.serialize(resolution, date)
56
+ "stat:task:#{key}:#{type}:#{formatted_time}"
57
+ end
58
+ end
59
+
53
60
  end
54
61
  end
55
62
  end
@@ -4,13 +4,6 @@ module Tabs
4
4
  class Token < String
5
5
  include Storage
6
6
 
7
- def self.keys_for_range(key, range, resolution, type)
8
- range.map do |date|
9
- formatted_time = Tabs::Resolution.serialize(resolution, date)
10
- "stat:task:#{key}:#{type}:#{formatted_time}"
11
- end
12
- end
13
-
14
7
  attr_reader :key
15
8
 
16
9
  def initialize(token, key)
@@ -18,25 +11,17 @@ module Tabs
18
11
  super(token)
19
12
  end
20
13
 
21
- def start_key
22
- "stat:started:#{key}:#{self}"
23
- end
24
-
25
- def end_key
26
- "stat:completed:#{key}:#{self}"
27
- end
28
-
29
- def start
30
- self.start_time = Time.now.utc
14
+ def start(timestamp=Time.now)
15
+ self.start_time = timestamp.utc
31
16
  sadd("stat:task:#{key}:tokens", self)
32
17
  Tabs::RESOLUTIONS.each { |res| record_start(res, start_time) }
33
18
  end
34
19
 
35
- def complete
20
+ def complete(timestamp=Time.now)
21
+ self.complete_time = timestamp.utc
36
22
  unless sismember("stat:task:#{key}:tokens", self)
37
23
  raise UnstartedTaskMetricError.new("No task for metric '#{key}' was started with token '#{self}'")
38
24
  end
39
- self.complete_time = Time.now.utc
40
25
  Tabs::RESOLUTIONS.each { |res| record_complete(res, complete_time) }
41
26
  end
42
27
 
@@ -10,8 +10,8 @@ module Tabs
10
10
  @key = key
11
11
  end
12
12
 
13
- def record(value)
14
- timestamp = Time.now.utc
13
+ def record(value, timestamp=Time.now)
14
+ timestamp.utc
15
15
  Tabs::RESOLUTIONS.each do |resolution|
16
16
  formatted_time = Tabs::Resolution.serialize(resolution, timestamp)
17
17
  stat_key = "stat:value:#{key}:data:#{formatted_time}"
@@ -23,27 +23,27 @@ module Tabs
23
23
  Config
24
24
  end
25
25
 
26
- def increment_counter(key)
26
+ def increment_counter(key, timestamp=Time.now)
27
27
  create_metric(key, "counter") unless metric_exists?(key)
28
28
  raise MetricTypeMismatchError.new("Only counter metrics can be incremented") unless metric_type(key) == "counter"
29
- get_metric(key).increment
29
+ get_metric(key).increment(timestamp)
30
30
  end
31
31
 
32
- def record_value(key, value)
32
+ def record_value(key, value, timestamp=Time.now)
33
33
  create_metric(key, "value") unless metric_exists?(key)
34
34
  raise MetricTypeMismatchError.new("Only value metrics can record a value") unless metric_type(key) == "value"
35
- get_metric(key).record(value)
35
+ get_metric(key).record(value, timestamp)
36
36
  end
37
37
 
38
- def start_task(key, token)
38
+ def start_task(key, token, timestamp=Time.now)
39
39
  create_metric(key, "task")
40
40
  raise MetricTypeMismatchError.new("Only task metrics can start a task") unless metric_type(key) == "task"
41
- get_metric(key).start(token)
41
+ get_metric(key).start(token, timestamp)
42
42
  end
43
43
 
44
- def complete_task(key, token)
44
+ def complete_task(key, token, timestamp=Time.now)
45
45
  raise MetricTypeMismatchError.new("Only task metrics can complete a task") unless metric_type(key) == "task"
46
- get_metric(key).complete(token)
46
+ get_metric(key).complete(token, timestamp)
47
47
  end
48
48
 
49
49
  def create_metric(key, type)
@@ -1,3 +1,3 @@
1
1
  module Tabs
2
- VERSION = "0.6.3"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -9,14 +9,22 @@ describe Tabs::Metrics::Counter do
9
9
 
10
10
  describe "incrementing stats" do
11
11
 
12
+ before { Timecop.freeze(now) }
13
+
12
14
  it "increments the value for the expected periods" do
13
- Timecop.freeze(now)
14
15
  metric.increment
15
16
  time = Time.utc(now.year, now.month, now.day, now.hour)
16
17
  stats = metric.stats(((now - 2.hours)..(now + 4.hours)), :hour)
17
18
  expect(stats).to include({ time => 1 })
18
19
  end
19
20
 
21
+ it "applys the increment to the specified timestamp if one is supplied" do
22
+ time = Time.utc(now.year, now.month, now.day, now.hour) - 2.hours
23
+ metric.increment(time)
24
+ stats = metric.stats(((now - 3.hours)..now), :hour)
25
+ expect(stats).to include({ time => 1 })
26
+ end
27
+
20
28
  end
21
29
 
22
30
  describe "total count" do
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ describe Tabs::Metrics::Task::Token do
4
+
5
+ describe "#time_elapsed" do
6
+
7
+ let(:token) { Tabs::Metrics::Task::Token.new("foo", "bar") }
8
+ let(:time) { Time.now }
9
+
10
+ it "should return the time between when the task/token started and completed" do
11
+ token.start(time - 2.days)
12
+ token.complete(time - 1.day)
13
+ expect(token.time_elapsed(:hour)).to eq(24)
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -9,8 +9,9 @@ describe Tabs::Metrics::Value do
9
9
 
10
10
  describe ".record" do
11
11
 
12
+ before { Timecop.freeze(now) }
13
+
12
14
  it "sets the expected values for the period" do
13
- Timecop.freeze(now)
14
15
  metric.record(17)
15
16
  metric.record(42)
16
17
  time = Time.utc(now.year, now.month, now.day, now.hour)
@@ -18,6 +19,13 @@ describe Tabs::Metrics::Value do
18
19
  expect(stats).to include({ time => {"count"=>2, "min"=>17, "max"=>42, "sum"=>59, "avg"=>29} })
19
20
  end
20
21
 
22
+ it "applys the value to the specified timestamp if one is supplied" do
23
+ time = Time.utc(now.year, now.month, now.day, now.hour) - 2.hours
24
+ metric.record(42, time)
25
+ stats = metric.stats(((now - 3.hours)..now), :hour)
26
+ expect(stats).to include({ time => {"count"=>1, "min"=>42, "max"=>42, "sum"=>42, "avg"=>42} })
27
+ end
28
+
21
29
  end
22
30
 
23
31
  describe ".stats" do
@@ -10,10 +10,41 @@ describe Tabs::Metrics::Task do
10
10
 
11
11
  describe ".start" do
12
12
 
13
+ let(:token) { stub(:token) }
14
+ let(:time) { Time.now }
15
+
16
+ it "calls start on the given token" do
17
+ Tabs::Metrics::Task::Token.should_receive(:new).with(token_1, "foo").and_return(token)
18
+ token.should_receive(:start)
19
+ metric.start(token_1)
20
+ end
21
+
22
+ it "passes through the specified timestamp" do
23
+ Tabs::Metrics::Task::Token.stub(new: token)
24
+ token.should_receive(:start).with(time)
25
+ metric.start(token_1, time)
26
+ end
27
+
13
28
  end
14
29
 
15
30
  describe ".complete" do
16
31
 
32
+ let(:token) { stub(:token) }
33
+ let(:time) { Time.now }
34
+
35
+ it "calls complete on the given token" do
36
+ token = stub(:token)
37
+ Tabs::Metrics::Task::Token.should_receive(:new).with(token_1, "foo").and_return(token)
38
+ token.should_receive(:complete)
39
+ metric.complete(token_1)
40
+ end
41
+
42
+ it "passes through the specified timestamp" do
43
+ Tabs::Metrics::Task::Token.stub(new: token)
44
+ token.should_receive(:complete).with(time)
45
+ metric.complete(token_1, time)
46
+ end
47
+
17
48
  it "raises an UnstartedTaskMetricError if the metric has not yet been started" do
18
49
  lambda { metric.complete("foobar") }.should raise_error(Tabs::Metrics::Task::UnstartedTaskMetricError)
19
50
  end
@@ -128,7 +128,7 @@ describe Tabs do
128
128
  it "calls record on the metric" do
129
129
  metric = Tabs.create_metric("foo", "value")
130
130
  Tabs.stub(get_metric: metric)
131
- metric.should_receive(:record).with(42)
131
+ metric.should_receive(:record).with(42, Time.now.utc)
132
132
  Tabs.record_value("foo", 42)
133
133
  end
134
134
 
@@ -142,7 +142,7 @@ describe Tabs do
142
142
  Tabs.create_metric("baz", "counter")
143
143
  expect(Tabs.list_metrics).to eq(["foo", "bar", "baz"])
144
144
  end
145
-
145
+
146
146
  end
147
147
 
148
148
  describe "#metric_type" do
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.6.3
4
+ version: 0.7.0
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-04-17 00:00:00.000000000 Z
12
+ date: 2013-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -172,6 +172,7 @@ files:
172
172
  - lib/tabs/tabs.rb
173
173
  - lib/tabs/version.rb
174
174
  - spec/lib/tabs/metrics/counter_spec.rb
175
+ - spec/lib/tabs/metrics/task/token_spec.rb
175
176
  - spec/lib/tabs/metrics/value_spec.rb
176
177
  - spec/lib/tabs/task_spec.rb
177
178
  - spec/lib/tabs_spec.rb
@@ -211,8 +212,8 @@ specification_version: 3
211
212
  summary: A redis-backed metrics tracker for keeping tabs on pretty much anything ;)
212
213
  test_files:
213
214
  - spec/lib/tabs/metrics/counter_spec.rb
215
+ - spec/lib/tabs/metrics/task/token_spec.rb
214
216
  - spec/lib/tabs/metrics/value_spec.rb
215
217
  - spec/lib/tabs/task_spec.rb
216
218
  - spec/lib/tabs_spec.rb
217
219
  - spec/spec_helper.rb
218
- has_rdoc: