metricize 0.4.5 → 0.4.6

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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- Yzk4NDUxZjlhZjY0YmQ1ZGI1NjEzYzQ1YmNmM2MyOGZlNjY4NWJmZg==
5
- data.tar.gz: !binary |-
6
- MmEyYTBiYjM4YmY4YzJlNTM3YjkxMGU4MDE1Y2M0YmFkMTJkNmI3OA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- NGJlNjNlNzM0NmNjZGE0YWY2MmRhYzllODAxOTljNTQyYWFmNWRjZTMzOGVh
10
- MDc2ZjMzZmJmNDc1YTRlMWRjMWFjNzdkZDExMjM0ODg4NmUwYjFhZTFhNDM2
11
- OWRiZTkyZmYxYjc0MTBlNGRkODUyZDkyMzU4NmM5MmVjYTVlOTU=
12
- data.tar.gz: !binary |-
13
- MmY5NmYwMWI0OGNlMTE4YTQ5YWY0NmUwYWI2YmYzMzM4ODk1MGU5ZGJjZDJh
14
- OTlkYjg0ODNhYjllMzA5OGJlMmI2ZmYyZGVlYzQzZTM2MzVhNGRmYTBlMGE2
15
- NTljNjU5OWQ2NDg2ODZiOTdmMGVjZTA2NGQwYzI5NjkxYjI1MDc=
2
+ SHA1:
3
+ metadata.gz: ba2d742a43d5df4f2744e1f9ee423097c953b947
4
+ data.tar.gz: 59f255649011baa295b25490ed3cd05dbdbab605
5
+ SHA512:
6
+ metadata.gz: 9131eb3bea2f4291c9578e2e7852ad330b80ecae486c1b91199164dfcd4b37ae4ff1c2dc5a8d13cd3922bd1a233ea4081ab11b77843af4c75c1b2ecd16b5b725
7
+ data.tar.gz: 3cefc14f6532f3d3f6dd00d070ffcb61983ca7efdcf7b99de445cc69121599f79c8c52019d5952f7ad7d8630424161c37ac8c3aebaf84c234305f6055708f2e0
@@ -11,4 +11,4 @@ require "metricize/shared"
11
11
  require "metricize/forwarder"
12
12
  require "metricize/client"
13
13
  require "metricize/stats"
14
- require "metricize/null_client"
14
+ require "metricize/null_objects"
@@ -4,6 +4,7 @@ module Metricize
4
4
 
5
5
  def initialize(options = {})
6
6
  @prefix = options[:prefix]
7
+ @sampling_ratio = options[:sampling_ratio] || 0.10
7
8
  establish_logger(options)
8
9
  initialize_redis(options)
9
10
  establish_redis_connection
@@ -39,10 +40,13 @@ module Metricize
39
40
 
40
41
  def push_to_queue(name, value, options)
41
42
  data = prepare_metric(name, value, options).to_json
42
- @redis.lpush(@queue_name, data)
43
+ with_error_handling do
44
+ @redis.lpush(@queue_name, data)
45
+ end
46
+ return unless rand < @sampling_ratio
43
47
  msg = "#{name.gsub('.', '_')}=#{value}" # splunk chokes on dots in field names
44
48
  msg << ", metric_source=#{options[:source].gsub('.', '_')}" if options[:source]
45
- log_message msg
49
+ log_message msg, :info
46
50
  end
47
51
 
48
52
  def build_metric_name(name)
@@ -19,12 +19,12 @@ module Metricize
19
19
  private
20
20
 
21
21
  def process_metric_queue
22
- queue = retrieve_queue_contents
23
- return if queue.empty?
24
- store_metrics(add_aggregate_info(queue))
25
- clear_queue
26
- rescue RuntimeError => e
27
- log_message "Error: " + e.message, :error
22
+ with_error_handling do
23
+ queue = retrieve_queue_contents
24
+ return if queue.empty?
25
+ store_metrics(add_aggregate_info(queue))
26
+ clear_queue
27
+ end
28
28
  end
29
29
 
30
30
  def retrieve_queue_contents
@@ -81,7 +81,9 @@ module Metricize
81
81
  value_groups[key] << metric[:value]
82
82
  end
83
83
  value_groups.each do |key, values|
84
- print_histogram(key, values)
84
+ with_error_handling do
85
+ print_histogram(key, values)
86
+ end
85
87
  gauges << add_stat_by_key(key, values.size, '.count').merge(counter_attributes)
86
88
  gauges << add_stat_by_key(key, values.max, ".max")
87
89
  gauges << add_stat_by_key(key, values.min, ".min")
@@ -118,8 +120,6 @@ module Metricize
118
120
  "#{name}.mean=#{round(values.mean, 2)}\n" +
119
121
  "#{name}.stddev=#{round(values.standard_deviation, 2)}\n"
120
122
  log_message(chart_output, :info)
121
- rescue => e
122
- log_message("#{e}: Could not print histogram for #{name} with these input values: #{values.inspect}", :error)
123
123
  end
124
124
 
125
125
  def add_stat_by_key(key, value, suffix = "")
