promenade 0.2.2 → 0.4.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 +4 -4
- data/.github/workflows/ci.yaml +2 -2
- data/.gitignore +10 -8
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +184 -46
- data/README.md +52 -0
- data/bin/integration_test +10 -1
- data/bin/rails +14 -0
- data/lib/promenade/client/rack/collector.rb +111 -0
- data/lib/promenade/client/rack/exception_handler.rb +51 -0
- data/lib/promenade/client/rack/request_labeler.rb +50 -0
- data/lib/promenade/client/rack/singleton_caller.rb +19 -0
- data/lib/promenade/engine.rb +5 -0
- data/lib/promenade/prometheus.rb +1 -1
- data/lib/promenade/railtie.rb +4 -0
- data/lib/promenade/setup.rb +14 -5
- data/lib/promenade/version.rb +1 -1
- data/promenade.gemspec +10 -6
- metadata +93 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fcfb43aad9817592d691db8877de9ac9df46e39e98df91d600121e497dd3b1b4
|
|
4
|
+
data.tar.gz: e152ba9577142a1648ab18914a777144930a685359c0ea874502027d2961b467
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 997977c4f41d8ecc5db991cece8ff6b7ab950104ac8ad996b273446fef94ac6d4c5ce8f5c90a515d686ccc02db828c77630d03eeb8bd83ed72b6460fc3a700ed
|
|
7
|
+
data.tar.gz: cdc7399c7d32986cd676d71cbddd333d535c2695068a278a01ef981ae75c88e1f43ca626341665b556cf3f421f9e0e74f0e1752f4f07cda132f249f5042efbc9
|
data/.github/workflows/ci.yaml
CHANGED
|
@@ -2,14 +2,14 @@ name: CI
|
|
|
2
2
|
on:
|
|
3
3
|
push:
|
|
4
4
|
branches:
|
|
5
|
-
-master
|
|
5
|
+
- master
|
|
6
6
|
pull_request:
|
|
7
7
|
jobs:
|
|
8
8
|
test:
|
|
9
9
|
strategy:
|
|
10
10
|
fail-fast: false
|
|
11
11
|
matrix:
|
|
12
|
-
ruby: ['2.
|
|
12
|
+
ruby: ['2.7', '3.0', "3.1"]
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
steps:
|
|
15
15
|
- uses: actions/checkout@v2
|
data/.gitignore
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
.rspec_status
|
|
2
|
+
.byebug_history
|
|
3
|
+
.rubocop-https*yml
|
|
1
4
|
/.bundle/
|
|
2
|
-
/.yardoc
|
|
3
|
-
/_yardoc/
|
|
4
5
|
/coverage/
|
|
5
6
|
/doc/
|
|
7
|
+
/log/
|
|
6
8
|
/pkg/
|
|
9
|
+
/.sass-cache/
|
|
7
10
|
/spec/reports/
|
|
11
|
+
/spec/dummy/log
|
|
12
|
+
/spec/dummy/tmp
|
|
8
13
|
/tmp/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
# rspec failure tracking
|
|
14
|
-
.rspec_status
|
|
14
|
+
/vendor/
|
|
15
|
+
/.yardoc
|
|
16
|
+
/_yardoc/
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,29 +1,92 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
promenade (0.
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
promenade (0.4.0)
|
|
5
|
+
actionpack
|
|
6
|
+
activesupport (> 6.0, < 8.0)
|
|
7
|
+
prometheus-client-mmap (~> 0.16.0)
|
|
7
8
|
rack
|
|
8
9
|
|
|
9
10
|
GEM
|
|
10
11
|
remote: https://rubygems.org/
|
|
11
12
|
specs:
|
|
12
|
-
|
|
13
|
+
actioncable (7.0.3)
|
|
14
|
+
actionpack (= 7.0.3)
|
|
15
|
+
activesupport (= 7.0.3)
|
|
16
|
+
nio4r (~> 2.0)
|
|
17
|
+
websocket-driver (>= 0.6.1)
|
|
18
|
+
actionmailbox (7.0.3)
|
|
19
|
+
actionpack (= 7.0.3)
|
|
20
|
+
activejob (= 7.0.3)
|
|
21
|
+
activerecord (= 7.0.3)
|
|
22
|
+
activestorage (= 7.0.3)
|
|
23
|
+
activesupport (= 7.0.3)
|
|
24
|
+
mail (>= 2.7.1)
|
|
25
|
+
net-imap
|
|
26
|
+
net-pop
|
|
27
|
+
net-smtp
|
|
28
|
+
actionmailer (7.0.3)
|
|
29
|
+
actionpack (= 7.0.3)
|
|
30
|
+
actionview (= 7.0.3)
|
|
31
|
+
activejob (= 7.0.3)
|
|
32
|
+
activesupport (= 7.0.3)
|
|
33
|
+
mail (~> 2.5, >= 2.5.4)
|
|
34
|
+
net-imap
|
|
35
|
+
net-pop
|
|
36
|
+
net-smtp
|
|
37
|
+
rails-dom-testing (~> 2.0)
|
|
38
|
+
actionpack (7.0.3)
|
|
39
|
+
actionview (= 7.0.3)
|
|
40
|
+
activesupport (= 7.0.3)
|
|
41
|
+
rack (~> 2.0, >= 2.2.0)
|
|
42
|
+
rack-test (>= 0.6.3)
|
|
43
|
+
rails-dom-testing (~> 2.0)
|
|
44
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
45
|
+
actiontext (7.0.3)
|
|
46
|
+
actionpack (= 7.0.3)
|
|
47
|
+
activerecord (= 7.0.3)
|
|
48
|
+
activestorage (= 7.0.3)
|
|
49
|
+
activesupport (= 7.0.3)
|
|
50
|
+
globalid (>= 0.6.0)
|
|
51
|
+
nokogiri (>= 1.8.5)
|
|
52
|
+
actionview (7.0.3)
|
|
53
|
+
activesupport (= 7.0.3)
|
|
54
|
+
builder (~> 3.1)
|
|
55
|
+
erubi (~> 1.4)
|
|
56
|
+
rails-dom-testing (~> 2.0)
|
|
57
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
58
|
+
activejob (7.0.3)
|
|
59
|
+
activesupport (= 7.0.3)
|
|
60
|
+
globalid (>= 0.3.6)
|
|
61
|
+
activemodel (7.0.3)
|
|
62
|
+
activesupport (= 7.0.3)
|
|
63
|
+
activerecord (7.0.3)
|
|
64
|
+
activemodel (= 7.0.3)
|
|
65
|
+
activesupport (= 7.0.3)
|
|
66
|
+
activestorage (7.0.3)
|
|
67
|
+
actionpack (= 7.0.3)
|
|
68
|
+
activejob (= 7.0.3)
|
|
69
|
+
activerecord (= 7.0.3)
|
|
70
|
+
activesupport (= 7.0.3)
|
|
71
|
+
marcel (~> 1.0)
|
|
72
|
+
mini_mime (>= 1.1.0)
|
|
73
|
+
activesupport (7.0.3)
|
|
13
74
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
14
75
|
i18n (>= 1.6, < 2)
|
|
15
76
|
minitest (>= 5.1)
|
|
16
77
|
tzinfo (~> 2.0)
|
|
17
|
-
zeitwerk (~> 2.3)
|
|
18
78
|
ast (2.4.2)
|
|
19
|
-
backports (3.
|
|
79
|
+
backports (3.23.0)
|
|
20
80
|
binding_of_caller (1.0.0)
|
|
21
81
|
debug_inspector (>= 0.0.1)
|
|
22
|
-
|
|
23
|
-
|
|
82
|
+
builder (3.2.4)
|
|
83
|
+
byebug (11.1.3)
|
|
84
|
+
climate_control (1.1.1)
|
|
85
|
+
codecov (0.6.0)
|
|
24
86
|
simplecov (>= 0.15, < 0.22)
|
|
25
87
|
coderay (1.1.3)
|
|
26
|
-
concurrent-ruby (1.1.
|
|
88
|
+
concurrent-ruby (1.1.10)
|
|
89
|
+
crass (1.0.6)
|
|
27
90
|
debug_inspector (1.1.0)
|
|
28
91
|
deep-cover (1.1.0)
|
|
29
92
|
deep-cover-core (= 1.1.0)
|
|
@@ -37,53 +100,120 @@ GEM
|
|
|
37
100
|
pry
|
|
38
101
|
term-ansicolor
|
|
39
102
|
terminal-table
|
|
40
|
-
diff-lcs (1.
|
|
103
|
+
diff-lcs (1.5.0)
|
|
104
|
+
digest (3.1.0)
|
|
41
105
|
docile (1.4.0)
|
|
106
|
+
erubi (1.10.0)
|
|
107
|
+
globalid (1.0.0)
|
|
108
|
+
activesupport (>= 5.0)
|
|
42
109
|
highline (2.0.3)
|
|
43
|
-
i18n (1.
|
|
110
|
+
i18n (1.10.0)
|
|
44
111
|
concurrent-ruby (~> 1.0)
|
|
112
|
+
loofah (2.18.0)
|
|
113
|
+
crass (~> 1.0.2)
|
|
114
|
+
nokogiri (>= 1.5.9)
|
|
115
|
+
mail (2.7.1)
|
|
116
|
+
mini_mime (>= 0.1.1)
|
|
117
|
+
marcel (1.0.2)
|
|
45
118
|
method_source (1.0.0)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
119
|
+
mini_mime (1.1.2)
|
|
120
|
+
mini_portile2 (2.8.0)
|
|
121
|
+
minitest (5.16.0)
|
|
122
|
+
net-imap (0.2.3)
|
|
123
|
+
digest
|
|
124
|
+
net-protocol
|
|
125
|
+
strscan
|
|
126
|
+
net-pop (0.1.1)
|
|
127
|
+
digest
|
|
128
|
+
net-protocol
|
|
129
|
+
timeout
|
|
130
|
+
net-protocol (0.1.3)
|
|
131
|
+
timeout
|
|
132
|
+
net-smtp (0.3.1)
|
|
133
|
+
digest
|
|
134
|
+
net-protocol
|
|
135
|
+
timeout
|
|
136
|
+
nio4r (2.5.8)
|
|
137
|
+
nokogiri (1.13.6)
|
|
138
|
+
mini_portile2 (~> 2.8.0)
|
|
139
|
+
racc (~> 1.4)
|
|
140
|
+
parallel (1.22.1)
|
|
141
|
+
parser (3.1.2.0)
|
|
49
142
|
ast (~> 2.4.1)
|
|
50
|
-
prometheus-client-mmap (0.
|
|
143
|
+
prometheus-client-mmap (0.16.0)
|
|
51
144
|
pry (0.14.1)
|
|
52
145
|
coderay (~> 1.1)
|
|
53
146
|
method_source (~> 1.0)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
147
|
+
racc (1.6.0)
|
|
148
|
+
rack (2.2.3.1)
|
|
149
|
+
rack-test (1.1.0)
|
|
150
|
+
rack (>= 1.0, < 3)
|
|
151
|
+
rails (7.0.3)
|
|
152
|
+
actioncable (= 7.0.3)
|
|
153
|
+
actionmailbox (= 7.0.3)
|
|
154
|
+
actionmailer (= 7.0.3)
|
|
155
|
+
actionpack (= 7.0.3)
|
|
156
|
+
actiontext (= 7.0.3)
|
|
157
|
+
actionview (= 7.0.3)
|
|
158
|
+
activejob (= 7.0.3)
|
|
159
|
+
activemodel (= 7.0.3)
|
|
160
|
+
activerecord (= 7.0.3)
|
|
161
|
+
activestorage (= 7.0.3)
|
|
162
|
+
activesupport (= 7.0.3)
|
|
163
|
+
bundler (>= 1.15.0)
|
|
164
|
+
railties (= 7.0.3)
|
|
165
|
+
rails-dom-testing (2.0.3)
|
|
166
|
+
activesupport (>= 4.2.0)
|
|
167
|
+
nokogiri (>= 1.6)
|
|
168
|
+
rails-html-sanitizer (1.4.3)
|
|
169
|
+
loofah (~> 2.3)
|
|
170
|
+
railties (7.0.3)
|
|
171
|
+
actionpack (= 7.0.3)
|
|
172
|
+
activesupport (= 7.0.3)
|
|
173
|
+
method_source
|
|
174
|
+
rake (>= 12.2)
|
|
175
|
+
thor (~> 1.0)
|
|
176
|
+
zeitwerk (~> 2.5)
|
|
177
|
+
rainbow (3.1.1)
|
|
178
|
+
rake (13.0.6)
|
|
179
|
+
regexp_parser (2.5.0)
|
|
58
180
|
rexml (3.2.5)
|
|
59
|
-
rspec (3.
|
|
60
|
-
rspec-core (~> 3.
|
|
61
|
-
rspec-expectations (~> 3.
|
|
62
|
-
rspec-mocks (~> 3.
|
|
63
|
-
rspec-core (3.
|
|
64
|
-
rspec-support (~> 3.
|
|
65
|
-
rspec-expectations (3.
|
|
181
|
+
rspec (3.11.0)
|
|
182
|
+
rspec-core (~> 3.11.0)
|
|
183
|
+
rspec-expectations (~> 3.11.0)
|
|
184
|
+
rspec-mocks (~> 3.11.0)
|
|
185
|
+
rspec-core (3.11.0)
|
|
186
|
+
rspec-support (~> 3.11.0)
|
|
187
|
+
rspec-expectations (3.11.0)
|
|
66
188
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
67
|
-
rspec-support (~> 3.
|
|
68
|
-
rspec-mocks (3.
|
|
189
|
+
rspec-support (~> 3.11.0)
|
|
190
|
+
rspec-mocks (3.11.1)
|
|
69
191
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
70
|
-
rspec-support (~> 3.
|
|
71
|
-
rspec-
|
|
72
|
-
|
|
192
|
+
rspec-support (~> 3.11.0)
|
|
193
|
+
rspec-rails (5.1.2)
|
|
194
|
+
actionpack (>= 5.2)
|
|
195
|
+
activesupport (>= 5.2)
|
|
196
|
+
railties (>= 5.2)
|
|
197
|
+
rspec-core (~> 3.10)
|
|
198
|
+
rspec-expectations (~> 3.10)
|
|
199
|
+
rspec-mocks (~> 3.10)
|
|
200
|
+
rspec-support (~> 3.10)
|
|
201
|
+
rspec-support (3.11.0)
|
|
202
|
+
rubocop (1.30.1)
|
|
73
203
|
parallel (~> 1.10)
|
|
74
|
-
parser (>= 3.
|
|
204
|
+
parser (>= 3.1.0.0)
|
|
75
205
|
rainbow (>= 2.2.2, < 4.0)
|
|
76
206
|
regexp_parser (>= 1.8, < 3.0)
|
|
77
|
-
rexml
|
|
78
|
-
rubocop-ast (>= 1.
|
|
207
|
+
rexml (>= 3.2.5, < 4.0)
|
|
208
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
|
79
209
|
ruby-progressbar (~> 1.7)
|
|
80
210
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
81
|
-
rubocop-ast (1.
|
|
82
|
-
parser (>= 3.
|
|
83
|
-
rubocop-performance (1.
|
|
211
|
+
rubocop-ast (1.18.0)
|
|
212
|
+
parser (>= 3.1.1.0)
|
|
213
|
+
rubocop-performance (1.14.2)
|
|
84
214
|
rubocop (>= 1.7.0, < 2.0)
|
|
85
215
|
rubocop-ast (>= 0.4.0)
|
|
86
|
-
rubocop-rails (2.
|
|
216
|
+
rubocop-rails (2.15.0)
|
|
87
217
|
activesupport (>= 4.2.0)
|
|
88
218
|
rack (>= 1.1)
|
|
89
219
|
rubocop (>= 1.7.0, < 2.0)
|
|
@@ -93,34 +223,42 @@ GEM
|
|
|
93
223
|
simplecov-html (~> 0.11)
|
|
94
224
|
simplecov_json_formatter (~> 0.1)
|
|
95
225
|
simplecov-html (0.12.3)
|
|
96
|
-
simplecov_json_formatter (0.1.
|
|
226
|
+
simplecov_json_formatter (0.1.4)
|
|
227
|
+
strscan (3.0.3)
|
|
97
228
|
sync (0.5.0)
|
|
98
229
|
term-ansicolor (1.7.1)
|
|
99
230
|
tins (~> 1.0)
|
|
100
|
-
terminal-table (3.0.
|
|
231
|
+
terminal-table (3.0.2)
|
|
101
232
|
unicode-display_width (>= 1.1.1, < 3)
|
|
102
|
-
thor (1.1
|
|
103
|
-
|
|
233
|
+
thor (1.2.1)
|
|
234
|
+
timeout (0.3.0)
|
|
235
|
+
tins (1.31.1)
|
|
104
236
|
sync
|
|
105
237
|
tzinfo (2.0.4)
|
|
106
238
|
concurrent-ruby (~> 1.0)
|
|
107
|
-
unicode-display_width (2.
|
|
239
|
+
unicode-display_width (2.1.0)
|
|
108
240
|
webrick (1.7.0)
|
|
241
|
+
websocket-driver (0.7.5)
|
|
242
|
+
websocket-extensions (>= 0.1.0)
|
|
243
|
+
websocket-extensions (0.1.5)
|
|
109
244
|
with_progress (1.0.1)
|
|
110
245
|
ruby-progressbar (~> 1.4)
|
|
111
|
-
zeitwerk (2.
|
|
246
|
+
zeitwerk (2.6.0)
|
|
112
247
|
|
|
113
248
|
PLATFORMS
|
|
114
249
|
ruby
|
|
115
250
|
|
|
116
251
|
DEPENDENCIES
|
|
117
252
|
bundler (~> 2.0)
|
|
253
|
+
byebug
|
|
118
254
|
climate_control
|
|
119
255
|
codecov
|
|
120
256
|
deep-cover
|
|
121
257
|
promenade!
|
|
122
|
-
|
|
123
|
-
|
|
258
|
+
rails (> 3.0, < 8.0)
|
|
259
|
+
rake
|
|
260
|
+
rspec (~> 3.11)
|
|
261
|
+
rspec-rails (~> 5.1)
|
|
124
262
|
rubocop
|
|
125
263
|
rubocop-performance
|
|
126
264
|
rubocop-rails
|
data/README.md
CHANGED
|
@@ -129,6 +129,58 @@ This is ideal if you are worried about accidentally exposing your metrics, are c
|
|
|
129
129
|
|
|
130
130
|
The exporter runs by default on port `9394` and the metrics are available at the standard path of `/metrics`, the stand-alone exporter is configured to use gzip.
|
|
131
131
|
|
|
132
|
+
|
|
133
|
+
### Rails Middleware
|
|
134
|
+
|
|
135
|
+
Promenade provides custom Rack middleware to track HTTP response times for requests in your Rails application.
|
|
136
|
+
|
|
137
|
+
This was originally inspired by [prometheus-client-mmap](https://gitlab.com/gitlab-org/prometheus-client-mmap/-/blob/master/lib/prometheus/client/rack/collector.rb).
|
|
138
|
+
|
|
139
|
+
**This middleware is automatically added to your Rack stack if your application is a Ruby on Rails app.**
|
|
140
|
+
|
|
141
|
+
We recommend you add the middleware after `ActionDispatch::ShowExceptions` in your stack, so you can accurately record the controller and action where an exception was raised.
|
|
142
|
+
|
|
143
|
+
If you want to change the position, or customise the labels and exception handling behaviour, simply remove the middleware from the stack and re-insert it with your own preferences.
|
|
144
|
+
|
|
145
|
+
``` ruby
|
|
146
|
+
Rails.application.middleware.delete(Promenade::Client::Rack::Collector)
|
|
147
|
+
Rails.application.middleware.insert_after(Rails::Rack::Logger, Promenade::Client::Rack::Collector)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Customising the labels recorded for each request
|
|
151
|
+
|
|
152
|
+
If you would like to collect different labels with each request, you may do so by customising the middleware installation:
|
|
153
|
+
|
|
154
|
+
``` ruby
|
|
155
|
+
label_builder = Proc.new do |env|
|
|
156
|
+
{
|
|
157
|
+
method: env["REQUEST_METHOD"].to_s.downcase,
|
|
158
|
+
host: env["HTTP_HOST"].to_s,
|
|
159
|
+
controller: env.dig("action_dispatch.request.parameters", "controller") || "unknown",
|
|
160
|
+
action: env.dig("action_dispatch.request.parameters", "action") || "unknown"
|
|
161
|
+
}
|
|
162
|
+
end
|
|
163
|
+
Rails.application.config.middleware.insert_after ActionDispatch::ShowExceptions,
|
|
164
|
+
Promenade::Client::Rack::Collector
|
|
165
|
+
label_builder: label_builder
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Customising how the middleware handles exceptions
|
|
169
|
+
|
|
170
|
+
The default implementation will capture exceptions, count the execption class name (e.g. `"StandardError"`), and then re-raise the exception.
|
|
171
|
+
|
|
172
|
+
If you would like to customise this behaviour, you may do so by customising the middleware installation:
|
|
173
|
+
|
|
174
|
+
``` ruby
|
|
175
|
+
exception_handler = Proc.new do |exception, exception_counter, env_hash, request_duration_seconds|
|
|
176
|
+
# This simple example just re-raises the execption
|
|
177
|
+
raise exception
|
|
178
|
+
end
|
|
179
|
+
Rails.application.config.middleware.insert_after ActionDispatch::ShowExceptions,
|
|
180
|
+
Promenade::Client::Rack::Collector
|
|
181
|
+
exception_handler: exception_handler
|
|
182
|
+
```
|
|
183
|
+
|
|
132
184
|
### Configuration
|
|
133
185
|
|
|
134
186
|
If you are using rails it should load a railtie and configure promenade.
|
data/bin/integration_test
CHANGED
|
@@ -4,14 +4,23 @@ require "bundler/setup"
|
|
|
4
4
|
require "promenade"
|
|
5
5
|
require "fileutils"
|
|
6
6
|
require "net/http"
|
|
7
|
+
require "./spec/support/integration_tests/metrics_line"
|
|
8
|
+
require "./spec/support/integration_tests/label_value"
|
|
7
9
|
|
|
8
10
|
def test_http_body(expected)
|
|
11
|
+
expectation = MetricsLine.new(expected)
|
|
9
12
|
uri = URI("http://localhost:9394/metrics")
|
|
10
13
|
|
|
11
14
|
Net::HTTP.start(uri.host, uri.port) do |http|
|
|
12
15
|
request = Net::HTTP::Get.new uri
|
|
13
16
|
response = http.request request
|
|
14
|
-
|
|
17
|
+
unless response.body.each_line.detect do |string|
|
|
18
|
+
next if string.start_with?("#")
|
|
19
|
+
|
|
20
|
+
MetricsLine.new(string) == expectation
|
|
21
|
+
end
|
|
22
|
+
fail "#{response.body} didn't include #{expected}"
|
|
23
|
+
end
|
|
15
24
|
end
|
|
16
25
|
end
|
|
17
26
|
|
data/bin/rails
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
|
3
|
+
# installed from the root of your application.
|
|
4
|
+
|
|
5
|
+
ENGINE_ROOT = File.expand_path("..", __dir__)
|
|
6
|
+
ENGINE_PATH = File.expand_path("../lib/promenade/engine", __dir__)
|
|
7
|
+
APP_PATH = File.expand_path("../spec/dummy/config/application", __dir__)
|
|
8
|
+
|
|
9
|
+
# Set up gems listed in the Gemfile.
|
|
10
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
11
|
+
require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
|
|
12
|
+
|
|
13
|
+
require "rails/all"
|
|
14
|
+
require "rails/engine/commands"
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
require "prometheus/client"
|
|
2
|
+
require_relative "request_labeler"
|
|
3
|
+
require_relative "exception_handler"
|
|
4
|
+
|
|
5
|
+
module Promenade
|
|
6
|
+
module Client
|
|
7
|
+
module Rack
|
|
8
|
+
# Original code taken from Prometheus Client MMap
|
|
9
|
+
# https://gitlab.com/gitlab-org/prometheus-client-mmap/-/blob/master/lib/prometheus/client/rack/collector.rb
|
|
10
|
+
#
|
|
11
|
+
# Collector is a Rack middleware that provides a sample implementation of
|
|
12
|
+
# a HTTP tracer. The default label builder can be modified to export a
|
|
13
|
+
# different set of labels per recorded metric.
|
|
14
|
+
class Collector
|
|
15
|
+
REQUEST_METHOD = "REQUEST_METHOD".freeze
|
|
16
|
+
|
|
17
|
+
HTTP_HOST = "HTTP_HOST".freeze
|
|
18
|
+
|
|
19
|
+
PATH_INFO = "PATH_INFO".freeze
|
|
20
|
+
|
|
21
|
+
HISTOGRAM_NAME = :http_req_duration_seconds
|
|
22
|
+
|
|
23
|
+
REQUESTS_COUNTER_NAME = :http_requests_total
|
|
24
|
+
|
|
25
|
+
EXCEPTIONS_COUNTER_NAME = :http_exceptions_total
|
|
26
|
+
|
|
27
|
+
private_constant *%i(
|
|
28
|
+
REQUEST_METHOD
|
|
29
|
+
HTTP_HOST
|
|
30
|
+
PATH_INFO
|
|
31
|
+
HISTOGRAM_NAME
|
|
32
|
+
REQUESTS_COUNTER_NAME
|
|
33
|
+
EXCEPTIONS_COUNTER_NAME
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def initialize(app,
|
|
37
|
+
registry: ::Prometheus::Client.registry,
|
|
38
|
+
label_builder: RequestLabeler,
|
|
39
|
+
exception_handler: nil)
|
|
40
|
+
@app = app
|
|
41
|
+
@registry = registry
|
|
42
|
+
@label_builder = label_builder
|
|
43
|
+
@exception_handler = exception_handler || default_exception_handler
|
|
44
|
+
register_metrics!
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def call(env)
|
|
48
|
+
trace(env) { app.call(env) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
attr_reader :app,
|
|
54
|
+
:registry,
|
|
55
|
+
:label_builder,
|
|
56
|
+
:exception_handler
|
|
57
|
+
|
|
58
|
+
def trace(env)
|
|
59
|
+
start = current_time
|
|
60
|
+
begin
|
|
61
|
+
response = yield
|
|
62
|
+
record(labels(env, response), duration_since(start))
|
|
63
|
+
response
|
|
64
|
+
rescue StandardError => e
|
|
65
|
+
exception_handler.call(e, env, duration_since(start))
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def labels(env, response)
|
|
70
|
+
label_builder.call(env).merge!(code: response.first.to_s)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def record(labels, duration)
|
|
74
|
+
requests_counter.increment(labels)
|
|
75
|
+
durations_histogram.observe(labels, duration)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def duration_since(start_time)
|
|
79
|
+
current_time - start_time
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def current_time
|
|
83
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def durations_histogram
|
|
87
|
+
registry.get(HISTOGRAM_NAME)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def requests_counter
|
|
91
|
+
registry.get(REQUESTS_COUNTER_NAME)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def register_metrics!
|
|
95
|
+
registry.counter(REQUESTS_COUNTER_NAME, "A counter of the total number of HTTP requests made.")
|
|
96
|
+
registry.histogram(HISTOGRAM_NAME, "A histogram of the response latency.")
|
|
97
|
+
registry.counter(EXCEPTIONS_COUNTER_NAME, "A counter of the total number of exceptions raised.")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def default_exception_handler
|
|
101
|
+
ExceptionHandler.initialize_singleton(
|
|
102
|
+
histogram_name: HISTOGRAM_NAME,
|
|
103
|
+
requests_counter_name: REQUESTS_COUNTER_NAME,
|
|
104
|
+
exceptions_counter_name: EXCEPTIONS_COUNTER_NAME,
|
|
105
|
+
registry: registry,
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require "action_dispatch/middleware/exception_wrapper"
|
|
2
|
+
require_relative "singleton_caller"
|
|
3
|
+
require_relative "request_labeler"
|
|
4
|
+
|
|
5
|
+
module Promenade
|
|
6
|
+
module Client
|
|
7
|
+
module Rack
|
|
8
|
+
class ExceptionHandler
|
|
9
|
+
extend SingletonCaller
|
|
10
|
+
|
|
11
|
+
attr_reader :histogram_name, :requests_counter_name, :exceptions_counter_name, :registry
|
|
12
|
+
|
|
13
|
+
def initialize(histogram_name:, requests_counter_name:, exceptions_counter_name:, registry:)
|
|
14
|
+
@histogram_name = histogram_name
|
|
15
|
+
@requests_counter_name = requests_counter_name
|
|
16
|
+
@exceptions_counter_name = exceptions_counter_name
|
|
17
|
+
@registry = registry
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call(exception, env_hash, duration)
|
|
21
|
+
labels = RequestLabeler.call(env_hash)
|
|
22
|
+
labels.merge!(code: status_code_for_exception(exception))
|
|
23
|
+
|
|
24
|
+
histogram.observe(labels, duration.to_f)
|
|
25
|
+
requests_counter.increment(labels)
|
|
26
|
+
exceptions_counter.increment(exception: exception.class.name)
|
|
27
|
+
|
|
28
|
+
raise exception
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def histogram
|
|
34
|
+
registry.get(histogram_name)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def requests_counter
|
|
38
|
+
registry.get(requests_counter_name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def exceptions_counter
|
|
42
|
+
registry.get(exceptions_counter_name)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def status_code_for_exception(exception)
|
|
46
|
+
ActionDispatch::ExceptionWrapper.new(nil, exception).status_code.to_s
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Promenade
|
|
2
|
+
module Client
|
|
3
|
+
module Rack
|
|
4
|
+
class RequestLabeler
|
|
5
|
+
require_relative "singleton_caller"
|
|
6
|
+
extend SingletonCaller
|
|
7
|
+
|
|
8
|
+
REQUEST_METHOD = "REQUEST_METHOD".freeze
|
|
9
|
+
|
|
10
|
+
HTTP_HOST = "HTTP_HOST".freeze
|
|
11
|
+
|
|
12
|
+
PARAMS_KEY = "action_dispatch.request.parameters".freeze
|
|
13
|
+
|
|
14
|
+
PATH_PARAMS_KEY = "action_dispatch.request.path_parameters".freeze
|
|
15
|
+
|
|
16
|
+
CONTROLLER = "controller".freeze
|
|
17
|
+
|
|
18
|
+
ACTION = "action".freeze
|
|
19
|
+
|
|
20
|
+
UNKNOWN = "unknown".freeze
|
|
21
|
+
|
|
22
|
+
SEPARATOR = "#".freeze
|
|
23
|
+
|
|
24
|
+
private_constant :REQUEST_METHOD, :HTTP_HOST, :PARAMS_KEY, :CONTROLLER, :ACTION, :UNKNOWN, :SEPARATOR
|
|
25
|
+
|
|
26
|
+
def call(env)
|
|
27
|
+
{
|
|
28
|
+
method: env[REQUEST_METHOD].to_s.downcase,
|
|
29
|
+
host: env[HTTP_HOST].to_s,
|
|
30
|
+
controller_action: controller_action_from_env(env),
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def controller_action_from_env(env)
|
|
37
|
+
controller = env.dig(PARAMS_KEY, CONTROLLER) ||
|
|
38
|
+
env.dig(PATH_PARAMS_KEY, CONTROLLER.to_sym) ||
|
|
39
|
+
UNKNOWN
|
|
40
|
+
|
|
41
|
+
action = env.dig(PARAMS_KEY, ACTION) ||
|
|
42
|
+
env.dig(PATH_PARAMS_KEY, ACTION.to_sym) ||
|
|
43
|
+
UNKNOWN
|
|
44
|
+
|
|
45
|
+
[controller, action].join(SEPARATOR)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Promenade
|
|
2
|
+
module Client
|
|
3
|
+
module Rack
|
|
4
|
+
module SingletonCaller
|
|
5
|
+
def initialize_singleton(...)
|
|
6
|
+
@singleton = new(...)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def call(...)
|
|
10
|
+
singleton.call(...)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def singleton
|
|
14
|
+
@singleton || initialize_singleton
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/promenade/prometheus.rb
CHANGED
data/lib/promenade/railtie.rb
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
require "promenade/setup"
|
|
2
|
+
require "promenade/engine"
|
|
3
|
+
require "promenade/client/rack/collector"
|
|
2
4
|
|
|
3
5
|
module Promenade
|
|
4
6
|
class Railtie < ::Rails::Railtie
|
|
5
7
|
initializer "promenade.configure_rails_initialization" do
|
|
6
8
|
Promenade.setup
|
|
9
|
+
Rails.application.config.middleware.insert_after ActionDispatch::ShowExceptions,
|
|
10
|
+
Promenade::Client::Rack::Collector
|
|
7
11
|
end
|
|
8
12
|
end
|
|
9
13
|
end
|
data/lib/promenade/setup.rb
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
require "pathname"
|
|
2
2
|
|
|
3
3
|
module Promenade
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
def root_dir
|
|
7
|
+
if rails_defined?
|
|
8
|
+
Rails.root
|
|
9
|
+
else
|
|
10
|
+
Pathname.new(ENV.fetch("RAILS_ROOT", Dir.pwd))
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def rails_defined?
|
|
15
|
+
defined?(Rails)
|
|
7
16
|
end
|
|
8
17
|
|
|
9
|
-
def
|
|
18
|
+
def multiprocess_files_dir
|
|
10
19
|
ENV.fetch("PROMETHEUS_MULTIPROC_DIR", root_dir.join("tmp", "promenade"))
|
|
11
20
|
end
|
|
12
21
|
|
|
13
|
-
def
|
|
22
|
+
def setup
|
|
14
23
|
unless File.directory? multiprocess_files_dir
|
|
15
24
|
FileUtils.mkdir_p multiprocess_files_dir
|
|
16
25
|
end
|
data/lib/promenade/version.rb
CHANGED
data/promenade.gemspec
CHANGED
|
@@ -22,19 +22,23 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
23
23
|
spec.require_paths = ["lib"]
|
|
24
24
|
|
|
25
|
-
spec.required_ruby_version = ">= 2.
|
|
25
|
+
spec.required_ruby_version = ">= 2.7", "< 3.2"
|
|
26
26
|
|
|
27
|
-
spec.add_dependency "
|
|
28
|
-
spec.add_dependency "
|
|
27
|
+
spec.add_dependency "actionpack"
|
|
28
|
+
spec.add_dependency "activesupport", "> 6.0", "< 8.0"
|
|
29
|
+
spec.add_dependency "prometheus-client-mmap", "~> 0.16.0"
|
|
29
30
|
spec.add_dependency "rack"
|
|
30
|
-
|
|
31
31
|
spec.add_development_dependency "bundler", "~> 2.0"
|
|
32
|
+
spec.add_development_dependency "byebug"
|
|
32
33
|
spec.add_development_dependency "climate_control"
|
|
33
34
|
spec.add_development_dependency "deep-cover"
|
|
34
|
-
spec.add_development_dependency "
|
|
35
|
-
spec.add_development_dependency "
|
|
35
|
+
spec.add_development_dependency "rails", "> 3.0", "< 8.0"
|
|
36
|
+
spec.add_development_dependency "rake"
|
|
37
|
+
spec.add_development_dependency "rspec", "~> 3.11"
|
|
38
|
+
spec.add_development_dependency "rspec-rails", "~> 5.1"
|
|
36
39
|
spec.add_development_dependency "rubocop"
|
|
37
40
|
spec.add_development_dependency "rubocop-performance"
|
|
38
41
|
spec.add_development_dependency "rubocop-rails"
|
|
39
42
|
spec.add_development_dependency "simplecov"
|
|
43
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
40
44
|
end
|
metadata
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: promenade
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ed Robinson
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-06-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: actionpack
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
@@ -24,20 +24,40 @@ dependencies:
|
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activesupport
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '6.0'
|
|
34
|
+
- - "<"
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '8.0'
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">"
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '6.0'
|
|
44
|
+
- - "<"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '8.0'
|
|
27
47
|
- !ruby/object:Gem::Dependency
|
|
28
48
|
name: prometheus-client-mmap
|
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
|
30
50
|
requirements:
|
|
31
51
|
- - "~>"
|
|
32
52
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
53
|
+
version: 0.16.0
|
|
34
54
|
type: :runtime
|
|
35
55
|
prerelease: false
|
|
36
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
57
|
requirements:
|
|
38
58
|
- - "~>"
|
|
39
59
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.
|
|
60
|
+
version: 0.16.0
|
|
41
61
|
- !ruby/object:Gem::Dependency
|
|
42
62
|
name: rack
|
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,6 +86,20 @@ dependencies:
|
|
|
66
86
|
- - "~>"
|
|
67
87
|
- !ruby/object:Gem::Version
|
|
68
88
|
version: '2.0'
|
|
89
|
+
- !ruby/object:Gem::Dependency
|
|
90
|
+
name: byebug
|
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
type: :development
|
|
97
|
+
prerelease: false
|
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
69
103
|
- !ruby/object:Gem::Dependency
|
|
70
104
|
name: climate_control
|
|
71
105
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,34 +128,68 @@ dependencies:
|
|
|
94
128
|
- - ">="
|
|
95
129
|
- !ruby/object:Gem::Version
|
|
96
130
|
version: '0'
|
|
131
|
+
- !ruby/object:Gem::Dependency
|
|
132
|
+
name: rails
|
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">"
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '3.0'
|
|
138
|
+
- - "<"
|
|
139
|
+
- !ruby/object:Gem::Version
|
|
140
|
+
version: '8.0'
|
|
141
|
+
type: :development
|
|
142
|
+
prerelease: false
|
|
143
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
144
|
+
requirements:
|
|
145
|
+
- - ">"
|
|
146
|
+
- !ruby/object:Gem::Version
|
|
147
|
+
version: '3.0'
|
|
148
|
+
- - "<"
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '8.0'
|
|
97
151
|
- !ruby/object:Gem::Dependency
|
|
98
152
|
name: rake
|
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
|
154
|
+
requirements:
|
|
155
|
+
- - ">="
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '0'
|
|
158
|
+
type: :development
|
|
159
|
+
prerelease: false
|
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
161
|
+
requirements:
|
|
162
|
+
- - ">="
|
|
163
|
+
- !ruby/object:Gem::Version
|
|
164
|
+
version: '0'
|
|
165
|
+
- !ruby/object:Gem::Dependency
|
|
166
|
+
name: rspec
|
|
99
167
|
requirement: !ruby/object:Gem::Requirement
|
|
100
168
|
requirements:
|
|
101
169
|
- - "~>"
|
|
102
170
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '
|
|
171
|
+
version: '3.11'
|
|
104
172
|
type: :development
|
|
105
173
|
prerelease: false
|
|
106
174
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
175
|
requirements:
|
|
108
176
|
- - "~>"
|
|
109
177
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '
|
|
178
|
+
version: '3.11'
|
|
111
179
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: rspec
|
|
180
|
+
name: rspec-rails
|
|
113
181
|
requirement: !ruby/object:Gem::Requirement
|
|
114
182
|
requirements:
|
|
115
183
|
- - "~>"
|
|
116
184
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
185
|
+
version: '5.1'
|
|
118
186
|
type: :development
|
|
119
187
|
prerelease: false
|
|
120
188
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
189
|
requirements:
|
|
122
190
|
- - "~>"
|
|
123
191
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
192
|
+
version: '5.1'
|
|
125
193
|
- !ruby/object:Gem::Dependency
|
|
126
194
|
name: rubocop
|
|
127
195
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -178,7 +246,7 @@ dependencies:
|
|
|
178
246
|
- - ">="
|
|
179
247
|
- !ruby/object:Gem::Version
|
|
180
248
|
version: '0'
|
|
181
|
-
description:
|
|
249
|
+
description:
|
|
182
250
|
email:
|
|
183
251
|
- edward-robinson@cookpad.com
|
|
184
252
|
executables:
|
|
@@ -199,9 +267,15 @@ files:
|
|
|
199
267
|
- Rakefile
|
|
200
268
|
- bin/console
|
|
201
269
|
- bin/integration_test
|
|
270
|
+
- bin/rails
|
|
202
271
|
- bin/setup
|
|
203
272
|
- exe/promenade
|
|
204
273
|
- lib/promenade.rb
|
|
274
|
+
- lib/promenade/client/rack/collector.rb
|
|
275
|
+
- lib/promenade/client/rack/exception_handler.rb
|
|
276
|
+
- lib/promenade/client/rack/request_labeler.rb
|
|
277
|
+
- lib/promenade/client/rack/singleton_caller.rb
|
|
278
|
+
- lib/promenade/engine.rb
|
|
205
279
|
- lib/promenade/kafka.rb
|
|
206
280
|
- lib/promenade/kafka/async_producer_subscriber.rb
|
|
207
281
|
- lib/promenade/kafka/connection_subscriber.rb
|
|
@@ -217,8 +291,9 @@ files:
|
|
|
217
291
|
homepage: https://github.com/errm/promenade
|
|
218
292
|
licenses:
|
|
219
293
|
- MIT
|
|
220
|
-
metadata:
|
|
221
|
-
|
|
294
|
+
metadata:
|
|
295
|
+
rubygems_mfa_required: 'true'
|
|
296
|
+
post_install_message:
|
|
222
297
|
rdoc_options: []
|
|
223
298
|
require_paths:
|
|
224
299
|
- lib
|
|
@@ -226,18 +301,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
226
301
|
requirements:
|
|
227
302
|
- - ">="
|
|
228
303
|
- !ruby/object:Gem::Version
|
|
229
|
-
version: '2.
|
|
304
|
+
version: '2.7'
|
|
230
305
|
- - "<"
|
|
231
306
|
- !ruby/object:Gem::Version
|
|
232
|
-
version: '
|
|
307
|
+
version: '3.2'
|
|
233
308
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
309
|
requirements:
|
|
235
310
|
- - ">="
|
|
236
311
|
- !ruby/object:Gem::Version
|
|
237
312
|
version: '0'
|
|
238
313
|
requirements: []
|
|
239
|
-
rubygems_version: 3.
|
|
240
|
-
signing_key:
|
|
314
|
+
rubygems_version: 3.3.8
|
|
315
|
+
signing_key:
|
|
241
316
|
specification_version: 4
|
|
242
317
|
summary: Promenade makes it simple to instrument Ruby apps for prometheus scraping
|
|
243
318
|
test_files: []
|