rack-queue-metrics 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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