activerabbit-ai 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/active_rabbit/client/cron_monitor.rb +65 -0
- data/lib/active_rabbit/client/exception_tracker.rb +3 -0
- data/lib/active_rabbit/client/http_client.rb +14 -2
- data/lib/active_rabbit/client/version.rb +1 -1
- data/lib/active_rabbit/client.rb +19 -0
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d02e83fd5992873b3b7aabb322ab9e3c914b91e7e64b4a80be335007561bc404
|
|
4
|
+
data.tar.gz: d60e55a0fcab7c981d7b7a214cff142825c613e7d32ddf15533bccd451cb6657
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 32a57acfde857e55a97932f56ae1a449f04a7e51e7ad8903d2cf63380ddd338cf0930d18785559f2bf358250470ce1890f503dde670aaebddf1756f6b5675c2f
|
|
7
|
+
data.tar.gz: dad613e6edf130e26c185b2b17670366400c4a40a36ebf0d8017a77189f01c1647c0cbd3ef7f810727a47beccf46b5f482394b681424982ad64a020eb1bcd768
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.6.3] - 2026-03-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **HTTP client request id**: `make_request` sends a stable `X-Request-Id` header (same value across retries) so APIs can correlate or deduplicate requests after timeouts and transient failures.
|
|
9
|
+
- **Explicit `securerandom` load**: `HttpClient` requires `securerandom` so `SecureRandom` is always available regardless of load order.
|
|
10
|
+
|
|
5
11
|
## [0.6.2] - 2026-01-26
|
|
6
12
|
|
|
7
13
|
### Fixed
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRabbit
|
|
4
|
+
module Client
|
|
5
|
+
# Sentry-style cron check-ins for Active Job: in_progress at start, ok on success, error on failure.
|
|
6
|
+
#
|
|
7
|
+
# class BackupJob < ApplicationJob
|
|
8
|
+
# include ActiveRabbit::Client::CronMonitor
|
|
9
|
+
# active_rabbit_cron slug: "nightly_backup"
|
|
10
|
+
#
|
|
11
|
+
# def perform
|
|
12
|
+
# # ...
|
|
13
|
+
# end
|
|
14
|
+
# end
|
|
15
|
+
module CronMonitor
|
|
16
|
+
def self.included(base)
|
|
17
|
+
base.extend(ClassMethods)
|
|
18
|
+
base.class_eval do
|
|
19
|
+
around_perform :_active_rabbit_cron_monitor_around
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
module ClassMethods
|
|
24
|
+
# @param value [String, Symbol, Hash] string/symbol slug, or { slug: "..." }
|
|
25
|
+
def active_rabbit_cron(value = nil)
|
|
26
|
+
case value
|
|
27
|
+
when String, Symbol
|
|
28
|
+
@active_rabbit_cron_slug = value.to_s.strip
|
|
29
|
+
when Hash
|
|
30
|
+
s = value[:slug].to_s.strip
|
|
31
|
+
@active_rabbit_cron_slug = s.empty? ? nil : s
|
|
32
|
+
when nil
|
|
33
|
+
@active_rabbit_cron_slug = nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def active_rabbit_cron_monitor_slug
|
|
38
|
+
slug = instance_variable_defined?(:@active_rabbit_cron_slug) ? @active_rabbit_cron_slug : nil
|
|
39
|
+
return slug if slug.is_a?(String) && !slug.strip.empty?
|
|
40
|
+
|
|
41
|
+
name.to_s.underscore.tr("/", "_")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def _active_rabbit_cron_monitor_around(&block)
|
|
48
|
+
slug = self.class.active_rabbit_cron_monitor_slug
|
|
49
|
+
if slug.to_s.strip.empty? || !ActiveRabbit::Client.configured?
|
|
50
|
+
block.call
|
|
51
|
+
return
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
ActiveRabbit::Client.capture_cron_check_in(slug, :in_progress)
|
|
55
|
+
begin
|
|
56
|
+
block.call
|
|
57
|
+
rescue StandardError => e
|
|
58
|
+
ActiveRabbit::Client.capture_cron_check_in(slug, :error)
|
|
59
|
+
raise e
|
|
60
|
+
end
|
|
61
|
+
ActiveRabbit::Client.capture_cron_check_in(slug, :ok)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -131,6 +131,9 @@ module ActiveRabbit
|
|
|
131
131
|
structured_stack_trace: structured_frames,
|
|
132
132
|
culprit_frame: culprit_frame,
|
|
133
133
|
|
|
134
|
+
# Error source: backend (Ruby gem) vs frontend (JS SDK)
|
|
135
|
+
source: "backend",
|
|
136
|
+
|
|
134
137
|
# Timing and environment
|
|
135
138
|
occurred_at: Time.now.iso8601(3),
|
|
136
139
|
environment: configuration.environment || 'development',
|
|
@@ -6,6 +6,7 @@ require "json"
|
|
|
6
6
|
require "concurrent"
|
|
7
7
|
require "time"
|
|
8
8
|
require "uri"
|
|
9
|
+
require "securerandom"
|
|
9
10
|
|
|
10
11
|
module ActiveRabbit
|
|
11
12
|
module Client
|
|
@@ -140,6 +141,12 @@ module ActiveRabbit
|
|
|
140
141
|
{ success: false, error: e.message }
|
|
141
142
|
end
|
|
142
143
|
|
|
144
|
+
# Cron / heartbeat check-in (project token + monitor slug). Synchronous, not batched.
|
|
145
|
+
def post_cron_check_in(slug:, status: :ok)
|
|
146
|
+
payload = stringify_and_sanitize({ slug: slug.to_s, status: status.to_s })
|
|
147
|
+
make_request(:post, "/api/v1/cron/check_ins", payload)
|
|
148
|
+
end
|
|
149
|
+
|
|
143
150
|
def flush
|
|
144
151
|
return if @request_queue.empty?
|
|
145
152
|
|
|
@@ -225,12 +232,16 @@ module ActiveRabbit
|
|
|
225
232
|
log(:debug, "[ActiveRabbit] Request headers: X-Project-Token=#{configuration.api_key}, X-Project-ID=#{configuration.project_id}")
|
|
226
233
|
log(:debug, "[ActiveRabbit] Request body: #{safe_preview(data)}")
|
|
227
234
|
|
|
235
|
+
# Generate a stable request ID for dedup — same ID is reused across retries
|
|
236
|
+
# so the server can reject duplicates when we retry after a timeout.
|
|
237
|
+
request_id = SecureRandom.uuid
|
|
238
|
+
|
|
228
239
|
# Retry logic with exponential backoff
|
|
229
240
|
retries = 0
|
|
230
241
|
max_retries = configuration.retry_count
|
|
231
242
|
|
|
232
243
|
begin
|
|
233
|
-
response = perform_request(uri, method, data)
|
|
244
|
+
response = perform_request(uri, method, data, request_id: request_id)
|
|
234
245
|
log(:info, "[ActiveRabbit] Response status: #{response.code}")
|
|
235
246
|
log(:debug, "[ActiveRabbit] Response headers: #{response.to_hash.inspect}")
|
|
236
247
|
log(:debug, "[ActiveRabbit] Response body: #{response.body}")
|
|
@@ -273,7 +284,7 @@ module ActiveRabbit
|
|
|
273
284
|
end
|
|
274
285
|
end
|
|
275
286
|
|
|
276
|
-
def perform_request(uri, method, data)
|
|
287
|
+
def perform_request(uri, method, data, request_id: nil)
|
|
277
288
|
log(:debug, "[ActiveRabbit] Making HTTP request: #{method.upcase} #{uri}")
|
|
278
289
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
279
290
|
|
|
@@ -308,6 +319,7 @@ module ActiveRabbit
|
|
|
308
319
|
request['Accept'] = 'application/json'
|
|
309
320
|
request['User-Agent'] = "ActiveRabbit-Client/#{ActiveRabbit::Client::VERSION}"
|
|
310
321
|
request['X-Project-Token'] = configuration.api_key
|
|
322
|
+
request['X-Request-Id'] = request_id if request_id
|
|
311
323
|
|
|
312
324
|
if configuration.project_id
|
|
313
325
|
request['X-Project-ID'] = configuration.project_id
|
data/lib/active_rabbit/client.rb
CHANGED
|
@@ -24,6 +24,12 @@ rescue LoadError
|
|
|
24
24
|
# Sidekiq not available, skip integration
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# Active Job cron monitors (optional)
|
|
28
|
+
begin
|
|
29
|
+
require_relative "client/cron_monitor" if defined?(ActiveJob)
|
|
30
|
+
rescue LoadError
|
|
31
|
+
end
|
|
32
|
+
|
|
27
33
|
module ActiveRabbit
|
|
28
34
|
module Client
|
|
29
35
|
class Error < StandardError; end
|
|
@@ -144,6 +150,19 @@ module ActiveRabbit
|
|
|
144
150
|
http_client.post_release(payload)
|
|
145
151
|
end
|
|
146
152
|
|
|
153
|
+
# Cron / heartbeat monitor (uses project API token + slug). Status: :ok, :success, :in_progress, :error.
|
|
154
|
+
def capture_cron_check_in(slug, status = :ok)
|
|
155
|
+
return unless configured?
|
|
156
|
+
|
|
157
|
+
s = slug.to_s.strip
|
|
158
|
+
return nil if s.empty?
|
|
159
|
+
|
|
160
|
+
http_client.post_cron_check_in(slug: s, status: status)
|
|
161
|
+
rescue => e
|
|
162
|
+
log(:error, "[ActiveRabbit] capture_cron_check_in failed: #{e.class}: #{e.message}")
|
|
163
|
+
nil
|
|
164
|
+
end
|
|
165
|
+
|
|
147
166
|
def log(level, message)
|
|
148
167
|
cfg = configuration
|
|
149
168
|
return if cfg.nil? || cfg.disable_console_logs
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerabbit-ai
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Shapalov
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: concurrent-ruby
|
|
@@ -90,6 +89,7 @@ files:
|
|
|
90
89
|
- lib/active_rabbit/client/action_mailer_patch.rb
|
|
91
90
|
- lib/active_rabbit/client/active_job_extensions.rb
|
|
92
91
|
- lib/active_rabbit/client/configuration.rb
|
|
92
|
+
- lib/active_rabbit/client/cron_monitor.rb
|
|
93
93
|
- lib/active_rabbit/client/dedupe.rb
|
|
94
94
|
- lib/active_rabbit/client/error_reporter.rb
|
|
95
95
|
- lib/active_rabbit/client/event_processor.rb
|
|
@@ -120,7 +120,6 @@ metadata:
|
|
|
120
120
|
allowed_push_host: https://rubygems.org
|
|
121
121
|
source_code_uri: https://github.com/bugrabbit/active_rabbit-client
|
|
122
122
|
changelog_uri: https://github.com/bugrabbit/active_rabbit-client/blob/main/CHANGELOG.md
|
|
123
|
-
post_install_message:
|
|
124
123
|
rdoc_options: []
|
|
125
124
|
require_paths:
|
|
126
125
|
- lib
|
|
@@ -135,8 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
135
134
|
- !ruby/object:Gem::Version
|
|
136
135
|
version: '0'
|
|
137
136
|
requirements: []
|
|
138
|
-
rubygems_version:
|
|
139
|
-
signing_key:
|
|
137
|
+
rubygems_version: 4.0.7
|
|
140
138
|
specification_version: 4
|
|
141
139
|
summary: Ruby client for ActiveRabbit.ai application monitoring and error tracking
|
|
142
140
|
test_files: []
|