Class: CloseYourIt::UsageRegistry
- Inherits:
-
Object
- Object
- CloseYourIt::UsageRegistry
- Defined in:
- lib/closeyourit/usage_registry.rb
Overview
CYSK-29 — la telemetria d'uso: registra QUALI simboli girano davvero (route come
Controller#action, job, chiavi custom letterali) e li flusha in una POST ogni
usage_flush_interval secondi per processo. Sul percorso caldo: una lookup e un increment.
Le regole che rendono il sistema immune alle perdite:
- i conteggi sono INDICATIVI, solo
last_seen_atè portante: un flush perso costa una finestra su un simbolo che si rivede subito dopo; - il registro SI SVUOTA a ogni flush: il tetto (
usage_max_symbols) limita i simboli distinti visti in una finestra — una grandezza legata al traffico, non alla dimensione del codice; - oltre il tetto il flush porta
truncated: true, e lato scanner quel flag SQUALIFICA il kind; - nessun sampling, mai: un campionamento su una rotta chiamata 3 volte al mese fabbrica esattamente il falso «mai vista» che il sistema esiste per evitare;
routeèController#action, MAI l'URL: niente path, parametri, user, IP.
Constant Summary collapse
- SYMBOL_FORMAT =
I simboli vengono da payload di framework o da stringhe letterali: il pattern è il contratto.
%r{\A[A-Za-z0-9_:#./-]{1,200}\z}- KINDS =
%w[route job custom].freeze
Instance Attribute Summary collapse
-
#timer ⇒ Object
readonly
esposto per i test (verifica dell'intervallo configurato).
Instance Method Summary collapse
- #flush ⇒ Object
-
#initialize(client:, configuration:) ⇒ UsageRegistry
constructor
A new instance of UsageRegistry.
- #record(kind, symbol) ⇒ Object
- #shutdown ⇒ Object
Constructor Details
#initialize(client:, configuration:) ⇒ UsageRegistry
Returns a new instance of UsageRegistry.
26 27 28 29 30 31 32 33 34 |
# File 'lib/closeyourit/usage_registry.rb', line 26 def initialize(client:, configuration:) @client = client @configuration = configuration @mutex = Mutex.new @symbols = {} @truncated = false @window_started_at = Time.now.utc @timer = nil end |
Instance Attribute Details
#timer ⇒ Object (readonly)
esposto per i test (verifica dell'intervallo configurato)
24 25 26 |
# File 'lib/closeyourit/usage_registry.rb', line 24 def timer @timer end |
Instance Method Details
#flush ⇒ Object
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/closeyourit/usage_registry.rb', line 58 def flush payload = drain return if payload[:symbols].empty? && !payload[:truncated] @client.flush_usage(**payload) rescue StandardError => e # Il flush gira sul thread timer: un errore non deve propagare nell'app né uccidere il # TimerTask. La semantica portante è last_seen_at: una finestra persa non falsifica niente. CloseYourIt.internal_logger.error("CloseYourIt usage registry: #{e.class}: #{e.}") end |
#record(kind, symbol) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/closeyourit/usage_registry.rb', line 36 def record(kind, symbol) return unless @configuration.usage_enabled kind = kind.to_s symbol = symbol.to_s return unless KINDS.include?(kind) && symbol.match?(SYMBOL_FORMAT) @mutex.synchronize do key = [ kind, symbol ] entry = @symbols[key] if entry entry[:count] += 1 entry[:last_seen_at] = Time.now.utc elsif @symbols.size >= @configuration.usage_max_symbols.to_i @truncated = true else @symbols[key] = { count: 1, last_seen_at: Time.now.utc } end ensure_timer end end |
#shutdown ⇒ Object
69 70 71 72 |
# File 'lib/closeyourit/usage_registry.rb', line 69 def shutdown @timer&.shutdown flush end |