salopulse 0.2.3 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ec917de87f35b31c9d7209c371690972280dd03fff4c45c631e8d997032194b
4
- data.tar.gz: dc7e512fca6d8d777db443fbbd24bba3c79b23609135ba6d4e939255d803813e
3
+ metadata.gz: 5c06e78cb26ed1b47d866b3cf8a0d403373cf9c8beb76ca91292b76505a56753
4
+ data.tar.gz: 71295dd725c6063cfd8bb72ea668ac8160e9e92878fcd46997eed64a8245a1b7
5
5
  SHA512:
6
- metadata.gz: e0c6c894cf599d0ae88616b619773e9ce38415d3fbd92405bf40d12bd40f9c2582fc8644f183fe0a8c02591bb57e824e464447f52c1bdf8ab91120fd8ba4b7d0
7
- data.tar.gz: e772de5379104c022958a411c850162cfa3e8bfbb3578241917b3fe620db6f2e3cf7e6eee284a0e145b019cc6df5affdc45c0c5ba2c518b294012ef195282e7d
6
+ metadata.gz: 4181cb25abebd7be379e294e136a0c33e9c07e8bcaac9d01b1abc7fb14ed5b9927ad1e6adb645e7cb3233ab578b307ba248a8b0dcf135a796c06b470b20d5429
7
+ data.tar.gz: 732c617c949e3f8f7897f229ed0ad5fb82aa7d99828afb6d5b2891e8bee591f86330c5899b3dc14a3e6ff4606d343226ff95e2ad05a37b5c420bc8b9bfc5d4a9
data/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
4
 
5
+ ## [0.3.0] - 2026-06-08
6
+
7
+ ### Added
8
+ - Sidekiq instrumentation with auto-install via Railtie
9
+ - `SidekiqServerMiddleware` opens a `RequestContext` for each job
10
+ (`endpoint: "Foo::BarJob"`, `http_method: "JOB"`, `source: :sidekiq`),
11
+ captures exceptions, emits a `capture_performance` event with the job
12
+ duration, and flushes request-scoped SQL events
13
+ - `SidekiqClientMiddleware` propagates `parent_request_id` from the
14
+ enqueueing request into the job payload so background work can be
15
+ correlated back to the originating HTTP request
16
+ - `Salopulse::RequestContext.start` now accepts `source:`,
17
+ `request_id:`, and `parent_request_id:` keyword arguments
18
+
5
19
  ## [0.2.3] - 2026-06-04
6
20
 
7
21
  First public release of the rewritten Salopulse APM SDK. Bumped past the
@@ -0,0 +1,31 @@
1
+ require_relative "sidekiq_server_middleware"
2
+ require_relative "sidekiq_client_middleware"
3
+
4
+ module Salopulse
5
+ module Instrumentation
6
+ module Sidekiq
7
+ module_function
8
+
9
+ def install!
10
+ return false unless defined?(::Sidekiq)
11
+
12
+ ::Sidekiq.configure_server do |config|
13
+ config.server_middleware do |chain|
14
+ chain.add(Salopulse::Instrumentation::SidekiqServerMiddleware) unless chain.exists?(Salopulse::Instrumentation::SidekiqServerMiddleware)
15
+ end
16
+ config.client_middleware do |chain|
17
+ chain.add(Salopulse::Instrumentation::SidekiqClientMiddleware) unless chain.exists?(Salopulse::Instrumentation::SidekiqClientMiddleware)
18
+ end
19
+ end
20
+
21
+ ::Sidekiq.configure_client do |config|
22
+ config.client_middleware do |chain|
23
+ chain.add(Salopulse::Instrumentation::SidekiqClientMiddleware) unless chain.exists?(Salopulse::Instrumentation::SidekiqClientMiddleware)
24
+ end
25
+ end
26
+
27
+ true
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "../request_context"
2
+
3
+ module Salopulse
4
+ module Instrumentation
5
+ class SidekiqClientMiddleware
6
+ PARENT_REQUEST_ID_KEY = "salopulse_parent_request_id".freeze
7
+
8
+ def call(_worker_class, job, _queue, _redis_pool)
9
+ ctx = Salopulse::RequestContext.current
10
+ job[PARENT_REQUEST_ID_KEY] = ctx[:request_id] if ctx && !job.key?(PARENT_REQUEST_ID_KEY)
11
+ yield
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,57 @@
1
+ require_relative "../request_context"
2
+
3
+ module Salopulse
4
+ module Instrumentation
5
+ class SidekiqServerMiddleware
6
+ PARENT_REQUEST_ID_KEY = "salopulse_parent_request_id".freeze
7
+
8
+ def initialize(client = Salopulse::Client.instance)
9
+ @client = client
10
+ end
11
+
12
+ def call(worker, job, _queue)
13
+ return yield if @client.disabled?
14
+
15
+ endpoint = derive_endpoint(worker, job)
16
+ parent_request_id = job[PARENT_REQUEST_ID_KEY]
17
+ Salopulse::RequestContext.start(
18
+ endpoint: endpoint,
19
+ http_method: "JOB",
20
+ source: :sidekiq,
21
+ parent_request_id: parent_request_id
22
+ )
23
+
24
+ status = 200
25
+ begin
26
+ yield
27
+ rescue Exception => e # rubocop:disable Lint/RescueException
28
+ status = 500
29
+ @client.capture_exception(e)
30
+ raise
31
+ ensure
32
+ begin
33
+ @client.capture_performance(
34
+ endpoint: endpoint,
35
+ http_method: "JOB",
36
+ duration_ms: Salopulse::RequestContext.elapsed_ms,
37
+ status_code: status
38
+ )
39
+ @client.flush_request_scope_events
40
+ rescue StandardError
41
+ # never let SDK errors propagate
42
+ end
43
+ Salopulse::RequestContext.clear
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def derive_endpoint(worker, job)
50
+ wrapped = job["wrapped"] || job["class"]
51
+ return wrapped.to_s if wrapped && !wrapped.to_s.empty?
52
+
53
+ worker.class.name.to_s
54
+ end
55
+ end
56
+ end
57
+ end
@@ -10,6 +10,13 @@ module Salopulse
10
10
  end
11
11
  end
12
12
 
13
+ initializer "salopulse.sidekiq" do
14
+ if defined?(::Sidekiq)
15
+ require_relative "instrumentation/sidekiq"
16
+ Salopulse::Instrumentation::Sidekiq.install!
17
+ end
18
+ end
19
+
13
20
  config.after_initialize do
14
21
  client = Salopulse::Client.instance
15
22
  if client.uninitialized? && ENV["SALOPULSE_DSN"]
@@ -7,11 +7,13 @@ module Salopulse
7
7
 
8
8
  module_function
9
9
 
10
- def start(endpoint:, http_method:)
10
+ def start(endpoint:, http_method:, source: :http, request_id: nil, parent_request_id: nil)
11
11
  Thread.current[KEY] = {
12
- request_id: SecureRandom.uuid,
12
+ request_id: request_id || SecureRandom.uuid,
13
+ parent_request_id: parent_request_id,
13
14
  endpoint: endpoint,
14
15
  http_method: http_method,
16
+ source: source,
15
17
  sql_events: [],
16
18
  sql_fingerprint_counts: Hash.new(0),
17
19
  started_at: monotonic_now,
@@ -1,3 +1,3 @@
1
1
  module Salopulse
2
- VERSION = "0.2.3".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: salopulse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salih İmran Büker
@@ -87,6 +87,9 @@ files:
87
87
  - lib/salopulse/flusher.rb
88
88
  - lib/salopulse/instrumentation/active_record_subscriber.rb
89
89
  - lib/salopulse/instrumentation/rack_middleware.rb
90
+ - lib/salopulse/instrumentation/sidekiq.rb
91
+ - lib/salopulse/instrumentation/sidekiq_client_middleware.rb
92
+ - lib/salopulse/instrumentation/sidekiq_server_middleware.rb
90
93
  - lib/salopulse/local_fingerprint.rb
91
94
  - lib/salopulse/railtie.rb
92
95
  - lib/salopulse/request_context.rb