counters 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -42,7 +42,7 @@ module Counters
42
42
  @namespace
43
43
  else
44
44
  other = self.dup
45
- other.namespace = [@namespace.to_s, args.first].join(".")
45
+ other.namespace = [@namespace.to_s, args.first].reject {|ns| ns.empty?}.join(".")
46
46
  other
47
47
  end
48
48
  end
@@ -1,3 +1,3 @@
1
1
  module Counters
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.1"
3
3
  end
@@ -89,7 +89,7 @@ describe Counters::File do
89
89
  Tempfile.new("counters.log")
90
90
  end
91
91
 
92
- let :counter do
92
+ subject do
93
93
  Counters::File.new(tempfile)
94
94
  end
95
95
 
@@ -104,60 +104,60 @@ describe Counters::File do
104
104
 
105
105
  context "given the counter is namespaced" do
106
106
  it "should namespace the key from #hit" do
107
- counter.namespace = "juice"
108
- counter.hit "foxglove"
107
+ subject.namespace = "juice"
108
+ subject.hit "foxglove"
109
109
  tempfile.rewind
110
110
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\shit:\sjuice\.foxglove$/
111
111
  end
112
112
 
113
113
  it "should namespace the key from #latency" do
114
- counter.namespace = "cocktail"
115
- counter.latency "angelica", 200
114
+ subject.namespace = "cocktail"
115
+ subject.latency "angelica", 200
116
116
  tempfile.rewind
117
117
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\slatency:\scocktail\.angelica\s200s$/
118
118
  end
119
119
 
120
120
  it "should namespace the key from #magnitude" do
121
- counter.namespace = "brew"
122
- counter.magnitude "crocus", 100
121
+ subject.namespace = "brew"
122
+ subject.magnitude "crocus", 100
123
123
  tempfile.rewind
124
124
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\smagnitude:\sbrew\.crocus 100$/
125
125
  end
126
126
 
127
127
  it "should namespace the key from #ping" do
128
- counter.namespace = "beer"
129
- counter.ping "tulip"
128
+ subject.namespace = "beer"
129
+ subject.ping "tulip"
130
130
  tempfile.rewind
131
131
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\sping:\sbeer\.tulip$/
132
132
  end
133
133
  end
134
134
 
135
135
  it "should log a message to the logfile when a hit is recorded" do
136
- counter.hit "urls.visited"
136
+ subject.hit "urls.visited"
137
137
  tempfile.rewind
138
138
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\shit.*urls\.visited$/
139
139
  end
140
140
 
141
141
  it "should log a message to the logfile when a magnitude is recorded" do
142
- counter.magnitude "bytes.read", 2_013
142
+ subject.magnitude "bytes.read", 2_013
143
143
  tempfile.rewind
144
144
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\smagnitude.*bytes\.read.*2013$/
145
145
  end
146
146
 
147
147
  it "should log a message to the logfile when a latency is recorded" do
148
- counter.latency "processing", 0.132 # in seconds
148
+ subject.latency "processing", 0.132 # in seconds
149
149
  tempfile.rewind
150
150
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\slatency.*processing.*0.132s$/
151
151
  end
152
152
 
153
153
  it "should record a message in the logfile when a ping is recorded" do
154
- counter.ping "crawler.alive"
154
+ subject.ping "crawler.alive"
155
155
  tempfile.rewind
156
156
  tempfile.read.should =~ /^#{TIMESTAMP_RE}\s-\sping.*crawler\.alive$/
157
157
  end
158
158
 
159
159
  it "should log a message to the logfile when a latency is recorded using a block" do
160
- counter.latency "crawling" do
160
+ subject.latency "crawling" do
161
161
  sleep 0.1
162
162
  end
163
163
 
@@ -166,7 +166,7 @@ describe Counters::File do
166
166
  end
167
167
 
168
168
  it "should raise an ArgumentError when calling #latency with both a block and a latency" do
169
- lambda { counter.latency("processing", 0.123) { sleep 0.1 } }.should raise_error(ArgumentError)
169
+ lambda { subject.latency("processing", 0.123) { sleep 0.1 } }.should raise_error(ArgumentError)
170
170
  end
171
171
 
172
172
  it "should accept a filename on instantiation" do
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Counters::Memory do
4
- let :counter do
4
+ subject do
5
5
  Counters::Memory.new
