rack-queue-metrics 1.0.2 → 2.0.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,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MjliYTU3ZTUxNmM4NmMxMjUxYWUwNGU1ODI5N2E2OWNkYjM2YzQ5Mg==
5
- data.tar.gz: !binary |-
6
- MzQ3ZTkwZGQ4MDE1MjY1NjU1NjZhMzRmNTdmMjc3NTI0NTQ2YWQwNQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- ZTMzMTY3MDI0MWUxM2UxYjkxMmFhNjI0ZTRlOGZkYThkYzg4NDVhNzg5YjVj
10
- M2U2M2E5MDc0M2EyYjNkOTRjYTEyNjdiMjUwMjVmYmFiNDkxZTA0NmM5N2Rh
11
- MDY1NjUyN2RkMzcwOWM2NzdmODM2YmQwNjU0ZTg4MmM2Y2M0Yzc=
12
- data.tar.gz: !binary |-
13
- ZTExOTcyZTNhYzkzZmE1MDRiY2E1MTY0OTMwZDdmYjg0Y2Y1NzgyZTE0NWRh
14
- ZDQwMDY4YTNiMjFjNmI0NzQ5ZTEzYmZjMDIwMDE0NDQ1OTdiNjgyMzFhZDgw
15
- YmFkMjUwZDQ4Y2U1MmYwNzQ5Y2M2MDFkZGRjNjljY2U0Mzc0YzQ=
2
+ SHA1:
3
+ metadata.gz: 753d70724e0d2f8d18d0fd147e0a170f9d8cc0f2
4
+ data.tar.gz: 55dbea922d5361e1d5c67926d9aed26f48283d05
5
+ SHA512:
6
+ metadata.gz: 7f0c153bfde9e3d7ee57ab5238f7c8eb870d3c5836f18f96f0cf025ba6637485efbe492e5945328412d5794133e6d2afd16876f460eae66f82ca78c5b025a34d
7
+ data.tar.gz: 38e3c1d9e3726a35349373ffc93504a0e9489e5e351ec984719e82702e7d0b3d1ba79532895d80b841840dcac7060157481eead78e4a7b2236ec14797ae623bf
data/README.md CHANGED
@@ -12,11 +12,11 @@ gem 'rack-queue-metrics'
12
12
 
13
13
  ### Rails
14
14
 
15
- You're done! If you want to instrument queue metrics beyond the default output, you can subscribe to the `unicorn.metrics.queue` notifcation in your Rails app. For example, to print queue information to your logs, add the following to `config/initializers/notifcations.rb:
15
+ You're done! If you want to instrument queue metrics beyond the default output, you can subscribe to the `rack.queue-metrics` notifcation in your Rails app. For example, to print queue information to your logs, add the following to `config/initializers/notifcations.rb:
16
16
 
