puma_metrics_engine 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 248a19d8e7fb9d4392b1f4c4bf3cfa13d8e4872426d843f171732264783eaf94
4
- data.tar.gz: b09efaf7ede10a759b435b8be828f0dbebde7f54ece70efddb050180e474ac4a
3
+ metadata.gz: 1ab335fa7843d45934fd97c5442b9bfd3a87006066b6f14ef99123a9316ab165
4
+ data.tar.gz: 7bd9134d5a436aecebd2a3f2a4073a5b51c46f3fb3d4a8b2391464e108326503
5
5
  SHA512:
6
- metadata.gz: 4bbfb1639f3157a75afc8bbc538eecfd52492c05240be8d96576884ea2448cd6d8598b16e0a87c8fd2a93153b0b051e186842083e18bb874b8c5bb14bb17813c
7
- data.tar.gz: 006066e431c7c1d7fed9cfb6c19b17715e2e7437a09ef23b8962838e33e063299a62ce7b47d6c6d535ebe535032ed8abd840f3851cf7e0505fab11bc023a041e
6
+ metadata.gz: c9f71532254eed460c8169a894c41e0ac03c7a089c37a133fc097d7632a0ab2bd2e282bbe84b7cd3ea667ea1adfa9f5a9cb3afc4aaaeb8d470107e5f403ab016
7
+ data.tar.gz: b704e4c376bdbdad8324b004c71ed20d176dbdda1febaaa63c6c411da33beee40cdb98460671dd8c558feb085a491602f2babc220d3ede42f2d77e90594b00d7
data/README.md CHANGED
@@ -25,6 +25,12 @@ end
25
25
 
26
26
  Access metrics at `/matrix` endpoint.
27
27
 
28
+ For debugging production issues, use `/debug` endpoint to check:
29
+ - Middleware registration status
30
+ - Redis connectivity
31
+ - Header presence
32
+ - Current data in Redis
33
+
28
34
  ## Response Format
29
35
 
