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 +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
|