rails_autoscale_agent 0.4.1 → 0.6.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
  SHA256:
3
- metadata.gz: 9599e5eb723b8e92f13eb6f820ce7f49f6af5ae946146eb140f13e42a465625a
4
- data.tar.gz: 94eeec3ac6376605b5d0db1c8aa406c1f7101fddbf2f188e1cbb41c5f2f836bc
3
+ metadata.gz: 5d8c84bc0e74990ad310505abc8666c54de4de76d16c31c8435c495afc17dc8a
4
+ data.tar.gz: a46f8f5e0bb5c5683d10b175162fb4fb1911fbc5390ae80716054062c13604f7
5
5
  SHA512:
6
- metadata.gz: c8d33309ab62d23341bc707e8b5e5da5158e21885911fd0418a58c5880b4fe24a309cabf3cd08513382e18570e7c28f8ff2fa1bb7362f040aac8f3210fdf306e
7
- data.tar.gz: 41999dbec255f00d7f3369f97e81acae12c556b126050ea28a50816a8c91801a8dfa256cdfc14f8126c4ad175ecd9dc16fd3b8136aaf0c9805301a362cdf81de
6
+ metadata.gz: dc1afd33ac4589472ffea027d24b6ff0cc9ef8b91fcdc237191248c8245baeee7ead3550ec8c1826c0bcdd708cbb83fe91457c8240efead5fef94e9109daaad3
7
+ data.tar.gz: cd381c1dd165c3830fa22d412603a966b4ecff5ab04bf6d3b8fb846f4c3bc0cde324c0e1fd0b5964bab2a72500e7bc752b06cbd95bb1c40b1fba3abd2871ce54
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rails_autoscale_agent/config'
4
+
3
5
  module RailsAutoscaleAgent
4
6
  module Logger
5
7
  def logger
6
8
  @logger ||= Config.instance.logger.tap do |logger|
7
9
  logger.extend(FakeTaggedLogging) unless logger.respond_to?(:tagged)
10
+ logger.extend(ConditionalDebugLogging)
8
11
  end
9
12
  end
10
13
 
@@ -14,5 +17,13 @@ module RailsAutoscaleAgent
14
17
  yield self
15
18
  end
16
19
  end
20
+
21
+ module ConditionalDebugLogging
22
+ def debug(*args)
23
+ # Rails logger defaults to DEBUG level in production, but I don't want
24
+ # to be chatty by default.
25
+ super if ENV['RAILS_AUTOSCALE_LOG_LEVEL'] == 'DEBUG'
26
+ end
27
+ end
17
28
  end
18
29
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAutoscaleAgent
4
- class Measurement < Struct.new(:time, :value)
5
- def initialize(time, value)
6
- super time.utc, value.to_i
4
+ class Measurement < Struct.new(:time, :value, :queue_name)
5
+ def initialize(time, value, queue_name = nil)
6
+ super time.utc, value.to_i, queue_name
7
7
  end
8
8
  end
9
9
  end
@@ -19,8 +19,6 @@ module RailsAutoscaleAgent
19
19
  config = Config.instance
20
20
  request = Request.new(env, config)
21
21
 
22
- logger.debug "Middleware entered - request_id=#{request.id} path=#{request.path} method=#{request.method} request_size=#{request.size}"
23
-
24
22
  store = Store.instance
25
23
  Reporter.start(config, store)
26
24
 
@@ -22,6 +22,12 @@ module RailsAutoscaleAgent
22
22
  result << measurement.time.to_i.to_s
23
23
  result << ','
24
24
  result << measurement.value.to_s
25
+
26
+ if measurement.queue_name
27
+ result << ','
28
+ result << measurement.queue_name
29
+ end
30
+
25
31
  result << "\n"
26
32
  end
27
33
  end
@@ -5,6 +5,7 @@ require 'rails_autoscale_agent/logger'
5
5
  require 'rails_autoscale_agent/autoscale_api'
6
6
  require 'rails_autoscale_agent/time_rounder'
7
7
  require 'rails_autoscale_agent/registration'
8
+ require 'rails_autoscale_agent/worker_adapters/sidekiq'
8
9
 
9
10
  # Reporter wakes up every minute to send metrics to the RailsAutoscale API
10
11
 
@@ -13,25 +14,34 @@ module RailsAutoscaleAgent
13
14
  include Singleton
14
15
  include Logger
15
16
 
17
+ WORKER_ADAPTERS = [
18
+ WorkerAdapters::Sidekiq.new,
19
+ ]
20
+
16
21
  def self.start(config, store)
17
- if config.api_base_url
18
- instance.start!(config, store) unless instance.running?
19
- else
20
- instance.logger.debug "Reporter not started: RAILS_AUTOSCALE_URL is not set"
21
- end
22
+ instance.start!(config, store) unless instance.started?
22
23
  end
23
24
 
24
25
  def start!(config, store)
25
- @running = true
26
+ @started = true
27
+ @worker_adapters = WORKER_ADAPTERS.select(&:enabled?)
28
+
29
+ if !config.api_base_url
30
+ logger.info "Reporter not started: RAILS_AUTOSCALE_URL is not set"
31
+ return
32
+ end
26
33
 
27
34
  Thread.new do