30
36
  ```json
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PumaMetricsEngine
4
+ class DebugController < ActionController::Base
5
+ skip_before_action :verify_authenticity_token
6
+
7
+ def show
8
+ render json: {
9
+ timestamp: Time.current,
10
+ middleware: middleware_status,
11
+ redis: redis_status,
12
+ headers: sample_headers,
13
+ data: redis_data_summary,
14
+ environment: environment_info
15
+ }
16
+ end
17
+
18
+ private
19
+
20
+ def middleware_status
21
+ middleware_stack = Rails.application.middleware.to_a.map(&:klass).map(&:name)
22
+ is_registered = middleware_stack.include?("PumaMetricsEngine::QueueTimeTracker")
23
+
24
+ {
25
+ registered: is_registered,
26
+ middleware_stack: middleware_stack,
27
+ note: is_registered ? "Middleware is registered" : "Middleware NOT found in stack"
28
+ }
29
+ rescue StandardError => e
30
+ { error: e.message }
31
+ end
32
+
33
+ def redis_status
34
+ client = redis
35
+ client.ping
36
+ {
37
+ connected: true,
38
+ url: ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" },
39
+ keys: {
40
+ queue_times: client.exists?(MatrixController::QUEUE_TIMES_KEY),
41
+ request_timestamps: client.exists?(MatrixController::REQUESTS_KEY)
42
+ }
43
+ }
44
+ rescue StandardError => e
45
+ {
46
+ connected: false,
47
+ error: e.message,
48
+ url: ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" }
49
+ }
50
+ end
51
+
52
+ def redis_data_summary
53
+ client = redis
54
+ {
55
+ queue_times_count: client.zcard(MatrixController::QUEUE_TIMES_KEY),
56
+ request_timestamps_count: client.zcard(MatrixController::REQUESTS_KEY),
57
+ recent_queue_times: client.zrange(MatrixController::QUEUE_TIMES_KEY, -10, -1),
58
+ recent_timestamps: client.zrange(MatrixController::REQUESTS_KEY, -10, -1)
59
+ }
60
+ rescue StandardError => e
61
+ { error: e.message }
62
+ end
63
+
64
+ def sample_headers
65
+ # Show what headers we're looking for
66
+ {
67
+ x_request_start: request.headers["X-Request-Start"],
68
+ http_x_request_start: request.headers["HTTP_X_REQUEST_START"],
69
+ all_x_headers: request.headers.select { |k, _| k.to_s.upcase.include?("X-REQUEST") },
70
+ note: "Check if X-Request-Start header is being sent by your load balancer"
71
+ }
72
+ end
73
+
74
+ def environment_info
75
+ {
76
+ rails_env: Rails.env,
77
+ redis_url_set: ENV.key?("REDIS_URL"),
78
+ puma_defined: defined?(Puma)
79
+ }
80
+ end
81
+
82
+ def redis
83
+ @redis ||= Redis.new(url: ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" })
84
+ end
85
+ end
86
+ end
87
+
data/config/routes.rb CHANGED
@@ -2,4 +2,5 @@
2
2
 
3
3
  PumaMetricsEngine::Engine.routes.draw do
4
4
  get "matrix", to: "matrix#show"
5
+ get "debug", to: "debug#show"
5
6
  end
@@ -14,6 +14,13 @@ module PumaMetricsEngine
14
14
  request_start_time = extract_request_start_time(env)
15
15
  process_start_time = Time.now.to_f
16
16
 
17
+ # Log header presence for debugging
18
+ if defined?(Rails)
19
+ header_value = env["HTTP_X_REQUEST_START"] || env["X-Request-Start"]
20
+ Rails.logger.debug("[QueueTimeTracker] X-Request-Start header: #{header_value.inspect}") if header_value
21
+ Rails.logger.debug("[QueueTimeTracker] No X-Request-Start header found") unless header_value
22
+ end
23
+
17
24
  status, headers, response = @app.call(env)
18
25
 
19
26
  # Calculate queue time if we have request start time
@@ -27,8 +34,10 @@ module PumaMetricsEngine
27
34
  timestamp = process_start_time
28
35
  # Store in Redis asynchronously to avoid blocking the request
29
36
  store_metrics_async(timestamp, queue_time_ms)
37
+ Rails.logger.debug("[QueueTimeTracker] Stored queue time: #{queue_time_ms}ms") if defined?(Rails)
30
38
  else
31
39
  # Still track request timestamp even if queue time is invalid
40
+ Rails.logger.warn("[QueueTimeTracker] Invalid queue time: #{queue_time_ms}ms (rejected)") if defined?(Rails)
32
41
  store_request_timestamp_async(process_start_time)
33
42
  end
34
43
  else
@@ -37,7 +46,8 @@ module PumaMetricsEngine
37
46
  end
38
47
  rescue StandardError => e
39
48
  # Don't let tracking errors break the request
40
- Rails.logger.error("QueueTimeTracker error: #{e.message}") if defined?(Rails)
49
+ Rails.logger.error("[QueueTimeTracker] Error: #{e.message}") if defined?(Rails)
50
+ Rails.logger.error("[QueueTimeTracker] Backtrace: #{e.backtrace.first(5).join("\n")}") if defined?(Rails)
41
51
  end
42
52
 
43
53
  [status, headers, response]
@@ -89,7 +99,8 @@ module PumaMetricsEngine
89
99
  # Cleanup old data (older than TTL)
90
100
  cleanup_old_data(redis_client)
91
101
  rescue StandardError => e
92
- Rails.logger.error("Failed to store queue time metrics: #{e.message}") if defined?(Rails)
102
+ Rails.logger.error("[QueueTimeTracker] Failed to store metrics: #{e.message}") if defined?(Rails)
103
+ Rails.logger.error("[QueueTimeTracker] Redis error backtrace: #{e.backtrace.first(3).join("\n")}") if defined?(Rails)
93
104
  end
94
105
  end
95
106
  end
@@ -101,7 +112,7 @@ module PumaMetricsEngine
101
112
  redis_client.zadd(REQUESTS_KEY, timestamp, timestamp)
102
113
  cleanup_old_data(redis_client)
103
114
  rescue StandardError => e
104
- Rails.logger.error("Failed to store request timestamp: #{e.message}") if defined?(Rails)
115
+ Rails.logger.error("[QueueTimeTracker] Failed to store request timestamp: #{e.message}") if defined?(Rails)
105
116
  end
106
117
  end
107
118
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PumaMetricsEngine
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma_metrics_engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neeto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-11-28 00:00:00.000000000 Z
11
+ date: 2025-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -146,6 +146,7 @@ extra_rdoc_files: []
146
146
  files:
147
147
  - LICENSE.txt
148
148
  - README.md
149
+ - app/controllers/puma_metrics_engine/debug_controller.rb
149
150
  - app/controllers/puma_metrics_engine/matrix_controller.rb
150
151
  - config/routes.rb
151
152
  - lib/puma_metrics_engine.rb