17
17
  ```
18
18
  # config/initializers/notifications.rb
19
- ActiveSupport::Notifications.subscribe(/unicorn.metrics.queue/) do |*args|
19
+ ActiveSupport::Notifications.subscribe(/rack.queue-metrics/) do |*args|
20
20
  event = ActiveSupport::Notifications::Event.new(*args)
21
21
  payload = event.payload
22
22
 
@@ -53,7 +53,7 @@ at=metric measure=rack.queue-metrics addr=10.10.10.90:5000 queue_time=0 queue_de
53
53
 
54
54
  The following information is sent in the notification payload:
55
55
 
56
- * `requests[:active]`: Number of requests currently being processed by Unicorn at the start of the request
56
+ * `requests[:active]`: Number of requests currently being processed by the dyno at the start of the request
57
57
  * `requests[:queued]`: Number of requests waiting to be processed at the start of the request
58
58
  * `queue_time`: Amount of time the current request spent in the queue
59
- * `addr`: Address of the dyno processing the request
59
+ * `addr`: Address of the dyno processing the request
@@ -0,0 +1,48 @@
1
+ require 'logger'
2
+ require 'queue-metrics/l2met_formatter'
3
+ require 'queue-metrics/notify'
4
+
5
+ module Rack
6
+ module QueueMetrics
7
+ class AppTime
8
+ include Notify
9
+
10
+ def initialize(app, logger = nil)
11
+ @app = app
12
+ @instrument_name = "rack.queue-metrics.app-time"
13
+ @logger = logger
14
+ if @logger.nil?
15
+ @logger = ::Logger.new($stdout)
16
+ @logger.formatter = L2MetFormatter.new
17
+ end
18
+ end
19
+
20
+ def call(env)
21
+ app_start = (Time.now.to_f * 1000.0).round
22
+ request_id = env["HTTP_REQUEST_ID"]
23
+ middleware_start = (env["MIDDLEWARE_START"] || 0).to_i
24
+ middleware_delta = nil
25
+ report = "measure=#{@instrument_name}.start app_start=#{app_start}"
26
+ if middleware_start > 0
27
+ middleware_delta = app_start - middleware_start
28
+ report << " middleware_delta=#{middleware_delta}"
29
+ end
30
+ report << " request_id=#{request_id}" if request_id
31
+ @logger.info report
32
+
33
+ status, headers, response = @app.call(env)
34
+
35
+ app_end = (Time.now.to_f * 1000.0).round
36
+ app_delta = app_end - app_start
37
+ report = "measure=#{@instrument_name}.end app_end=#{app_end}"
38
+ report << " app_delta=#{app_delta}"
39
+ report << " request_id=#{request_id}" if request_id
40
+ @logger.info report
41
+
42
+ notify(:app_end => app_end, :app_start => app_start, :app_delta => app_delta, :middleware_delta => middleware_delta, :request_id => request_id) if should_notify?
43
+
44
+ [status, headers, response]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,9 @@
1
+ module Rack
2
+ module QueueMetrics
3
+ class L2MetFormatter
4
+ def call(serverity, datetime, progname, msg)
5
+ "at=metric #{msg}\n"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module Rack
2
+ module QueueMetrics
3
+ module Notify
4
+ def should_notify?
5
+ if defined?(ActiveSupport::Notifications)
6
+ ActiveSupport::Notifications.notifier.listening?(@instrument_name)
7
+ end
8
+ end
9
+
10
+ def notify(data)
11
+ ActiveSupport::Notifications.instrument(@instrument_name, data)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,60 @@
1
+ require 'logger'
2
+ require 'queue-metrics/l2met_formatter'
3
+ require 'queue-metrics/notify'
4
+
5
+ module Rack
6
+ module QueueMetrics
7
+ class QueueDepth
8
+ include Notify
9
+
10
+ def initialize(app, logger = nil)
11
+ @app = app
12
+ @addr = getaddr
13
+ @instrument_name = "rack.queue-metrics.queue-depth"
14
+ @logger = logger
15
+ if @logger.nil?
16
+ @logger = ::Logger.new($stdout)
17
+ @logger.formatter = L2MetFormatter.new
18
+ end
19
+
20
+ Thread.new {report(1)}
21
+ end
22
+
23
+ def call(env)
24
+ return @app.call(env) unless ENV['PORT']
25
+ status, headers, body = @app.call(env)
26
+ [status, headers, body]
27
+ end
28
+
29
+ private
30
+
31
+ def getaddr
32
+ IPSocket.getaddress(Socket.gethostname).to_s + ':' + ENV['PORT']
33
+ rescue SocketError
34
+ nil
35
+ end
36
+
37
+ def report(interval)
38
+ loop do
39
+ stats = raindrops_stats
40
+ stats[:addr] = @addr
41
+ notify(stats) if should_notify?
42
+ @logger.info(["measure=#{@instrument_name}",
43
+ "addr=#{@addr}",
44
+ "queue_depth=#{stats[:requests][:queued]}"].join(' '))
45
+ sleep(interval)
46
+ end
47
+ end
48
+
49
+ def raindrops_stats
50
+ if defined? Raindrops::Linux.tcp_listener_stats
51
+ stats = Raindrops::Linux.tcp_listener_stats([ '0.0.0.0:'+ENV['PORT'] ])['0.0.0.0:'+ENV['PORT']]
52
+ return { :requests => { :active => stats.active, :queued => stats.queued }}
53
+ else
54
+ return { :requests => { :active => 0, :queued => 0 }}
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,41 @@
1
+ require 'logger'
2
+ require 'queue-metrics/l2met_formatter'
3
+ require 'queue-metrics/notify'
4
+
5
+ module Rack
6
+ module QueueMetrics
7
+ class QueueTime
8
+ include Notify
9
+
10
+ def initialize(app, logger = nil)
11
+ @app = app
12
+ @instrument_name = "rack.queue-metrics.queue-time"
13
+ @logger = logger
14
+ if @logger.nil?
15
+ @logger = ::Logger.new($stdout)
16
+ @logger.formatter = L2MetFormatter.new
17
+ end
18
+ end
19
+
20
+ def call(env)
21
+ middleware_start = (Time.now.to_f * 1000.0).round
22
+ request_start = (env["HTTP_X_REQUEST_START"] || 0).to_i
23
+ request_id = env["HTTP_REQUEST_ID"]
24
+ request_start_delta = nil
25
+ report = "measure=#{@instrument_name} middleware_start=#{middleware_start}"
26
+ if request_start > 0
27
+ request_start_delta = middleware_start - request_start
28
+ report << " request_start=#{request_start} request_start_delta=#{request_start_delta}"
29
+ end
30
+ report << " request_id=#{request_id}" if request_id
31
+ @logger.info report
32
+
33
+ notify(:middleware_start => middleware_start, :request_start => request_start, :request_start_delta => request_start_delta, :request_id => request_id) if should_notify?
34
+
35
+ env["MIDDLEWARE_START"] = middleware_start
36
+
37
+ @app.call(env)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,9 +2,11 @@ module Rack
2
2
  module QueueMetrics
3
3
  class RackQueueRailtie < Rails::Railtie
4
4
  initializer "rack_queue_railtie.configure_rails_initialization" do |app|
5
+ app.middleware.use Rack::QueueMetrics::QueueTime
5
6
  app.middleware.use Raindrops::Middleware
6
- app.middleware.use Rack::QueueMetrics::Middleware
7
+ app.middleware.use Rack::QueueMetrics::QueueDepth
8
+ app.middleware.use Rack::QueueMetrics::AppTime
7
9
  end
8
10
  end
9
11
  end
10
- end
12
+ end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module QueueMetrics
3
- VERSION = "1.0.2"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
@@ -1,2 +1,4 @@
1
- require 'queue-metrics/middleware'
2
- require 'queue-metrics/railtie' if defined?(Rails)
1
+ require 'queue-metrics/queue_time'
2
+ require 'queue-metrics/queue_depth'
3
+ require 'queue-metrics/app_time'
4
+ require 'queue-metrics/railtie' if defined?(Rails)
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-queue-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dominic (Dominic Dagradi)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-08 00:00:00.000000000 Z
11
+ date: 2014-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: raindrops
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description: Measure queueing metrics for Rack apps
@@ -32,7 +32,11 @@ extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
34
  - README.md
35
- - lib/queue-metrics/middleware.rb
35
+ - lib/queue-metrics/app_time.rb
36
+ - lib/queue-metrics/l2met_formatter.rb
37
+ - lib/queue-metrics/notify.rb
38
+ - lib/queue-metrics/queue_depth.rb
39
+ - lib/queue-metrics/queue_time.rb
36
40
  - lib/queue-metrics/railtie.rb
37
41
  - lib/queue-metrics/version.rb
38
42
  - lib/rack-queue-metrics.rb
@@ -46,17 +50,17 @@ require_paths:
46
50
  - lib
47
51
  required_ruby_version: !ruby/object:Gem::Requirement
48
52
  requirements:
49
- - - ! '>='
53
+ - - '>='
50
54
  - !ruby/object:Gem::Version
51
55
  version: '0'
52
56
  required_rubygems_version: !ruby/object:Gem::Requirement
53
57
  requirements:
54
- - - ! '>='
58
+ - - '>='
55
59
  - !ruby/object:Gem::Version
56
60
  version: '0'
57
61
  requirements: []
58
62
  rubyforge_project:
59
- rubygems_version: 2.0.2
63
+ rubygems_version: 2.0.3
60
64
  signing_key:
61
65
  specification_version: 4
62
66
  summary: Measure queueing metrics for Rack apps
@@ -1,41 +0,0 @@
1
- require 'socket'
2
-
3
- module Rack
4
- module QueueMetrics
5
- class Middleware
6
-
7
- def initialize(app)
8
- @app = app
9
- end
10
-
11
- def call(env)
12
- return @app.call(env) unless ENV['PORT']
13
-
14
- start_time = Time.now.to_f*1000.0
15
- stats = raindrops_stats
16
-
17
- status, headers, body = @app.call(env)
18
-
19
- stats[:addr] = IPSocket.getaddress(Socket.gethostname).to_s + ':'+ENV['PORT']
20
- stats[:queue_time] = env["HTTP_X_REQUEST_START"] ? (start_time - env["HTTP_X_REQUEST_START"].to_f).round : 0
21
-
22
- puts "at=metric measure=rack.queue-metrics addr=#{stats[:addr]} queue_time=#{stats[:queue_time]} queue_depth=#{stats[:requests][:queued]}"
23
- ActiveSupport::Notifications.instrument("rack.queue-metrics", stats) if defined?(ActiveSupport::Notifications)
24
-
25
- [status, headers, body]
26
- end
27
-
28
- private
29
-
30
- def raindrops_stats
31
- if defined? Raindrops::Linux.tcp_listener_stats
32
- stats = Raindrops::Linux.tcp_listener_stats([ '0.0.0.0:'+ENV['PORT'] ])['0.0.0.0:'+ENV['PORT']]
33
- return { :requests => { :active => stats.active, :queued => stats.queued }}
34
- else
35
- return { :requests => { :active => 0, :queued => 0 }}
36
- end
37
- end
38
-
39
- end
40
- end
41
- end