nexaas-queue_time 0.3.0 → 0.4.0.pre.rc1
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 +4 -4
- data/README.md +27 -5
- data/bin/sidekiq_metric_collector +9 -0
- data/lib/nexaas/queue_time/dogstatsd.rb +23 -0
- data/lib/nexaas/queue_time/middleware.rb +6 -20
- data/lib/nexaas/queue_time/sidekiq.rb +25 -0
- data/lib/nexaas/queue_time/version.rb +1 -1
- data/nexaas-queue_time.gemspec +7 -2
- metadata +26 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2699d2c676058c63f554ece97e6814a0f612eb4cc42f77f677b7653d2f4907d6
|
4
|
+
data.tar.gz: d2e6f76b7c61c3efb14374025b24dbb8f2c6bec9c84411cad0dac312be890d0c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0170f983fcac8522f0dd255a740b5221f77e7ca0c4c592c08a4ce9efcce8803da7766e85049d4a657634fdfafa4939c5fb83d180ecd91e6a7e23a494fe605188
|
7
|
+
data.tar.gz: 50fa088ed9abeb91150fe7299c545f6980a1b13a11b1b46af1f697827cedac1317fe57822a42f8caa1c247fc34cff44e66405f17b41dfb396cea25ffd3040594
|
data/README.md
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
[](https://travis-ci.org/myfreecomm/nexaas-queue_time)
|
2
2
|
# Nexaas::QueueTime
|
3
3
|
|
4
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/nexaas/queue_time`. To experiment with that code, run `bin/console` for an interactive prompt.
|
5
|
-
|
6
|
-
TODO: Delete this and the text above, and describe your gem
|
7
4
|
|
8
5
|
## Installation
|
9
6
|
|
@@ -23,7 +20,32 @@ Or install it yourself as:
|
|
23
20
|
|
24
21
|
## Usage
|
25
22
|
|
26
|
-
|
23
|
+
### Rails initialization
|
24
|
+
Add this gem to the Middleware stack before `Rack::Runtime`, like this:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
require "nexaas/queue_time/middleware"
|
28
|
+
config.middleware.insert_before Rack::Runtime, Nexaas::QueueTime::Middleware
|
29
|
+
```
|
30
|
+
You can place it in `config/application.rb` or in a specific environment file, such as `config/environments/production.rb`
|
31
|
+
|
32
|
+
This code can also be placed in an initializer file, such as `config/initializers/middlewares.rb`:
|
33
|
+
```ruby
|
34
|
+
Rails.env.on(:any) do |config|
|
35
|
+
require "nexaas/queue_time/middleware"
|
36
|
+
config.middleware.insert_before Rack::Runtime, Nexaas::QueueTime::Middleware
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
### Header requirement
|
41
|
+
For the gem to work, someone **must** set the header `X-Request-Start` with the format `t=timestamp`, where `timestamp` is the UNIX timestamp.
|
42
|
+
This someone could be a load balancer, reverse proxy or router. Heroku already does that for you automatically.
|
43
|
+
|
44
|
+
### DogStatsD
|
45
|
+
|
46
|
+
After calculating the `queue_time`, this gem sends it to a [DogStatsD](https://docs.datadoghq.com/developers/dogstatsd/) server via [UDS](https://en.wikipedia.org/wiki/Unix_domain_socket).
|
47
|
+
|
48
|
+
Without the _DogStatsD_ agent this gem is pretty much useless.
|
27
49
|
|
28
50
|
## Development
|
29
51
|
|
@@ -33,7 +55,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
33
55
|
|
34
56
|
## Contributing
|
35
57
|
|
36
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
58
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/myfreecomm/nexaas-queue_time.
|
37
59
|
|
38
60
|
## License
|
39
61
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'datadog/statsd'
|
4
|
+
|
5
|
+
module Nexaas
|
6
|
+
module QueueTime
|
7
|
+
class DogStatsd
|
8
|
+
# By default, Datadog::Statsd opens a UDP connection with a given host and port.
|
9
|
+
# Instead, we are giving it a socket path so it communicates with the statsd server via UDS.
|
10
|
+
#
|
11
|
+
# This approach is easier to setup in containerized environments since all it requires
|
12
|
+
# is the path to the socket file instead of the host address.
|
13
|
+
#
|
14
|
+
# UDS also performs better than UDP,
|
15
|
+
# although the app would need to receive huge traffic to actually feel the difference.
|
16
|
+
def self.timing(metric_name, metric, options = {})
|
17
|
+
Datadog::Statsd.open(nil, nil, socket_path: '/var/run/datadog/dsd.socket') do |statsd|
|
18
|
+
statsd.timing(metric_name, metric, options)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'nexaas/queue_time/dogstatsd'
|
4
4
|
|
5
5
|
module Nexaas
|
6
6
|
module QueueTime
|
7
7
|
# This middleware calculates the time a request has been waiting
|
8
|
-
#
|
8
|
+
# in the queue before being served by the application server.
|
9
9
|
#
|
10
10
|
# It requires the header `X_REQUEST_START`. This header contains
|
11
|
-
#
|
11
|
+
# the timestamp of when the request first apperead in the stack.
|
12
12
|
# This header is usually set by a LoadBalancer, Reverse Proxy or Router.
|
13
13
|
#
|
14
|
-
# The format of the header
|
15
|
-
#
|
14
|
+
# The format of the header *must* match:
|
15
|
+
# `t=TIMESTAMP`, where TIMESTAMP is the unix timestamp.
|
16
16
|
# This format is supported by APMs such as New Relic and Scout
|
17
17
|
class Middleware
|
18
18
|
METRIC_NAME = 'request.queue_time'
|
@@ -34,7 +34,7 @@ module Nexaas
|
|
34
34
|
if request_start_header && request_start_header =~ HEADER_FORMAT_PATTERN
|
35
35
|
left_queue_at = Time.now.to_f
|
36
36
|
metric = calculate_queue_time_in_ms(left_queue_at, request_start_header)
|
37
|
-
|
37
|
+
DogStatsd.timing(METRIC_NAME, metric.to_i, sample_rate: 1)
|
38
38
|
end
|
39
39
|
|
40
40
|
@app.call(env)
|
@@ -50,20 +50,6 @@ module Nexaas
|
|
50
50
|
def extract_timestamp(entered_queue)
|
51
51
|
entered_queue.delete('t=')
|
52
52
|
end
|
53
|
-
|
54
|
-
# By default, Datadog::Statsd opens a UDP connection with a given host and port.
|
55
|
-
# Instead, we are giving it a socket path so it communicates with the statsd server via UDS.
|
56
|
-
#
|
57
|
-
# This approach is easier to setup in containerized environments since all it requires
|
58
|
-
# is the path to the socket file instead of the host address.
|
59
|
-
#
|
60
|
-
# UDS also performs better than UDP,
|
61
|
-
# although the app would need to receive huge traffic to actually feel the difference.
|
62
|
-
def send_metric(metric)
|
63
|
-
Datadog::Statsd.open(nil, nil, socket_path: '/var/run/datadog/dsd.socket') do |statsd|
|
64
|
-
statsd.timing(METRIC_NAME, metric.to_i, sample_rate: 1)
|
65
|
-
end
|
66
|
-
end
|
67
53
|
end
|
68
54
|
end
|
69
55
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nexaas/queue_time/dogstatsd'
|
4
|
+
require 'sidekiq/api'
|
5
|
+
|
6
|
+
module Nexaas
|
7
|
+
module QueueTime
|
8
|
+
# Measures the latency for all Sidekiq queues
|
9
|
+
# and send it to Datadog.
|
10
|
+
class Sidekiq
|
11
|
+
METRIC_NAME = 'sidekiq.queue.latency'
|
12
|
+
|
13
|
+
def self.measure_latency
|
14
|
+
::Sidekiq::Queue.all.each do |queue|
|
15
|
+
latency_in_ms = (queue.latency * 1000).ceil
|
16
|
+
opts = {
|
17
|
+
sample_rate: 1,
|
18
|
+
tags: { queue_name: queue.name }
|
19
|
+
}
|
20
|
+
DogStatsd.timing(METRIC_NAME, latency_in_ms, opts)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/nexaas-queue_time.gemspec
CHANGED
@@ -13,13 +13,17 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://nexaas.com"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
+
spec.metadata = {
|
17
|
+
"source_code_uri" => "https://github.com/myfreecomm/nexaas-queue_time"
|
18
|
+
}
|
19
|
+
|
16
20
|
# Specify which files should be added to the gem when it is released.
|
17
21
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
22
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
19
23
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
24
|
end
|
21
|
-
spec.bindir = "
|
22
|
-
spec.executables
|
25
|
+
spec.bindir = "bin"
|
26
|
+
spec.executables << 'sidekiq_metric_collector'
|
23
27
|
spec.require_paths = ["lib"]
|
24
28
|
|
25
29
|
spec.add_dependency "dogstatsd-ruby", "~> 4.3"
|
@@ -27,6 +31,7 @@ Gem::Specification.new do |spec|
|
|
27
31
|
spec.add_development_dependency "bundler", "~> 2.0"
|
28
32
|
spec.add_development_dependency "rake", "~> 10.0"
|
29
33
|
spec.add_development_dependency "rspec", "~> 3.0"
|
34
|
+
spec.add_development_dependency "sidekiq", "~> 4"
|
30
35
|
spec.add_development_dependency "pry"
|
31
36
|
spec.add_development_dependency "pry-byebug"
|
32
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexaas-queue_time
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0.pre.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Mansur
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dogstatsd-ruby
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sidekiq
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: pry
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,7 +111,8 @@ dependencies:
|
|
97
111
|
description:
|
98
112
|
email:
|
99
113
|
- lucas.mansur2@gmail.com
|
100
|
-
executables:
|
114
|
+
executables:
|
115
|
+
- sidekiq_metric_collector
|
101
116
|
extensions: []
|
102
117
|
extra_rdoc_files: []
|
103
118
|
files:
|
@@ -111,14 +126,18 @@ files:
|
|
111
126
|
- Rakefile
|
112
127
|
- bin/console
|
113
128
|
- bin/setup
|
129
|
+
- bin/sidekiq_metric_collector
|
114
130
|
- lib/nexaas/queue_time.rb
|
131
|
+
- lib/nexaas/queue_time/dogstatsd.rb
|
115
132
|
- lib/nexaas/queue_time/middleware.rb
|
133
|
+
- lib/nexaas/queue_time/sidekiq.rb
|
116
134
|
- lib/nexaas/queue_time/version.rb
|
117
135
|
- nexaas-queue_time.gemspec
|
118
136
|
homepage: https://nexaas.com
|
119
137
|
licenses:
|
120
138
|
- MIT
|
121
|
-
metadata:
|
139
|
+
metadata:
|
140
|
+
source_code_uri: https://github.com/myfreecomm/nexaas-queue_time
|
122
141
|
post_install_message:
|
123
142
|
rdoc_options: []
|
124
143
|
require_paths:
|
@@ -130,9 +149,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
149
|
version: '0'
|
131
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
151
|
requirements:
|
133
|
-
- - "
|
152
|
+
- - ">"
|
134
153
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
154
|
+
version: 1.3.1
|
136
155
|
requirements: []
|
137
156
|
rubygems_version: 3.0.3
|
138
157
|
signing_key:
|