@@ -129,12 +129,5 @@ module Metricize
129
129
  metric
130
130
  end
131
131
 
132
- def calculate_percentile(values, percentile)
133
- return values.first if values.size == 1
134
- values_sorted = values.sort
135
- k = (percentile*(values_sorted.length-1)+1).floor - 1
136
- values_sorted[k]
137
- end
138
-
139
132
  end
140
133
  end
@@ -3,8 +3,10 @@ module Metricize
3
3
 
4
4
  def establish_redis_connection
5
5
  log_message "metricize_version=#{VERSION} connecting to Redis at #{@queue_host}:#{@queue_port}", :info
6
- @redis = Redis.connect(:host => @queue_host, :port => @queue_port)
7
- @redis.ping
6
+ with_error_handling do
7
+ @redis = Redis.connect(:host => @queue_host, :port => @queue_port)
8
+ @redis.ping
9
+ end
8
10
  end
9
11
 
10
12
  private
@@ -33,6 +35,12 @@ module Metricize
33
35
  ((value * factor).round) / factor
34
36
  end
35
37
 
38
+ def with_error_handling
39
+ yield
40
+ rescue StandardError => e
41
+ log_message %Q(#{e.class}:#{e.message}\n#{e.backtrace.join("\n")}), :error
42
+ end
43
+
36
44
  end
37
45
  end
38
46
 
@@ -1,3 +1,3 @@
1
1
  module Metricize
2
- VERSION = "0.4.5"
2
+ VERSION = "0.4.6"
3
3
  end
@@ -1,5 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
+ class TestError < StandardError; end
4
+
3
5
  describe Metricize do
4
6
  let(:logger) { double.as_null_object }
5
7
  let(:forwarder) { Metricize::Forwarder.new( :password => 'api_key',
@@ -120,6 +122,13 @@ describe Metricize do
120
122
  forwarder.go!
121
123
  end
122
124
 
125
+ it "logs in splunk format a sampling of metrics" do
126
+ logger.should_receive(:info).with(/prefix_value1=10.0/m).at_least(5).times
127
+ 100.times { client.measure('value1', 10) }
128
+ logger.should_receive(:info).with(/prefix_value2=20.0/m).at_most(20).times
129
+ 100.times { client.measure('value2', 20) }
130
+ end
131
+
123
132
  it "raises an error when measure is called without a numeric value" do
124
133
  expect { client.measure('boom', {}) }.to raise_error(ArgumentError, /no numeric value provided in measure call/)
125
134
  expect { client.measure('boom', 'NaN') }.to raise_error(ArgumentError, /no numeric value provided in measure call/)
@@ -234,11 +243,23 @@ describe Metricize do
234
243
  forwarder.go!
235
244
  end
236
245
 
237
- it "retries sending if it encounters an error" do
246
+ it "rescues and logs redis errors in client" do
247
+ Redis.any_instance.stub(:lpush).and_raise(TestError)
248
+ logger.should_receive(:error).with(/Client.*TestError/)
238
249
  client.increment('counter1')
239
- RestClient.stub(:post).and_raise(RestClient::Exception)
250
+ end
251
+
252
+ it "rescues and logs redis errors in forwarder" do
253
+ client.increment('counter1')
254
+ Redis.any_instance.stub(:lrange).and_raise(TestError)
255
+ logger.should_receive(:error).with(/Forwarder.*TestError/)
240
256
  forwarder.go!
241
- RestClient.should_receive(:post)
257
+ end
258
+
259
+ it "rescues and logs errors when printing histograms" do
260
+ 10.times { client.measure('value1', 1.0) }
261
+ AsciiCharts::Cartesian.any_instance.stub(:draw).and_raise(TestError)
262
+ logger.should_receive(:error).with(/Forwarder.*TestError/)
242
263
  forwarder.go!
243
264
  end
244
265
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metricize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt McNeil
@@ -11,145 +11,145 @@ cert_chain: []
11
11
  date: 2013-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- prerelease: false
15
14
  name: bundler
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ~>
19
- - !ruby/object:Gem::Version
20
- version: '1.3'
21
15
  requirement: !ruby/object:Gem::Requirement
22
16
  requirements:
23
17
  - - ~>
24
18
  - !ruby/object:Gem::Version
25
19
  version: '1.3'
26
20
  type: :development
27
- - !ruby/object:Gem::Dependency
28
21
  prerelease: false
29
- name: rake
30
22
  version_requirements: !ruby/object:Gem::Requirement
31
23
  requirements:
32
- - - ! '>='
24
+ - - ~>
33
25
  - !ruby/object:Gem::Version
34
- version: '0'
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - ! '>='
31
+ - - '>='
38
32
  - !ruby/object:Gem::Version
39
33
  version: '0'
40
34
  type: :development
41
- - !ruby/object:Gem::Dependency
42
35
  prerelease: false
43
- name: rspec
44
36
  version_requirements: !ruby/object:Gem::Requirement
45
37
  requirements:
46
- - - ! '>='
38
+ - - '>='
47
39
  - !ruby/object:Gem::Version
48
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
49
43
  requirement: !ruby/object:Gem::Requirement
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
- - !ruby/object:Gem::Dependency
56
49
  prerelease: false
57
- name: timecop
58
50
  version_requirements: !ruby/object:Gem::Requirement
59
51
  requirements:
60
- - - ! '>='
52
+ - - '>='
61
53
  - !ruby/object:Gem::Version
62
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: timecop
63
57
  requirement: !ruby/object:Gem::Requirement
64
58
  requirements:
65
- - - ! '>='
59
+ - - '>='
66
60
  - !ruby/object:Gem::Version
67
61
  version: '0'
68
62
  type: :development
69
- - !ruby/object:Gem::Dependency
70
63
  prerelease: false
71
- name: fakeredis
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
65
  requirements:
74
- - - ! '>='
66
+ - - '>='
75
67
  - !ruby/object:Gem::Version
76
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: fakeredis
77
71
  requirement: !ruby/object:Gem::Requirement
78
72
  requirements:
79
- - - ! '>='
73
+ - - '>='
80
74
  - !ruby/object:Gem::Version
81
75
  version: '0'
82
76
  type: :development
83
- - !ruby/object:Gem::Dependency
84
77
  prerelease: false
85
- name: simplecov
86
78
  version_requirements: !ruby/object:Gem::Requirement
87
79
  requirements:
88
- - - ! '>='
80
+ - - '>='
89
81
  - !ruby/object:Gem::Version
90
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
91
85
  requirement: !ruby/object:Gem::Requirement
92
86
  requirements:
93
- - - ! '>='
87
+ - - '>='
94
88
  - !ruby/object:Gem::Version
95
89
  version: '0'
96
90
  type: :development
97
- - !ruby/object:Gem::Dependency
98
91
  prerelease: false
99
- name: rest-client
100
92
  version_requirements: !ruby/object:Gem::Requirement
101
93
  requirements:
102
- - - ! '>='
94
+ - - '>='
103
95
  - !ruby/object:Gem::Version
104
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rest-client
105
99
  requirement: !ruby/object:Gem::Requirement
106
100
  requirements:
107
- - - ! '>='
101
+ - - '>='
108
102
  - !ruby/object:Gem::Version
109
103
  version: '0'
110
104
  type: :runtime
111
- - !ruby/object:Gem::Dependency
112
105
  prerelease: false
113
- name: json
114
106
  version_requirements: !ruby/object:Gem::Requirement
115
107
  requirements:
116
- - - ! '>='
108
+ - - '>='
117
109
  - !ruby/object:Gem::Version
118
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: json
119
113
  requirement: !ruby/object:Gem::Requirement
120
114
  requirements:
121
- - - ! '>='
115
+ - - '>='
122
116
  - !ruby/object:Gem::Version
123
117
  version: '0'
124
118
  type: :runtime
125
- - !ruby/object:Gem::Dependency
126
119
  prerelease: false
127
- name: redis
128
120
  version_requirements: !ruby/object:Gem::Requirement
129
121
  requirements:
130
- - - ! '>='
122
+ - - '>='
131
123
  - !ruby/object:Gem::Version
132
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: redis
133
127
  requirement: !ruby/object:Gem::Requirement
134
128
  requirements:
135
- - - ! '>='
129
+ - - '>='
136
130
  - !ruby/object:Gem::Version
137
131
  version: '0'
138
132
  type: :runtime
139
- - !ruby/object:Gem::Dependency
140
133
  prerelease: false
141
- name: ascii_charts
142
134
  version_requirements: !ruby/object:Gem::Requirement
143
135
  requirements:
144
- - - ! '>='
136
+ - - '>='
145
137
  - !ruby/object:Gem::Version
146
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: ascii_charts
147
141
  requirement: !ruby/object:Gem::Requirement
148
142
  requirements:
149
- - - ! '>='
143
+ - - '>='
150
144
  - !ruby/object:Gem::Version
151
145
  version: '0'
152
146
  type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
153
  description: Simple client/forwarder system to aggregate metrics and periodically
154
154
  send them to a stats service
155
155
  email:
@@ -166,7 +166,7 @@ files:
166
166
  - lib/metricize.rb
167
167
  - lib/metricize/client.rb
168
168
  - lib/metricize/forwarder.rb
169
- - lib/metricize/null_client.rb
169
+ - lib/metricize/null_objects.rb
170
170
  - lib/metricize/shared.rb
171
171
  - lib/metricize/stats.rb
172
172
  - lib/metricize/version.rb
@@ -183,12 +183,12 @@ require_paths:
183
183
  - lib
184
184
  required_ruby_version: !ruby/object:Gem::Requirement
185
185
  requirements:
186
- - - ! '>='
186
+ - - '>='
187
187
  - !ruby/object:Gem::Version
188
188
  version: '0'
189
189
  required_rubygems_version: !ruby/object:Gem::Requirement
190
190
  requirements:
191
- - - ! '>='
191
+ - - '>='
192
192
  - !ruby/object:Gem::Version
193
193
  version: '0'
194
194
  requirements: []