6
6
  end
7
7
 
@@ -16,67 +16,67 @@ describe Counters::Memory do
16
16
 
17
17
  context "given the counter is namespaced" do
18
18
  it "should namespace the key from #hit" do
19
- counter.namespace = "juice"
20
- counter.hit "foxglove"
21
- counter.hits["juice.foxglove"].should == 1
19
+ subject.namespace = "juice"
20
+ subject.hit "foxglove"
21
+ subject.hits["juice.foxglove"].should == 1
22
22
  end
23
23
 
24
24
  it "should namespace the key from #latency" do
25
- counter.namespace = "cocktail"
26
- counter.latency "angelica", 200
27
- counter.latencies["cocktail.angelica"].should == [200]
25
+ subject.namespace = "cocktail"
26
+ subject.latency "angelica", 200
27
+ subject.latencies["cocktail.angelica"].should == [200]
28
28
  end
29
29
 
30
30
  it "should namespace the key from #magnitude" do
31
- counter.namespace = "brew"
32
- counter.magnitude "crocus", 100
33
- counter.magnitudes["brew.crocus"].should == 100
31
+ subject.namespace = "brew"
32
+ subject.magnitude "crocus", 100
33
+ subject.magnitudes["brew.crocus"].should == 100
34
34
  end
35
35
 
36
36
  it "should namespace the key from #ping" do
37
- counter.namespace = "beer"
37
+ subject.namespace = "beer"
38
38
  Timecop.freeze(Time.now.utc) do
39
- counter.ping "tulip"
40
- counter.pings["beer.tulip"].should == Time.now.utc
39
+ subject.ping "tulip"
40
+ subject.pings["beer.tulip"].should == Time.now.utc
41
41
  end
42
42
  end
43
43
  end
44
44
 
45
45
  it "should record a hit with key 'pages.read'" do
46
- counter.hit "pages.read"
47
- counter.hits.should have_key("pages.read")
48
- counter.hits["pages.read"].should == 1
46
+ subject.hit "pages.read"
47
+ subject.hits.should have_key("pages.read")
48
+ subject.hits["pages.read"].should == 1
49
49
 
50
- counter.hit "pages.read"
51
- counter.hits["pages.read"].should == 2
50
+ subject.hit "pages.read"
51
+ subject.hits["pages.read"].should == 2
52
52
  end
53
53
 
54
54
  it "should record a ping with key 'processor.alive'" do
55
55
  Timecop.freeze do
56
- counter.ping "processor.alive"
57
- counter.pings.should have_key("processor.alive")
58
- counter.pings["processor.alive"].strftime("%Y-%m-%d %H:%M:%S").should == Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
56
+ subject.ping "processor.alive"
57
+ subject.pings.should have_key("processor.alive")
58
+ subject.pings["processor.alive"].strftime("%Y-%m-%d %H:%M:%S").should == Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
59
59
  end
60
60
 
61
61
  target_time = Time.now + 9
62
62
  Timecop.travel(target_time) do
63
- counter.ping "processor.alive"
64
- counter.pings.should have_key("processor.alive")
65
- counter.pings["processor.alive"].strftime("%Y-%m-%d %H:%M:%S").should == target_time.utc.strftime("%Y-%m-%d %H:%M:%S")
63
+ subject.ping "processor.alive"
64
+ subject.pings.should have_key("processor.alive")
65
+ subject.pings["processor.alive"].strftime("%Y-%m-%d %H:%M:%S").should == target_time.utc.strftime("%Y-%m-%d %H:%M:%S")
66
66
  end
67
67
  end
68
68
 
69
69
  it "should record a latency with a passed value" do
70
- counter.latency "processor.enqueue", 0.00012
71
- counter.latencies["processor.enqueue"].should == [0.00012]
70
+ subject.latency "processor.enqueue", 0.00012
71
+ subject.latencies["processor.enqueue"].should == [0.00012]
72
72
 
73
- counter.latency "processor.enqueue", 0.00121
74
- counter.latencies["processor.enqueue"].should == [0.00012, 0.00121]
73
+ subject.latency "processor.enqueue", 0.00121
74
+ subject.latencies["processor.enqueue"].should == [0.00012, 0.00121]
75
75
  end
76
76
 
77
77
  it "should record a magnitude" do
