neetodeploy-autoscale 2.1.0 → 2.1.2
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7c7841930ad563bfa0d372de339715f70ba9dba99e0ef61ec09fcc9f0624a683
|
|
4
|
+
data.tar.gz: 1134df572ad17a7a6678770ac3a63227e4544f7d9b195489070ae14f3fead18d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3a6eb8853074dc0029d1c8dbab103916fda6f1719206dc966d3dcd5f2ea43250ec8762e52c00a2b32efa2071af3b3e7e3d7ea35cc07a664e69383e354ee0a61f
|
|
7
|
+
data.tar.gz: 55374376294d4c77f712423b16d5df3d9b5755ca99210697f225904a3d952dae6930e277d7ab2c8a3261d9cef978990943ffda50c95cfbb8e04b3d4440520a64
|
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "neetodeploy/autoscale/config"
|
|
4
|
+
require "neetodeploy/autoscale/logger"
|
|
4
5
|
|
|
5
6
|
module Neetodeploy
|
|
6
7
|
module Rails
|
|
7
8
|
class Metrics
|
|
8
9
|
def initialize(env, config = Config.instance)
|
|
9
10
|
@config = config
|
|
10
|
-
@
|
|
11
|
+
@request_start_header_raw = env["HTTP_X_REQUEST_START"]
|
|
12
|
+
@request_start_header = @request_start_header_raw.to_i
|
|
11
13
|
@network_time = env["puma.request_body_wait"].to_i
|
|
14
|
+
|
|
15
|
+
# Debug: Log all HTTP headers to help diagnose
|
|
16
|
+
if @request_start_header_raw.nil? || @request_start_header_raw.empty?
|
|
17
|
+
# Get all HTTP_* headers (these are the request headers)
|
|
18
|
+
http_headers = env.keys.grep(/^HTTP_/)
|
|
19
|
+
|
|
20
|
+
if http_headers.any?
|
|
21
|
+
NeetoDeploy::Logger.logger.debug("All HTTP headers found: #{http_headers.sort.join(', ')}")
|
|
22
|
+
else
|
|
23
|
+
NeetoDeploy::Logger.logger.debug("No HTTP headers found in env. Available env keys: #{env.keys.grep(/^HTTP|^REQUEST|^SERVER/).sort.join(', ')}")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Also check for X-Request-Start with different casing
|
|
27
|
+
x_request_variants = env.select { |k, _| k.to_s.upcase.include?("REQUEST_START") || k.to_s.upcase.include?("X_REQUEST") }
|
|
28
|
+
if x_request_variants.any?
|
|
29
|
+
NeetoDeploy::Logger.logger.debug("Found X-Request-Start variants: #{x_request_variants.keys.join(', ')}")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
12
32
|
end
|
|
13
33
|
|
|
14
34
|
def ignore?
|
|
@@ -16,13 +36,26 @@ module Neetodeploy
|
|
|
16
36
|
end
|
|
17
37
|
|
|
18
38
|
def queue_time
|
|
19
|
-
|
|
39
|
+
# Debug: Log if header is missing or invalid
|
|
40
|
+
if @request_start_header_raw.nil? || @request_start_header_raw.empty?
|
|
41
|
+
NeetoDeploy::Logger.logger.debug("X-Request-Start header missing or empty")
|
|
42
|
+
return nil
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
return nil if @request_start_header.zero?
|
|
20
46
|
|
|
21
47
|
time_now = Time.now.to_f * 1000
|
|
22
48
|
|
|
23
49
|
queue_time = (time_now - @request_start_header).round
|
|
24
50
|
queue_time -= @network_time
|
|
25
51
|
|
|
52
|
+
# Log both values for debugging
|
|
53
|
+
NeetoDeploy::Logger.logger.debug(
|
|
54
|
+
"Queue time calculation: X-Request-Start=#{@request_start_header_raw} (#{@request_start_header}ms), " \
|
|
55
|
+
"puma.request_body_wait=#{@network_time}ms, time_now=#{time_now.round}ms, " \
|
|
56
|
+
"calculated_queue_time=#{queue_time}ms"
|
|
57
|
+
)
|
|
58
|
+
|
|
26
59
|
queue_time.positive? ? queue_time : nil
|
|
27
60
|
end
|
|
28
61
|
end
|
|
@@ -74,11 +74,20 @@ module Neetodeploy
|
|
|
74
74
|
sorted_data = data.sort
|
|
75
75
|
size = sorted_data.size
|
|
76
76
|
|
|
77
|
+
# Calculate percentiles
|
|
78
|
+
p90 = percentile_value(sorted_data, size, 0.90)
|
|
79
|
+
p95 = percentile_value(sorted_data, size, 0.95)
|
|
80
|
+
p99 = percentile_value(sorted_data, size, 0.99)
|
|
81
|
+
avg = data.sum / data.size
|
|
82
|
+
|
|
83
|
+
# Log sample size and values for debugging
|
|
84
|
+
logger.debug("Calculated metrics from #{size} samples: avg=#{avg}, p90=#{p90}, p95=#{p95}, p99=#{p99}")
|
|
85
|
+
|
|
77
86
|
metrics = [
|
|
78
|
-
{ metric_name: "queue_time_p90", metric_value:
|
|
79
|
-
{ metric_name: "queue_time_p95", metric_value:
|
|
80
|
-
{ metric_name: "queue_time_p99", metric_value:
|
|
81
|
-
{ metric_name: "queue_time", metric_value:
|
|
87
|
+
{ metric_name: "queue_time_p90", metric_value: p90 },
|
|
88
|
+
{ metric_name: "queue_time_p95", metric_value: p95 },
|
|
89
|
+
{ metric_name: "queue_time_p99", metric_value: p99 },
|
|
90
|
+
{ metric_name: "queue_time", metric_value: avg }
|
|
82
91
|
]
|
|
83
92
|
|
|
84
93
|
Reporter.report_batch(metrics, "web", nil, config)
|
|
@@ -90,7 +99,11 @@ module Neetodeploy
|
|
|
90
99
|
end
|
|
91
100
|
|
|
92
101
|
def percentile_value(sorted_data, size, percentile)
|
|
102
|
+
# Use nearest rank method: index = ceil(size * percentile) - 1
|
|
103
|
+
# For small samples, this ensures we get a valid index
|
|
93
104
|
index = [(size * percentile).ceil - 1, 0].max
|
|
105
|
+
# Clamp index to valid range
|
|
106
|
+
index = [index, size - 1].min
|
|
94
107
|
sorted_data[index]
|
|
95
108
|
end
|
|
96
109
|
|