Module: Snare::Transport

Defined in:
lib/snare/transport.rb

Overview

HTTP delivery — mirrors packages/sdk/src/transport.ts. The API key rides in the JSON body, never a header (docs/snare-multi-language-sdk-wire-protocol.md, Section 1) — every language SDK follows the same envelope regardless of what's idiomatic for that language's HTTP client.

Class Method Summary collapse

Class Method Details

.build_body(api_key, events) ⇒ Object



34
35
36
# File 'lib/snare/transport.rb', line 34

def build_body(api_key, events)
  { apiKey: api_key, events: events.map { |event| to_wire_format(event) } }
end

.send_batch(api_base:, project_id:, api_key:, events:) ⇒ Object

Never raises into the host application — network errors, timeouts, and non-2xx responses are all best-effort, silent failures. A dropped telemetry batch must never surface as an error in the host app.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/snare/transport.rb', line 18

def send_batch(api_base:, project_id:, api_key:, events:)
  return if events.empty?

  uri = URI.parse("#{api_base.chomp("/")}/telemetry/#{project_id}/events")
  body = JSON.generate(build_body(api_key, events))

  Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", open_timeout: 5, read_timeout: 5) do |http|
    request = Net::HTTP::Post.new(uri.request_uri, { "content-type" => "application/json" })
    request.body = body
    http.request(request)
  end
  nil
rescue StandardError
  nil
end

.to_wire_format(event) ⇒ Object

Converts an internal (snake_case) event hash to the fixed camelCase wire shape (docs/snare-multi-language-sdk-wire-protocol.md, Section 1).



40
41
42
43
44
45
46
47
48
49
# File 'lib/snare/transport.rb', line 40

def to_wire_format(event)
  wire = {
    message: event[:message],
    timestamp: event[:timestamp],
    consoleLog: event[:console_log],
    platform: event[:platform],
  }
  wire[:stack] = event[:stack] if event.key?(:stack)
  wire
end