Module: Lapsoss::Adapters::Concerns::HttpDelivery

Extended by:
ActiveSupport::Concern
Included in:
OpenobserveAdapter, OtlpAdapter, RollbarAdapter, SentryAdapter
Defined in:
lib/lapsoss/adapters/concerns/http_delivery.rb

Instance Method Summary collapse

Instance Method Details

#adapter_specific_headersObject

Override for adapter-specific headers



56
57
58
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 56

def adapter_specific_headers
  {}
end

#build_delivery_headers(compressed: false, content_type: "application/json") ⇒ Object

Common headers for all adapters



46
47
48
49
50
51
52
53
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 46

def build_delivery_headers(compressed: false, content_type: "application/json")
  {
    "User-Agent" => user_agent,
    "Content-Type" => content_type,
    "Content-Encoding" => ("gzip" if compressed),
    "X-Lapsoss-Version" => Lapsoss::VERSION
  }.merge(adapter_specific_headers).compact_blank
end

#deliver(event) ⇒ Object

Unified HTTP delivery with instrumentation



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 23

def deliver(event)
  return unless enabled?

  payload = build_payload(event)
  return if payload.blank?

  body, compressed = serialize_payload(payload)
  headers = build_delivery_headers(compressed: compressed)

  ActiveSupport::Notifications.instrument("deliver.lapsoss",
    adapter: self.class.name,
    event_type: event.type,
    compressed: compressed,
    size: body.bytesize
  ) do
    response = http_client.post(api_path, body: body, headers: headers)
    handle_response(response)
  end
rescue => error
  handle_delivery_error(error, event)
end

#git_branchObject

Git info with AS memoization



61
62
63
64
65
66
67
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 61

def git_branch
  self.class.git_info_cache[:branch] ||= begin
    `git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip.presence
  rescue
    nil
  end
end

#git_shaObject



69
70
71
72
73
74
75
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 69

def git_sha
  self.class.git_info_cache[:sha] ||= begin
    `git rev-parse HEAD 2>/dev/null`.strip.presence
  rescue
    nil
  end
end

#handle_client_error(response) ⇒ Object

Raises:



98
99
100
101
102
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 98

def handle_client_error(response)
  body = ActiveSupport::JSON.decode(response.body) rescue {}
  message = body["message"].presence || body["error"].presence || "Bad request"
  raise DeliveryError.new("Client error: #{message}", response: response)
end

#handle_delivery_error(error, event = nil) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 104

def handle_delivery_error(error, event = nil)
  ActiveSupport::Notifications.instrument("error.lapsoss",
    adapter: self.class.name,
    error: error.class.name,
    message: error.message
  )

  Lapsoss.configuration.logger&.error("[#{self.class.name}] Delivery failed: #{error.message}")
  Lapsoss.call_error_handler(adapter: self, event: event, error: error)
  mark_error_handled(error)

  if error.is_a?(DeliveryError)
    raise error
  else
    delivery_error = DeliveryError.new("Delivery failed: #{error.message}", cause: error)
    mark_error_handled(delivery_error)
    raise delivery_error
  end
end

#handle_response(response) ⇒ Object

Common response handling



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 78

def handle_response(response)
  code = response.respond_to?(:status) ? response.status.to_i : response.code.to_i
  case code
  when 200..299
    ActiveSupport::Notifications.instrument("success.lapsoss",
      adapter: self.class.name,
      response_code: code
    )
    true
  when 429
    raise DeliveryError.new("Rate limit exceeded", response: response)
  when 401, 403
    raise DeliveryError.new("Authentication failed", response: response)
  when 400..499
    handle_client_error(response)
  else
    raise DeliveryError.new("Server error: #{code}", response: response)
  end
end

#mark_error_handled(error) ⇒ Object



124
125
126
127
128
# File 'lib/lapsoss/adapters/concerns/http_delivery.rb', line 124

def mark_error_handled(error)
  error.instance_variable_set(:@lapsoss_error_handled, true)
rescue StandardError
  # If setting the flag fails, we still continue
end