78
- counter.magnitude "processor.bytes_compressed", 9_312
79
- counter.magnitude "processor.bytes_compressed", 8_271
80
- counter.magnitudes["processor.bytes_compressed"].should == 8_271
78
+ subject.magnitude "processor.bytes_compressed", 9_312
79
+ subject.magnitude "processor.bytes_compressed", 8_271
80
+ subject.magnitudes["processor.bytes_compressed"].should == 8_271
81
81
  end
82
82
  end
@@ -6,7 +6,7 @@ describe Counters::Redis, "integration tests" do
6
6
  ::Redis.new
7
7
  end
8
8
 
9
- let :counter do
9
+ subject do
10
10
  Counters::Redis.new(redis, :base_key => "counters")
11
11
  end
12
12
 
@@ -25,40 +25,40 @@ describe Counters::Redis, "integration tests" do
25
25
 
26
26
  context "given the counter is namespaced" do
27
27
  it "should namespace the key from #hit" do
28
- counter.namespace = "juice"
29
- counter.hit "foxglove"
28
+ subject.namespace = "juice"
29
+ subject.hit "foxglove"
30
30
  redis.hget("counters", "hits.juice.foxglove").should == "1"
31
31
  end
32
32
 
33
33
  it "should namespace the key from #latency" do
34
- counter.namespace = "cocktail"
35
- counter.latency "angelica", 200
34
+ subject.namespace = "cocktail"
35
+ subject.latency "angelica", 200
36
36
  redis.hget("counters", "latencies.cocktail.angelica.nanoseconds").should == (200 * Counters::Redis::SCALING_FACTOR).to_s
37
37
  end
38
38
 
39
39
  it "should namespace the key from #magnitude" do
40
- counter.namespace = "brew"
41
- counter.magnitude "crocus", 100
40
+ subject.namespace = "brew"
41
+ subject.magnitude "crocus", 100
42
42
  redis.hget("counters", "magnitudes.brew.crocus.value").should == "100"
43
43
  end
44
44
 
45
45
  it "should namespace the key from #ping" do
46
- counter.namespace = "beer"
46
+ subject.namespace = "beer"
47
47
  Timecop.freeze(Time.now.utc) do
48
- counter.ping "tulip"
48
+ subject.ping "tulip"
49
49
  redis.hget("counters", "pings.beer.tulip").should == Time.now.utc.to_i.to_s
50
50
  end
51
51
  end
52
52
  end
53
53
 
54
54
  it "should record 2 hits on 'pages.read'" do
55
- 2.times { counter.hit "pages.read" }
55
+ 2.times { subject.hit "pages.read" }
56
56
  redis.hkeys("counters").should == ["hits.pages.read"]
57
57
  redis.hget("counters", "hits.pages.read").to_i.should == 2
58
58
  end
59
59
 
60
60
  it "should record magnitude using a signed 64 bit 'value' and a 'count'" do
61
- 4.times { counter.magnitude "bytes.in", 2_047 }
61
+ 4.times { subject.magnitude "bytes.in", 2_047 }
62
62
  redis.hkeys("counters").sort.should == %w(magnitudes.bytes.in.value magnitudes.bytes.in.count).sort
63
63
 
64
64
  redis.hget("counters", "magnitudes.bytes.in.count").to_i.should == 4
@@ -66,8 +66,8 @@ describe Counters::Redis, "integration tests" do
66
66
  end
67
67
 
68
68
  it "does not detect 63 bit integer overflow" do
69
- counter.magnitude "bytes.in", 2**63 - 20
70
- counter.magnitude "bytes.in", 2_047
69
+ subject.magnitude "bytes.in", 2**63 - 20
70
+ subject.magnitude "bytes.in", 2_047
71
71
 
72
72
  target_value = (2**63 - 20) + 2_047
73
73
 
@@ -78,29 +78,29 @@ describe Counters::Redis, "integration tests" do
78
78
  it "should record a ping on 'crawler' by HSET counters/pings.crawler with today's date/time as an int" do
79
79
  now = Time.now
80
80
  Timecop.freeze(now) do
81
- counter.ping "crawler"
81
+ subject.ping "crawler"
82
82
  end
83
83
 
84
84
  redis.hget("counters", "pings.crawler").should == now.to_i.to_s
85
85
 
86
86
  target_time = Time.now + 9
