rack-mini-profiler 2.3.4 → 3.1.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/CHANGELOG.md +15 -0
- data/README.md +65 -68
- data/lib/generators/rack_mini_profiler/USAGE +9 -0
- data/lib/generators/rack_mini_profiler/install_generator.rb +13 -0
- data/lib/generators/{rack_profiler/templates/rack_profiler.rb → rack_mini_profiler/templates/rack_mini_profiler.rb} +1 -1
- data/lib/generators/rack_profiler/install_generator.rb +6 -3
- data/lib/mini_profiler/config.rb +7 -4
- data/lib/mini_profiler/storage/abstract_store.rb +30 -57
- data/lib/mini_profiler/storage/file_store.rb +2 -0
- data/lib/mini_profiler/storage/memory_store.rb +56 -12
- data/lib/mini_profiler/storage/redis_store.rb +144 -61
- data/lib/mini_profiler/storage.rb +7 -0
- data/lib/mini_profiler/timer_struct/base.rb +2 -0
- data/lib/mini_profiler/timer_struct/sql.rb +2 -0
- data/lib/mini_profiler/timer_struct.rb +8 -0
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/{mini_profiler/profiler.rb → mini_profiler.rb} +103 -69
- data/lib/patches/net_patches.rb +18 -17
- data/lib/rack-mini-profiler.rb +1 -24
- data/rack-mini-profiler.gemspec +2 -2
- metadata +12 -8
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'digest'
|
4
|
+
require 'securerandom'
|
4
5
|
|
5
6
|
module Rack
|
6
7
|
class MiniProfiler
|
@@ -133,85 +134,127 @@ unviewed_ids: #{get_unviewed_ids(user)}
|
|
133
134
|
)
|
134
135
|
end
|
135
136
|
|
136
|
-
def push_snapshot(page_struct, config)
|
137
|
-
|
138
|
-
|
137
|
+
def push_snapshot(page_struct, group_name, config)
|
138
|
+
group_zset_key = group_snapshot_zset_key(group_name)
|
139
|
+
group_hash_key = group_snapshot_hash_key(group_name)
|
140
|
+
overview_zset_key = snapshot_overview_zset_key
|
139
141
|
|
140
142
|
id = page_struct[:id]
|
141
|
-
score = page_struct.duration_ms
|
142
|
-
|
143
|
+
score = page_struct.duration_ms.to_s
|
144
|
+
|
145
|
+
per_group_limit = config.max_snapshots_per_group.to_s
|
146
|
+
groups_limit = config.max_snapshot_groups.to_s
|
143
147
|
bytes = Marshal.dump(page_struct)
|
144
148
|
|
145
149
|
lua = <<~LUA
|
146
|
-
local
|
147
|
-
local
|
150
|
+
local group_zset_key = KEYS[1]
|
151
|
+
local group_hash_key = KEYS[2]
|
152
|
+
local overview_zset_key = KEYS[3]
|
153
|
+
|
148
154
|
local id = ARGV[1]
|
149
155
|
local score = tonumber(ARGV[2])
|
150
|
-
local
|
151
|
-
local
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
156
|
+
local group_name = ARGV[3]
|
157
|
+
local per_group_limit = tonumber(ARGV[4])
|
158
|
+
local groups_limit = tonumber(ARGV[5])
|
159
|
+
local prefix = ARGV[6]
|
160
|
+
local bytes = ARGV[7]
|
161
|
+
|
162
|
+
local current_group_score = redis.call("ZSCORE", overview_zset_key, group_name)
|
163
|
+
if current_group_score == false or score > tonumber(current_group_score) then
|
164
|
+
redis.call("ZADD", overview_zset_key, score, group_name)
|
165
|
+
end
|
166
|
+
|
167
|
+
local do_save = true
|
168
|
+
local overview_size = redis.call("ZCARD", overview_zset_key)
|
169
|
+
while (overview_size > groups_limit) do
|
170
|
+
local lowest_group = redis.call("ZRANGE", overview_zset_key, 0, 0)[1]
|
171
|
+
redis.call("ZREM", overview_zset_key, lowest_group)
|
172
|
+
if lowest_group == group_name then
|
173
|
+
do_save = false
|
174
|
+
else
|
175
|
+
local lowest_group_zset_key = prefix .. "-mp-group-snapshot-zset-key-" .. lowest_group
|
176
|
+
local lowest_group_hash_key = prefix .. "-mp-group-snapshot-hash-key-" .. lowest_group
|
177
|
+
redis.call("DEL", lowest_group_zset_key, lowest_group_hash_key)
|
178
|
+
end
|
179
|
+
overview_size = overview_size - 1
|
180
|
+
end
|
181
|
+
|
182
|
+
if do_save then
|
183
|
+
redis.call("ZADD", group_zset_key, score, id)
|
184
|
+
local group_size = redis.call("ZCARD", group_zset_key)
|
185
|
+
while (group_size > per_group_limit) do
|
186
|
+
local lowest_snapshot_id = redis.call("ZRANGE", group_zset_key, 0, 0)[1]
|
187
|
+
redis.call("ZREM", group_zset_key, lowest_snapshot_id)
|
188
|
+
if lowest_snapshot_id == id then
|
189
|
+
do_save = false
|
190
|
+
else
|
191
|
+
redis.call("HDEL", group_hash_key, lowest_snapshot_id)
|
192
|
+
end
|
193
|
+
group_size = group_size - 1
|
194
|
+
end
|
195
|
+
if do_save then
|
196
|
+
redis.call("HSET", group_hash_key, id, bytes)
|
197
|
+
end
|
158
198
|
end
|
159
199
|
LUA
|
160
200
|
redis.eval(
|
161
201
|
lua,
|
162
|
-
keys: [
|
163
|
-
argv: [id, score,
|
202
|
+
keys: [group_zset_key, group_hash_key, overview_zset_key],
|
203
|
+
argv: [id, score, group_name, per_group_limit, groups_limit, @prefix, bytes]
|
164
204
|
)
|
165
205
|
end
|
166
206
|
|
167
|
-
def
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
batch.map! do |id, bytes|
|
181
|
-
begin
|
182
|
-
# rubocop:disable Security/MarshalLoad
|
183
|
-
Marshal.load(bytes)
|
184
|
-
# rubocop:enable Security/MarshalLoad
|
185
|
-
rescue
|
186
|
-
corrupt_snapshots << id
|
187
|
-
nil
|
188
|
-
end
|
207
|
+
def fetch_snapshots_overview
|
208
|
+
overview_zset_key = snapshot_overview_zset_key
|
209
|
+
groups = redis
|
210
|
+
.zrange(overview_zset_key, 0, -1, withscores: true)
|
211
|
+
.map { |(name, worst_score)| [name, { worst_score: worst_score }] }
|
212
|
+
|
213
|
+
prefixed_group_names = groups.map { |(group_name, _)| group_snapshot_zset_key(group_name) }
|
214
|
+
metadata = redis.eval(<<~LUA, keys: prefixed_group_names)
|
215
|
+
local metadata = {}
|
216
|
+
for i, k in ipairs(KEYS) do
|
217
|
+
local best = redis.call("ZRANGE", k, 0, 0, "WITHSCORES")[2]
|
218
|
+
local count = redis.call("ZCARD", k)
|
219
|
+
metadata[i] = {best, count}
|
189
220
|
end
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
221
|
+
return metadata
|
222
|
+
LUA
|
223
|
+
groups.each.with_index do |(_, hash), index|
|
224
|
+
best, count = metadata[index]
|
225
|
+
hash[:best_score] = best.to_f
|
226
|
+
hash[:snapshots_count] = count.to_i
|
227
|
+
end
|
228
|
+
groups.to_h
|
229
|
+
end
|
230
|
+
|
231
|
+
def fetch_snapshots_group(group_name)
|
232
|
+
group_hash_key = group_snapshot_hash_key(group_name)
|
233
|
+
snapshots = []
|
234
|
+
corrupt_snapshots = []
|
235
|
+
redis.hgetall(group_hash_key).each do |id, bytes|
|
236
|
+
# rubocop:disable Security/MarshalLoad
|
237
|
+
snapshots << Marshal.load(bytes)
|
238
|
+
# rubocop:enable Security/MarshalLoad
|
239
|
+
rescue
|
240
|
+
corrupt_snapshots << id
|
194
241
|
end
|
195
242
|
if corrupt_snapshots.size > 0
|
196
|
-
|
197
|
-
pipeline.zrem(zset_key, corrupt_snapshots)
|
198
|
-
pipeline.hdel(hash_key, corrupt_snapshots)
|
199
|
-
end
|
243
|
+
cleanup_corrupt_snapshots(corrupt_snapshots, group_name)
|
200
244
|
end
|
245
|
+
snapshots
|
201
246
|
end
|
202
247
|
|
203
|
-
def load_snapshot(id)
|
204
|
-
|
205
|
-
bytes = redis.hget(
|
248
|
+
def load_snapshot(id, group_name)
|
249
|
+
group_hash_key = group_snapshot_hash_key(group_name)
|
250
|
+
bytes = redis.hget(group_hash_key, id)
|
251
|
+
return if !bytes
|
206
252
|
begin
|
207
253
|
# rubocop:disable Security/MarshalLoad
|
208
254
|
Marshal.load(bytes)
|
209
255
|
# rubocop:enable Security/MarshalLoad
|
210
256
|
rescue
|
211
|
-
|
212
|
-
pipeline.zrem(snapshot_zset_key(), id)
|
213
|
-
pipeline.hdel(hash_key, id)
|
214
|
-
end
|
257
|
+
cleanup_corrupt_snapshots([id], group_name)
|
215
258
|
nil
|
216
259
|
end
|
217
260
|
end
|
@@ -237,12 +280,20 @@ unviewed_ids: #{get_unviewed_ids(user)}
|
|
237
280
|
@snapshot_counter_key ||= "#{@prefix}-mini-profiler-snapshots-counter"
|
238
281
|
end
|
239
282
|
|
240
|
-
def
|
241
|
-
|
283
|
+
def group_snapshot_zset_key(group_name)
|
284
|
+
# if you change this key, remember to change it in the LUA script in
|
285
|
+
# the push_snapshot method as well
|
286
|
+
"#{@prefix}-mp-group-snapshot-zset-key-#{group_name}"
|
242
287
|
end
|
243
288
|
|
244
|
-
def
|
245
|
-
|
289
|
+
def group_snapshot_hash_key(group_name)
|
290
|
+
# if you change this key, remember to change it in the LUA script in
|
291
|
+
# the push_snapshot method as well
|
292
|
+
"#{@prefix}-mp-group-snapshot-hash-key-#{group_name}"
|
293
|
+
end
|
294
|
+
|
295
|
+
def snapshot_overview_zset_key
|
296
|
+
"#{@prefix}-mp-overviewgroup-snapshot-zset-key"
|
246
297
|
end
|
247
298
|
|
248
299
|
def cached_redis_eval(script, script_sha, reraise: true, argv: [], keys: [])
|
@@ -257,12 +308,44 @@ unviewed_ids: #{get_unviewed_ids(user)}
|
|
257
308
|
end
|
258
309
|
end
|
259
310
|
|
311
|
+
def cleanup_corrupt_snapshots(corrupt_snapshots_ids, group_name)
|
312
|
+
group_hash_key = group_snapshot_hash_key(group_name)
|
313
|
+
group_zset_key = group_snapshot_zset_key(group_name)
|
314
|
+
overview_zset_key = snapshot_overview_zset_key
|
315
|
+
lua = <<~LUA
|
316
|
+
local group_hash_key = KEYS[1]
|
317
|
+
local group_zset_key = KEYS[2]
|
318
|
+
local overview_zset_key = KEYS[3]
|
319
|
+
local group_name = ARGV[1]
|
320
|
+
for i, k in ipairs(ARGV) do
|
321
|
+
if k ~= group_name then
|
322
|
+
redis.call("HDEL", group_hash_key, k)
|
323
|
+
redis.call("ZREM", group_zset_key, k)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
if redis.call("ZCARD", group_zset_key) == 0 then
|
327
|
+
redis.call("ZREM", overview_zset_key, group_name)
|
328
|
+
redis.call("DEL", group_hash_key, group_zset_key)
|
329
|
+
else
|
330
|
+
local worst_score = tonumber(redis.call("ZRANGE", group_zset_key, -1, -1, "WITHSCORES")[2])
|
331
|
+
redis.call("ZADD", overview_zset_key, worst_score, group_name)
|
332
|
+
end
|
333
|
+
LUA
|
334
|
+
redis.eval(
|
335
|
+
lua,
|
336
|
+
keys: [group_hash_key, group_zset_key, overview_zset_key],
|
337
|
+
argv: [group_name, *corrupt_snapshots_ids]
|
338
|
+
)
|
339
|
+
end
|
340
|
+
|
260
341
|
# only used in tests
|
261
342
|
def wipe_snapshots_data
|
343
|
+
keys = redis.keys(group_snapshot_hash_key('*'))
|
344
|
+
keys += redis.keys(group_snapshot_zset_key('*'))
|
262
345
|
redis.del(
|
263
|
-
|
264
|
-
|
265
|
-
|
346
|
+
keys,
|
347
|
+
snapshot_overview_zset_key,
|
348
|
+
snapshot_counter_key
|
266
349
|
)
|
267
350
|
end
|
268
351
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mini_profiler/timer_struct/base'
|
4
|
+
require 'mini_profiler/timer_struct/page'
|
5
|
+
require 'mini_profiler/timer_struct/sql'
|
6
|
+
require 'mini_profiler/timer_struct/custom'
|
7
|
+
require 'mini_profiler/timer_struct/client'
|
8
|
+
require 'mini_profiler/timer_struct/request'
|