salopulse 0.2.2 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 512fe8f0a9da0a15111a1729565fe2625f2041738742ac2839b4a393b6d1a1ef
4
- data.tar.gz: 2589d8bbbabb05653a35966f31e09a8332be762440bb1bb098e7ed379cd4d020
3
+ metadata.gz: 6ec917de87f35b31c9d7209c371690972280dd03fff4c45c631e8d997032194b
4
+ data.tar.gz: dc7e512fca6d8d777db443fbbd24bba3c79b23609135ba6d4e939255d803813e
5
5
  SHA512:
6
- metadata.gz: 87cbf76171f6b4bd640e753ef5ddcb3e81b6cfcf6174fd0dbb8e029beedfda52c46b78b5ff163f46ee97f9bc798f8bcebc22af6a142bf957c03483cf8d32543a
7
- data.tar.gz: e8cb2ebc978d880e87b51b98f8988dac008729b6863de71b12be5a65ceeeb4d2a0d3e49e66af42e1941597d9294fbc991f0bec591954f72f4e3a4c26895c98c2
6
+ metadata.gz: e0c6c894cf599d0ae88616b619773e9ce38415d3fbd92405bf40d12bd40f9c2582fc8644f183fe0a8c02591bb57e824e464447f52c1bdf8ab91120fd8ba4b7d0
7
+ data.tar.gz: e772de5379104c022958a411c850162cfa3e8bfbb3578241917b3fe620db6f2e3cf7e6eee284a0e145b019cc6df5affdc45c0c5ba2c518b294012ef195282e7d
data/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
4
 
5
- ## [0.2.2] - 2026-06-04
5
+ ## [0.2.3] - 2026-06-04
6
6
 
7
7
  First public release of the rewritten Salopulse APM SDK. Bumped past the
8
8
  legacy `salopulse` 0.1.x line on RubyGems.
data/README.md CHANGED
@@ -70,6 +70,13 @@ SDK aşağıdaki alanları otomatik maskeler (`[FILTERED]`):
70
70
  - Buffer üst sınırlı (`max_buffer_size`); patlayıp uygulamayı çökertmez
71
71
  - Transport hatalarında exponential backoff retry (max 3) — başarısızsa event düşer, uygulamaya hata sızmaz
72
72
 
73
+ ## Teslimat Davranışı
74
+
75
+ - SQL event'leri request içinde hemen POST edilmez; önce request sonunda `flush_request_scope_events` ile kuyruğa alınır. Bu, N+1 tespiti için bilinçli bir tasarım.
76
+ - Kuyruğa alınan event'ler varsayılan olarak anında değil, background flusher tarafından `flush_interval` kadar bekletilip toplu gönderilir. Varsayılan değer `5` saniyedir.
77
+ - Process kapanırken `close` son flush'ı zorlar. Bu yüzden fork'lu sunucularda veya kısa ömürlü process'lerde sorun varsa davranış "ancak kapanışta gidiyor" gibi görünebilir.
78
+ - Daha hızlı görünürlük istiyorsanız `flush_interval` değerini düşürün veya kritik yerlerde `Salopulse.flush` çağırın.
79
+
73
80
  ## Geliştirme
74
81
 
75
82
  ```
@@ -19,11 +19,15 @@ module Salopulse
19
19
  def initialize
20
20
  @initialized = false
21
21
  @mutex = Mutex.new
22
+ @pid = nil
22
23
  end
23
24
 
24
25
  def init(options = {})
25
26
  @mutex.synchronize do
26
- return self if @initialized
27
+ if @initialized
28
+ build_runtime!(reset_buffer: forked_process?) unless runtime_ready?
29
+ return self
30
+ end
27
31
 
28
32
  @configuration = Configuration.new
29
33
  options.each { |k, v| @configuration.public_send("#{k}=", v) if @configuration.respond_to?("#{k}=") }
@@ -31,20 +35,7 @@ module Salopulse
31
35
  return self unless @configuration.enabled
32
36
 
33
37
  @dsn = DSN.new(@configuration.dsn)
34
- @buffer = Buffer.new(max_size: @configuration.max_buffer_size)
35
- @transport = Transport.new(
36
- dsn: @dsn,
37
- sdk_version: Salopulse::VERSION,
38
- logger: @configuration.logger
39
- )
40
- @flusher = Flusher.new(
41
- buffer: @buffer,
42
- transport: @transport,
43
- interval: @configuration.flush_interval,
44
- batch_size: @configuration.flush_batch_size,
45
- logger: @configuration.logger
46
- )
47
- @flusher.start
38
+ build_runtime!(reset_buffer: true)
48
39
 
49
40
  install_at_exit_hook
50
41
 
@@ -179,12 +170,15 @@ module Salopulse
179
170
 
180
171
  def flush(timeout: 5)
181
172
  return 0 if disabled?
173
+ ensure_runtime_ready!
182
174
  @flusher.flush_all(timeout: timeout)
183
175
  end
184
176
 
185
177
  def close
186
178
  return unless @initialized
179
+ ensure_runtime_ready!
187
180
  @flusher&.stop(timeout: 5)
181
+ @pid = nil
188
182
  @initialized = false
189
183
  end
190
184
 
@@ -196,12 +190,14 @@ module Salopulse
196
190
  @transport = nil
197
191
  @flusher = nil
198
192
  @dsn = nil
193
+ @pid = nil
199
194
  @initialized = false
200
195
  end
201
196
 
202
197
  private
203
198
 
204
199
  def enqueue(event)
200
+ return false unless ensure_runtime_ready!
205
201
  return false unless @buffer
206
202
  if @configuration.before_send
207
203
  event = @configuration.before_send.call(event)
@@ -228,6 +224,45 @@ module Salopulse
228
224
  rand < rate
229
225
  end
230
226
 
227
+ def ensure_runtime_ready!
228
+ return false if !@initialized || !@configuration&.enabled
229
+ return true if runtime_ready?
230
+
231
+ @mutex.synchronize do
232
+ return false if !@initialized || !@configuration&.enabled
233
+ return true if runtime_ready?
234
+
235
+ build_runtime!(reset_buffer: forked_process?)
236
+ end
237
+ true
238
+ end
239
+
240
+ def build_runtime!(reset_buffer:)
241
+ @buffer = Buffer.new(max_size: @configuration.max_buffer_size) if reset_buffer || @buffer.nil?
242
+ @transport = Transport.new(
243
+ dsn: @dsn,
244
+ sdk_version: Salopulse::VERSION,
245
+ logger: @configuration.logger
246
+ )
247
+ @flusher = Flusher.new(
248
+ buffer: @buffer,
249
+ transport: @transport,
250
+ interval: @configuration.flush_interval,
251
+ batch_size: @configuration.flush_batch_size,
252
+ logger: @configuration.logger
253
+ )
254
+ @flusher.start
255
+ @pid = Process.pid
256
+ end
257
+
258
+ def runtime_ready?
259
+ @pid == Process.pid && @flusher&.alive?
260
+ end
261
+
262
+ def forked_process?
263
+ !@pid.nil? && @pid != Process.pid
264
+ end
265
+
231
266
  def detect_dialect
232
267
  return "unknown" unless defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
233
268
  adapter = ActiveRecord::Base.connection.adapter_name.to_s.downcase
@@ -49,6 +49,10 @@ module Salopulse
49
49
  @thread&.join(timeout)
50
50
  end
51
51
 
52
+ def alive?
53
+ @thread&.alive? || false
54
+ end
55
+
52
56
  private
53
57
 
54
58
  def sleep_with_interrupt(seconds)
@@ -1,3 +1,3 @@
1
1
  module Salopulse
2
- VERSION = "0.2.2".freeze
2
+ VERSION = "0.2.3".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.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salih İmran Büker
@@ -10,61 +10,61 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: rspec
13
+ name: activesupport
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '3.12'
18
+ version: '7.0'
19
19
  type: :development
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '3.12'
25
+ version: '7.0'
26
26
  - !ruby/object:Gem::Dependency
27
- name: webmock
27
+ name: rake
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '3.18'
32
+ version: '13.0'
33
33
  type: :development
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '3.18'
39
+ version: '13.0'
40
40
  - !ruby/object:Gem::Dependency
41
- name: rake
41
+ name: rspec
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '13.0'
46
+ version: '3.12'
47
47
  type: :development
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '13.0'
53
+ version: '3.12'
54
54
  - !ruby/object:Gem::Dependency
55
- name: activesupport
55
+ name: webmock
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ">="
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '7.0'
60
+ version: '3.18'
61
61
  type: :development
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ">="
65
+ - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '7.0'
67
+ version: '3.18'
68
68
  description: Automatic SQL, error, and HTTP performance telemetry for Ruby applications.
69
69
  Captures ActiveRecord queries, exceptions, and Rack request performance with zero-config
70
70
  setup for Rails.