heroku-vector 0.0.2

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.
@@ -0,0 +1,50 @@
1
+
2
+ module HerokuVector
3
+ class Sampler
4
+ include HerokuVector::Helper
5
+
6
+ attr_reader :capacity, :data
7
+
8
+ def initialize(capacity)
9
+ @capacity = capacity
10
+ clear
11
+ end
12
+
13
+ def clear
14
+ @data = []
15
+ end
16
+
17
+ def full?
18
+ @capacity == size
19
+ end
20
+
21
+ def size
22
+ data.size
23
+ end
24
+
25
+ def push(value)
26
+ data.push value
27
+ data.shift if size > capacity
28
+ end
29
+ alias_method :<<, :push
30
+
31
+ def mean
32
+ return 0 unless size >= 1
33
+
34
+ mean_value = data.reduce(:+).to_f / size.to_f
35
+ round_to_one_decimal( mean_value )
36
+ end
37
+
38
+ class << self
39
+ def capacity_for_sample_period(period_in_sec)
40
+ case period_in_sec
41
+ when 60; 5 # Last 5 mins (every minute)
42
+ when 10; 2 * 6 # Last 2 mins
43
+ when 5; 2 * 12 # Last 2 mins (every 5s)
44
+ when 1; 2 * 60 # Last 2 mins (every sec)
45
+ else; 100
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,50 @@
1
+ require 'newrelic_api'
2
+
3
+ module HerokuVector::Source
4
+ class NewRelic
5
+ attr_reader :account_id, :app_id, :api_key
6
+
7
+ def initialize(options={})
8
+ options[:api_key] ||= HerokuVector.newrelic_api_key
9
+ options[:account_id] ||= HerokuVector.newrelic_account_id
10
+ options[:app_id] ||= HerokuVector.newrelic_app_id
11
+
12
+ @api_key = options[:api_key]
13
+ @account_id = options[:account_id]
14
+ @app_id = options[:app_id]
15
+
16
+ NewRelicApi.api_key = api_key
17
+ end
18
+
19
+ def newrelic_account
20
+ # Safe to memoize the parent Account
21
+ @newrelic_account ||= NewRelicApi::Account.find(account_id || :first)
22
+ end
23
+
24
+ def newrelic_app
25
+ # App Must be fetched from network every time, to get latest metrics
26
+ if app_id
27
+ newrelic_account.applications.find {|app| app.id == app_id }
28
+ else
29
+ newrelic_account.applications.first
30
+ end
31
+ end
32
+
33
+ def throughput
34
+ begin
35
+ # Fetch fresh App instance and extract Trhoughput metric from Threshold Values
36
+ # Threshold Values are current instantaneous measures, not periodic averages
37
+ metric = newrelic_app.threshold_values.find {|m| m.name == 'Throughput' }
38
+ metric.metric_value
39
+ rescue
40
+ return 0.0
41
+ end
42
+ end
43
+ alias_method :sample, :throughput
44
+
45
+ def unit
46
+ 'RPM'
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ require 'redis'
2
+ require 'redis-namespace'
3
+ require 'sidekiq'
4
+ require 'sidekiq/api'
5
+
6
+ module HerokuVector::Source
7
+ class Sidekiq
8
+ def initialize(options={})
9
+ configure_sidekiq_client(options)
10
+ end
11
+
12
+ def configure_sidekiq_client(options={})
13
+ ::Sidekiq.configure_client do |config|
14
+ pool_options = { :size => 3, :timeout => 10 }
15
+ config.redis = ConnectionPool.new(pool_options) { build_redis_client(options) }
16
+ end
17
+ end
18
+
19
+ def build_redis_client(options={})
20
+ return options[:redis] if options[:redis]
21
+
22
+ connection = Redis.new({
23
+ url: options[:redis_url] || HerokuVector.sidekiq_redis_url,
24
+ timeout: 60
25
+ })
26
+
27
+ namespace = options[:redis_namespace] || HerokuVector.sidekiq_redis_namespace
28
+ if namespace
29
+ return ::Redis::Namespace.new(namespace, redis: connection)
30
+ else
31
+ return connection
32
+ end
33
+ end
34
+
35
+ def sidekiq_processes
36
+ ::Sidekiq::ProcessSet.new
37
+ end
38
+
39
+ def busy_workers
40
+ sidekiq_processes.reduce(0) {|i, process| i + process['busy'].to_i }
41
+ end
42
+ alias_method :sample, :busy_workers
43
+
44
+ def unit
45
+ 'busy threads'
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module HerokuVector
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,49 @@
1
+ require 'eventmachine'
2
+
3
+ module HerokuVector
4
+ class Worker
5
+ include HerokuVector::Helper
6
+
7
+ attr_accessor :options, :dyno_scalers, :engine
8
+
9
+ def initialize(options={})
10
+ @options = options
11
+ @dyno_scalers = []
12
+ end
13
+
14
+ def run
15
+ if options[:config]
16
+ if File.exist?(options[:config])
17
+ logger.info "Loading config from '#{options[:config]}'"
18
+ load options[:config]
19
+ else
20
+ logger.fatal "No config found at '#{options[:config]}'"
21
+ logger.info "You can copy config.rb.example => config.rb to get started"
22
+ logger.info "OR run heroku_vector -c /path/to/your/config.rb"
23
+ logger.info "Just Starting? Test your Source config with sampler mode: heroku_vector -s"
24
+ exit 1
25
+ end
26
+ end
27
+
28
+ load_dyno_scalers
29
+
30
+ EM.run do
31
+ dyno_scalers.each do |scaler|
32
+ EM::PeriodicTimer.new(scaler.period) do
33
+ scaler.run
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def load_dyno_scalers
40
+ HerokuVector.dyno_scalers.each do |scaler_def|
41
+ name, options = scaler_def
42
+ logger.info "Loading Scaler: #{name}, #{options.inspect}"
43
+
44
+ @dyno_scalers << DynoScaler.new(name, options)
45
+ end
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,69 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.heroku.com/apps/app_name/dyno-types
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ Accept-Encoding:
13
+ - gzip
14
+ User-Agent:
15
+ - heroku-rb/0.3.19
16
+ X-Ruby-Version:
17
+ - 2.1.2
18
+ X-Ruby-Platform:
19
+ - x86_64-darwin12.0
20
+ Authorization:
21
+ - Basic REAL_AUTH_GOES_HERE
22
+ response:
23
+ status:
24
+ code: 200
25
+ message: ''
26
+ headers:
27
+ Content-Encoding:
28
+ - gzip
29
+ Content-Type:
30
+ - application/json;charset=utf-8
31
+ Date:
32
+ - Sun, 07 Sep 2014 03:55:14 GMT
33
+ Etag:
34
+ - '"2066ae00e17dbce2b2a0a51ddcb99426"'
35
+ Last-Modified:
36
+ - Sun, 07 Sep 2014 03:54:22 GMT
37
+ Oauth-Scope:
38
+ - global
39
+ Oauth-Scope-Accepted:
40
+ - global read read-protected write write-protected
41
+ Request-Id:
42
+ - c2abc0bf-d7e4-4840-b2c6-742038b43334
43
+ Server:
44
+ - nginx/1.4.7
45
+ Status:
46
+ - 200 OK
47
+ Vary:
48
+ - Accept-Encoding
49
+ X-Content-Type-Options:
50
+ - nosniff
51
+ X-Ratelimit-Remaining:
52
+ - '2399'
53
+ X-Runtime:
54
+ - '0.050453792'
55
+ Content-Length:
56
+ - '207'
57
+ Connection:
58
+ - keep-alive
59
+ body:
60
+ encoding: ASCII-8BIT
61
+ string: !binary |-
62
+ H4sIAO7WC1QAA3yOPQ+CQAyG/0pzMx/iSOKmA3EyjsaYu6Niw9GDAwRj/O9C
63
+ ogEcnNq+yfs8PT2FtkUhORWxQL7DMdnu9slh07gWQbWcGgTsUUNNKeZUga8h
64
+ WoFfwY2y2zhTvMrWNONayhKdNlQKT7AscGB21uXohrtqJTfUPES8fnlzqyIO
65
+ OSPuL52T5QBYaJ0kVrarR28QastXysJvGDg1M6FaaKIfzQKa41T8XFNz9a9J
66
+ pobhjdqaGWIK5pTzGwAA//8DAJawUYVeAQAA
67
+ http_version:
68
+ recorded_at: Sun, 07 Sep 2014 03:55:13 GMT
69
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,65 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.heroku.com/apps/app_name/ps/scale?qty=1&type=web
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ Accept-Encoding:
13
+ - gzip
14
+ User-Agent:
15
+ - heroku-rb/0.3.19
16
+ X-Ruby-Version:
17
+ - 2.1.2
18
+ X-Ruby-Platform:
19
+ - x86_64-darwin12.0
20
+ Authorization:
21
+ - Basic YOUR_AUTH_HERE==
22
+ response:
23
+ status:
24
+ code: 200
25
+ message: ''
26
+ headers:
27
+ Content-Encoding:
28
+ - gzip
29
+ Content-Type:
30
+ - text/html;charset=utf-8
31
+ Date:
32
+ - Sun, 07 Sep 2014 04:24:14 GMT
33
+ Oauth-Scope:
34
+ - global
35
+ Oauth-Scope-Accepted:
36
+ - global write write-protected
37
+ Request-Id:
38
+ - 034d545b-b3e7-4f69-a0bb-89d57630f6e4
39
+ Server:
40
+ - nginx/1.4.7
41
+ Status:
42
+ - 200 OK
43
+ Vary:
44
+ - Accept-Encoding
45
+ X-Content-Type-Options:
46
+ - nosniff
47
+ X-Frame-Options:
48
+ - SAMEORIGIN
49
+ X-Ratelimit-Remaining:
50
+ - '2399'
51
+ X-Runtime:
52
+ - '0.118657809'
53
+ X-Xss-Protection:
54
+ - 1; mode=block
55
+ Content-Length:
56
+ - '27'
57
+ Connection:
58
+ - keep-alive
59
+ body:
60
+ encoding: ASCII-8BIT
61
+ string: !binary |-
62
+ H4sIAO7dC1QAAzIEAAAA//8DALfv3IMBAAAA
63
+ http_version:
64
+ recorded_at: Sun, 07 Sep 2014 04:24:13 GMT
65
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,78 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://rpm.newrelic.com/accounts.xml
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/xml
12
+ X-Api-Key:
13
+ - api_key
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ User-Agent:
17
+ - Ruby
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx
25
+ Date:
26
+ - Sun, 07 Sep 2014 06:28:44 GMT
27
+ Content-Type:
28
+ - application/xml; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ Status:
34
+ - 200 OK
35
+ X-Newrelic-Api-Version:
36
+ - v1
37
+ Etag:
38
+ - '"6421a9efd042eb1f557d443b6010b3b9"'
39
+ Cache-Control:
40
+ - max-age=0, private, must-revalidate
41
+ X-Ua-Compatible:
42
+ - IE=Edge,chrome=1
43
+ X-Runtime:
44
+ - '0.016534'
45
+ body:
46
+ encoding: UTF-8
47
+ string: |
48
+ <?xml version="1.0" encoding="UTF-8"?>
49
+ <accounts type="array">
50
+ <account>
51
+ <allow-rails-core>false</allow-rails-core>
52
+ <api-key>api_key</api-key>
53
+ <data-access-key>8fe689a3c6e5b099a28551733333c2acaeb2a80136c9357</data-access-key>
54
+ <id type="integer">231237</id>
55
+ <license-key>adb4b49abefe681dce6d228d764082f1b36c9357</license-key>
56
+ <name>polar-rails-staging Heroku</name>
57
+ <partner-external-identifier nil="true"></partner-external-identifier>
58
+ <phone-number nil="true"></phone-number>
59
+ <event-feed-uri>/account_feeds/8fe689a3c6e5b099a28551733333c2acaeb2a80136c9357/events.rss</event-feed-uri>
60
+ <primary-admin>
61
+ <email>cole.jeff.services@gmail.com</email>
62
+ <first-name nil="true"></first-name>
63
+ <last-name nil="true"></last-name>
64
+ <state>active</state>
65
+ </primary-admin>
66
+ <subscription>
67
+ <annual-renewal-on nil="true"></annual-renewal-on>
68
+ <expires-on nil="true"></expires-on>
69
+ <number-of-hosts>unlimited</number-of-hosts>
70
+ <starts-on>2013-11-02</starts-on>
71
+ <state>free</state>
72
+ <product-name>Standard</product-name>
73
+ </subscription>
74
+ </account>
75
+ </accounts>
76
+ http_version:
77
+ recorded_at: Sun, 07 Sep 2014 06:28:43 GMT
78
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,134 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://rpm.newrelic.com/accounts.xml
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/xml
12
+ X-Api-Key:
13
+ - api_key
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ User-Agent:
17
+ - Ruby
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx
25
+ Date:
26
+ - Sun, 07 Sep 2014 06:32:38 GMT
27
+ Content-Type:
28
+ - application/xml; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ Status:
34
+ - 200 OK
35
+ X-Newrelic-Api-Version:
36
+ - v1
37
+ Etag:
38
+ - '"6421a9efd042eb1f557d443b6010b3b9"'
39
+ Cache-Control:
40
+ - max-age=0, private, must-revalidate
41
+ X-Ua-Compatible:
42
+ - IE=Edge,chrome=1
43
+ X-Runtime:
44
+ - '0.019620'
45
+ body:
46
+ encoding: UTF-8
47
+ string: |
48
+ <?xml version="1.0" encoding="UTF-8"?>
49
+ <accounts type="array">
50
+ <account>
51
+ <allow-rails-core>false</allow-rails-core>
52
+ <api-key>api_key</api-key>
53
+ <data-access-key>8fe689a3c6e5b099a28551733333c2acaeb2a80136c9357</data-access-key>
54
+ <id type="integer">1</id>
55
+ <license-key>adb4b49abefe681dce6d228d764082f1b36c9357</license-key>
56
+ <name>polar-rails-staging Heroku</name>
57
+ <partner-external-identifier nil="true"></partner-external-identifier>
58
+ <phone-number nil="true"></phone-number>
59
+ <event-feed-uri>/account_feeds/8fe689a3c6e5b099a28551733333c2acaeb2a80136c9357/events.rss</event-feed-uri>
60
+ <primary-admin>
61
+ <email>cole.jeff.services@gmail.com</email>
62
+ <first-name nil="true"></first-name>
63
+ <last-name nil="true"></last-name>
64
+ <state>active</state>
65
+ </primary-admin>
66
+ <subscription>
67
+ <annual-renewal-on nil="true"></annual-renewal-on>
68
+ <expires-on nil="true"></expires-on>
69
+ <number-of-hosts>unlimited</number-of-hosts>
70
+ <starts-on>2013-11-02</starts-on>
71
+ <state>free</state>
72
+ <product-name>Standard</product-name>
73
+ </subscription>
74
+ </account>
75
+ </accounts>
76
+ http_version:
77
+ recorded_at: Sun, 07 Sep 2014 06:32:37 GMT
78
+ - request:
79
+ method: get
80
+ uri: http://rpm.newrelic.com/accounts/1/applications.xml
81
+ body:
82
+ encoding: US-ASCII
83
+ string: ''
84
+ headers:
85
+ Accept:
86
+ - application/xml
87
+ X-Api-Key:
88
+ - api_key
89
+ Accept-Encoding:
90
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
91
+ User-Agent:
92
+ - Ruby
93
+ response:
94
+ status:
95
+ code: 200
96
+ message: OK
97
+ headers:
98
+ Server:
99
+ - nginx
100
+ Date:
101
+ - Sun, 07 Sep 2014 06:32:38 GMT
102
+ Content-Type:
103
+ - application/xml; charset=utf-8
104
+ Transfer-Encoding:
105
+ - chunked
106
+ Connection:
107
+ - keep-alive
108
+ Status:
109
+ - 200 OK
110
+ X-Newrelic-Api-Version:
111
+ - v1
112
+ Etag:
113
+ - '"a2f87f24fee08dc231c1275662707617"'
114
+ Cache-Control:
115
+ - max-age=0, private, must-revalidate
116
+ X-Ua-Compatible:
117
+ - IE=Edge,chrome=1
118
+ X-Runtime:
119
+ - '0.026049'
120
+ body:
121
+ encoding: UTF-8
122
+ string: |
123
+ <?xml version="1.0" encoding="UTF-8"?>
124
+ <applications type="array">
125
+ <application>
126
+ <id type="integer">app_id</id>
127
+ <name>polar-rails-staging</name>
128
+ <overview-url>https://rpm.newrelic.com/accounts/1/applications/app_id</overview-url>
129
+ <servers-url>https://rpm.newrelic.com/api/v1/accounts/1/applications/app_id/servers</servers-url>
130
+ </application>
131
+ </applications>
132
+ http_version:
133
+ recorded_at: Sun, 07 Sep 2014 06:32:37 GMT
134
+ recorded_with: VCR 2.9.2