brainzlab 0.1.2 → 0.1.3
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/LICENSE +6 -21
- data/README.md +16 -2
- data/lib/brainzlab/beacon/client.rb +38 -40
- data/lib/brainzlab/beacon/provisioner.rb +1 -1
- data/lib/brainzlab/beacon.rb +15 -15
- data/lib/brainzlab/configuration.rb +92 -90
- data/lib/brainzlab/context.rb +2 -3
- data/lib/brainzlab/cortex/client.rb +29 -31
- data/lib/brainzlab/cortex/provisioner.rb +1 -1
- data/lib/brainzlab/cortex.rb +7 -11
- data/lib/brainzlab/dendrite/client.rb +42 -44
- data/lib/brainzlab/dendrite/provisioner.rb +1 -1
- data/lib/brainzlab/dendrite.rb +4 -4
- data/lib/brainzlab/devtools/data/collector.rb +22 -22
- data/lib/brainzlab/devtools/middleware/asset_server.rb +14 -14
- data/lib/brainzlab/devtools/middleware/database_handler.rb +52 -55
- data/lib/brainzlab/devtools/middleware/debug_panel.rb +19 -19
- data/lib/brainzlab/devtools/middleware/error_page.rb +45 -44
- data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +39 -35
- data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +13 -9
- data/lib/brainzlab/devtools.rb +11 -11
- data/lib/brainzlab/flux/buffer.rb +3 -3
- data/lib/brainzlab/flux/client.rb +14 -16
- data/lib/brainzlab/flux/provisioner.rb +13 -13
- data/lib/brainzlab/flux.rb +8 -8
- data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
- data/lib/brainzlab/instrumentation/active_record.rb +13 -15
- data/lib/brainzlab/instrumentation/aws.rb +43 -39
- data/lib/brainzlab/instrumentation/dalli.rb +20 -20
- data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
- data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
- data/lib/brainzlab/instrumentation/excon.rb +27 -27
- data/lib/brainzlab/instrumentation/faraday.rb +3 -4
- data/lib/brainzlab/instrumentation/good_job.rb +28 -28
- data/lib/brainzlab/instrumentation/grape.rb +24 -24
- data/lib/brainzlab/instrumentation/graphql.rb +24 -23
- data/lib/brainzlab/instrumentation/httparty.rb +13 -14
- data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
- data/lib/brainzlab/instrumentation/net_http.rb +6 -6
- data/lib/brainzlab/instrumentation/redis.rb +14 -21
- data/lib/brainzlab/instrumentation/resque.rb +23 -24
- data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
- data/lib/brainzlab/instrumentation/solid_queue.rb +37 -41
- data/lib/brainzlab/instrumentation/stripe.rb +36 -37
- data/lib/brainzlab/instrumentation/typhoeus.rb +19 -17
- data/lib/brainzlab/instrumentation.rb +20 -20
- data/lib/brainzlab/nerve/client.rb +38 -40
- data/lib/brainzlab/nerve/provisioner.rb +1 -1
- data/lib/brainzlab/nerve.rb +6 -6
- data/lib/brainzlab/pulse/client.rb +15 -11
- data/lib/brainzlab/pulse/instrumentation.rb +61 -57
- data/lib/brainzlab/pulse/propagation.rb +28 -28
- data/lib/brainzlab/pulse/provisioner.rb +12 -12
- data/lib/brainzlab/pulse/tracer.rb +3 -3
- data/lib/brainzlab/pulse.rb +13 -13
- data/lib/brainzlab/rails/log_formatter.rb +127 -121
- data/lib/brainzlab/rails/log_subscriber.rb +70 -76
- data/lib/brainzlab/rails/railtie.rb +66 -89
- data/lib/brainzlab/recall/buffer.rb +1 -1
- data/lib/brainzlab/recall/client.rb +14 -10
- data/lib/brainzlab/recall/logger.rb +16 -18
- data/lib/brainzlab/recall/provisioner.rb +16 -16
- data/lib/brainzlab/recall.rb +11 -13
- data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
- data/lib/brainzlab/reflex/client.rb +14 -10
- data/lib/brainzlab/reflex/provisioner.rb +12 -12
- data/lib/brainzlab/reflex.rb +29 -29
- data/lib/brainzlab/sentinel/client.rb +40 -42
- data/lib/brainzlab/sentinel/provisioner.rb +1 -1
- data/lib/brainzlab/sentinel.rb +5 -5
- data/lib/brainzlab/signal/client.rb +12 -14
- data/lib/brainzlab/signal/provisioner.rb +12 -12
- data/lib/brainzlab/signal.rb +7 -7
- data/lib/brainzlab/synapse/client.rb +42 -44
- data/lib/brainzlab/synapse/provisioner.rb +1 -1
- data/lib/brainzlab/synapse.rb +6 -6
- data/lib/brainzlab/utilities/circuit_breaker.rb +37 -41
- data/lib/brainzlab/utilities/health_check.rb +53 -55
- data/lib/brainzlab/utilities/log_formatter.rb +38 -40
- data/lib/brainzlab/utilities/rate_limiter.rb +5 -5
- data/lib/brainzlab/utilities.rb +4 -4
- data/lib/brainzlab/vault/cache.rb +1 -1
- data/lib/brainzlab/vault/client.rb +39 -41
- data/lib/brainzlab/vault/provisioner.rb +1 -1
- data/lib/brainzlab/vault.rb +19 -25
- data/lib/brainzlab/version.rb +1 -1
- data/lib/brainzlab/vision/client.rb +20 -20
- data/lib/brainzlab/vision/provisioner.rb +21 -21
- data/lib/brainzlab/vision.rb +17 -19
- data/lib/brainzlab-sdk.rb +1 -1
- data/lib/brainzlab.rb +22 -24
- data/lib/generators/brainzlab/install/install_generator.rb +29 -27
- metadata +1 -1
|
@@ -5,7 +5,8 @@ module BrainzLab
|
|
|
5
5
|
class LogFormatter
|
|
6
6
|
ASSET_PATHS = %w[/assets /packs /vite /images /fonts /stylesheets /javascripts].freeze
|
|
7
7
|
ASSET_EXTENSIONS = %w[.css .js .map .png .jpg .jpeg .gif .svg .ico .woff .woff2 .ttf .eot].freeze
|
|
8
|
-
SIMPLE_PATHS = %w[/up /health /healthz /ready /readiness /live /liveness /ping /favicon.ico /apple-touch-icon.png
|
|
8
|
+
SIMPLE_PATHS = %w[/up /health /healthz /ready /readiness /live /liveness /ping /favicon.ico /apple-touch-icon.png
|
|
9
|
+
/apple-touch-icon-precomposed.png /robots.txt /sitemap.xml].freeze
|
|
9
10
|
IGNORED_PATHS = %w[/apple-touch-icon.png /apple-touch-icon-precomposed.png /favicon.ico].freeze
|
|
10
11
|
|
|
11
12
|
# Thresholds for highlighting
|
|
@@ -29,12 +30,12 @@ module BrainzLab
|
|
|
29
30
|
|
|
30
31
|
# Box drawing characters
|
|
31
32
|
BOX = {
|
|
32
|
-
top_left:
|
|
33
|
-
top_right:
|
|
34
|
-
bottom_left:
|
|
35
|
-
bottom_right:
|
|
36
|
-
vertical:
|
|
37
|
-
horizontal:
|
|
33
|
+
top_left: '┌',
|
|
34
|
+
top_right: '─',
|
|
35
|
+
bottom_left: '└',
|
|
36
|
+
bottom_right: '─',
|
|
37
|
+
vertical: '│',
|
|
38
|
+
horizontal: '─'
|
|
38
39
|
}.freeze
|
|
39
40
|
|
|
40
41
|
attr_reader :config
|
|
@@ -54,7 +55,7 @@ module BrainzLab
|
|
|
54
55
|
show_params: true,
|
|
55
56
|
show_sql_count: true,
|
|
56
57
|
show_sql_details: true,
|
|
57
|
-
show_sql_queries: true,
|
|
58
|
+
show_sql_queries: true, # Show actual SQL queries
|
|
58
59
|
show_views: true,
|
|
59
60
|
slow_query_threshold: SLOW_QUERY_MS,
|
|
60
61
|
n_plus_one_threshold: N_PLUS_ONE_THRESHOLD,
|
|
@@ -64,16 +65,16 @@ module BrainzLab
|
|
|
64
65
|
|
|
65
66
|
def detect_terminal_width
|
|
66
67
|
# Try to get terminal width, fallback to 120
|
|
67
|
-
width = ENV[
|
|
68
|
-
return width if width
|
|
68
|
+
width = ENV['COLUMNS']&.to_i
|
|
69
|
+
return width if width&.positive?
|
|
69
70
|
|
|
70
71
|
if $stdout.tty? && IO.respond_to?(:console) && IO.console
|
|
71
72
|
_rows, cols = IO.console.winsize
|
|
72
|
-
return cols if cols
|
|
73
|
+
return cols if cols.positive?
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
120 # Default to 120 for wider output
|
|
76
|
-
rescue
|
|
77
|
+
rescue StandardError
|
|
77
78
|
120
|
|
78
79
|
end
|
|
79
80
|
|
|
@@ -231,12 +232,12 @@ module BrainzLab
|
|
|
231
232
|
colorize(time, :gray),
|
|
232
233
|
method,
|
|
233
234
|
colorize(path, :white),
|
|
234
|
-
colorize(
|
|
235
|
+
colorize('→', :gray),
|
|
235
236
|
status,
|
|
236
237
|
duration
|
|
237
238
|
]
|
|
238
239
|
|
|
239
|
-
parts.join(
|
|
240
|
+
"#{parts.join(' ')}\n"
|
|
240
241
|
end
|
|
241
242
|
|
|
242
243
|
# Format full block output
|
|
@@ -250,40 +251,36 @@ module BrainzLab
|
|
|
250
251
|
lines << header
|
|
251
252
|
|
|
252
253
|
# Status line
|
|
253
|
-
status_text = data[:status] ? "#{data[:status]} #{status_phrase(data[:status])}" :
|
|
254
|
-
lines << build_line(
|
|
254
|
+
status_text = data[:status] ? "#{data[:status]} #{status_phrase(data[:status])}" : '---'
|
|
255
|
+
lines << build_line('status', format_status_value(data[:status], status_text))
|
|
255
256
|
|
|
256
257
|
# Duration line
|
|
257
|
-
if data[:duration]
|
|
258
|
-
lines << build_line("duration", format_duration_full(data[:duration]))
|
|
259
|
-
end
|
|
258
|
+
lines << build_line('duration', format_duration_full(data[:duration])) if data[:duration]
|
|
260
259
|
|
|
261
260
|
# Database line with query analysis
|
|
262
261
|
if data[:db_runtime] || data[:sql_queries].any?
|
|
263
262
|
db_info = format_db_info(data)
|
|
264
|
-
lines << build_line(
|
|
263
|
+
lines << build_line('db', db_info)
|
|
265
264
|
end
|
|
266
265
|
|
|
267
266
|
# Views line
|
|
268
|
-
if data[:view_runtime]
|
|
269
|
-
lines << build_line("views", "#{data[:view_runtime].round(1)}ms")
|
|
270
|
-
end
|
|
267
|
+
lines << build_line('views', "#{data[:view_runtime].round(1)}ms") if data[:view_runtime]
|
|
271
268
|
|
|
272
269
|
# Params section (if enabled and present) - TOML style
|
|
273
270
|
if config[:show_params] && data[:params].present?
|
|
274
271
|
params_str = format_params(data[:params])
|
|
275
272
|
if params_str
|
|
276
|
-
lines << build_line(
|
|
273
|
+
lines << build_line('', colorize('[params]', :gray))
|
|
277
274
|
lines << params_str
|
|
278
275
|
end
|
|
279
276
|
end
|
|
280
277
|
|
|
281
278
|
# Error lines
|
|
282
279
|
if data[:error]
|
|
283
|
-
lines << build_line(
|
|
280
|
+
lines << build_line('error', colorize(data[:error], :red))
|
|
284
281
|
if data[:error_message]
|
|
285
282
|
msg = truncate(data[:error_message], width - 15)
|
|
286
|
-
lines << build_line(
|
|
283
|
+
lines << build_line('message', colorize("\"#{msg}\"", :red))
|
|
287
284
|
end
|
|
288
285
|
end
|
|
289
286
|
|
|
@@ -308,7 +305,7 @@ module BrainzLab
|
|
|
308
305
|
# Footer line
|
|
309
306
|
lines << build_footer(width)
|
|
310
307
|
|
|
311
|
-
lines.join("\n")
|
|
308
|
+
"#{lines.join("\n")}\n\n"
|
|
312
309
|
end
|
|
313
310
|
|
|
314
311
|
def analyze_sql_queries(queries)
|
|
@@ -325,21 +322,20 @@ module BrainzLab
|
|
|
325
322
|
|
|
326
323
|
# This is a potential N+1
|
|
327
324
|
sample = matching_queries.first
|
|
328
|
-
source = sample[:source] ||
|
|
329
|
-
name = sample[:name] ||
|
|
325
|
+
source = sample[:source] || 'unknown'
|
|
326
|
+
name = sample[:name] || 'Query'
|
|
330
327
|
|
|
331
328
|
# Extract table name from pattern
|
|
332
329
|
table_match = pattern.match(/FROM "?(\w+)"?/i)
|
|
333
330
|
table = table_match ? table_match[1] : name
|
|
334
331
|
|
|
335
|
-
issues << build_line(
|
|
336
|
-
|
|
337
|
-
|
|
332
|
+
issues << build_line('',
|
|
333
|
+
"#{colorize('N+1',
|
|
334
|
+
:red)} #{colorize("#{table} × #{matching_queries.size}",
|
|
335
|
+
:yellow)}#{colorize(" (#{source})", :gray)}")
|
|
338
336
|
|
|
339
337
|
# Show the query SQL in TOML-like format
|
|
340
|
-
if config[:show_sql_queries] && sample[:sql]
|
|
341
|
-
issues << format_sql_toml(sample[:sql], sample[:duration])
|
|
342
|
-
end
|
|
338
|
+
issues << format_sql_toml(sample[:sql], sample[:duration]) if config[:show_sql_queries] && sample[:sql]
|
|
343
339
|
end
|
|
344
340
|
|
|
345
341
|
# Find slow queries (not cached, not already reported as N+1)
|
|
@@ -350,18 +346,17 @@ module BrainzLab
|
|
|
350
346
|
.first(3)
|
|
351
347
|
|
|
352
348
|
slow_queries.each do |query|
|
|
353
|
-
source = query[:source] ||
|
|
354
|
-
name = query[:name] ||
|
|
349
|
+
source = query[:source] || 'unknown'
|
|
350
|
+
name = query[:name] || 'Query'
|
|
355
351
|
duration = query[:duration].round(1)
|
|
356
352
|
|
|
357
|
-
issues << build_line(
|
|
358
|
-
|
|
359
|
-
|
|
353
|
+
issues << build_line('',
|
|
354
|
+
"#{colorize('Slow',
|
|
355
|
+
:yellow)} #{colorize("#{name} #{duration}ms",
|
|
356
|
+
:white)}#{colorize(" (#{source})", :gray)}")
|
|
360
357
|
|
|
361
358
|
# Show the query SQL in TOML-like format
|
|
362
|
-
if config[:show_sql_queries] && query[:sql]
|
|
363
|
-
issues << format_sql_toml(query[:sql], query[:duration])
|
|
364
|
-
end
|
|
359
|
+
issues << format_sql_toml(query[:sql], query[:duration]) if config[:show_sql_queries] && query[:sql]
|
|
365
360
|
end
|
|
366
361
|
|
|
367
362
|
issues
|
|
@@ -370,7 +365,7 @@ module BrainzLab
|
|
|
370
365
|
def format_sql_toml(sql, duration = nil)
|
|
371
366
|
lines = []
|
|
372
367
|
prefix = colorize("#{BOX[:vertical]} ", :cyan)
|
|
373
|
-
indent =
|
|
368
|
+
indent = ' '
|
|
374
369
|
|
|
375
370
|
# Parse SQL to extract key components
|
|
376
371
|
parsed = parse_sql(sql)
|
|
@@ -379,16 +374,15 @@ module BrainzLab
|
|
|
379
374
|
lines << "#{prefix}#{indent}#{colorize('[query]', :gray)}"
|
|
380
375
|
|
|
381
376
|
if parsed[:operation]
|
|
382
|
-
lines << "#{prefix}#{indent}#{colorize('operation',
|
|
377
|
+
lines << "#{prefix}#{indent}#{colorize('operation',
|
|
378
|
+
:gray)} = #{colorize("\"#{parsed[:operation]}\"", :green)}"
|
|
383
379
|
end
|
|
384
380
|
|
|
385
|
-
if parsed[:table]
|
|
386
|
-
lines << "#{prefix}#{indent}#{colorize('table', :gray)} = #{colorize("\"#{parsed[:table]}\"", :green)}"
|
|
387
|
-
end
|
|
381
|
+
lines << "#{prefix}#{indent}#{colorize('table', :gray)} = #{colorize("\"#{parsed[:table]}\"", :green)}" if parsed[:table]
|
|
388
382
|
|
|
389
383
|
if parsed[:columns].any?
|
|
390
|
-
cols = parsed[:columns].first(5).map { |c| "\"#{c}\"" }.join(
|
|
391
|
-
cols +=
|
|
384
|
+
cols = parsed[:columns].first(5).map { |c| "\"#{c}\"" }.join(', ')
|
|
385
|
+
cols += ', ...' if parsed[:columns].size > 5
|
|
392
386
|
lines << "#{prefix}#{indent}#{colorize('columns', :gray)} = [#{colorize(cols, :cyan)}]"
|
|
393
387
|
end
|
|
394
388
|
|
|
@@ -399,17 +393,11 @@ module BrainzLab
|
|
|
399
393
|
end
|
|
400
394
|
end
|
|
401
395
|
|
|
402
|
-
if parsed[:order]
|
|
403
|
-
lines << "#{prefix}#{indent}#{colorize('order', :gray)} = #{colorize("\"#{parsed[:order]}\"", :green)}"
|
|
404
|
-
end
|
|
396
|
+
lines << "#{prefix}#{indent}#{colorize('order', :gray)} = #{colorize("\"#{parsed[:order]}\"", :green)}" if parsed[:order]
|
|
405
397
|
|
|
406
|
-
if parsed[:limit]
|
|
407
|
-
lines << "#{prefix}#{indent}#{colorize('limit', :gray)} = #{colorize(parsed[:limit].to_s, :magenta)}"
|
|
408
|
-
end
|
|
398
|
+
lines << "#{prefix}#{indent}#{colorize('limit', :gray)} = #{colorize(parsed[:limit].to_s, :magenta)}" if parsed[:limit]
|
|
409
399
|
|
|
410
|
-
if duration
|
|
411
|
-
lines << "#{prefix}#{indent}#{colorize('duration_ms', :gray)} = #{colorize(duration.round(2).to_s, :magenta)}"
|
|
412
|
-
end
|
|
400
|
+
lines << "#{prefix}#{indent}#{colorize('duration_ms', :gray)} = #{colorize(duration.round(2).to_s, :magenta)}" if duration
|
|
413
401
|
|
|
414
402
|
lines.join("\n")
|
|
415
403
|
end
|
|
@@ -428,10 +416,10 @@ module BrainzLab
|
|
|
428
416
|
|
|
429
417
|
# Detect operation
|
|
430
418
|
result[:operation] = case sql
|
|
431
|
-
when /^\s*SELECT/i then
|
|
432
|
-
when /^\s*INSERT/i then
|
|
433
|
-
when /^\s*UPDATE/i then
|
|
434
|
-
when /^\s*DELETE/i then
|
|
419
|
+
when /^\s*SELECT/i then 'SELECT'
|
|
420
|
+
when /^\s*INSERT/i then 'INSERT'
|
|
421
|
+
when /^\s*UPDATE/i then 'UPDATE'
|
|
422
|
+
when /^\s*DELETE/i then 'DELETE'
|
|
435
423
|
else sql.split.first&.upcase
|
|
436
424
|
end
|
|
437
425
|
|
|
@@ -447,9 +435,7 @@ module BrainzLab
|
|
|
447
435
|
# Extract selected columns (for SELECT)
|
|
448
436
|
if (match = sql.match(/SELECT\s+(.+?)\s+FROM/i))
|
|
449
437
|
cols = match[1]
|
|
450
|
-
if cols.strip !=
|
|
451
|
-
result[:columns] = cols.split(",").map { |c| c.strip.gsub(/"/, "").split(".").last }
|
|
452
|
-
end
|
|
438
|
+
result[:columns] = cols.split(',').map { |c| c.strip.gsub('"', '').split('.').last } if cols.strip != '*'
|
|
453
439
|
end
|
|
454
440
|
|
|
455
441
|
# Extract WHERE conditions
|
|
@@ -485,10 +471,10 @@ module BrainzLab
|
|
|
485
471
|
partial_counts = partials.group_by { |p| p[:template] }
|
|
486
472
|
|
|
487
473
|
templates.each do |template|
|
|
488
|
-
duration = template[:duration] ? " (#{template[:duration].round(1)}ms)" :
|
|
489
|
-
lines << build_line(
|
|
490
|
-
|
|
491
|
-
|
|
474
|
+
duration = template[:duration] ? " (#{template[:duration].round(1)}ms)" : ''
|
|
475
|
+
lines << build_line('',
|
|
476
|
+
"#{colorize('View',
|
|
477
|
+
:cyan)} #{colorize(template[:template], :white)}#{colorize(duration, :gray)}")
|
|
492
478
|
end
|
|
493
479
|
|
|
494
480
|
# Show partials that were rendered multiple times (potential issue)
|
|
@@ -496,9 +482,12 @@ module BrainzLab
|
|
|
496
482
|
next if renders.size < 3 # Only show if rendered 3+ times
|
|
497
483
|
|
|
498
484
|
total_duration = renders.sum { |r| r[:duration] || 0 }
|
|
499
|
-
lines << build_line(
|
|
500
|
-
|
|
501
|
-
|
|
485
|
+
lines << build_line('',
|
|
486
|
+
"#{colorize('Partial',
|
|
487
|
+
:yellow)} #{colorize("#{name} × #{renders.size}",
|
|
488
|
+
:white)}#{colorize(
|
|
489
|
+
" (#{total_duration.round(1)}ms total)", :gray
|
|
490
|
+
)}")
|
|
502
491
|
end
|
|
503
492
|
|
|
504
493
|
lines
|
|
@@ -506,7 +495,7 @@ module BrainzLab
|
|
|
506
495
|
|
|
507
496
|
def build_header(text, has_error, width)
|
|
508
497
|
prefix = "#{BOX[:top_left]}#{BOX[:horizontal]} "
|
|
509
|
-
suffix = has_error ? " #{BOX[:horizontal]} ERROR #{BOX[:horizontal]}" :
|
|
498
|
+
suffix = has_error ? " #{BOX[:horizontal]} ERROR #{BOX[:horizontal]}" : ' '
|
|
510
499
|
|
|
511
500
|
available = width - prefix.length - suffix.length
|
|
512
501
|
text = truncate(text, available)
|
|
@@ -542,25 +531,25 @@ module BrainzLab
|
|
|
542
531
|
end
|
|
543
532
|
|
|
544
533
|
def format_time(time)
|
|
545
|
-
return
|
|
534
|
+
return '--:--:--' unless time
|
|
546
535
|
|
|
547
|
-
time.strftime(
|
|
536
|
+
time.strftime('%H:%M:%S')
|
|
548
537
|
end
|
|
549
538
|
|
|
550
539
|
def format_method(method)
|
|
551
540
|
method = method.to_s.upcase
|
|
552
541
|
color = case method
|
|
553
|
-
when
|
|
554
|
-
when
|
|
555
|
-
when
|
|
556
|
-
when
|
|
542
|
+
when 'GET' then :green
|
|
543
|
+
when 'POST' then :blue
|
|
544
|
+
when 'PUT', 'PATCH' then :yellow
|
|
545
|
+
when 'DELETE' then :red
|
|
557
546
|
else :white
|
|
558
547
|
end
|
|
559
548
|
colorize(method.ljust(6), color)
|
|
560
549
|
end
|
|
561
550
|
|
|
562
551
|
def format_status(status)
|
|
563
|
-
return colorize(
|
|
552
|
+
return colorize('---', :gray) unless status
|
|
564
553
|
|
|
565
554
|
color = case status
|
|
566
555
|
when 200..299 then :green
|
|
@@ -584,10 +573,10 @@ module BrainzLab
|
|
|
584
573
|
end
|
|
585
574
|
|
|
586
575
|
def format_duration(ms)
|
|
587
|
-
return colorize(
|
|
576
|
+
return colorize('--', :gray) unless ms
|
|
588
577
|
|
|
589
578
|
formatted = if ms < 1
|
|
590
|
-
|
|
579
|
+
'<1ms'
|
|
591
580
|
elsif ms < 1000
|
|
592
581
|
"#{ms.round}ms"
|
|
593
582
|
else
|
|
@@ -620,9 +609,7 @@ module BrainzLab
|
|
|
620
609
|
def format_db_info(data)
|
|
621
610
|
parts = []
|
|
622
611
|
|
|
623
|
-
if data[:db_runtime]
|
|
624
|
-
parts << "#{data[:db_runtime].round(1)}ms"
|
|
625
|
-
end
|
|
612
|
+
parts << "#{data[:db_runtime].round(1)}ms" if data[:db_runtime]
|
|
626
613
|
|
|
627
614
|
if config[:show_sql_count]
|
|
628
615
|
queries = data[:sql_queries] || []
|
|
@@ -631,25 +618,21 @@ module BrainzLab
|
|
|
631
618
|
non_cached = total - cached
|
|
632
619
|
|
|
633
620
|
query_text = "#{non_cached} #{non_cached == 1 ? 'query' : 'queries'}"
|
|
634
|
-
if cached.positive?
|
|
635
|
-
query_text += ", #{cached} cached"
|
|
636
|
-
end
|
|
621
|
+
query_text += ", #{cached} cached" if cached.positive?
|
|
637
622
|
parts << "(#{query_text})"
|
|
638
623
|
end
|
|
639
624
|
|
|
640
|
-
parts.join(
|
|
625
|
+
parts.join(' ')
|
|
641
626
|
end
|
|
642
627
|
|
|
643
628
|
def format_params(params)
|
|
644
629
|
return nil if params.empty?
|
|
645
630
|
|
|
646
631
|
# Filter out controller, action, and duplicate keys
|
|
647
|
-
filtered = params.except(
|
|
632
|
+
filtered = params.except('controller', 'action', :controller, :action)
|
|
648
633
|
|
|
649
634
|
# Skip 'ingest' if 'logs' exists (they're the same data)
|
|
650
|
-
if filtered.key?(
|
|
651
|
-
filtered = filtered.except("ingest", :ingest)
|
|
652
|
-
end
|
|
635
|
+
filtered = filtered.except('ingest', :ingest) if filtered.key?('logs') || filtered.key?(:logs)
|
|
653
636
|
|
|
654
637
|
return nil if filtered.empty?
|
|
655
638
|
|
|
@@ -658,23 +641,27 @@ module BrainzLab
|
|
|
658
641
|
end
|
|
659
642
|
|
|
660
643
|
def hash_like?(obj)
|
|
661
|
-
obj.is_a?(Hash) || obj.respond_to?(:to_h) && obj.respond_to?(:each)
|
|
644
|
+
obj.is_a?(Hash) || (obj.respond_to?(:to_h) && obj.respond_to?(:each))
|
|
662
645
|
end
|
|
663
646
|
|
|
664
|
-
def format_params_toml(params, prefix =
|
|
647
|
+
def format_params_toml(params, prefix = '', depth = 0)
|
|
665
648
|
lines = []
|
|
666
649
|
line_prefix = colorize("#{BOX[:vertical]} ", :cyan)
|
|
667
|
-
indent = "
|
|
650
|
+
indent = " #{' ' * depth}"
|
|
668
651
|
|
|
669
652
|
params.each do |key, value|
|
|
670
653
|
full_key = prefix.empty? ? key.to_s : "#{prefix}.#{key}"
|
|
671
654
|
|
|
672
655
|
case value
|
|
673
656
|
when Hash, ActionController::Parameters
|
|
674
|
-
value_hash =
|
|
657
|
+
value_hash = begin
|
|
658
|
+
value.to_h
|
|
659
|
+
rescue StandardError
|
|
660
|
+
value
|
|
661
|
+
end
|
|
675
662
|
if value_hash.keys.length <= 3 && value_hash.values.all? { |v| !hash_like?(v) && !v.is_a?(Array) }
|
|
676
663
|
# Compact inline hash for simple cases
|
|
677
|
-
inline = value_hash.map { |k, v| "#{k} = #{format_value(v)}" }.join(
|
|
664
|
+
inline = value_hash.map { |k, v| "#{k} = #{format_value(v)}" }.join(', ')
|
|
678
665
|
lines << "#{line_prefix}#{indent}#{colorize(full_key, :white)} = { #{inline} }"
|
|
679
666
|
else
|
|
680
667
|
# Nested section - expand fully
|
|
@@ -684,9 +671,14 @@ module BrainzLab
|
|
|
684
671
|
# Recursively format nested hashes
|
|
685
672
|
lines << format_hash_nested(v.to_h, "#{full_key}.#{k}", depth + 1)
|
|
686
673
|
elsif v.is_a?(Array) && hash_like?(v.first)
|
|
687
|
-
lines << "#{line_prefix}#{indent} #{colorize("[[#{full_key}.#{k}]]",
|
|
674
|
+
lines << "#{line_prefix}#{indent} #{colorize("[[#{full_key}.#{k}]]",
|
|
675
|
+
:gray)} #{colorize("# #{v.length} items", :gray)}"
|
|
688
676
|
if v.first
|
|
689
|
-
first_hash =
|
|
677
|
+
first_hash = begin
|
|
678
|
+
v.first.to_h
|
|
679
|
+
rescue StandardError
|
|
680
|
+
v.first
|
|
681
|
+
end
|
|
690
682
|
first_hash.each do |nested_k, nested_v|
|
|
691
683
|
lines << "#{line_prefix}#{indent} #{colorize(nested_k.to_s, :white)} = #{format_value(nested_v)}"
|
|
692
684
|
end
|
|
@@ -699,21 +691,31 @@ module BrainzLab
|
|
|
699
691
|
when Array
|
|
700
692
|
if value.length <= 5 && value.all? { |v| !hash_like?(v) && !v.is_a?(Array) }
|
|
701
693
|
# Compact inline array
|
|
702
|
-
arr = value.map { |v| format_value(v) }.join(
|
|
694
|
+
arr = value.map { |v| format_value(v) }.join(', ')
|
|
703
695
|
lines << "#{line_prefix}#{indent}#{colorize(full_key, :white)} = [#{arr}]"
|
|
704
696
|
elsif hash_like?(value.first)
|
|
705
697
|
# Array of hashes (like logs array) - show each item
|
|
706
|
-
lines << "#{line_prefix}#{indent}#{colorize("[[#{full_key}]]",
|
|
698
|
+
lines << "#{line_prefix}#{indent}#{colorize("[[#{full_key}]]",
|
|
699
|
+
:gray)} #{colorize("# #{value.length} items", :gray)}"
|
|
707
700
|
# Show first item fully expanded
|
|
708
701
|
if value.first
|
|
709
|
-
first_item =
|
|
702
|
+
first_item = begin
|
|
703
|
+
value.first.to_h
|
|
704
|
+
rescue StandardError
|
|
705
|
+
value.first
|
|
706
|
+
end
|
|
710
707
|
first_item.each do |k, v|
|
|
711
708
|
if hash_like?(v)
|
|
712
709
|
# Expand nested hash fully
|
|
713
|
-
nested_hash =
|
|
710
|
+
nested_hash = begin
|
|
711
|
+
v.to_h
|
|
712
|
+
rescue StandardError
|
|
713
|
+
v
|
|
714
|
+
end
|
|
714
715
|
lines << "#{line_prefix}#{indent} #{colorize("[#{k}]", :gray)}"
|
|
715
716
|
nested_hash.each do |nested_k, nested_v|
|
|
716
|
-
lines << "#{line_prefix}#{indent} #{colorize(nested_k.to_s,
|
|
717
|
+
lines << "#{line_prefix}#{indent} #{colorize(nested_k.to_s,
|
|
718
|
+
:white)} = #{format_value(nested_v)}"
|
|
717
719
|
end
|
|
718
720
|
else
|
|
719
721
|
lines << "#{line_prefix}#{indent} #{colorize(k.to_s, :white)} = #{format_value(v)}"
|
|
@@ -722,9 +724,11 @@ module BrainzLab
|
|
|
722
724
|
end
|
|
723
725
|
else
|
|
724
726
|
# Large array of primitives
|
|
725
|
-
arr = value.first(5).map { |v| format_value(v) }.join(
|
|
726
|
-
arr +=
|
|
727
|
-
lines << "#{line_prefix}#{indent}#{colorize(full_key,
|
|
727
|
+
arr = value.first(5).map { |v| format_value(v) }.join(', ')
|
|
728
|
+
arr += ', ...' if value.length > 5
|
|
729
|
+
lines << "#{line_prefix}#{indent}#{colorize(full_key,
|
|
730
|
+
:white)} = [#{arr}] #{colorize("# #{value.length} items",
|
|
731
|
+
:gray)}"
|
|
728
732
|
end
|
|
729
733
|
else
|
|
730
734
|
lines << "#{line_prefix}#{indent}#{colorize(full_key, :white)} = #{format_value(value)}"
|
|
@@ -737,15 +741,15 @@ module BrainzLab
|
|
|
737
741
|
def format_hash_nested(hash, prefix, depth)
|
|
738
742
|
lines = []
|
|
739
743
|
line_prefix = colorize("#{BOX[:vertical]} ", :cyan)
|
|
740
|
-
indent = "
|
|
744
|
+
indent = " #{' ' * depth}"
|
|
741
745
|
|
|
742
746
|
lines << "#{line_prefix}#{indent}#{colorize("[#{prefix}]", :gray)}"
|
|
743
747
|
hash.each do |k, v|
|
|
744
|
-
if v.is_a?(Hash)
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
748
|
+
lines << if v.is_a?(Hash)
|
|
749
|
+
format_hash_nested(v, "#{prefix}.#{k}", depth + 1)
|
|
750
|
+
else
|
|
751
|
+
"#{line_prefix}#{indent} #{colorize(k.to_s, :white)} = #{format_value(v)}"
|
|
752
|
+
end
|
|
749
753
|
end
|
|
750
754
|
|
|
751
755
|
lines.join("\n")
|
|
@@ -764,16 +768,18 @@ module BrainzLab
|
|
|
764
768
|
when TrueClass, FalseClass
|
|
765
769
|
colorize(value.to_s, :cyan)
|
|
766
770
|
when NilClass
|
|
767
|
-
colorize(
|
|
771
|
+
colorize('null', :gray)
|
|
768
772
|
when Hash
|
|
769
|
-
items = value.first(3).map { |k, v| "#{k} = #{format_value(v)}" }.join(
|
|
770
|
-
items +=
|
|
773
|
+
items = value.first(3).map { |k, v| "#{k} = #{format_value(v)}" }.join(', ')
|
|
774
|
+
items += ', ...' if value.keys.length > 3
|
|
771
775
|
"{ #{items} }"
|
|
772
776
|
when Array
|
|
773
777
|
if value.length <= 3
|
|
774
|
-
"[#{value.map { |v| format_value(v) }.join(
|
|
778
|
+
"[#{value.map { |v| format_value(v) }.join(', ')}]"
|
|
775
779
|
else
|
|
776
|
-
"[#{value.first(3).map
|
|
780
|
+
"[#{value.first(3).map do |v|
|
|
781
|
+
format_value(v)
|
|
782
|
+
end.join(', ')}, ...] #{colorize("# #{value.length} items", :gray)}"
|
|
777
783
|
end
|
|
778
784
|
else
|
|
779
785
|
colorize(value.to_s, :white)
|
|
@@ -781,7 +787,7 @@ module BrainzLab
|
|
|
781
787
|
end
|
|
782
788
|
|
|
783
789
|
def status_phrase(status)
|
|
784
|
-
Rack::Utils::HTTP_STATUS_CODES[status] ||
|
|
790
|
+
Rack::Utils::HTTP_STATUS_CODES[status] || 'Unknown'
|
|
785
791
|
end
|
|
786
792
|
|
|
787
793
|
def truncate(text, length)
|