28
35
  logger.tagged 'RailsAutoscale' do
29
36
  register!(config)
30
37
 
31
38
  loop do
32
- sleep config.report_interval
39
+ # Stagger reporting to spread out reports from many processes
40
+ multiplier = 1 - (rand / 4) # between 0.75 and 1.0
41
+ sleep config.report_interval * multiplier
33
42
 
34
43
  begin
44
+ @worker_adapters.map { |a| a.collect!(store) }
35
45
  report!(config, store)
36
46
  rescue => ex
37
47
  # Exceptions in threads other than the main thread will fail silently
@@ -44,15 +54,15 @@ module RailsAutoscaleAgent
44
54
  end
45
55
  end
46
56
 
47
- def running?
48
- @running
57
+ def started?
58
+ @started
49
59
  end
50
60
 
51
61
  def report!(config, store)
52
62
  report = store.pop_report
53
63
 
54
64
  if report.measurements.any?
55
- logger.info "Reporting queue times for #{report.measurements.size} requests"
65
+ logger.info "Reporting #{report.measurements.size} measurements"
56
66
 
57
67
  params = report.to_params(config)
58
68
  result = AutoscaleApi.new(config.api_base_url).report_metrics!(params, report.to_csv)
@@ -76,7 +86,7 @@ module RailsAutoscaleAgent
76
86
  when AutoscaleApi::SuccessResponse
77
87
  config.report_interval = result.data['report_interval'] if result.data['report_interval']
78
88
  config.max_request_size = result.data['max_request_size'] if result.data['max_request_size']
79
- logger.info "Reporter starting, will report every #{config.report_interval} seconds"
89
+ logger.info "Reporter starting, will report every #{config.report_interval} seconds or so"
80
90
  when AutoscaleApi::FailureResponse
81
91
  logger.error "Reporter failed to register: #{result.failure_message}"
82
92
  end
@@ -24,16 +24,11 @@ module RailsAutoscaleAgent
24
24
 
25
25
  def queue_time
26
26
  if entered_queue_at
27
- if entered_queue_at < (Time.now - 60 * 10)
28
- # ignore unreasonable values
29
- logger.warn "request queued for more than 10 minutes... skipping collection"
30
- else
31
- queue_time = ((Time.now - entered_queue_at) * 1000).to_i
32
- queue_time = 0 if queue_time < 0
33
- logger.debug "Collected queue_time=#{queue_time}ms request_id=#{id} request_size=#{size}"
27
+ queue_time = ((Time.now - entered_queue_at) * 1000).to_i
28
+ queue_time = 0 if queue_time < 0
29
+ logger.debug "Collected queue_time=#{queue_time}ms request_id=#{id} request_size=#{size}"
34
30
 
35
- queue_time
36
- end
31
+ queue_time
37
32
  end
38
33
  end
39
34
  end
@@ -9,12 +9,14 @@ module RailsAutoscaleAgent
9
9
  class Store
10
10
  include Singleton
11
11
 
12
+ attr_reader :measurements
13
+
12
14
  def initialize
13
15
  @measurements = []
14
16
  end
15
17
 
16
- def push(value, time = Time.now)
17
- @measurements << Measurement.new(time, value)
18
+ def push(value, time = Time.now, queue_name = nil)
19
+ @measurements << Measurement.new(time, value, queue_name)
18
20
  end
19
21
 
20
22
  def pop_report
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAutoscaleAgent
4
- VERSION = "0.4.1"
4
+ VERSION = "0.6.0"
5
5
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_autoscale_agent/logger'
4
+ require 'sidekiq/api'
5
+
6
+ module WorkerAdapters
7
+ class Sidekiq
8
+ include RailsAutoscaleAgent::Logger
9
+
10
+ def enabled?
11
+ defined?(::Sidekiq)
12
+ end
13
+
14
+ # TODO: specs
15
+ def collect!(store)
16
+ log_msg = String.new('Sidekiq latency ')
17
+
18
+ ::Sidekiq::Queue.all.each do |queue|
19
+ latency_ms = (queue.latency * 1000).ceil
20
+ store.push latency_ms, Time.now, queue.name
21
+ log_msg << "#{queue.name}=#{latency_ms} "
22
+ end
23
+
24
+ logger.debug log_msg
25
+ end
26
+ end
27
+ end
@@ -25,4 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "webmock"
26
26
  spec.add_development_dependency "pry"
27
27
  spec.add_development_dependency "pry-byebug"
28
+ spec.add_development_dependency "sidekiq", "~> 5.0"
28
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_autoscale_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam McCrea
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-21 00:00:00.000000000 Z
11
+ date: 2019-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sidekiq
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '5.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '5.0'
125
139
  description:
126
140
  email:
127
141
  - adam@adamlogic.com
@@ -153,6 +167,7 @@ files:
153
167
  - lib/rails_autoscale_agent/store.rb
154
168
  - lib/rails_autoscale_agent/time_rounder.rb
155
169
  - lib/rails_autoscale_agent/version.rb
170
+ - lib/rails_autoscale_agent/worker_adapters/sidekiq.rb
156
171
  - log/.gitkeep
157
172
  - rails_autoscale_agent.gemspec
158
173
  homepage: https://github.com/adamlogic/rails_autoscale_agent