metriks-addons 2.2.6 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dd102e75443cab2b7a78f801e4fde90b2f552f0f
4
- data.tar.gz: e9b7d5e7b293635bc2e5c76048a9ecfd4cbae071
3
+ metadata.gz: ea2d1d23539d5721da6b13d7435000a6d183457d
4
+ data.tar.gz: d4df482e5faaa8c98e979b65cf8919589173d45a
5
5
  SHA512:
6
- metadata.gz: c367fd4cb118869b008d56ca2692e49fe94f7b1f72975816089830eb568644b7182ebb1ddb1aa680105a28f7710f727f8e9c56add8688fd3187a8147ec0969ba
7
- data.tar.gz: d62f4f8cf83172369e1d823f3290a71f9d7b54a11f9fd3026b6c47fac4302e9b2f29ebb5b25ff44ba11e12677bc303e6e2f7fe90ebe23e3ca9e9dcb28f62c57e
6
+ metadata.gz: dea3f88202c6b82dc2b3657000b8ce22770e82ef401f5c4b8a06a6617c6ba4ead6ce1a69e4f9e81fd7f3e6790618864b9ea068df1753c84d77c0b2471929960b
7
+ data.tar.gz: f2166eead807181eee4e6c9c5642344581b0f0711bea89cf4871df4486993461c3eeb6fc408fdb9fd0eb5e86d684de6fa6214a68e0bf8b30554159c6df91f369
data/Gemfile CHANGED
@@ -8,3 +8,4 @@ group :test do
8
8
  end
9
9
 
10
10
  gem "rest-client"
11
+ gem 'aws-sdk', '1.40.3'
@@ -1,6 +1,7 @@
1
1
  require 'metriks/opentsdb_reporter'
2
2
  require 'metriks/signalfx_reporter'
3
+ require 'metriks/cloudwatch_reporter'
3
4
 
4
5
  module MetriksAddons
5
- VERSION = '2.2.4'
6
+ VERSION = '2.3.0'
6
7
  end
@@ -0,0 +1,195 @@
1
+ require 'metriks/time_tracker'
2
+ require 'logger'
3
+ require 'aws'
4
+ require 'time'
5
+
6
+ module Metriks
7
+ class CloudWatchReporter
8
+ attr_accessor :prefix, :source, :cw, :tags, :logger
9
+
10
+ def initialize(access_key, secret_key, namespace, tags, options = {})
11
+ @cw = AWS::CloudWatch.new(:access_key_id => access_key, :secret_access_key => secret_key)
12
+ @namespace = namespace
13
+ @dimensions = get_dimensions(tags)
14
+
15
+ @prefix = options[:prefix]
16
+ @source = options[:source]
17
+
18
+ @logger = options[:logger] || nil
19
+ @batch_size = options[:batch_size] || 50
20
+ @registry = options[:registry] || Metriks::Registry.default
21
+ @interval = options[:interval] || 60
22
+ @time_tracker = Metriks::TimeTracker.new(@interval)
23
+ @on_error = options[:on_error] || proc { |ex| }
24
+
25
+ if options[:percentiles]
26
+ @percentiles = options[:percentiles]
27
+ else
28
+ @percentiles = [ 0.95, 0.99]
29
+ end
30
+
31
+ @mutex = Mutex.new
32
+ @running = false
33
+ end
34
+
35
+ def log(level, msg)
36
+ if !@logger.nil?
37
+ @logger.send level, msg
38
+ end
39
+ end
40
+
41
+ def start
42
+ if @thread && @thread.alive?
43
+ return
44
+ end
45
+
46
+ @running = true
47
+ @thread = Thread.new do
48
+ while @running
49
+ @time_tracker.sleep
50
+
51
+ Thread.new do
52
+ flush
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def stop
59
+ @running = false
60
+
61
+ if @thread
62
+ @thread.join
63
+ @thread = nil
64
+ end
65
+ end
66
+
67
+ def restart
68
+ stop
69
+ start
70
+ end
71
+
72
+ def flush
73
+ begin
74
+ @mutex.synchronize do
75
+ log "debug", "Flushing metrics"
76
+ submit get_datapoints
77
+ end
78
+ rescue Exception => ex
79
+ log "error",ex.message
80
+ @on_error[ex] rescue nil
81
+ end
82
+ end
83
+
84
+ def submit(datapoints)
85
+ return if datapoints.empty?
86
+ datapoints.each do |datapoint|
87
+ response = @cw.put_metric_data({:namespace => @namespace, :metric_data => [datapoint]})
88
+ end
89
+ log "info", "Sent #{datapoints.size} metrics to CloudWatch"
90
+ end
91
+
92
+ def get_datapoints
93
+ time = Time.at(@time_tracker.now_floored).iso8601
94
+
95
+ datapoints = []
96
+ @registry.each do |name, metric|
97
+ next if name.nil? || name.empty?
98
+ name = name.to_s.gsub(/ +/, '_')
99
+ if @prefix
100
+ name = "#{@prefix}.#{name}"
101
+ end
102
+
103
+ case metric
104
+ when Metriks::Meter
105
+ datapoints |= create_datapoints name, metric, time, [
106
+ :count, :one_minute_rate, :five_minute_rate,
107
+ :fifteen_minute_rate, :mean_rate
108
+ ], [
109
+ 'Count', 'Count/Second', 'Count/Second',
110
+ 'Count/Second', 'Count/Second'
111
+ ]
112
+ when Metriks::Counter
113
+ datapoints |= create_datapoints name, metric, time, [
114
+ :count
115
+ ], [
116
+ 'Count'
117
+ ]
118
+ when Metriks::Gauge
119
+ datapoints |= create_datapoints name, metric, time, [
120
+ :value
121
+ ], [
122
+ 'Count'
123
+ ]
124
+ when Metriks::Timer
125
+ datapoints |= create_datapoints name, metric, time, [
126
+ :count, :one_minute_rate, :five_minute_rate,
127
+ :fifteen_minute_rate, :mean_rate,
128
+ :min, :max, :mean, :stddev
129
+ ], [
130
+ 'Count', 'Count/Second', 'Count/Second',
131
+ 'Count/Second', 'Count/Second',
132
+ 'Seconds', 'Seconds', 'Seconds', 'Seconds'
133
+ ], [
134
+ :median, :get_95th_percentile
135
+ ], [
136
+ 'Seconds', 'Seconds'
137
+ ]
138
+ when Metriks::Histogram
139
+ datapoints |= create_datapoints name, metric, time, [
140
+ :count, :min, :max, :mean, :stddev
141
+ ], [
142
+ 'Count', 'Count', 'Count', 'Count',
143
+ 'Count'
144
+ ], [
145
+ :median, :get_95th_percentile
146
+ ], [
147
+ 'Count', 'Count'
148
+ ]
149
+ end
150
+ end
151
+ datapoints
152
+ end
153
+
154
+ def create_datapoints(base_name, metric, time, keys, keys_unit, snapshot_keys = [], snapshot_keys_unit = [])
155
+ datapoints = []
156
+
157
+ keys.flatten.zip(keys_unit.flatten).each do |key, key_unit|
158
+ name = key.to_s.gsub(/^get_/, '')
159
+ datapoints << {
160
+ :metric_name => "#{base_name}.#{name}",
161
+ :timestamp => time,
162
+ :value => metric.send(key),
163
+ :dimensions => @dimensions,
164
+ :unit => key_unit
165
+ }
166
+ end
167
+
168
+ unless snapshot_keys.empty?
169
+ snapshot = metric.snapshot
170
+ snapshot_keys.flatten.zip(snapshot_keys_unit.flatten).each do |key, key_unit|
171
+ name = key.to_s.gsub(/^get_/, '')
172
+ datapoints << {
173
+ :metric_name => "#{base_name}.#{name}",
174
+ :timestamp => time,
175
+ :value => snapshot.send(key),
176
+ :dimensions => @dimensions,
177
+ :unit => key_unit
178
+ }
179
+ end
180
+ end
181
+ datapoints
182
+ end
183
+
184
+ def get_dimensions(tags)
185
+ dimensions =[]
186
+ tags.each do |name, value|
187
+ dimensions << {
188
+ :name => "#{name}",
189
+ :value => value
190
+ }
191
+ end
192
+ dimensions
193
+ end
194
+ end
195
+ end
@@ -91,15 +91,14 @@ module Metriks
91
91
 
92
92
  def submit(datapoints)
93
93
  return if datapoints.empty?
94
-
95
- log "info", "Datapoints: #{datapoints}"
94
+
96
95
  jsonstr = datapoints.to_json
97
- log "info", "Json for SignalFx: #{jsonstr}"
96
+ log "debug", "Json for SignalFx: #{jsonstr}"
98
97
  response = RestClient.post "#{@hostname}?orgid=#{@orgid}",
99
98
  jsonstr,
100
99
  :content_type => :json, :accept => :json, :'X-SF-TOKEN' => @x_sf_token
101
100
  log "info", "Sent #{datapoints.size} metrics to SignalFX"
102
- log "info", "Response is: #{response}"
101
+ log "debug", "Response is: #{response}"
103
102
  end
104
103
 
105
104
  def get_datapoints
@@ -108,7 +107,7 @@ module Metriks
108
107
  datapoints = {}
109
108
  counter = []
110
109
  gauge = []
111
- log "info", "Resgistry: #{@registry}"
110
+ log "debug", "Resgistry: #{@registry}"
112
111
  @registry.each do |name, metric|
113
112
  next if name.nil? || name.empty?
114
113
  name = name.to_s.gsub(/ +/, '_')
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'metriks-addons'
16
- s.version = '2.2.6'
17
- s.date = '2015-09-24'
16
+ s.version = '2.3.0'
17
+ s.date = '2015-10-04'
18
18
 
19
19
  ## Make sure your summary is short. The description may be as long
20
20
  ## as you like.
@@ -63,9 +63,11 @@ Gem::Specification.new do |s|
63
63
  README.md
64
64
  Rakefile
65
65
  lib/metriks-addons.rb
66
+ lib/metriks/cloudwatch_reporter.rb
66
67
  lib/metriks/opentsdb_reporter.rb
67
68
  lib/metriks/signalfx_reporter.rb
68
69
  metriks-addons.gemspec
70
+ spec/cloudwatch_spec.rb
69
71
  spec/opentsdb_spec.rb
70
72
  spec/signalfx_spec.rb
71
73
  ]
