marlowe 2.1 → 3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +59 -0
- data/.standard.yml +4 -0
- data/History.md +20 -6
- data/Licence.md +11 -13
- data/Manifest.txt +5 -0
- data/README.rdoc +60 -34
- data/Rakefile +4 -7
- data/lib/marlowe/config.rb +116 -0
- data/lib/marlowe/faraday.rb +20 -0
- data/lib/marlowe/middleware.rb +17 -48
- data/lib/marlowe/rails.rb +7 -9
- data/lib/marlowe/simple_formatter.rb +2 -0
- data/lib/marlowe.rb +34 -1
- data/test/minitest_config.rb +26 -0
- data/test/test_marlowe.rb +33 -32
- data/test/test_marlowe_config.rb +110 -0
- metadata +34 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab7ab600bebd938d83401763fdb4da4e46448cce69f2421e0e8e68dec967c289
|
4
|
+
data.tar.gz: 5b5a7f77d71cabe799fba50b54e5639c0f9e3e0fc75600b0c5cd486dab850d1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 630dea03e6bb4aed6e325baba7152a18c129c76d3ef2a029bdb7079432ff9b5bc8477742cb7d64c2e78718554eaf95bf8f9ce43aaaab66110c95e32616532f93
|
7
|
+
data.tar.gz: 6a6a17555432e901b74abbefb5f65385e79cb22c942e6605d5885e04366f246012ba8681ff74b30583bb808835782b9b8a380971bb7ca0d7b4b13ed324b37eb5
|
@@ -0,0 +1,59 @@
|
|
1
|
+
name: Ruby CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
push:
|
6
|
+
branches:
|
7
|
+
- main
|
8
|
+
- master
|
9
|
+
workflow_dispatch:
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
ruby-ci:
|
13
|
+
name: Ruby ${{ matrix.ruby }} - ${{ matrix.os }}
|
14
|
+
|
15
|
+
strategy:
|
16
|
+
fail-fast: true
|
17
|
+
matrix:
|
18
|
+
os:
|
19
|
+
- ubuntu-20.04
|
20
|
+
ruby:
|
21
|
+
- '2.7'
|
22
|
+
- '3.0'
|
23
|
+
- '3.1'
|
24
|
+
- '3.2'
|
25
|
+
- '3.3'
|
26
|
+
- head
|
27
|
+
- jruby
|
28
|
+
- jruby-head
|
29
|
+
- truffleruby
|
30
|
+
- truffleruby-head
|
31
|
+
include:
|
32
|
+
- ruby: head
|
33
|
+
continue-on-error: true
|
34
|
+
- ruby: jruby-head
|
35
|
+
continue-on-error: true
|
36
|
+
- os: ubuntu-22.04
|
37
|
+
ruby: head
|
38
|
+
- os: ubuntu-22.04
|
39
|
+
ruby: '3.2'
|
40
|
+
- os: ubuntu-22.04
|
41
|
+
ruby: '3.3'
|
42
|
+
|
43
|
+
runs-on: ${{ matrix.os }}
|
44
|
+
|
45
|
+
continue-on-error: ${{ matrix.continue-on-error || false }}
|
46
|
+
|
47
|
+
steps:
|
48
|
+
- uses: actions/checkout@v3
|
49
|
+
- uses: ruby/setup-ruby@v1
|
50
|
+
with:
|
51
|
+
ruby-version: ${{ matrix.ruby }}
|
52
|
+
bundler-cache: true
|
53
|
+
|
54
|
+
- run: bundle exec ruby -S rake test --trace
|
55
|
+
- run: bundle exec ruby -S appraisal install
|
56
|
+
- run: bundle exec ruby -S appraisal rake test
|
57
|
+
|
58
|
+
- run: bundle exec standardrb
|
59
|
+
if: ${{ matrix.ruby == '3.3' && matrix.os == 'ubuntu-22.04' }}
|
data/.standard.yml
ADDED
data/History.md
CHANGED
@@ -1,10 +1,24 @@
|
|
1
|
-
|
1
|
+
# History
|
2
|
+
|
3
|
+
## 3.1 / 2024-02-29
|
4
|
+
|
5
|
+
- Fixed some noise in the tests as preparation for Rack 3.1.
|
6
|
+
- Updated dependencies.
|
7
|
+
|
8
|
+
## 3.0 / 2022-09-11
|
9
|
+
|
10
|
+
- Added a Faraday request middleware.
|
11
|
+
- Replaced Hurley example with examples for the use of the Faraday
|
12
|
+
middleware.
|
13
|
+
- Added global Marlowe configuration.
|
14
|
+
|
15
|
+
## 2.1 / 2021-09-08
|
2
16
|
|
3
17
|
- Allow the use of Ruby 3.
|
4
18
|
- Switch to standardruby instead of rubocop.
|
5
19
|
- Switch from Travis to Github Actions.
|
6
20
|
|
7
|
-
|
21
|
+
## 2.0 / 2016-11-16
|
8
22
|
|
9
23
|
- Breaking change: the correlation header defaults to `X-Request-Id` instead of
|
10
24
|
`Correlation-Id`.
|
@@ -15,21 +29,21 @@
|
|
15
29
|
part of the response.
|
16
30
|
- Marlowe is more configurable now.
|
17
31
|
|
18
|
-
|
32
|
+
## 1.0.3 / 2016-01-15
|
19
33
|
|
20
34
|
- Update Readme example of using available formatted subclass.
|
21
35
|
- Make the correlation header name configurable
|
22
36
|
|
23
|
-
|
37
|
+
## 1.0.2 / 2015-11-24
|
24
38
|
|
25
39
|
- Add documentation for using Marlowe with [lograge][].
|
26
40
|
|
27
|
-
|
41
|
+
## 1.0.1 / 2015-10-20
|
28
42
|
|
29
43
|
- Update gemspec with homepage
|
30
44
|
- Update Rakefile
|
31
45
|
|
32
|
-
|
46
|
+
## 1.0.0 / 2015-10-16
|
33
47
|
|
34
48
|
- Initial Commit
|
35
49
|
|
data/Licence.md
CHANGED
@@ -2,26 +2,24 @@
|
|
2
2
|
|
3
3
|
This software is available under an MIT-style licence.
|
4
4
|
|
5
|
-
|
5
|
+
- Copyright 2015–2022 Kinetic Cafe
|
6
6
|
|
7
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
8
8
|
this software and associated documentation files (the "Software"), to deal in
|
9
9
|
the Software without restriction, including without limitation the rights to
|
10
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
11
|
-
|
12
|
-
|
10
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
11
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
12
|
+
subject to the following conditions:
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
permission.
|
14
|
+
- The names of its contributors may not be used to endorse or promote products
|
15
|
+
derived from this software without specific prior written permission.
|
17
16
|
|
18
17
|
The above copyright notice and this permission notice shall be included in all
|
19
18
|
copies or substantial portions of the Software.
|
20
19
|
|
21
20
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
22
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
SOFTWARE.
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
22
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
23
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
24
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
25
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
.github/workflows/ruby.yml
|
2
|
+
.standard.yml
|
1
3
|
Contributing.md
|
2
4
|
History.md
|
3
5
|
Licence.md
|
@@ -5,9 +7,12 @@ Manifest.txt
|
|
5
7
|
README.rdoc
|
6
8
|
Rakefile
|
7
9
|
lib/marlowe.rb
|
10
|
+
lib/marlowe/config.rb
|
11
|
+
lib/marlowe/faraday.rb
|
8
12
|
lib/marlowe/formatter.rb
|
9
13
|
lib/marlowe/middleware.rb
|
10
14
|
lib/marlowe/rails.rb
|
11
15
|
lib/marlowe/simple_formatter.rb
|
12
16
|
test/minitest_config.rb
|
13
17
|
test/test_marlowe.rb
|
18
|
+
test/test_marlowe_config.rb
|
data/README.rdoc
CHANGED
@@ -14,7 +14,41 @@ correlation across multiple services.
|
|
14
14
|
When using Rails, Marlowe automatically adds itself to the middleware before
|
15
15
|
<tt>Rails::Rack::Logger</tt>.
|
16
16
|
|
17
|
-
|
17
|
+
As of Marlowe 3.0, a Faraday middleware is provided (<tt>require 'marlowe/faraday'</tt>).
|
18
|
+
|
19
|
+
=== Upgrading
|
20
|
+
|
21
|
+
==== from Marlowe 2.0
|
22
|
+
|
23
|
+
In Marlowe 2.0, configuration was entirely specified in Rails configuration or
|
24
|
+
in the Rack +use+ clause. With the addition of a Faraday middleware for use with
|
25
|
+
Marlowe, centralization of the configuration is advisable.
|
26
|
+
|
27
|
+
The existing configuration mechanisms will work (and create instance
|
28
|
+
configurations if provided), but it is instead recommended to use the global
|
29
|
+
configuration:
|
30
|
+
|
31
|
+
# Compatibility with Marlowe 1.0
|
32
|
+
Marlowe.configure do |config|
|
33
|
+
config.header = 'Correlation-ID'
|
34
|
+
config.handler = :simple
|
35
|
+
config.return = false
|
36
|
+
end
|
37
|
+
|
38
|
+
Configuration is static for Marlowe::Middleware or Marlowe::Faraday instances
|
39
|
+
and changes to Marlowe configuration only affect *new* instances. If the
|
40
|
+
configuration options are provided in the middleware +use+ clause, they will
|
41
|
+
override the configured values.
|
42
|
+
|
43
|
+
Marlowe.configure do |config|
|
44
|
+
config.header = 'Correlation-ID'
|
45
|
+
config.handler = :simple
|
46
|
+
config.return = false
|
47
|
+
end
|
48
|
+
use Marlowe::Middleware, handler: :clean
|
49
|
+
# The handler will be the :clean handler for the used middleware.
|
50
|
+
|
51
|
+
==== from Marlowe 1.x
|
18
52
|
|
19
53
|
In Marlowe 1.0, the correlation header was called <tt>Correlation-Id</tt>;
|
20
54
|
since then, Rails 5 and other tools and frameworks (such as Phoenix) have
|
@@ -109,7 +143,7 @@ The correlation id can be accessed throughout the application by accessing the
|
|
109
143
|
|
110
144
|
For a Rails application, you simply need to change the log formatter to one of
|
111
145
|
the provided ones. Correlated versions of both the SimpleFormatter and
|
112
|
-
Formatter are included.
|
146
|
+
Formatter are included.
|
113
147
|
|
114
148
|
# config/environments/development.rb
|
115
149
|
Rails.application.configure do
|
@@ -134,7 +168,7 @@ As {lograge}[https://github.com/roidrage/lograge] supplies its own formatter,
|
|
134
168
|
you will need to do something a little different:
|
135
169
|
|
136
170
|
# config/application.rb
|
137
|
-
|
171
|
+
|
138
172
|
class Application < Rails::Application
|
139
173
|
config.before_initialize do
|
140
174
|
...
|
@@ -146,47 +180,39 @@ you will need to do something a little different:
|
|
146
180
|
end
|
147
181
|
end
|
148
182
|
|
149
|
-
|
150
|
-
|
151
|
-
Catching and creating the correlation ID is a great all on its own, but to
|
152
|
-
really take advantage of the correlation in a service based architecture you'll
|
153
|
-
need to pass the request ID to the next service in the change.
|
154
|
-
|
155
|
-
Here's an example of a {Hurley}[https://github.com/lostisland/hurley] client:
|
183
|
+
=== SemanticLogger
|
156
184
|
|
157
|
-
|
185
|
+
As {semantic_logger}[https://github.com/rocketjob/semantic_logger] provides its
|
186
|
+
own formatters this should be added as a tag. The best way that I can see to do
|
187
|
+
this is to capture the +correlation_id+ in an +on_log+ event:
|
158
188
|
|
159
|
-
|
160
|
-
require 'request_store'
|
189
|
+
# config/initializers/semantic_logger.rb
|
161
190
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
header['X-Request-Id'] = ::RequestStore.store[:correlation_id]
|
191
|
+
SemanticLogger.on_log do |log|
|
192
|
+
if RequestStore[:correlation_id]
|
193
|
+
log.named_tags[:correlation_id] = RequestStore[:correlation_id]
|
166
194
|
end
|
167
195
|
end
|
168
196
|
|
169
|
-
|
170
|
-
{callback machanism}[https://github.com/lostisland/hurley#client-callbacks] to
|
171
|
-
add the outgoing headers:
|
197
|
+
== Clients
|
172
198
|
|
173
|
-
|
174
|
-
|
175
|
-
|
199
|
+
Catching and creating the correlation ID is a great all on its own, but to
|
200
|
+
really take advantage of the correlation in a service based architecture you'll
|
201
|
+
need to pass the request ID to the next service in the change.
|
176
202
|
|
177
|
-
|
178
|
-
|
179
|
-
class Correlator
|
180
|
-
def name
|
181
|
-
:correlator
|
182
|
-
end
|
203
|
+
Here's an example with {Faraday}[https://github.com/lostisland/faraday]:
|
183
204
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
205
|
+
require 'faraday'
|
206
|
+
require 'faraday_middleware'
|
207
|
+
require 'marlowe/faraday'
|
208
|
+
|
209
|
+
conn = Faraday.new(url: 'https://example.org/') do |conn|
|
210
|
+
conn.request :marlowe
|
211
|
+
conn.request :json
|
188
212
|
|
189
|
-
|
213
|
+
conn.response :json
|
214
|
+
conn.adapter Faraday.default_adapter
|
215
|
+
end
|
190
216
|
|
191
217
|
== Install
|
192
218
|
|
data/Rakefile
CHANGED
@@ -23,29 +23,26 @@ spec = Hoe.spec "marlowe" do
|
|
23
23
|
require_ruby_version ">= 2.0", "< 4"
|
24
24
|
|
25
25
|
extra_deps << ["request_store", "~> 1.2"]
|
26
|
-
extra_deps << ["rack", ">=
|
26
|
+
extra_deps << ["rack", ">= 1", "< 4"]
|
27
27
|
|
28
28
|
extra_dev_deps << ["appraisal", "~> 2.1"]
|
29
29
|
extra_dev_deps << ["hoe-doofus", "~> 1.0"]
|
30
30
|
extra_dev_deps << ["hoe-gemspec2", "~> 1.1"]
|
31
|
-
extra_dev_deps << ["hoe-
|
31
|
+
extra_dev_deps << ["hoe-git2", "~> 1.7"]
|
32
32
|
extra_dev_deps << ["hoe-rubygems", "~> 1.0"]
|
33
33
|
extra_dev_deps << ["minitest", "~> 5.4"]
|
34
34
|
extra_dev_deps << ["minitest-autotest", "~> 1.0"]
|
35
|
-
extra_dev_deps << ["minitest-bonus-assertions", "~> 3.0"]
|
36
35
|
extra_dev_deps << ["minitest-focus", "~> 1.1"]
|
37
36
|
extra_dev_deps << ["minitest-moar", "~> 0.0"]
|
38
|
-
extra_dev_deps << ["rack-test", "~>
|
37
|
+
extra_dev_deps << ["rack-test", "~> 2.0"]
|
39
38
|
extra_dev_deps << ["rake", ">= 10.0", "< 14"]
|
40
|
-
extra_dev_deps << ["rdoc", ">= 4.2"]
|
41
39
|
extra_dev_deps << ["standard", "~> 1.0"]
|
42
40
|
extra_dev_deps << ["simplecov", "~> 0.21"]
|
43
|
-
extra_dev_deps << ["psych", "~> 3.1"]
|
44
41
|
end
|
45
42
|
|
46
43
|
ENV["RUBYOPT"] = "-W0"
|
47
44
|
|
48
|
-
module Hoe::Publish
|
45
|
+
module Hoe::Publish # :nodoc:
|
49
46
|
alias_method :__make_rdoc_cmd__marlowe__, :make_rdoc_cmd
|
50
47
|
|
51
48
|
def make_rdoc_cmd(*extra_args) # :nodoc:
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Configuration object for Marlowe.
|
4
|
+
class Marlowe::Config
|
5
|
+
# The name of the default header to look for and put the correlation id in.
|
6
|
+
CORRELATION_HEADER = "X-Request-Id" # :nodoc:
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# The global Marlowe configuration.
|
10
|
+
def global
|
11
|
+
@global ||= new
|
12
|
+
end
|
13
|
+
|
14
|
+
# Override the global Marlowe configuration.
|
15
|
+
def override(opts)
|
16
|
+
new(global, opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def configure(&block) # :nodoc:
|
20
|
+
@global = new(global, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def clear_global!
|
26
|
+
@global = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# The name of the header to inspect. Defaults to 'X-Request-Id'.
|
31
|
+
attr_accessor :header
|
32
|
+
# The HTTP formatted version of the header name to inspect. Defaults to
|
33
|
+
# 'HTTP_X_REQUEST_ID'.
|
34
|
+
attr_reader :http_header
|
35
|
+
# The handler for request correlation IDs. Defaults to sanitizing provided
|
36
|
+
# request IDs or generating a UUID. If <tt>:simple</tt> is provided, provided
|
37
|
+
# request IDs will not be sanitized. A callable (expecting a single input of
|
38
|
+
# any possible existing request ID) may be provided to introduce more complex
|
39
|
+
# request ID handling.
|
40
|
+
attr_accessor :handler
|
41
|
+
# If +true+ (the default), the request correlation ID will be returned as
|
42
|
+
# part of the response headers. Only affects Marlowe::Middleware.
|
43
|
+
attr_accessor :return
|
44
|
+
# If +true+, Marlowe will add code to behave like
|
45
|
+
# <tt>ActionDispatch::RequestId</tt>. Depends on
|
46
|
+
# <tt>ActionDispatch::Request</tt>. Only affects Marlowe::Middleware.
|
47
|
+
attr_accessor :action_dispatch
|
48
|
+
|
49
|
+
# === Option Values
|
50
|
+
#
|
51
|
+
# <tt>:header</tt>:: The name of the header to inspect. Defaults to
|
52
|
+
# 'X-Request-Id'. Also available as
|
53
|
+
# <tt>:correlation_header</tt>.
|
54
|
+
# <tt>:handler</tt>:: The handler for request correlation IDs. Defaults to
|
55
|
+
# sanitizing provided request IDs or generating a UUID.
|
56
|
+
# If <tt>:simple</tt> is provided, provided request IDs
|
57
|
+
# will not be sanitized. A callable (expecting a single
|
58
|
+
# input of any possible existing request ID) may be
|
59
|
+
# provided to introduce more complex request ID
|
60
|
+
# handling.
|
61
|
+
# <tt>:return</tt>:: If +true+ (the default), the request correlation ID
|
62
|
+
# will be returned as part of the response headers.
|
63
|
+
# <tt>:action_dispatch</tt>:: If +true+, Marlowe will add code to behave
|
64
|
+
# like <tt>ActionDispatch::RequestId</tt>.
|
65
|
+
# Depends on <tt>ActionDispatch::Request</tt>.
|
66
|
+
def initialize(base = nil, opts = nil) # :yields: self
|
67
|
+
opts =
|
68
|
+
if base.nil? && opts.nil?
|
69
|
+
{}
|
70
|
+
elsif base.nil? && opts.is_a?(Hash)
|
71
|
+
opts
|
72
|
+
elsif base.is_a?(Hash) && opts.nil?
|
73
|
+
base
|
74
|
+
elsif base.is_a?(self.class) && opts.nil?
|
75
|
+
base.to_hash
|
76
|
+
elsif (base.is_a?(Hash) || base.is_a?(self.class)) && opts.is_a?(Hash)
|
77
|
+
hash =
|
78
|
+
if base.is_a?(self.class)
|
79
|
+
base.to_hash
|
80
|
+
else
|
81
|
+
base
|
82
|
+
end
|
83
|
+
hash.update(opts)
|
84
|
+
end
|
85
|
+
|
86
|
+
@header, @http_header = format_header_name(
|
87
|
+
opts[:header] || opts[:correlation_header] || CORRELATION_HEADER
|
88
|
+
)
|
89
|
+
|
90
|
+
@handler = opts.fetch(:handler, :clean)
|
91
|
+
@return = opts.fetch(:return, true)
|
92
|
+
@action_dispatch = opts.fetch(:action_dispatch, false)
|
93
|
+
|
94
|
+
yield self if block_given?
|
95
|
+
|
96
|
+
freeze
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_hash
|
100
|
+
{
|
101
|
+
header: header,
|
102
|
+
handler: handler,
|
103
|
+
return: self.return,
|
104
|
+
action_dispatch: action_dispatch
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def format_header_name(header)
|
111
|
+
[
|
112
|
+
header.to_s.tr("_", "-").freeze,
|
113
|
+
"HTTP_#{header.to_s.tr("-", "_").upcase}"
|
114
|
+
]
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "marlowe"
|
4
|
+
|
5
|
+
# Marlowe correlation ID middleware for Faraday. Including this into your
|
6
|
+
# request middleware stack will use the captured correlation ID.
|
7
|
+
class Marlowe::Faraday < Faraday::Middleware
|
8
|
+
def initialize(app, opts = {})
|
9
|
+
super(app)
|
10
|
+
@config = Marlowe::Config.override(opts)
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
env[:request_headers][@config.header] =
|
15
|
+
Marlowe.make_request_id(RequestStore[:correlation_id], @config)
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Faraday::Request.register_middleware marlowe: -> { Marlowe::Faraday }
|
data/lib/marlowe/middleware.rb
CHANGED
@@ -6,11 +6,11 @@ require "securerandom"
|
|
6
6
|
|
7
7
|
module Marlowe
|
8
8
|
# Marlowe correlation id middleware. Including this into your middleware
|
9
|
-
# stack will add a correlation id header
|
10
|
-
# that id in a request session variable.
|
9
|
+
# stack will capture or add a correlation id header on an incoming request,
|
10
|
+
# and save that id in a request session variable.
|
11
11
|
class Middleware
|
12
12
|
# The name of the default header to look for and put the correlation id in.
|
13
|
-
CORRELATION_HEADER =
|
13
|
+
CORRELATION_HEADER = Marlowe::Config::CORRELATION_HEADER # :nodoc:
|
14
14
|
|
15
15
|
# Configure the Marlowe middleware to call +app+ with options +opts+.
|
16
16
|
#
|
@@ -31,67 +31,36 @@ module Marlowe
|
|
31
31
|
# <tt>:action_dispatch</tt>:: If +true+, Marlowe will add code to behave
|
32
32
|
# like <tt>ActionDispatch::RequestId</tt>.
|
33
33
|
# Depends on <tt>ActionDispatch::Request</tt>.
|
34
|
-
def initialize(app, opts =
|
34
|
+
def initialize(app, opts = nil)
|
35
35
|
@app = app
|
36
|
-
@
|
37
|
-
opts[:header] || opts[:correlation_header] || CORRELATION_HEADER
|
38
|
-
)
|
39
|
-
@handler = opts.fetch(:handler, :clean)
|
40
|
-
@return = opts.fetch(:return, true)
|
41
|
-
@action_dispatch = opts.fetch(:action_dispatch, false)
|
36
|
+
@config = Marlowe::Config.override(opts)
|
42
37
|
end
|
43
38
|
|
44
39
|
# Stores the incoming correlation id from the +env+ hash. If the correlation
|
45
40
|
# id has not been sent, a new UUID is generated and the +env+ is modified.
|
46
41
|
def call(env)
|
47
|
-
req_id = make_request_id(env[
|
48
|
-
RequestStore.store[:correlation_id] = env[
|
42
|
+
req_id = Marlowe.make_request_id(env[config.http_header], config)
|
43
|
+
RequestStore.store[:correlation_id] = env[config.http_header] = req_id
|
49
44
|
|
50
|
-
if
|
45
|
+
if config.action_dispatch
|
51
46
|
req = ActionDispatch::Request.new(env)
|
52
47
|
req.request_id = req_id
|
53
48
|
end
|
54
49
|
|
55
|
-
|
56
|
-
if
|
57
|
-
headers[
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
50
|
+
app.call(env).tap { |_status, headers, _body|
|
51
|
+
if config.return
|
52
|
+
headers[config.header] =
|
53
|
+
if config.action_dispatch
|
54
|
+
req.request_id
|
55
|
+
else
|
56
|
+
RequestStore.store[:correlation_id]
|
57
|
+
end
|
62
58
|
end
|
63
59
|
}
|
64
60
|
end
|
65
61
|
|
66
62
|
private
|
67
63
|
|
68
|
-
|
69
|
-
[
|
70
|
-
header.to_s.tr("_", "-").freeze,
|
71
|
-
"HTTP_#{header.to_s.tr("-", "_").upcase}"
|
72
|
-
]
|
73
|
-
end
|
74
|
-
|
75
|
-
def make_request_id(request_id)
|
76
|
-
if @handler == :simple
|
77
|
-
simple(request_id)
|
78
|
-
elsif @handler.is_a?(Proc)
|
79
|
-
simple(@handler.call(request_id))
|
80
|
-
else
|
81
|
-
clean(request_id)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def clean(request_id)
|
86
|
-
simple(request_id).gsub(/[^\w\-]/, "")[0, 255]
|
87
|
-
end
|
88
|
-
|
89
|
-
def simple(request_id)
|
90
|
-
if request_id && !request_id.empty? && request_id !~ /\A[[:space]]*\z/
|
91
|
-
request_id
|
92
|
-
else
|
93
|
-
SecureRandom.uuid
|
94
|
-
end
|
95
|
-
end
|
64
|
+
attr_reader :app, :config
|
96
65
|
end
|
97
66
|
end
|
data/lib/marlowe/rails.rb
CHANGED
@@ -6,23 +6,21 @@ module Marlowe
|
|
6
6
|
config = app.config
|
7
7
|
|
8
8
|
opts = {
|
9
|
-
header: config
|
10
|
-
handler: config
|
11
|
-
return: config
|
12
|
-
action_dispatch: config
|
9
|
+
header: config&.marlowe_header || config&.marlowe_correlation_header,
|
10
|
+
handler: config&.marlowe_request_id_handler,
|
11
|
+
return: config&.marlowe_return_request_id,
|
12
|
+
action_dispatch: config&.marlowe_replace_action_dispatch_request_id
|
13
13
|
}.compact
|
14
14
|
|
15
15
|
if opts[:action_dispatch]
|
16
|
-
app.middleware.insert_before ActionDispatch::RequestId,
|
17
|
-
Marlowe::Middleware, opts
|
16
|
+
app.middleware.insert_before ActionDispatch::RequestId, Marlowe::Middleware, opts
|
18
17
|
app.middleware.delete ActionDispatch::RequestId
|
19
18
|
else
|
20
|
-
app.middleware.insert_before Rails::Rack::Logger, Marlowe::Middleware,
|
21
|
-
opts
|
19
|
+
app.middleware.insert_before Rails::Rack::Logger, Marlowe::Middleware, opts
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
25
|
-
def app
|
23
|
+
def app # :nodoc:
|
26
24
|
Rails.application
|
27
25
|
end
|
28
26
|
end
|
data/lib/marlowe.rb
CHANGED
@@ -2,11 +2,44 @@
|
|
2
2
|
|
3
3
|
# Marlowe, a correlation id injector.
|
4
4
|
module Marlowe
|
5
|
-
VERSION = "
|
5
|
+
VERSION = "3.1" # :nodoc:
|
6
6
|
|
7
|
+
require "marlowe/config"
|
7
8
|
require "marlowe/middleware"
|
8
9
|
require "marlowe/rails" if defined? Rails::Railtie
|
9
10
|
|
10
11
|
autoload :Formatter, "marlowe/formatter"
|
11
12
|
autoload :SimpleFormatter, "marlowe/simple_formatter"
|
13
|
+
|
14
|
+
class << self
|
15
|
+
# Configure Marlowe
|
16
|
+
def configure(&block)
|
17
|
+
Marlowe::Config.configure(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Make a Marlowe request ID
|
21
|
+
def make_request_id(request_id, config = Marlowe::Config.global)
|
22
|
+
if config.handler == :simple
|
23
|
+
simple(request_id)
|
24
|
+
elsif config.handler.is_a?(Proc)
|
25
|
+
simple(config.handler.call(request_id))
|
26
|
+
else
|
27
|
+
clean(request_id)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def clean(request_id)
|
34
|
+
simple(request_id).gsub(/[^\w\-]/, "")[0, 255]
|
35
|
+
end
|
36
|
+
|
37
|
+
def simple(request_id)
|
38
|
+
if request_id && !request_id.empty? && request_id !~ /\A[[:space]]*\z/
|
39
|
+
request_id
|
40
|
+
else
|
41
|
+
SecureRandom.uuid
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
12
45
|
end
|
data/test/minitest_config.rb
CHANGED
@@ -9,3 +9,29 @@ require "minitest/focus"
|
|
9
9
|
require "minitest/moar"
|
10
10
|
|
11
11
|
require "marlowe"
|
12
|
+
|
13
|
+
RackV1 = Rack.release.start_with?("1.")
|
14
|
+
|
15
|
+
module NormalizeRackResponseHeaders
|
16
|
+
private
|
17
|
+
|
18
|
+
def has_header?(key)
|
19
|
+
if RackV1
|
20
|
+
last_response.header.key?(key)
|
21
|
+
else
|
22
|
+
last_response.has_header?(key)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_header(key)
|
27
|
+
if RackV1
|
28
|
+
last_response.header[key]
|
29
|
+
else
|
30
|
+
last_response.get_header(key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Minitest::Test
|
36
|
+
include NormalizeRackResponseHeaders
|
37
|
+
end
|
data/test/test_marlowe.rb
CHANGED
@@ -9,6 +9,7 @@ class TestMarlowe < Minitest::Test
|
|
9
9
|
|
10
10
|
def setup
|
11
11
|
@marlowe_options = {}
|
12
|
+
Marlowe::Config.send(:clear_global!)
|
12
13
|
end
|
13
14
|
|
14
15
|
def app
|
@@ -28,75 +29,75 @@ class TestMarlowe < Minitest::Test
|
|
28
29
|
|
29
30
|
def test_default_config_no_header_value
|
30
31
|
get "/"
|
31
|
-
assert
|
32
|
-
refute_empty
|
33
|
-
assert_equal
|
32
|
+
assert has_header?("X-Request-Id")
|
33
|
+
refute_empty get_header("X-Request-Id")
|
34
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
34
35
|
end
|
35
36
|
|
36
37
|
def test_default_config_with_header_value
|
37
38
|
get "/", {}, {"HTTP_X_REQUEST_ID" => "testvalue"}
|
38
|
-
assert
|
39
|
-
refute_empty
|
40
|
-
assert_equal
|
41
|
-
assert_equal "testvalue",
|
39
|
+
assert has_header?("X-Request-Id")
|
40
|
+
refute_empty get_header("X-Request-Id")
|
41
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
42
|
+
assert_equal "testvalue", get_header("X-Request-Id")
|
42
43
|
end
|
43
44
|
|
44
45
|
def test_header_config_no_header_value
|
45
46
|
marlowe_options[:header] = "Correlation-Id"
|
46
47
|
get "/"
|
47
|
-
assert
|
48
|
-
refute_empty
|
49
|
-
assert_equal
|
48
|
+
assert has_header?("Correlation-Id")
|
49
|
+
refute_empty get_header("Correlation-Id")
|
50
|
+
assert_equal get_header("Correlation-Id"), last_response.body
|
50
51
|
end
|
51
52
|
|
52
53
|
def test_header_config_no_header_with_header_value
|
53
54
|
marlowe_options[:header] = "Correlation-Id"
|
54
55
|
get "/", {}, {"HTTP_CORRELATION_ID" => "testvalue"}
|
55
|
-
assert
|
56
|
-
refute_empty
|
57
|
-
assert_equal
|
58
|
-
assert_equal "testvalue",
|
56
|
+
assert has_header?("Correlation-Id")
|
57
|
+
refute_empty get_header("Correlation-Id")
|
58
|
+
assert_equal get_header("Correlation-Id"), last_response.body
|
59
|
+
assert_equal "testvalue", get_header("Correlation-Id")
|
59
60
|
end
|
60
61
|
|
61
62
|
def test_handler_config_default_handler
|
62
63
|
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
63
|
-
assert
|
64
|
-
refute_empty
|
65
|
-
assert_equal
|
66
|
-
assert_equal "testvalue",
|
64
|
+
assert has_header?("X-Request-Id")
|
65
|
+
refute_empty get_header("X-Request-Id")
|
66
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
67
|
+
assert_equal "testvalue", get_header("X-Request-Id")
|
67
68
|
end
|
68
69
|
|
69
70
|
def test_handler_config_with_simple_handler
|
70
71
|
marlowe_options[:handler] = :simple
|
71
72
|
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
72
|
-
assert
|
73
|
-
refute_empty
|
74
|
-
assert_equal
|
75
|
-
assert_equal "test+value",
|
73
|
+
assert has_header?("X-Request-Id")
|
74
|
+
refute_empty get_header("X-Request-Id")
|
75
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
76
|
+
assert_equal "test+value", get_header("X-Request-Id")
|
76
77
|
end
|
77
78
|
|
78
79
|
def test_handler_config_with_proc_handler
|
79
80
|
marlowe_options[:handler] = ->(item) { item && item.reverse || SecureRandom.uuid }
|
80
81
|
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
81
|
-
assert
|
82
|
-
refute_empty
|
83
|
-
assert_equal
|
84
|
-
assert_equal "eulav+tset",
|
82
|
+
assert has_header?("X-Request-Id")
|
83
|
+
refute_empty get_header("X-Request-Id")
|
84
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
85
|
+
assert_equal "eulav+tset", get_header("X-Request-Id")
|
85
86
|
end
|
86
87
|
|
87
88
|
def test_handler_config_with_proc_handler_returning_nil
|
88
|
-
marlowe_options[:handler] = ->(
|
89
|
+
marlowe_options[:handler] = ->(_item) {}
|
89
90
|
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
90
|
-
assert
|
91
|
-
refute_empty
|
92
|
-
assert_equal
|
93
|
-
assert_match(/\A[-\w]+\z/,
|
91
|
+
assert has_header?("X-Request-Id")
|
92
|
+
refute_empty get_header("X-Request-Id")
|
93
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
94
|
+
assert_match(/\A[-\w]+\z/, get_header("X-Request-Id"))
|
94
95
|
end
|
95
96
|
|
96
97
|
def test_return_config_false
|
97
98
|
marlowe_options[:return] = false
|
98
99
|
get "/"
|
99
|
-
refute
|
100
|
+
refute has_header?("X-Request-Id")
|
100
101
|
assert_equal RequestStore[:correlation_id], last_response.body
|
101
102
|
end
|
102
103
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "minitest_config"
|
4
|
+
|
5
|
+
class TestMarloweConfig < Minitest::Test
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
attr_reader :marlowe_options
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@marlowe_options = {}
|
12
|
+
Marlowe::Config.send(:clear_global!)
|
13
|
+
end
|
14
|
+
|
15
|
+
def app
|
16
|
+
Marlowe.configure do |config|
|
17
|
+
marlowe_options.each do |k, v|
|
18
|
+
config.send(:"#{k}=", v) if config.respond_to?(:"#{k}=")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
options = marlowe_options
|
23
|
+
Rack::Builder.new do
|
24
|
+
use Marlowe::Middleware, options
|
25
|
+
|
26
|
+
run lambda { |_env|
|
27
|
+
[
|
28
|
+
200,
|
29
|
+
{"Content-Type" => "text/plain"},
|
30
|
+
[RequestStore[:correlation_id]]
|
31
|
+
]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_default_config_no_header_value
|
37
|
+
get "/"
|
38
|
+
|
39
|
+
assert has_header?("X-Request-Id")
|
40
|
+
refute_empty get_header("X-Request-Id")
|
41
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_default_config_with_header_value
|
45
|
+
get "/", {}, {"HTTP_X_REQUEST_ID" => "testvalue"}
|
46
|
+
assert has_header?("X-Request-Id")
|
47
|
+
refute_empty get_header("X-Request-Id")
|
48
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
49
|
+
assert_equal "testvalue", get_header("X-Request-Id")
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_header_config_no_header_value
|
53
|
+
marlowe_options[:header] = "Correlation-Id"
|
54
|
+
get "/"
|
55
|
+
assert has_header?("Correlation-Id")
|
56
|
+
refute_empty get_header("Correlation-Id")
|
57
|
+
assert_equal get_header("Correlation-Id"), last_response.body
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_header_config_no_header_with_header_value
|
61
|
+
marlowe_options[:header] = "Correlation-Id"
|
62
|
+
get "/", {}, {"HTTP_CORRELATION_ID" => "testvalue"}
|
63
|
+
assert has_header?("Correlation-Id")
|
64
|
+
refute_empty get_header("Correlation-Id")
|
65
|
+
assert_equal get_header("Correlation-Id"), last_response.body
|
66
|
+
assert_equal "testvalue", get_header("Correlation-Id")
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_handler_config_default_handler
|
70
|
+
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
71
|
+
assert has_header?("X-Request-Id")
|
72
|
+
refute_empty get_header("X-Request-Id")
|
73
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
74
|
+
assert_equal "testvalue", get_header("X-Request-Id")
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_handler_config_with_simple_handler
|
78
|
+
marlowe_options[:handler] = :simple
|
79
|
+
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
80
|
+
assert has_header?("X-Request-Id")
|
81
|
+
refute_empty get_header("X-Request-Id")
|
82
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
83
|
+
assert_equal "test+value", get_header("X-Request-Id")
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_handler_config_with_proc_handler
|
87
|
+
marlowe_options[:handler] = ->(item) { item && item.reverse || SecureRandom.uuid }
|
88
|
+
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
89
|
+
assert has_header?("X-Request-Id")
|
90
|
+
refute_empty get_header("X-Request-Id")
|
91
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
92
|
+
assert_equal "eulav+tset", get_header("X-Request-Id")
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_handler_config_with_proc_handler_returning_nil
|
96
|
+
marlowe_options[:handler] = ->(_item) {}
|
97
|
+
get "/", {}, {"HTTP_X_REQUEST_ID" => "test+value"}
|
98
|
+
assert has_header?("X-Request-Id")
|
99
|
+
refute_empty get_header("X-Request-Id")
|
100
|
+
assert_equal get_header("X-Request-Id"), last_response.body
|
101
|
+
assert_match(/\A[-\w]+\z/, get_header("X-Request-Id"))
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_return_config_false
|
105
|
+
marlowe_options[:return] = false
|
106
|
+
get "/"
|
107
|
+
refute has_header?("X-Request-Id")
|
108
|
+
assert_equal RequestStore[:correlation_id], last_response.body
|
109
|
+
end
|
110
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marlowe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '3.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Trevor Oke
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-02-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: request_store
|
@@ -31,34 +31,34 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '1'
|
35
35
|
- - "<"
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
37
|
+
version: '4'
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
42
|
- - ">="
|
43
43
|
- !ruby/object:Gem::Version
|
44
|
-
version: '
|
44
|
+
version: '1'
|
45
45
|
- - "<"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '4'
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: minitest
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '5.
|
54
|
+
version: '5.22'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '5.
|
61
|
+
version: '5.22'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: appraisal
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,19 +102,19 @@ dependencies:
|
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '1.1'
|
104
104
|
- !ruby/object:Gem::Dependency
|
105
|
-
name: hoe-
|
105
|
+
name: hoe-git2
|
106
106
|
requirement: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '1.
|
110
|
+
version: '1.7'
|
111
111
|
type: :development
|
112
112
|
prerelease: false
|
113
113
|
version_requirements: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '1.
|
117
|
+
version: '1.7'
|
118
118
|
- !ruby/object:Gem::Dependency
|
119
119
|
name: hoe-rubygems
|
120
120
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,20 +143,6 @@ dependencies:
|
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '1.0'
|
146
|
-
- !ruby/object:Gem::Dependency
|
147
|
-
name: minitest-bonus-assertions
|
148
|
-
requirement: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '3.0'
|
153
|
-
type: :development
|
154
|
-
prerelease: false
|
155
|
-
version_requirements: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - "~>"
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '3.0'
|
160
146
|
- !ruby/object:Gem::Dependency
|
161
147
|
name: minitest-focus
|
162
148
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,14 +177,14 @@ dependencies:
|
|
191
177
|
requirements:
|
192
178
|
- - "~>"
|
193
179
|
- !ruby/object:Gem::Version
|
194
|
-
version: '
|
180
|
+
version: '2.0'
|
195
181
|
type: :development
|
196
182
|
prerelease: false
|
197
183
|
version_requirements: !ruby/object:Gem::Requirement
|
198
184
|
requirements:
|
199
185
|
- - "~>"
|
200
186
|
- !ruby/object:Gem::Version
|
201
|
-
version: '
|
187
|
+
version: '2.0'
|
202
188
|
- !ruby/object:Gem::Dependency
|
203
189
|
name: rake
|
204
190
|
requirement: !ruby/object:Gem::Requirement
|
@@ -219,20 +205,6 @@ dependencies:
|
|
219
205
|
- - "<"
|
220
206
|
- !ruby/object:Gem::Version
|
221
207
|
version: '14'
|
222
|
-
- !ruby/object:Gem::Dependency
|
223
|
-
name: rdoc
|
224
|
-
requirement: !ruby/object:Gem::Requirement
|
225
|
-
requirements:
|
226
|
-
- - ">="
|
227
|
-
- !ruby/object:Gem::Version
|
228
|
-
version: '4.2'
|
229
|
-
type: :development
|
230
|
-
prerelease: false
|
231
|
-
version_requirements: !ruby/object:Gem::Requirement
|
232
|
-
requirements:
|
233
|
-
- - ">="
|
234
|
-
- !ruby/object:Gem::Version
|
235
|
-
version: '4.2'
|
236
208
|
- !ruby/object:Gem::Dependency
|
237
209
|
name: standard
|
238
210
|
requirement: !ruby/object:Gem::Requirement
|
@@ -262,33 +234,39 @@ dependencies:
|
|
262
234
|
- !ruby/object:Gem::Version
|
263
235
|
version: '0.21'
|
264
236
|
- !ruby/object:Gem::Dependency
|
265
|
-
name:
|
237
|
+
name: rdoc
|
266
238
|
requirement: !ruby/object:Gem::Requirement
|
267
239
|
requirements:
|
268
|
-
- - "
|
240
|
+
- - ">="
|
269
241
|
- !ruby/object:Gem::Version
|
270
|
-
version: '
|
242
|
+
version: '4.0'
|
243
|
+
- - "<"
|
244
|
+
- !ruby/object:Gem::Version
|
245
|
+
version: '7'
|
271
246
|
type: :development
|
272
247
|
prerelease: false
|
273
248
|
version_requirements: !ruby/object:Gem::Requirement
|
274
249
|
requirements:
|
275
|
-
- - "
|
250
|
+
- - ">="
|
276
251
|
- !ruby/object:Gem::Version
|
277
|
-
version: '
|
252
|
+
version: '4.0'
|
253
|
+
- - "<"
|
254
|
+
- !ruby/object:Gem::Version
|
255
|
+
version: '7'
|
278
256
|
- !ruby/object:Gem::Dependency
|
279
257
|
name: hoe
|
280
258
|
requirement: !ruby/object:Gem::Requirement
|
281
259
|
requirements:
|
282
260
|
- - "~>"
|
283
261
|
- !ruby/object:Gem::Version
|
284
|
-
version: '
|
262
|
+
version: '4.2'
|
285
263
|
type: :development
|
286
264
|
prerelease: false
|
287
265
|
version_requirements: !ruby/object:Gem::Requirement
|
288
266
|
requirements:
|
289
267
|
- - "~>"
|
290
268
|
- !ruby/object:Gem::Version
|
291
|
-
version: '
|
269
|
+
version: '4.2'
|
292
270
|
description: |-
|
293
271
|
{Marlowe}[https://github.com/KineticCafe/marlowe] is a Rack middleware that
|
294
272
|
extracts or creates a request ID using a pre-defined header, permitting request
|
@@ -296,6 +274,8 @@ description: |-
|
|
296
274
|
|
297
275
|
When using Rails, Marlowe automatically adds itself to the middleware before
|
298
276
|
<tt>Rails::Rack::Logger</tt>.
|
277
|
+
|
278
|
+
As of Marlowe 3.0, a Faraday middleware is provided (<tt>require 'marlowe/faraday'</tt>).
|
299
279
|
email:
|
300
280
|
- toke@kineticcafe.com
|
301
281
|
- dev@kineticcafe.com
|
@@ -308,6 +288,8 @@ extra_rdoc_files:
|
|
308
288
|
- Manifest.txt
|
309
289
|
- README.rdoc
|
310
290
|
files:
|
291
|
+
- ".github/workflows/ruby.yml"
|
292
|
+
- ".standard.yml"
|
311
293
|
- Contributing.md
|
312
294
|
- History.md
|
313
295
|
- Licence.md
|
@@ -315,12 +297,15 @@ files:
|
|
315
297
|
- README.rdoc
|
316
298
|
- Rakefile
|
317
299
|
- lib/marlowe.rb
|
300
|
+
- lib/marlowe/config.rb
|
301
|
+
- lib/marlowe/faraday.rb
|
318
302
|
- lib/marlowe/formatter.rb
|
319
303
|
- lib/marlowe/middleware.rb
|
320
304
|
- lib/marlowe/rails.rb
|
321
305
|
- lib/marlowe/simple_formatter.rb
|
322
306
|
- test/minitest_config.rb
|
323
307
|
- test/test_marlowe.rb
|
308
|
+
- test/test_marlowe_config.rb
|
324
309
|
homepage: https://github.com/KineticCafe/marlowe/
|
325
310
|
licenses:
|
326
311
|
- MIT
|
@@ -347,7 +332,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
347
332
|
- !ruby/object:Gem::Version
|
348
333
|
version: '0'
|
349
334
|
requirements: []
|
350
|
-
rubygems_version: 3.
|
335
|
+
rubygems_version: 3.4.10
|
351
336
|
signing_key:
|
352
337
|
specification_version: 4
|
353
338
|
summary: "{Marlowe}[https://github.com/KineticCafe/marlowe] is a Rack middleware that
|