87
87
  Timecop.travel(target_time) do
88
- counter.ping "crawler"
88
+ subject.ping "crawler"
89
89
  end
90
90
 
91
91
  redis.hget("counters", "pings.crawler").should == target_time.to_i.to_s
92
92
  end
93
93
 
94
94
  it "should record latency on 'crawler.download' by HINCRBY counters/latencies.crawler.download.count by 1 and counters/latencies.crawler.download.nanoseconds by the latency" do
95
- counter.latency "crawler.download", 1.9
96
- counter.latency "crawler.download", 2.02
95
+ subject.latency "crawler.download", 1.9
96
+ subject.latency "crawler.download", 2.02
97
97
 
98
98
  redis.hget("counters", "latencies.crawler.download.count").to_i.should == 2
99
99
  redis.hget("counters", "latencies.crawler.download.nanoseconds").to_i.should == (2.02 + 1.90) * ONE_NANOSECOND
100
100
  end
101
101
 
102
102
  it "should record a block's latency" do
103
- counter.latency "crawler.process" do
103
+ subject.latency "crawler.process" do
104
104
  sleep 0.2
105
105
  end
106
106
 
@@ -9,29 +9,29 @@ end
9
9
 
10
10
  shared_examples_for "all counters" do
11
11
  it "should raise a ArgumentError when the key includes invalid chars" do
12
- lambda { counter.hit "hit!" }.should raise_error(ArgumentError)
13
- lambda { counter.hit "hit counter" }.should raise_error(ArgumentError)
14
- lambda { counter.hit "boy.hit?" }.should raise_error(ArgumentError)
15
- lambda { counter.hit "hit/a" }.should raise_error(ArgumentError)
16
- lambda { counter.hit "hit-a" }.should raise_error(ArgumentError)
17
- lambda { counter.hit "" }.should raise_error(ArgumentError)
18
- lambda { counter.hit nil }.should raise_error(ArgumentError)
12
+ lambda { subject.hit "hit!" }.should raise_error(ArgumentError)
13
+ lambda { subject.hit "hit counter" }.should raise_error(ArgumentError)
14
+ lambda { subject.hit "boy.hit?" }.should raise_error(ArgumentError)
15
+ lambda { subject.hit "hit/a" }.should raise_error(ArgumentError)
16
+ lambda { subject.hit "hit-a" }.should raise_error(ArgumentError)
17
+ lambda { subject.hit "" }.should raise_error(ArgumentError)
18
+ lambda { subject.hit nil }.should raise_error(ArgumentError)
19
19
  end
20
20
 
21
21
  it "should not raise ArgumentError when the key includes a number" do
22
- lambda { counter.hit "hit1" }.should_not raise_error(ArgumentError)
22
+ lambda { subject.hit "hit1" }.should_not raise_error(ArgumentError)
23
23
  end
24
24
 
25
25
  it "should not raise ArgumentError when the key includes a dot / fullstop" do
26
- lambda { counter.hit "hit." }.should_not raise_error(ArgumentError)
26
+ lambda { subject.hit "hit." }.should_not raise_error(ArgumentError)
27
27
  end
28
28
 
29
29
  it "should not raise ArgumentError when the key includes an underscore" do
30
- lambda { counter.hit "hit_" }.should_not raise_error(ArgumentError)
30
+ lambda { subject.hit "hit_" }.should_not raise_error(ArgumentError)
31
31
  end
32
32
 
33
33
  it "should return the latency block's value" do
34
- value = counter.latency "process" do
34
+ value = subject.latency "process" do
35
35
  "the returned value"
36
36
  end
37
37
 
@@ -39,11 +39,32 @@ shared_examples_for "all counters" do
39
39
  end
40
40
 
41
41
  it "should allow hitting with a specific value increment" do
42
- lambda { counter.hit "tada", 17 }.should_not raise_error
42
+ lambda { subject.hit "tada", 17 }.should_not raise_error
43
43
  end
44
44
 
