Class: CloseYourIt::Client
- Inherits:
-
Object
- Object
- CloseYourIt::Client
- Defined in:
- lib/closeyourit/client.rb
Overview
Compone Transport + BackgroundWorker: applica before_send e dispatcha
l'invio in modo fire-and-forget.
Constant Summary collapse
- LOGS_MAX_BATCH =
Tetto di log per singola richiesta a /logs. Il backend rifiuta un batch oltre questo limite (413 R413-LOG-002) scartando l'INTERA richiesta — e il buffer è già stato drenato → log persi. Deve restare ≤ del limite server (LOGS_MAX_BATCH backend = 1000). Vedi #flush_logs.
1000
Instance Method Summary collapse
- #capture_event(event) ⇒ Object
-
#flush_logs(events) ⇒ Object
Invia un batch di log come ARRAY a /logs (l'endpoint accetta singolo o array).
-
#initialize(configuration) ⇒ Client
constructor
A new instance of Client.
- #shutdown ⇒ Object
Constructor Details
#initialize(configuration) ⇒ Client
Returns a new instance of Client.
12 13 14 15 16 17 18 19 |
# File 'lib/closeyourit/client.rb', line 12 def initialize(configuration) @configuration = configuration @transport = Transport.new(configuration) @worker = BackgroundWorker.new( threads: configuration.async_threads, max_queue: configuration.background_worker_max_queue ) end |
Instance Method Details
#capture_event(event) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/closeyourit/client.rb', line 21 def capture_event(event) payload = event.to_h payload = @configuration.before_send.call(payload) if @configuration.before_send if payload.nil? # before_send ha scartato l'evento (ritorna nil): scarto voluto, reso visibile (CYRB-12). CloseYourIt.stats.increment(:dropped) CloseYourIt.notify_diagnostic(:drop, reason: :before_send) return nil end path = event.ingest_path(@configuration.project_id) accepted = @worker.perform { @transport.send_event(payload, path: path) } if accepted CloseYourIt.stats.increment(:enqueued) CloseYourIt.notify_diagnostic(:enqueue, path: path) end payload rescue StandardError => e # La telemetria non deve MAI propagare nel path dell'app ospite: capture_event è invocato dal # subscriber sql.active_record, che gira nel thread della query. to_h (scrubber su bind # malformato) e before_send sono valutati qui in modo sincrono → se sollevano, assorbiamo, # logghiamo e scartiamo l'evento invece di disturbare la query ospite. Vedi CYRB-2. CloseYourIt.internal_logger.error("CloseYourIt client: #{e.class}: #{e.}") CloseYourIt.stats.increment(:dropped) CloseYourIt.notify_diagnostic(:drop, reason: :error, error: e.class.name) nil end |
#flush_logs(events) ⇒ Object
Invia un batch di log come ARRAY a /logs (l'endpoint accetta singolo o array). before_send è applicato a ciascun payload; quelli scartati (nil) non vengono inviati. I payload oltre LOGS_MAX_BATCH sono spezzati in più POST sequenziali (un chunk = un POST), così un flush grande non viene rigettato in blocco dal backend e perso — vedi R3 / LOGS_MAX_BATCH. Un flush entro il limite resta un singolo POST.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/closeyourit/client.rb', line 54 def flush_logs(events) return nil if events.nil? || events.empty? payloads = events.map(&:to_h) if @configuration.before_send kept = payloads.filter_map { |payload| @configuration.before_send.call(payload) } # I log che before_send porta a nil sono scarti voluti: contabilizzali come gli errori/metriche # (parità con #capture_event), altrimenti sparirebbero silenziosamente dai contatori (CYRB-12). (payloads.size - kept.size).times do CloseYourIt.stats.increment(:dropped) CloseYourIt.notify_diagnostic(:drop, reason: :before_send) end payloads = kept end return nil if payloads.empty? path = events.first.ingest_path(@configuration.project_id) payloads.each_slice(LOGS_MAX_BATCH) do |chunk| accepted = @worker.perform { @transport.send_event(chunk, path: path) } next unless accepted CloseYourIt.stats.increment(:enqueued) CloseYourIt.notify_diagnostic(:enqueue, path: path, batch: chunk.size) end payloads end |
#shutdown ⇒ Object
81 82 83 |
# File 'lib/closeyourit/client.rb', line 81 def shutdown @worker.shutdown end |