Evita di saturare Puma in diretta, separa i check Rails/pubblico e traccia la latenza /up per alert più affidabili. Co-authored-by: Cursor <cursoragent@cursor.com>
45 lines
995 B
Ruby
45 lines
995 B
Ruby
# frozen_string_literal: true
|
|
|
|
module Ops
|
|
# Campioni latenza GET /up (edge → rails) per calcolo p95.
|
|
class UpLatencyTracker
|
|
REDIS_KEY = "ops:up_latency_ms"
|
|
MAX_SAMPLES = -> { ENV.fetch("OPS_UP_LATENCY_SAMPLES", "60").to_i }
|
|
|
|
class << self
|
|
def record(latency_ms)
|
|
return unless redis
|
|
|
|
redis.pipelined do |pipe|
|
|
pipe.lpush(REDIS_KEY, latency_ms.to_i)
|
|
pipe.ltrim(REDIS_KEY, 0, MAX_SAMPLES.call - 1)
|
|
end
|
|
end
|
|
|
|
def samples
|
|
return [] unless redis
|
|
|
|
redis.lrange(REDIS_KEY, 0, -1).map(&:to_i)
|
|
end
|
|
|
|
def sample_count
|
|
samples.size
|
|
end
|
|
|
|
def p95
|
|
sorted = samples.sort
|
|
return nil if sorted.empty?
|
|
|
|
index = [(sorted.size * 0.95).ceil - 1, 0].max
|
|
sorted[index]
|
|
end
|
|
|
|
def redis
|
|
@redis ||= Redis.new(url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0"))
|
|
rescue Redis::CannotConnectError
|
|
nil
|
|
end
|
|
end
|
|
end
|
|
end
|