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 +6 -14
- data/README.md +4 -4
- data/lib/queue-metrics/app_time.rb +48 -0
- data/lib/queue-metrics/l2met_formatter.rb +9 -0
- data/lib/queue-metrics/notify.rb +15 -0
- data/lib/queue-metrics/queue_depth.rb +60 -0
- data/lib/queue-metrics/queue_time.rb +41 -0
- data/lib/queue-metrics/railtie.rb +4 -2
- data/lib/queue-metrics/version.rb +1 -1
- data/lib/rack-queue-metrics.rb +4 -2
- metadata +12 -8
- data/lib/queue-metrics/middleware.rb +0 -41
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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 `
|
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(/
|
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
|
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,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::
|
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
|
data/lib/rack-queue-metrics.rb
CHANGED
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:
|
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:
|
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/
|
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.
|
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
|