promenade 0.12.2 → 0.12.4
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 +6 -2
- data/Gemfile +0 -1
- data/Gemfile.lock +80 -81
- data/README.md +1 -0
- data/bin/yjit_intergration_test +11 -0
- data/codecove.yml +2 -0
- data/lib/promenade/pitchfork/mem_stats.rb +32 -0
- data/lib/promenade/pitchfork/middleware.rb +28 -0
- data/lib/promenade/pitchfork/stats.rb +62 -0
- data/lib/promenade/pitchfork/worker_pid_provider.rb +31 -0
- data/lib/promenade/railtie.rb +10 -0
- data/lib/promenade/raindrops/middleware.rb +39 -0
- data/lib/promenade/raindrops/stats.rb +42 -0
- data/lib/promenade/setup.rb +22 -2
- data/lib/promenade/version.rb +1 -1
- data/lib/promenade/yjit/stats.rb +12 -1
- data/promenade.gemspec +2 -0
- metadata +39 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 49d2e750dd0fdec89e701c966a98d411a8b9eceabd2ccb64024d413660ef82d0
|
|
4
|
+
data.tar.gz: e5bd7c4e94c30ae55b733bf8db4a18d7149f7f55786e167e0c1e8ad278f6a4bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 07d9e832b3589d10022e2efa2a42a1be6cf7c3372baf12148b6fbb14a1c63e979b061ce71c9e00dca611b928eb3d4cad3b29fe32af05765fb54debf524265bf3
|
|
7
|
+
data.tar.gz: 32dd9293280f03230133283a72e78f1153b4e44116f65c4a3192e81f33ee1da4b50931238fc1327f83b30e4a58df26820dc60aa9b7a3d5b045e215baa5037256
|
data/.github/workflows/ci.yaml
CHANGED
|
@@ -9,12 +9,16 @@ jobs:
|
|
|
9
9
|
strategy:
|
|
10
10
|
fail-fast: false
|
|
11
11
|
matrix:
|
|
12
|
-
ruby: ["3.
|
|
12
|
+
ruby: ["3.1", "3.2", "3.3"]
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
16
|
- uses: ruby/setup-ruby@v1
|
|
17
17
|
with:
|
|
18
18
|
ruby-version: ${{ matrix.ruby }}
|
|
19
19
|
bundler-cache: true
|
|
20
20
|
- run: bundle exec rake
|
|
21
|
+
- name: Upload test results to Codecov
|
|
22
|
+
uses: codecov/codecov-action@v4
|
|
23
|
+
with:
|
|
24
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
promenade (0.12.
|
|
4
|
+
promenade (0.12.4)
|
|
5
5
|
actionpack
|
|
6
6
|
activesupport (> 6.0, < 8.0)
|
|
7
7
|
prometheus-client-mmap (~> 1.1)
|
|
@@ -11,35 +11,35 @@ PATH
|
|
|
11
11
|
GEM
|
|
12
12
|
remote: https://rubygems.org/
|
|
13
13
|
specs:
|
|
14
|
-
actioncable (7.1.3)
|
|
15
|
-
actionpack (= 7.1.3)
|
|
16
|
-
activesupport (= 7.1.3)
|
|
14
|
+
actioncable (7.1.3.4)
|
|
15
|
+
actionpack (= 7.1.3.4)
|
|
16
|
+
activesupport (= 7.1.3.4)
|
|
17
17
|
nio4r (~> 2.0)
|
|
18
18
|
websocket-driver (>= 0.6.1)
|
|
19
19
|
zeitwerk (~> 2.6)
|
|
20
|
-
actionmailbox (7.1.3)
|
|
21
|
-
actionpack (= 7.1.3)
|
|
22
|
-
activejob (= 7.1.3)
|
|
23
|
-
activerecord (= 7.1.3)
|
|
24
|
-
activestorage (= 7.1.3)
|
|
25
|
-
activesupport (= 7.1.3)
|
|
20
|
+
actionmailbox (7.1.3.4)
|
|
21
|
+
actionpack (= 7.1.3.4)
|
|
22
|
+
activejob (= 7.1.3.4)
|
|
23
|
+
activerecord (= 7.1.3.4)
|
|
24
|
+
activestorage (= 7.1.3.4)
|
|
25
|
+
activesupport (= 7.1.3.4)
|
|
26
26
|
mail (>= 2.7.1)
|
|
27
27
|
net-imap
|
|
28
28
|
net-pop
|
|
29
29
|
net-smtp
|
|
30
|
-
actionmailer (7.1.3)
|
|
31
|
-
actionpack (= 7.1.3)
|
|
32
|
-
actionview (= 7.1.3)
|
|
33
|
-
activejob (= 7.1.3)
|
|
34
|
-
activesupport (= 7.1.3)
|
|
30
|
+
actionmailer (7.1.3.4)
|
|
31
|
+
actionpack (= 7.1.3.4)
|
|
32
|
+
actionview (= 7.1.3.4)
|
|
33
|
+
activejob (= 7.1.3.4)
|
|
34
|
+
activesupport (= 7.1.3.4)
|
|
35
35
|
mail (~> 2.5, >= 2.5.4)
|
|
36
36
|
net-imap
|
|
37
37
|
net-pop
|
|
38
38
|
net-smtp
|
|
39
39
|
rails-dom-testing (~> 2.2)
|
|
40
|
-
actionpack (7.1.3)
|
|
41
|
-
actionview (= 7.1.3)
|
|
42
|
-
activesupport (= 7.1.3)
|
|
40
|
+
actionpack (7.1.3.4)
|
|
41
|
+
actionview (= 7.1.3.4)
|
|
42
|
+
activesupport (= 7.1.3.4)
|
|
43
43
|
nokogiri (>= 1.8.5)
|
|
44
44
|
racc
|
|
45
45
|
rack (>= 2.2.4)
|
|
@@ -47,35 +47,35 @@ GEM
|
|
|
47
47
|
rack-test (>= 0.6.3)
|
|
48
48
|
rails-dom-testing (~> 2.2)
|
|
49
49
|
rails-html-sanitizer (~> 1.6)
|
|
50
|
-
actiontext (7.1.3)
|
|
51
|
-
actionpack (= 7.1.3)
|
|
52
|
-
activerecord (= 7.1.3)
|
|
53
|
-
activestorage (= 7.1.3)
|
|
54
|
-
activesupport (= 7.1.3)
|
|
50
|
+
actiontext (7.1.3.4)
|
|
51
|
+
actionpack (= 7.1.3.4)
|
|
52
|
+
activerecord (= 7.1.3.4)
|
|
53
|
+
activestorage (= 7.1.3.4)
|
|
54
|
+
activesupport (= 7.1.3.4)
|
|
55
55
|
globalid (>= 0.6.0)
|
|
56
56
|
nokogiri (>= 1.8.5)
|
|
57
|
-
actionview (7.1.3)
|
|
58
|
-
activesupport (= 7.1.3)
|
|
57
|
+
actionview (7.1.3.4)
|
|
58
|
+
activesupport (= 7.1.3.4)
|
|
59
59
|
builder (~> 3.1)
|
|
60
60
|
erubi (~> 1.11)
|
|
61
61
|
rails-dom-testing (~> 2.2)
|
|
62
62
|
rails-html-sanitizer (~> 1.6)
|
|
63
|
-
activejob (7.1.3)
|
|
64
|
-
activesupport (= 7.1.3)
|
|
63
|
+
activejob (7.1.3.4)
|
|
64
|
+
activesupport (= 7.1.3.4)
|
|
65
65
|
globalid (>= 0.3.6)
|
|
66
|
-
activemodel (7.1.3)
|
|
67
|
-
activesupport (= 7.1.3)
|
|
68
|
-
activerecord (7.1.3)
|
|
69
|
-
activemodel (= 7.1.3)
|
|
70
|
-
activesupport (= 7.1.3)
|
|
66
|
+
activemodel (7.1.3.4)
|
|
67
|
+
activesupport (= 7.1.3.4)
|
|
68
|
+
activerecord (7.1.3.4)
|
|
69
|
+
activemodel (= 7.1.3.4)
|
|
70
|
+
activesupport (= 7.1.3.4)
|
|
71
71
|
timeout (>= 0.4.0)
|
|
72
|
-
activestorage (7.1.3)
|
|
73
|
-
actionpack (= 7.1.3)
|
|
74
|
-
activejob (= 7.1.3)
|
|
75
|
-
activerecord (= 7.1.3)
|
|
76
|
-
activesupport (= 7.1.3)
|
|
72
|
+
activestorage (7.1.3.4)
|
|
73
|
+
actionpack (= 7.1.3.4)
|
|
74
|
+
activejob (= 7.1.3.4)
|
|
75
|
+
activerecord (= 7.1.3.4)
|
|
76
|
+
activesupport (= 7.1.3.4)
|
|
77
77
|
marcel (~> 1.0)
|
|
78
|
-
activesupport (7.1.3)
|
|
78
|
+
activesupport (7.1.3.4)
|
|
79
79
|
base64
|
|
80
80
|
bigdecimal
|
|
81
81
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
@@ -87,24 +87,21 @@ GEM
|
|
|
87
87
|
tzinfo (~> 2.0)
|
|
88
88
|
ast (2.4.2)
|
|
89
89
|
base64 (0.2.0)
|
|
90
|
-
bigdecimal (3.1.
|
|
91
|
-
builder (3.
|
|
90
|
+
bigdecimal (3.1.8)
|
|
91
|
+
builder (3.3.0)
|
|
92
92
|
byebug (11.1.3)
|
|
93
93
|
climate_control (1.2.0)
|
|
94
|
-
|
|
95
|
-
simplecov (>= 0.15, < 0.22)
|
|
96
|
-
concurrent-ruby (1.2.3)
|
|
94
|
+
concurrent-ruby (1.3.4)
|
|
97
95
|
connection_pool (2.4.1)
|
|
98
96
|
crass (1.0.6)
|
|
99
97
|
date (3.3.4)
|
|
100
98
|
diff-lcs (1.5.1)
|
|
101
99
|
docile (1.4.0)
|
|
102
|
-
drb (2.2.
|
|
103
|
-
|
|
104
|
-
erubi (1.12.0)
|
|
100
|
+
drb (2.2.1)
|
|
101
|
+
erubi (1.13.0)
|
|
105
102
|
globalid (1.2.1)
|
|
106
103
|
activesupport (>= 6.1)
|
|
107
|
-
i18n (1.14.
|
|
104
|
+
i18n (1.14.5)
|
|
108
105
|
concurrent-ruby (~> 1.0)
|
|
109
106
|
io-console (0.7.2)
|
|
110
107
|
irb (1.11.2)
|
|
@@ -120,9 +117,9 @@ GEM
|
|
|
120
117
|
net-imap
|
|
121
118
|
net-pop
|
|
122
119
|
net-smtp
|
|
123
|
-
marcel (1.0.
|
|
120
|
+
marcel (1.0.4)
|
|
124
121
|
mini_mime (1.1.5)
|
|
125
|
-
minitest (5.
|
|
122
|
+
minitest (5.25.0)
|
|
126
123
|
mutex_m (0.2.0)
|
|
127
124
|
net-imap (0.4.10)
|
|
128
125
|
date
|
|
@@ -134,20 +131,16 @@ GEM
|
|
|
134
131
|
net-smtp (0.4.0.1)
|
|
135
132
|
net-protocol
|
|
136
133
|
nio4r (2.7.0)
|
|
137
|
-
nokogiri (1.16.
|
|
134
|
+
nokogiri (1.16.7-arm64-darwin)
|
|
138
135
|
racc (~> 1.4)
|
|
139
|
-
nokogiri (1.16.
|
|
136
|
+
nokogiri (1.16.7-x86_64-darwin)
|
|
140
137
|
racc (~> 1.4)
|
|
141
|
-
nokogiri (1.16.
|
|
142
|
-
racc (~> 1.4)
|
|
143
|
-
nokogiri (1.16.2-x86_64-linux)
|
|
138
|
+
nokogiri (1.16.7-x86_64-linux)
|
|
144
139
|
racc (~> 1.4)
|
|
145
140
|
parallel (1.24.0)
|
|
146
141
|
parser (3.3.0.5)
|
|
147
142
|
ast (~> 2.4.1)
|
|
148
143
|
racc
|
|
149
|
-
prometheus-client-mmap (1.1.1)
|
|
150
|
-
rb_sys (~> 0.9.86)
|
|
151
144
|
prometheus-client-mmap (1.1.1-arm64-darwin)
|
|
152
145
|
rb_sys (~> 0.9.86)
|
|
153
146
|
prometheus-client-mmap (1.1.1-x86_64-darwin)
|
|
@@ -156,8 +149,8 @@ GEM
|
|
|
156
149
|
rb_sys (~> 0.9.86)
|
|
157
150
|
psych (5.1.2)
|
|
158
151
|
stringio
|
|
159
|
-
racc (1.
|
|
160
|
-
rack (3.
|
|
152
|
+
racc (1.8.1)
|
|
153
|
+
rack (3.1.7)
|
|
161
154
|
rack-session (2.0.0)
|
|
162
155
|
rack (>= 3.0.0)
|
|
163
156
|
rack-test (2.1.0)
|
|
@@ -165,20 +158,20 @@ GEM
|
|
|
165
158
|
rackup (2.1.0)
|
|
166
159
|
rack (>= 3)
|
|
167
160
|
webrick (~> 1.8)
|
|
168
|
-
rails (7.1.3)
|
|
169
|
-
actioncable (= 7.1.3)
|
|
170
|
-
actionmailbox (= 7.1.3)
|
|
171
|
-
actionmailer (= 7.1.3)
|
|
172
|
-
actionpack (= 7.1.3)
|
|
173
|
-
actiontext (= 7.1.3)
|
|
174
|
-
actionview (= 7.1.3)
|
|
175
|
-
activejob (= 7.1.3)
|
|
176
|
-
activemodel (= 7.1.3)
|
|
177
|
-
activerecord (= 7.1.3)
|
|
178
|
-
activestorage (= 7.1.3)
|
|
179
|
-
activesupport (= 7.1.3)
|
|
161
|
+
rails (7.1.3.4)
|
|
162
|
+
actioncable (= 7.1.3.4)
|
|
163
|
+
actionmailbox (= 7.1.3.4)
|
|
164
|
+
actionmailer (= 7.1.3.4)
|
|
165
|
+
actionpack (= 7.1.3.4)
|
|
166
|
+
actiontext (= 7.1.3.4)
|
|
167
|
+
actionview (= 7.1.3.4)
|
|
168
|
+
activejob (= 7.1.3.4)
|
|
169
|
+
activemodel (= 7.1.3.4)
|
|
170
|
+
activerecord (= 7.1.3.4)
|
|
171
|
+
activestorage (= 7.1.3.4)
|
|
172
|
+
activesupport (= 7.1.3.4)
|
|
180
173
|
bundler (>= 1.15.0)
|
|
181
|
-
railties (= 7.1.3)
|
|
174
|
+
railties (= 7.1.3.4)
|
|
182
175
|
rails-dom-testing (2.2.0)
|
|
183
176
|
activesupport (>= 5.0.0)
|
|
184
177
|
minitest
|
|
@@ -186,23 +179,25 @@ GEM
|
|
|
186
179
|
rails-html-sanitizer (1.6.0)
|
|
187
180
|
loofah (~> 2.21)
|
|
188
181
|
nokogiri (~> 1.14)
|
|
189
|
-
railties (7.1.3)
|
|
190
|
-
actionpack (= 7.1.3)
|
|
191
|
-
activesupport (= 7.1.3)
|
|
182
|
+
railties (7.1.3.4)
|
|
183
|
+
actionpack (= 7.1.3.4)
|
|
184
|
+
activesupport (= 7.1.3.4)
|
|
192
185
|
irb
|
|
193
186
|
rackup (>= 1.0.0)
|
|
194
187
|
rake (>= 12.2)
|
|
195
188
|
thor (~> 1.0, >= 1.2.2)
|
|
196
189
|
zeitwerk (~> 2.6)
|
|
197
190
|
rainbow (3.1.1)
|
|
191
|
+
raindrops (0.20.1)
|
|
198
192
|
rake (13.1.0)
|
|
199
193
|
rb_sys (0.9.87)
|
|
200
|
-
rdoc (6.6.
|
|
194
|
+
rdoc (6.6.3.1)
|
|
201
195
|
psych (>= 4.0.0)
|
|
202
196
|
regexp_parser (2.9.0)
|
|
203
|
-
reline (0.4.
|
|
197
|
+
reline (0.4.3)
|
|
204
198
|
io-console (~> 0.5)
|
|
205
|
-
rexml (3.
|
|
199
|
+
rexml (3.3.6)
|
|
200
|
+
strscan
|
|
206
201
|
rspec (3.13.0)
|
|
207
202
|
rspec-core (~> 3.13.0)
|
|
208
203
|
rspec-expectations (~> 3.13.0)
|
|
@@ -254,15 +249,18 @@ GEM
|
|
|
254
249
|
rubocop-capybara (~> 2.17)
|
|
255
250
|
rubocop-factory_bot (~> 2.22)
|
|
256
251
|
ruby-progressbar (1.13.0)
|
|
257
|
-
ruby2_keywords (0.0.5)
|
|
258
252
|
simplecov (0.21.2)
|
|
259
253
|
docile (~> 1.1)
|
|
260
254
|
simplecov-html (~> 0.11)
|
|
261
255
|
simplecov_json_formatter (~> 0.1)
|
|
256
|
+
simplecov-cobertura (2.1.0)
|
|
257
|
+
rexml
|
|
258
|
+
simplecov (~> 0.19)
|
|
262
259
|
simplecov-html (0.12.3)
|
|
263
260
|
simplecov_json_formatter (0.1.4)
|
|
264
261
|
stringio (3.1.0)
|
|
265
|
-
|
|
262
|
+
strscan (3.1.0)
|
|
263
|
+
thor (1.3.1)
|
|
266
264
|
timeout (0.4.1)
|
|
267
265
|
tzinfo (2.0.6)
|
|
268
266
|
concurrent-ruby (~> 1.0)
|
|
@@ -274,8 +272,8 @@ GEM
|
|
|
274
272
|
zeitwerk (2.6.13)
|
|
275
273
|
|
|
276
274
|
PLATFORMS
|
|
275
|
+
arm64-darwin-21
|
|
277
276
|
arm64-darwin-22
|
|
278
|
-
arm64-linux
|
|
279
277
|
x86_64-darwin-22
|
|
280
278
|
x86_64-linux
|
|
281
279
|
|
|
@@ -283,9 +281,9 @@ DEPENDENCIES
|
|
|
283
281
|
bundler (~> 2.0)
|
|
284
282
|
byebug
|
|
285
283
|
climate_control
|
|
286
|
-
codecov
|
|
287
284
|
promenade!
|
|
288
285
|
rails (> 3.0, < 8.0)
|
|
286
|
+
raindrops
|
|
289
287
|
rake
|
|
290
288
|
rspec (~> 3.11)
|
|
291
289
|
rspec-rails (~> 5.1)
|
|
@@ -294,6 +292,7 @@ DEPENDENCIES
|
|
|
294
292
|
rubocop-rails
|
|
295
293
|
rubocop-rspec
|
|
296
294
|
simplecov
|
|
295
|
+
simplecov-cobertura
|
|
297
296
|
webrick
|
|
298
297
|
|
|
299
298
|
BUNDLED WITH
|
data/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/errm/promenade/actions/workflows/ci.yaml)
|
|
4
4
|
[](https://badge.fury.io/rb/promenade)
|
|
5
|
+
[](https://codecov.io/github/errm/promenade)
|
|
5
6
|
|
|
6
7
|
Promenade is a library to simplify instrumenting Ruby applications with Prometheus.
|
|
7
8
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "promenade"
|
|
5
|
+
require "promenade/yjit/stats"
|
|
6
|
+
require "prometheus/client"
|
|
7
|
+
require "prometheus/client/formats/text"
|
|
8
|
+
|
|
9
|
+
Promenade.setup
|
|
10
|
+
Promenade::YJIT::Stats.instrument
|
|
11
|
+
puts Prometheus::Client::Formats::Text.marshal_multiprocess
|
data/codecove.yml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require "pitchfork/mem_info"
|
|
3
|
+
rescue LoadError
|
|
4
|
+
# No pitchfork available, dont do anything
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module Promenade
|
|
8
|
+
module Pitchfork
|
|
9
|
+
class MemStats
|
|
10
|
+
Promenade.gauge :pitchfork_memory_usage_bytes do
|
|
11
|
+
doc "Memory usage in bytes, broken down by type (RSS, PSS, SHARED_MEMORY)"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
return unless defined?(::Pitchfork) && defined?(::Pitchfork::MemInfo)
|
|
16
|
+
|
|
17
|
+
@mem_info = ::Pitchfork::MemInfo.new(Process.pid)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def instrument
|
|
21
|
+
Promenade.metric(:pitchfork_memory_usage_bytes).set({ type: "RSS" }, @mem_info.rss * 1024)
|
|
22
|
+
Promenade.metric(:pitchfork_memory_usage_bytes).set({ type: "PSS" }, @mem_info.pss * 1024)
|
|
23
|
+
Promenade.metric(:pitchfork_memory_usage_bytes).set({ type: "Shared" }, @mem_info.shared_memory * 1024)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.instrument
|
|
27
|
+
new.instrument
|
|
28
|
+
rescue StandardError
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "promenade/pitchfork/stats"
|
|
2
|
+
require "promenade/pitchfork/mem_stats"
|
|
3
|
+
|
|
4
|
+
module Promenade
|
|
5
|
+
module Pitchfork
|
|
6
|
+
class Middleware
|
|
7
|
+
RACK_AFTER_REPLY = "rack.after_reply".freeze
|
|
8
|
+
|
|
9
|
+
def initialize(app)
|
|
10
|
+
@app = app
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
if env.key?(RACK_AFTER_REPLY)
|
|
15
|
+
env[RACK_AFTER_REPLY] << -> { instrument }
|
|
16
|
+
end
|
|
17
|
+
@app.call(env)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def instrument
|
|
23
|
+
Promenade::Pitchfork::Stats.instrument
|
|
24
|
+
Promenade::Pitchfork::MemStats.instrument
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require "promenade/raindrops/stats"
|
|
2
|
+
|
|
3
|
+
module Promenade
|
|
4
|
+
module Pitchfork
|
|
5
|
+
class Stats
|
|
6
|
+
Promenade.gauge :pitchfork_workers_count do
|
|
7
|
+
doc "Number of workers configured"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
Promenade.gauge :pitchfork_live_workers_count do
|
|
11
|
+
doc "Number of live / booted workers"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Promenade.gauge :pitchfork_capacity do
|
|
15
|
+
doc "Number of workers that are currently idle"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Promenade.gauge :pitchfork_busy_percent do
|
|
19
|
+
doc "Percentage of workers that are currently busy"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def initialize
|
|
23
|
+
return unless defined?(::Pitchfork) && defined?(::Pitchfork::Info)
|
|
24
|
+
|
|
25
|
+
@workers_count = ::Pitchfork::Info.workers_count
|
|
26
|
+
@live_workers_count = ::Pitchfork::Info.live_workers_count
|
|
27
|
+
|
|
28
|
+
raindrops_stats = Raindrops::Stats.new
|
|
29
|
+
|
|
30
|
+
@active_workers = raindrops_stats.active_workers || 0
|
|
31
|
+
@queued_requests = raindrops_stats.queued_requests || 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def instrument
|
|
35
|
+
Promenade.metric(:pitchfork_workers_count).set({}, workers_count)
|
|
36
|
+
Promenade.metric(:pitchfork_live_workers_count).set({}, live_workers_count)
|
|
37
|
+
Promenade.metric(:pitchfork_capacity).set({}, capacity)
|
|
38
|
+
Promenade.metric(:pitchfork_busy_percent).set({}, busy_percent)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.instrument
|
|
42
|
+
new.instrument
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
attr_reader :workers_count, :live_workers_count, :active_workers, :queued_requests
|
|
48
|
+
|
|
49
|
+
def capacity
|
|
50
|
+
return 0 if live_workers_count.nil? || live_workers_count == 0
|
|
51
|
+
|
|
52
|
+
live_workers_count - active_workers
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def busy_percent
|
|
56
|
+
return 0 if live_workers_count == 0
|
|
57
|
+
|
|
58
|
+
(active_workers.to_f / live_workers_count) * 100
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Promenade
|
|
2
|
+
module Pitchfork
|
|
3
|
+
class WorkerPidProvider
|
|
4
|
+
def self.fetch
|
|
5
|
+
worker_id || "process_id_#{Process.pid}"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.object_based_worker_id
|
|
9
|
+
return unless defined?(::Pitchfork::Worker)
|
|
10
|
+
|
|
11
|
+
workers = ObjectSpace.each_object(::Pitchfork::Worker)
|
|
12
|
+
return if workers.nil?
|
|
13
|
+
|
|
14
|
+
workers_first = workers.first
|
|
15
|
+
workers_first&.nr
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.program_name
|
|
19
|
+
$PROGRAM_NAME
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.worker_id
|
|
23
|
+
if matchdata = program_name.match(/pitchfork.*worker\[(.+)\]/) # rubocop:disable Lint/AssignmentInCondition
|
|
24
|
+
"pitchfork_#{matchdata[1]}"
|
|
25
|
+
elsif object_worker_id = object_based_worker_id # rubocop:disable Lint/AssignmentInCondition
|
|
26
|
+
"pitchfork_#{object_worker_id}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/promenade/railtie.rb
CHANGED
|
@@ -13,6 +13,16 @@ module Promenade
|
|
|
13
13
|
Promenade::Client::Rack::HTTPRequestDurationCollector
|
|
14
14
|
Rails.application.config.middleware.insert 0,
|
|
15
15
|
Promenade::Client::Rack::HTTPRequestQueueTimeCollector
|
|
16
|
+
|
|
17
|
+
if defined?(::Raindrops) && (defined?(::Pitchfork) || defined?(::Unicorn))
|
|
18
|
+
require "promenade/raindrops/middleware"
|
|
19
|
+
Rails.application.config.middleware.use Promenade::Raindrops::Middleware
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if defined?(::Pitchfork)
|
|
23
|
+
require "promenade/pitchfork/middleware"
|
|
24
|
+
Rails.application.config.middleware.use Promenade::Pitchfork::Middleware
|
|
25
|
+
end
|
|
16
26
|
end
|
|
17
27
|
end
|
|
18
28
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require "promenade/raindrops/stats"
|
|
2
|
+
|
|
3
|
+
module Promenade
|
|
4
|
+
module Raindrops
|
|
5
|
+
class Middleware
|
|
6
|
+
RACK_AFTER_REPLY = "rack.after_reply".freeze
|
|
7
|
+
|
|
8
|
+
def initialize(app)
|
|
9
|
+
@app = app
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(env)
|
|
13
|
+
if env.key?(RACK_AFTER_REPLY)
|
|
14
|
+
env[RACK_AFTER_REPLY] << -> { instrument }
|
|
15
|
+
end
|
|
16
|
+
@app.call(env)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def tcp_listener_names
|
|
22
|
+
if defined?(::Pitchfork)
|
|
23
|
+
::Pitchfork.listener_names
|
|
24
|
+
elsif defined?(::Unicorn)
|
|
25
|
+
::Unicorn.listener_names
|
|
26
|
+
else
|
|
27
|
+
raise StandardError,
|
|
28
|
+
"Promenade::Raindrops::Middleware expects either ::Pitchfork or ::Unicorn to be defined"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def instrument
|
|
33
|
+
tcp_listener_names.each do |name|
|
|
34
|
+
Promenade::Raindrops::Stats.instrument(listener_address: name)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require "raindrops"
|
|
3
|
+
rescue LoadError
|
|
4
|
+
# No raindrops available, dont do anything
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module Promenade
|
|
8
|
+
module Raindrops
|
|
9
|
+
Promenade.gauge :rack_active_workers do
|
|
10
|
+
doc "Number of active workers in the Application Server"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Promenade.gauge :rack_queued_requests do
|
|
14
|
+
doc "Number of requests waiting to be processed by the Application Server"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class Stats
|
|
18
|
+
attr_reader :active_workers, :queued_requests, :listener_address
|
|
19
|
+
|
|
20
|
+
def initialize(listener_address: nil)
|
|
21
|
+
return unless defined?(::Raindrops)
|
|
22
|
+
return unless defined?(::Raindrops::Linux.tcp_listener_stats)
|
|
23
|
+
|
|
24
|
+
@listener_address = listener_address || "127.0.0.1:#{ENV.fetch('PORT', 3000)}"
|
|
25
|
+
|
|
26
|
+
stats = ::Raindrops::Linux.tcp_listener_stats([@listener_address])[@listener_address]
|
|
27
|
+
|
|
28
|
+
@active_workers = stats.active
|
|
29
|
+
@queued_requests = stats.queued
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def instrument
|
|
33
|
+
Promenade.metric(:rack_active_workers).set({}, active_workers) if active_workers
|
|
34
|
+
Promenade.metric(:rack_queued_requests).set({}, queued_requests) if queued_requests
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.instrument(listener_address: nil)
|
|
38
|
+
new(listener_address: listener_address).instrument
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/promenade/setup.rb
CHANGED
|
@@ -27,11 +27,31 @@ module Promenade
|
|
|
27
27
|
ENV["prometheus_multiproc_dir"] = multiprocess_files_dir.to_s
|
|
28
28
|
|
|
29
29
|
require "prometheus/client"
|
|
30
|
-
require "prometheus/client/support/unicorn"
|
|
31
30
|
|
|
32
31
|
::Prometheus::Client.configure do |config|
|
|
33
32
|
config.multiprocess_files_dir = multiprocess_files_dir
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
config.pid_provider = pid_provider_method
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def pid_provider_method
|
|
39
|
+
# This workaround enables us to utilize the same PID provider for both Unicorn, Pitchfork and Puma.
|
|
40
|
+
# We cannot employ the same method directly because Unicorn and Pitchfork are not loaded simultaneously.
|
|
41
|
+
# Instead, we define a method that dynamically loads the appropriate PID provider based on the active server.
|
|
42
|
+
# As a fallback, we use the process ID.
|
|
43
|
+
|
|
44
|
+
if defined?(::Unicorn)
|
|
45
|
+
require "prometheus/client/support/unicorn"
|
|
46
|
+
::Prometheus::Client::Support::Unicorn.method(:worker_pid_provider)
|
|
47
|
+
elsif defined?(::Pitchfork)
|
|
48
|
+
require "promenade/pitchfork/worker_pid_provider"
|
|
49
|
+
Pitchfork::WorkerPidProvider.method(:fetch)
|
|
50
|
+
elsif defined?(::Puma)
|
|
51
|
+
require "prometheus/client/support/puma"
|
|
52
|
+
::Prometheus::Client::Support::Puma.method(:worker_pid_provider)
|
|
53
|
+
else
|
|
54
|
+
-> { "process_id_#{Process.pid}" }
|
|
35
55
|
end
|
|
36
56
|
end
|
|
37
57
|
end
|
data/lib/promenade/version.rb
CHANGED
data/lib/promenade/yjit/stats.rb
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
module Promenade
|
|
2
2
|
module YJIT
|
|
3
3
|
class Stats
|
|
4
|
+
RUNTIME_STATS = %i(
|
|
5
|
+
code_region_size
|
|
6
|
+
ratio_in_yjit
|
|
7
|
+
).freeze
|
|
8
|
+
|
|
4
9
|
Promenade.gauge :ruby_yjit_code_region_size do
|
|
5
10
|
doc "Ruby YJIT code size"
|
|
6
11
|
end
|
|
7
12
|
|
|
13
|
+
Promenade.gauge :ruby_yjit_ratio_in_yjit do
|
|
14
|
+
doc "Shows the ratio of YJIT-executed instructions in %"
|
|
15
|
+
end
|
|
16
|
+
|
|
8
17
|
def self.instrument
|
|
9
18
|
return unless defined?(::RubyVM::YJIT) && ::RubyVM::YJIT.enabled?
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
::RubyVM::YJIT.runtime_stats.select { |stat, _| RUNTIME_STATS.include? stat }.each do |stat, value|
|
|
21
|
+
Promenade.metric(:"ruby_yjit_#{stat}").set({}, value)
|
|
22
|
+
end
|
|
12
23
|
end
|
|
13
24
|
end
|
|
14
25
|
end
|
data/promenade.gemspec
CHANGED
|
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
|
|
|
33
33
|
spec.add_development_dependency "byebug"
|
|
34
34
|
spec.add_development_dependency "climate_control"
|
|
35
35
|
spec.add_development_dependency "rails", "> 3.0", "< 8.0"
|
|
36
|
+
spec.add_development_dependency "raindrops"
|
|
36
37
|
spec.add_development_dependency "rake"
|
|
37
38
|
spec.add_development_dependency "rspec", "~> 3.11"
|
|
38
39
|
spec.add_development_dependency "rspec-rails", "~> 5.1"
|
|
@@ -41,5 +42,6 @@ Gem::Specification.new do |spec|
|
|
|
41
42
|
spec.add_development_dependency "rubocop-rails"
|
|
42
43
|
spec.add_development_dependency "rubocop-rspec"
|
|
43
44
|
spec.add_development_dependency "simplecov"
|
|
45
|
+
spec.add_development_dependency "simplecov-cobertura"
|
|
44
46
|
spec.metadata["rubygems_mfa_required"] = "true"
|
|
45
47
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: promenade
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.12.
|
|
4
|
+
version: 0.12.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ed Robinson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-
|
|
11
|
+
date: 2024-09-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionpack
|
|
@@ -148,6 +148,20 @@ dependencies:
|
|
|
148
148
|
- - "<"
|
|
149
149
|
- !ruby/object:Gem::Version
|
|
150
150
|
version: '8.0'
|
|
151
|
+
- !ruby/object:Gem::Dependency
|
|
152
|
+
name: raindrops
|
|
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'
|
|
151
165
|
- !ruby/object:Gem::Dependency
|
|
152
166
|
name: rake
|
|
153
167
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -260,6 +274,20 @@ dependencies:
|
|
|
260
274
|
- - ">="
|
|
261
275
|
- !ruby/object:Gem::Version
|
|
262
276
|
version: '0'
|
|
277
|
+
- !ruby/object:Gem::Dependency
|
|
278
|
+
name: simplecov-cobertura
|
|
279
|
+
requirement: !ruby/object:Gem::Requirement
|
|
280
|
+
requirements:
|
|
281
|
+
- - ">="
|
|
282
|
+
- !ruby/object:Gem::Version
|
|
283
|
+
version: '0'
|
|
284
|
+
type: :development
|
|
285
|
+
prerelease: false
|
|
286
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
287
|
+
requirements:
|
|
288
|
+
- - ">="
|
|
289
|
+
- !ruby/object:Gem::Version
|
|
290
|
+
version: '0'
|
|
263
291
|
description:
|
|
264
292
|
email:
|
|
265
293
|
- edward-robinson@cookpad.com
|
|
@@ -283,6 +311,8 @@ files:
|
|
|
283
311
|
- bin/integration_test
|
|
284
312
|
- bin/rails
|
|
285
313
|
- bin/setup
|
|
314
|
+
- bin/yjit_intergration_test
|
|
315
|
+
- codecove.yml
|
|
286
316
|
- exe/promenade
|
|
287
317
|
- lib/promenade.rb
|
|
288
318
|
- lib/promenade/client/rack/exception_handler.rb
|
|
@@ -307,8 +337,14 @@ files:
|
|
|
307
337
|
- lib/promenade/karafka/error_subscriber.rb
|
|
308
338
|
- lib/promenade/karafka/statistics_subscriber.rb
|
|
309
339
|
- lib/promenade/karafka/subscriber.rb
|
|
340
|
+
- lib/promenade/pitchfork/mem_stats.rb
|
|
341
|
+
- lib/promenade/pitchfork/middleware.rb
|
|
342
|
+
- lib/promenade/pitchfork/stats.rb
|
|
343
|
+
- lib/promenade/pitchfork/worker_pid_provider.rb
|
|
310
344
|
- lib/promenade/prometheus.rb
|
|
311
345
|
- lib/promenade/railtie.rb
|
|
346
|
+
- lib/promenade/raindrops/middleware.rb
|
|
347
|
+
- lib/promenade/raindrops/stats.rb
|
|
312
348
|
- lib/promenade/setup.rb
|
|
313
349
|
- lib/promenade/version.rb
|
|
314
350
|
- lib/promenade/waterdrop.rb
|
|
@@ -339,7 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
339
375
|
- !ruby/object:Gem::Version
|
|
340
376
|
version: '0'
|
|
341
377
|
requirements: []
|
|
342
|
-
rubygems_version: 3.5.
|
|
378
|
+
rubygems_version: 3.5.7
|
|
343
379
|
signing_key:
|
|
344
380
|
specification_version: 4
|
|
345
381
|
summary: Promenade makes it simple to instrument Ruby apps for prometheus scraping
|