@@ -0,0 +1,197 @@
1
+ require 'webmock/rspec'
2
+ require 'metriks'
3
+ require 'metriks/cloudwatch_reporter'
4
+
5
+ describe "Smoke test" do
6
+ before(:each) do
7
+ AWS::CloudWatch.any_instance.stub(:put_metric_data)
8
+ @registry = Metriks::Registry.new
9
+ @reporter = Metriks::CloudWatchReporter.new(
10
+ 'DummyDummyDummyDummy',
11
+ "DummyDummyDummyDummyDummyDummyDummyDummy",
12
+ "testingtier",
13
+ {:env =>"test"},
14
+ { :registry => @registry, :batch_size => 3})
15
+ end
16
+
17
+ after(:each) do
18
+ @reporter.stop
19
+ @registry.stop
20
+ end
21
+
22
+ it "meter" do
23
+ @registry.meter('meter.testing').mark
24
+ datapoints = @reporter.get_datapoints
25
+ expect(datapoints.size).to eql(5)
26
+ expect(datapoints[0][:metric_name]).to eql("meter.testing.count")
27
+ expect(datapoints[0][:value]).to eql(1)
28
+ expect(datapoints[0][:dimensions]).to include({:name => "env", :value => "test"})
29
+ expect(datapoints[0][:timestamp]).not_to be_nil
30
+ expect(datapoints[0][:unit]).to eql('Count')
31
+
32
+ expect(datapoints[1][:metric_name]).to eql("meter.testing.one_minute_rate")
33
+ expect(datapoints[1][:value]).not_to be_nil
34
+ expect(datapoints[1][:dimensions]).to include({:name => "env", :value => "test"})
35
+ expect(datapoints[1][:timestamp]).not_to be_nil
36
+ expect(datapoints[1][:unit]).to eql('Count/Second')
37
+
38
+ expect(datapoints[2][:metric_name]).to eql("meter.testing.five_minute_rate")
39
+ expect(datapoints[2][:value]).to eql(0.0)
40
+ expect(datapoints[2][:dimensions]).to include({:name => "env", :value => "test"})
41
+ expect(datapoints[2][:timestamp]).not_to be_nil
42
+ expect(datapoints[2][:unit]).to eql('Count/Second')
43
+
44
+ expect(datapoints[3][:metric_name]).to eql("meter.testing.fifteen_minute_rate")
45
+ expect(datapoints[3][:value]).to eql(0.0)
46
+ expect(datapoints[3][:dimensions]).to include({:name => "env", :value => "test"})
47
+ expect(datapoints[3][:timestamp]).not_to be_nil
48
+ expect(datapoints[3][:unit]).to eql('Count/Second')
49
+
50
+ expect(datapoints[4][:metric_name]).to eql("meter.testing.mean_rate")
51
+ expect(datapoints[4][:value]).not_to be_nil
52
+ expect(datapoints[4][:dimensions]).to include({:name => "env", :value => "test"})
53
+ expect(datapoints[4][:timestamp]).not_to be_nil
54
+ expect(datapoints[4][:unit]).to eql('Count/Second')
55
+ end
56
+
57
+ it "counter" do
58
+ @registry.counter('counter.testing').increment
59
+ datapoints = @reporter.get_datapoints
60
+ expect(datapoints.size).to eql(1)
61
+ expect(datapoints[0][:metric_name]).to eql("counter.testing.count")
62
+ expect(datapoints[0][:value]).to eql(1)
63
+ expect(datapoints[0][:dimensions]).to include({:name => "env", :value => "test"})
64
+ expect(datapoints[0][:timestamp]).not_to be_nil
65
+ expect(datapoints[0][:unit]).to eql('Count')
66
+ end
67
+
68
+ it "timer" do
69
+ @registry.timer('timer.testing').update(1.5)
70
+ datapoints = @reporter.get_datapoints
71
+ expect(datapoints.size).to eql(11)
72
+ expect(datapoints[0][:metric_name]).to eql("timer.testing.count")
73
+ expect(datapoints[0][:value]).to eql(1)
74
+ expect(datapoints[0][:dimensions]).to include({:name => "env", :value => "test"})
75
+ expect(datapoints[0][:timestamp]).not_to be_nil
76
+ expect(datapoints[0][:unit]).to eql('Count')
77
+
78
+ expect(datapoints[1][:metric_name]).to eql("timer.testing.one_minute_rate")
79
+ expect(datapoints[1][:value]).not_to be_nil
80
+ expect(datapoints[1][:dimensions]).to include({:name => "env", :value => "test"})
81
+ expect(datapoints[1][:timestamp]).not_to be_nil
82
+ expect(datapoints[1][:unit]).to eql('Count/Second')
83
+
84
+ expect(datapoints[2][:metric_name]).to eql("timer.testing.five_minute_rate")
85
+ expect(datapoints[2][:value]).to eql(0.0)
86
+ expect(datapoints[2][:dimensions]).to include({:name => "env", :value => "test"})
87
+ expect(datapoints[2][:timestamp]).not_to be_nil
88
+ expect(datapoints[2][:unit]).to eql('Count/Second')
89
+
90
+ expect(datapoints[3][:metric_name]).to eql("timer.testing.fifteen_minute_rate")
91
+ expect(datapoints[3][:value]).to eql(0.0)
92
+ expect(datapoints[3][:dimensions]).to include({:name => "env", :value => "test"})
93
+ expect(datapoints[3][:timestamp]).not_to be_nil
94
+ expect(datapoints[3][:unit]).to eql('Count/Second')
95
+
96
+ expect(datapoints[4][:metric_name]).to eql("timer.testing.mean_rate")
97
+ expect(datapoints[4][:value]).not_to be_nil
98
+ expect(datapoints[4][:dimensions]).to include({:name => "env", :value => "test"})
99
+ expect(datapoints[4][:timestamp]).not_to be_nil
100
+ expect(datapoints[4][:unit]).to eql('Count/Second')
101
+
102
+ expect(datapoints[5][:metric_name]).to eql("timer.testing.min")
103
+ expect(datapoints[5][:value]).not_to be_nil
104
+ expect(datapoints[5][:dimensions]).to include({:name => "env", :value => "test"})
105
+ expect(datapoints[5][:timestamp]).not_to be_nil
106
+ expect(datapoints[5][:unit]).to eql('Seconds')
107
+
108
+ expect(datapoints[6][:metric_name]).to eql("timer.testing.max")
109
+ expect(datapoints[6][:value]).not_to be_nil
110
+ expect(datapoints[6][:dimensions]).to include({:name => "env", :value => "test"})
111
+ expect(datapoints[6][:timestamp]).not_to be_nil
112
+ expect(datapoints[6][:unit]).to eql('Seconds')
113
+
114
+ expect(datapoints[7][:metric_name]).to eql("timer.testing.mean")
115
+ expect(datapoints[7][:value]).not_to be_nil
116
+ expect(datapoints[7][:dimensions]).to include({:name => "env", :value => "test"})
117
+ expect(datapoints[7][:timestamp]).not_to be_nil
118
+ expect(datapoints[7][:unit]).to eql('Seconds')
119
+
120
+ expect(datapoints[8][:metric_name]).to eql("timer.testing.stddev")
121
+ expect(datapoints[8][:value]).not_to be_nil
122
+ expect(datapoints[8][:dimensions]).to include({:name => "env", :value => "test"})
123
+ expect(datapoints[8][:timestamp]).not_to be_nil
124
+ expect(datapoints[8][:unit]).to eql('Seconds')
125
+
126
+ expect(datapoints[9][:metric_name]).to eql("timer.testing.median")
127
+ expect(datapoints[9][:value]).not_to be_nil
128
+ expect(datapoints[9][:dimensions]).to include({:name => "env", :value => "test"})
129
+ expect(datapoints[9][:timestamp]).not_to be_nil
130
+ expect(datapoints[9][:unit]).to eql('Seconds')
131
+
132
+ expect(datapoints[10][:metric_name]).to eql("timer.testing.95th_percentile")
133
+ expect(datapoints[10][:value]).not_to be_nil
134
+ expect(datapoints[10][:dimensions]).to include({:name => "env", :value => "test"})
135
+ expect(datapoints[10][:timestamp]).not_to be_nil
136
+ expect(datapoints[10][:unit]).to eql('Seconds')
137
+ end
138
+
139
+ it "histogram" do
140
+ @registry.histogram('histogram.testing').update(1.5)
141
+ datapoints = @reporter.get_datapoints
142
+ expect(datapoints.size).to eql(7)
143
+ expect(datapoints[0][:metric_name]).to eql("histogram.testing.count")
144
+ expect(datapoints[0][:value]).to eql(1)
145
+ expect(datapoints[0][:dimensions]).to include({:name => "env", :value => "test"})
146
+ expect(datapoints[0][:timestamp]).not_to be_nil
147
+ expect(datapoints[0][:unit]).to eql('Count')
148
+
149
+ expect(datapoints[1][:metric_name]).to eql("histogram.testing.min")
150
+ expect(datapoints[1][:value]).not_to be_nil
151
+ expect(datapoints[1][:dimensions]).to include({:name => "env", :value => "test"})
152
+ expect(datapoints[1][:timestamp]).not_to be_nil
153
+ expect(datapoints[1][:unit]).to eql('Count')
154
+
155
+ expect(datapoints[2][:metric_name]).to eql("histogram.testing.max")
156
+ expect(datapoints[2][:value]).not_to be_nil
157
+ expect(datapoints[2][:dimensions]).to include({:name => "env", :value => "test"})
158
+ expect(datapoints[2][:timestamp]).not_to be_nil
159
+ expect(datapoints[2][:unit]).to eql('Count')
160
+
161
+ expect(datapoints[3][:metric_name]).to eql("histogram.testing.mean")
162
+ expect(datapoints[3][:value]).not_to be_nil
163
+ expect(datapoints[3][:dimensions]).to include({:name => "env", :value => "test"})
164
+ expect(datapoints[3][:timestamp]).not_to be_nil
165
+ expect(datapoints[3][:unit]).to eql('Count')
166
+
167
+ expect(datapoints[4][:metric_name]).to eql("histogram.testing.stddev")
168
+ expect(datapoints[4][:value]).not_to be_nil
169
+ expect(datapoints[4][:dimensions]).to include({:name => "env", :value => "test"})
170
+ expect(datapoints[4][:timestamp]).not_to be_nil
171
+ expect(datapoints[4][:unit]).to eql('Count')
172
+
173
+ expect(datapoints[5][:metric_name]).to eql("histogram.testing.median")
174
+ expect(datapoints[5][:value]).not_to be_nil
175
+ expect(datapoints[5][:dimensions]).to include({:name => "env", :value => "test"})
176
+ expect(datapoints[5][:timestamp]).not_to be_nil
177
+ expect(datapoints[5][:unit]).to eql('Count')
178
+
179
+ expect(datapoints[6][:metric_name]).to eql("histogram.testing.95th_percentile")
180
+ expect(datapoints[6][:value]).not_to be_nil
181
+ expect(datapoints[6][:dimensions]).to include({:name => "env", :value => "test"})
182
+ expect(datapoints[6][:timestamp]).not_to be_nil
183
+ expect(datapoints[6][:unit]).to eql('Count')
184
+ end
185
+
186
+ it "gauge" do
187
+ @registry.gauge('gauge.testing') { 123 }
188
+ datapoints = @reporter.get_datapoints
189
+ expect(datapoints.size).to eql(1)
190
+ expect(datapoints[0][:metric_name]).to eql("gauge.testing.value")
191
+ expect(datapoints[0][:value]).to eql(123)
192
+ expect(datapoints[0][:dimensions]).to include({:name => "env", :value => "test"})
193
+ expect(datapoints[0][:timestamp]).not_to be_nil
194
+ expect(datapoints[0][:unit]).to eql('Count')
195
+ end
196
+ end
197
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metriks-addons
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.6
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rajat Venkatesh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-24 00:00:00.000000000 Z
11
+ date: 2015-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: metriks
@@ -71,9 +71,11 @@ files:
71
71
  - README.md
72
72
  - Rakefile
73
73
  - lib/metriks-addons.rb
74
+ - lib/metriks/cloudwatch_reporter.rb
74
75
  - lib/metriks/opentsdb_reporter.rb
75
76
  - lib/metriks/signalfx_reporter.rb
76
77
  - metriks-addons.gemspec
78
+ - spec/cloudwatch_spec.rb
77
79
  - spec/opentsdb_spec.rb
78
80
  - spec/signalfx_spec.rb
79
81
  homepage: https://github.com/vrajat/metriks-addons
@@ -96,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
98
  version: '0'
97
99
  requirements: []
98
100
  rubyforge_project:
99
- rubygems_version: 2.2.2
101
+ rubygems_version: 2.4.5
100
102
  signing_key:
101
103
  specification_version: 2
102
104
  summary: Reporters for Metriks.