metriks-addons 2.2.6 → 2.3.0

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,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.