45
- it "should return a sub-namespaced counter on-demand" do
46
- other = counter.namespace("sub")
47
- other.namespace.should == "#{counter.namespace}.sub"
45
+ context "given a non-namespaced counter" do
46
+ before(:each) do
47
+ subject.namespace = nil
48
+ end
49
+
50
+ it "should return a sub-namespaced counter on-demand" do
51
+ subject.namespace.to_s.should be_empty
52
+
53
+ other = subject.namespace("sub")
54
+ other.namespace.should == "sub"
55
+ end
56
+ end
57
+
58
+ context "when the counter is namespaced" do
59
+ before(:each) do
60
+ subject.namespace = "origin"
61
+ end
62
+
63
+ it "should return a namespaced counter on-demand" do
64
+ subject.namespace.to_s.should_not be_empty
65
+
66
+ other = subject.namespace("sub")
67
+ other.namespace.should == "#{subject.namespace}.sub"
68
+ end
48
69
  end
49
70
  end
@@ -27,7 +27,7 @@ describe Counters::StatsD do
27
27
  8125
28
28
  end
29
29
 
30
- let :counter do
30
+ subject do
31
31
  Counters::StatsD.new(host, port, :socket => socket)
32
32
  end
33
33
 
@@ -41,22 +41,22 @@ describe Counters::StatsD do
41
41
 
42
42
  it "should record a hit as an increment of the key" do
43
43
  socket.should_receive(:send).with("hits.tweets_received:1|c", 0, host, port)
44
- counter.hit "tweets_received"
44
+ subject.hit "tweets_received"
45
45
  end
46
46
 
47
47
  it "should record a magnitude as a timer" do
48
48
  socket.should_receive(:send).with("magnitudes.bytes_in:381|ms", 0, host, port)
49
- counter.magnitude "bytes_in", 381
49
+ subject.magnitude "bytes_in", 381
50
50
  end
51
51
 
52
52
  it "should record a latency as a timer" do
53
53
  socket.should_receive(:send).with("latencies.json_parsing:9|ms", 0, host, port)
54
- counter.latency "json_parsing", 0.009
54
+ subject.latency "json_parsing", 0.009
55
55
  end
56
56
 
57
57
  it "should record a ping as a counter" do
58
58
  socket.should_receive(:send).with("pings.tweet_processor:1|c", 0, host, port)
59
- counter.ping "tweet_processor"
59
+ subject.ping "tweet_processor"
60
60
  end
61
61
 
62
62
  context "#initialize" do
@@ -68,33 +68,33 @@ describe Counters::StatsD do
68
68
 
69
69
  context "given the counter is namespaced" do
70
70
  it "should namespace the key from #hit" do
71
- counter.namespace = "juice"
71
+ subject.namespace = "juice"
72
72
  socket.should_receive(:send).with(/^hits\.juice\.foxglove\b/, anything, anything, anything)
73
- counter.hit "foxglove"
73
+ subject.hit "foxglove"
74
74
  end
75
75
 
76
76
  it "should namespace the key from #latency" do
77
- counter.namespace = "cocktail"
77
+ subject.namespace = "cocktail"
78
78
  socket.should_receive(:send).with(/^latencies\.cocktail\.angelica\b/, anything, anything, anything)
79
- counter.latency "angelica", 200
79
+ subject.latency "angelica", 200
80
80
  end
81
81
 
82
82
  it "should namespace the key from #magnitude" do
83
- counter.namespace = "brew"
83
+ subject.namespace = "brew"
84
84
  socket.should_receive(:send).with(/^magnitudes\.brew\.crocus\b/, anything, anything, anything)
85
- counter.magnitude "crocus", 100
85
+ subject.magnitude "crocus", 100
86
86
  end
87
87
 
88
88
  it "should namespace the key from #ping" do
89
- counter.namespace = "beer"
89
+ subject.namespace = "beer"
90
90
  socket.should_receive(:send).with(/^pings\.beer\.tulip\b/, anything, anything, anything)
91
- counter.ping "tulip"
91
+ subject.ping "tulip"
92
92
  end
93
93
 
94
94
  it "should increment with the #hit value" do
95
- counter.namespace = "pow"
95
+ subject.namespace = "pow"
96
96
  socket.should_receive(:send).with(/^hits\.pow\.loudness:17\b/, anything, anything, anything)
97
- counter.hit "loudness", 17
97
+ subject.hit "loudness", 17
98
98
  end
99
99
  end
100
100
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: counters
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.3.0
5
+ version: 1.3.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - "Fran\xC3\xA7ois Beausoleil"
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-01 00:00:00 -04:00
13
+ date: 2011-06-03 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency