appsignal 4.6.0 → 4.7.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 +4 -4
- data/CHANGELOG.md +29 -0
- data/CLAUDE.md +15 -0
- data/lib/appsignal/integrations/railtie.rb +15 -6
- data/lib/appsignal/integrations/sidekiq.rb +12 -1
- data/lib/appsignal/loaders/hanami.rb +1 -4
- data/lib/appsignal/loaders/padrino.rb +1 -1
- data/lib/appsignal/loaders/sinatra.rb +1 -1
- data/lib/appsignal/rack/event_handler.rb +21 -3
- data/lib/appsignal/rack/event_middleware.rb +111 -0
- data/lib/appsignal/rack/instrumentation_middleware.rb +2 -2
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +1 -0
- data/sig/appsignal.rbi +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 882fa8b34594a9f3bf529528056c1578707ec0cd45f5ef1563933863e6690bc4
|
4
|
+
data.tar.gz: a0e19b771ec45cd1b6e734e7e04b6f26ca2bb9abc6b713fca7b752ec93f2f427
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0aaa738024f11463a5731dc423891ce7bcc34b124ed5db021b6456ddbf4cd42b735e024c5cfba390aea82f6578d6070f17e7cd03cb70f51f1aa78172c34735aa
|
7
|
+
data.tar.gz: 20c7183bd8fbb5848c469fdd5b2103041fdd09f4e8e45caa81df31e539e4fc76eaf728b0c6de169043c9ede80c91694606fcaa0dd5fad77660a7b47b38a839a1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
# AppSignal for Ruby gem Changelog
|
2
2
|
|
3
|
+
## 4.7.0
|
4
|
+
|
5
|
+
_Published on 2025-08-29._
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- Add Sidekiq worker-level job status metric: `worker_job_count`. This new counter metric's `status` tag will be `processed` for each job that's processed and reports another counter with the `failure` status if the job encountered an error. (minor [fa9859af](https://github.com/appsignal/appsignal-ruby/commit/fa9859af3c82c34201cf68c80858596014fe9c34))
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
- Support streaming bodies. AppSignal's Rack instrumentation now supports streaming bodies in responses, such as those produced by `Async::Cable`. This fixes an issue where AppSignal's Rack instrumentation would cause requests with streaming bodies to crash.
|
14
|
+
|
15
|
+
If you use our Rack instrumentation through a framework that is automatically instrumented by AppSignal, such as Rails, Hanami, Padrino or Sinatra, this fix is applied automatically.
|
16
|
+
|
17
|
+
If your application instruments Rack manually, you must remove the following line from your application's initial setup:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
use Rack::Events, [Appsignal::Rack::EventHandler.new]
|
21
|
+
```
|
22
|
+
|
23
|
+
And replace it with the following line:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
use Appsignal::Rack::EventMiddleware
|
27
|
+
```
|
28
|
+
|
29
|
+
(minor [c94315e3](https://github.com/appsignal/appsignal-ruby/commit/c94315e337801347620826504a24f44ba3ee2b53))
|
30
|
+
- Avoid instrumenting Rails when AppSignal is not active. If AppSignal is configured to start when the Rails application loads, rather than after it has initialised, only add Rails' instrumentation middlewares if AppSignal was actually started. (patch [0239a2c3](https://github.com/appsignal/appsignal-ruby/commit/0239a2c32d0835af00a4659cc7533465ef17f451))
|
31
|
+
|
3
32
|
## 4.6.0
|
4
33
|
|
5
34
|
_Published on 2025-07-29._
|
data/CLAUDE.md
CHANGED
@@ -142,6 +142,21 @@ rake extension:install
|
|
142
142
|
cd ext && rake
|
143
143
|
```
|
144
144
|
|
145
|
+
### Type signatures
|
146
|
+
|
147
|
+
The Ruby gem includes type signatures for better IDE support and static analysis:
|
148
|
+
|
149
|
+
- `sig/appsignal.rbi` - Sorbet type signatures
|
150
|
+
- `sig/appsignal.rbs` - RBS type signatures
|
151
|
+
|
152
|
+
To regenerate type signatures from YARD documentation:
|
153
|
+
|
154
|
+
```bash
|
155
|
+
script/generate_signatures
|
156
|
+
```
|
157
|
+
|
158
|
+
This script uses [sord](https://github.com/AaronC81/sord) to generate both RBI and RBS files from YARD comments in the source code.
|
159
|
+
|
145
160
|
## File organization
|
146
161
|
|
147
162
|
### Configuration files
|
@@ -28,11 +28,19 @@ module Appsignal
|
|
28
28
|
|
29
29
|
def self.on_load(app)
|
30
30
|
load_default_config
|
31
|
-
Appsignal::Integrations::Railtie.add_instrumentation_middleware(app)
|
32
31
|
|
33
|
-
|
32
|
+
Appsignal::Integrations::Railtie.start if app.config.appsignal.start_at == :on_load
|
34
33
|
|
35
|
-
|
34
|
+
# If AppSignal is supposed to start after initialization, we need to add the
|
35
|
+
# instrumentation middleware now, even if AppSignal may not actually start
|
36
|
+
# later, because the middleware stack will be frozen after initialization.
|
37
|
+
#
|
38
|
+
# Otherwise, only add the instrumentation middleware if AppSignal did actually
|
39
|
+
# start before this point, preventing the middleware from being added when
|
40
|
+
# AppSignal is not active.
|
41
|
+
return unless app.config.appsignal.start_at == :after_initialize || Appsignal.started?
|
42
|
+
|
43
|
+
add_instrumentation_middleware(app)
|
36
44
|
end
|
37
45
|
|
38
46
|
def self.after_initialize(app)
|
@@ -52,14 +60,15 @@ module Appsignal
|
|
52
60
|
|
53
61
|
def self.start
|
54
62
|
Appsignal.start
|
55
|
-
|
63
|
+
return unless Appsignal.started?
|
64
|
+
|
65
|
+
initialize_error_reporter
|
56
66
|
end
|
57
67
|
|
58
68
|
def self.add_instrumentation_middleware(app)
|
59
69
|
app.middleware.insert(
|
60
70
|
0,
|
61
|
-
::Rack::
|
62
|
-
[Appsignal::Rack::EventHandler.new]
|
71
|
+
::Appsignal::Rack::EventMiddleware
|
63
72
|
)
|
64
73
|
app.middleware.insert_after(
|
65
74
|
ActionDispatch::DebugExceptions,
|
@@ -66,8 +66,9 @@ module Appsignal
|
|
66
66
|
|
67
67
|
def call(_worker, item, _queue, &block)
|
68
68
|
job_status = nil
|
69
|
+
action_name = formatted_action_name(item)
|
69
70
|
transaction = Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
|
70
|
-
transaction.set_action_if_nil(
|
71
|
+
transaction.set_action_if_nil(action_name)
|
71
72
|
|
72
73
|
formatted_metadata(item).each do |key, value|
|
73
74
|
transaction.set_metadata key, value
|
@@ -93,14 +94,24 @@ module Appsignal
|
|
93
94
|
Appsignal::Transaction.complete_current! unless exception
|
94
95
|
|
95
96
|
queue = item["queue"] || "unknown"
|
97
|
+
|
96
98
|
if job_status
|
97
99
|
increment_counter "queue_job_count", 1,
|
98
100
|
:queue => queue,
|
99
101
|
:status => job_status
|
102
|
+
increment_counter "worker_job_count", 1,
|
103
|
+
:worker => action_name,
|
104
|
+
:queue => queue,
|
105
|
+
:status => job_status
|
100
106
|
end
|
101
107
|
increment_counter "queue_job_count", 1,
|
102
108
|
:queue => queue,
|
103
109
|
:status => :processed
|
110
|
+
increment_counter "worker_job_count", 1,
|
111
|
+
:worker => action_name,
|
112
|
+
:queue => queue,
|
113
|
+
:status => :processed
|
114
|
+
|
104
115
|
end
|
105
116
|
end
|
106
117
|
|
@@ -21,10 +21,7 @@ module Appsignal
|
|
21
21
|
require "appsignal/rack/hanami_middleware"
|
22
22
|
|
23
23
|
hanami_app_config = ::Hanami.app.config
|
24
|
-
hanami_app_config.middleware.use(
|
25
|
-
::Rack::Events,
|
26
|
-
[Appsignal::Rack::EventHandler.new]
|
27
|
-
)
|
24
|
+
hanami_app_config.middleware.use(Appsignal::Rack::EventMiddleware)
|
28
25
|
hanami_app_config.middleware.use(Appsignal::Rack::HanamiMiddleware)
|
29
26
|
|
30
27
|
return unless Gem::Version.new(Hanami::VERSION) < Gem::Version.new("2.2.0")
|
@@ -18,7 +18,7 @@ module Appsignal
|
|
18
18
|
Padrino::Application.prepend(Appsignal::Loaders::PadrinoLoader::PadrinoIntegration)
|
19
19
|
|
20
20
|
Padrino.before_load do
|
21
|
-
Padrino.use
|
21
|
+
Padrino.use Appsignal::Rack::EventMiddleware
|
22
22
|
Padrino.use Appsignal::Rack::SinatraBaseInstrumentation,
|
23
23
|
:instrument_event_name => "process_action.padrino"
|
24
24
|
end
|
@@ -16,7 +16,7 @@ module Appsignal
|
|
16
16
|
def on_start
|
17
17
|
require "appsignal/rack/sinatra_instrumentation"
|
18
18
|
|
19
|
-
::Sinatra::Base.use(
|
19
|
+
::Sinatra::Base.use(Appsignal::Rack::EventMiddleware)
|
20
20
|
::Sinatra::Base.use(Appsignal::Rack::SinatraBaseInstrumentation)
|
21
21
|
end
|
22
22
|
end
|
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
module Appsignal
|
4
4
|
module Rack
|
5
|
-
# Instrumentation
|
5
|
+
# Instrumentation event handler for `Rack::Events`.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
# {
|
7
|
+
# Using this middleware directly with `Rack::Events` is deprecated.
|
8
|
+
# We recommend using {EventMiddleware} instead, which is compatible with
|
9
|
+
# streaming bodies, in combination with the {InstrumentationMiddleware}.
|
9
10
|
#
|
10
11
|
# This middleware will report the response status code as the
|
11
12
|
# `response_status` tag on the sample. It will also report the response
|
@@ -38,10 +39,12 @@ module Appsignal
|
|
38
39
|
|
39
40
|
# @api private
|
40
41
|
attr_reader :id
|
42
|
+
attr_writer :using_appsignal_rack_events_middleware
|
41
43
|
|
42
44
|
# @api private
|
43
45
|
def initialize
|
44
46
|
@id = SecureRandom.uuid
|
47
|
+
@using_appsignal_rack_events_middleware = false
|
45
48
|
end
|
46
49
|
|
47
50
|
# @api private
|
@@ -51,6 +54,8 @@ module Appsignal
|
|
51
54
|
|
52
55
|
# @api private
|
53
56
|
def on_start(request, _response)
|
57
|
+
emit_warning_once
|
58
|
+
|
54
59
|
return unless Appsignal.active?
|
55
60
|
|
56
61
|
event_handler = self
|
@@ -152,6 +157,19 @@ module Appsignal
|
|
152
157
|
namespace
|
153
158
|
end
|
154
159
|
end
|
160
|
+
|
161
|
+
def emit_warning_once
|
162
|
+
return if @using_appsignal_rack_events_middleware
|
163
|
+
|
164
|
+
Appsignal.internal_logger.warn <<~MSG
|
165
|
+
Rack::Events is not compatible with streaming bodies. Using `Appsignal::Rack::EventHandler`#{" "}
|
166
|
+
with `Rack::Events` will break streaming responses in your application and is deprecated.#{" "}
|
167
|
+
To silence this warning, use `Appsignal::Rack::EventMiddleware` instead, which is compatible#{" "}
|
168
|
+
with streaming bodies.#{" "}
|
169
|
+
See https://docs.appsignal.com/ruby/integrations/rack.html for more information.
|
170
|
+
MSG
|
171
|
+
@using_appsignal_rack_events_middleware = true
|
172
|
+
end
|
155
173
|
end
|
156
174
|
end
|
157
175
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Rack
|
5
|
+
# Modified version of the {::Rack::Events} instrumentation
|
6
|
+
# middleware.
|
7
|
+
#
|
8
|
+
# We recommend using this instead of {::Rack::Events}, as it
|
9
|
+
# is compatible with streaming bodies.
|
10
|
+
#
|
11
|
+
# We do not recommend using this middleware directly, instead
|
12
|
+
# recommending the use of {EventMiddleware}, which is a
|
13
|
+
# convenience wrapper around this middleware that includes
|
14
|
+
# AppSignal's {EventHandler}.
|
15
|
+
#
|
16
|
+
# See the original implementation at:
|
17
|
+
# https://github.com/rack/rack/blob/8d3d7857fcd9e5df057a6c22458bab35b3a19c12/lib/rack/events.rb
|
18
|
+
class Events < ::Rack::Events
|
19
|
+
# A stub for {::Rack::Events::EventedBodyProxy}. It
|
20
|
+
# allows the same initialization arguments, but
|
21
|
+
# otherwise behaves identically to {::Rack::BodyProxy}.
|
22
|
+
#
|
23
|
+
# It does not implement `#each`, fixing an issue
|
24
|
+
# where the evented body proxy would break
|
25
|
+
# streaming responses by always responding to `#each`
|
26
|
+
# even if the proxied body did not implement it.
|
27
|
+
#
|
28
|
+
# Because it ignores the handlers passed to it and
|
29
|
+
# behaves like a normal body proxy, the `on_send`
|
30
|
+
# event on the handlers is never called.
|
31
|
+
class EventedBodyProxy < ::Rack::BodyProxy
|
32
|
+
def initialize(body, _request, _response, _handlers, &block)
|
33
|
+
super(body, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Notifies the AppSignal event handler that it's being
|
38
|
+
# used with the modified middleware, suppressing a
|
39
|
+
# deprecation warning.
|
40
|
+
def initialize(app, handlers = [])
|
41
|
+
super
|
42
|
+
handlers.each do |handler|
|
43
|
+
if handler.respond_to?(:using_appsignal_rack_events_middleware=)
|
44
|
+
handler.using_appsignal_rack_events_middleware = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# The `call` method, exactly as implemented by {::Rack::Events},
|
50
|
+
# but redefined here so that it uses our {EventedBodyProxy}
|
51
|
+
# instead of the original {::Rack::Events::EventedBodyProxy}.
|
52
|
+
#
|
53
|
+
# This fixes streaming bodies, but it also means that the
|
54
|
+
# `on_send` event on the handlers is never called.
|
55
|
+
#
|
56
|
+
# See the original implementation at:
|
57
|
+
# https://github.com/rack/rack/blob/8d3d7857fcd9e5df057a6c22458bab35b3a19c12/lib/rack/events.rb#L111-L129
|
58
|
+
def call(env)
|
59
|
+
request = make_request env
|
60
|
+
on_start request, nil
|
61
|
+
|
62
|
+
begin
|
63
|
+
status, headers, body = @app.call request.env
|
64
|
+
response = make_response status, headers, body
|
65
|
+
on_commit request, response
|
66
|
+
rescue StandardError => e
|
67
|
+
on_error request, response, e
|
68
|
+
on_finish request, response
|
69
|
+
raise
|
70
|
+
end
|
71
|
+
|
72
|
+
body = EventedBodyProxy.new(body, request, response, @handlers) do
|
73
|
+
on_finish request, response
|
74
|
+
end
|
75
|
+
[response.status, response.headers, body]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Instrumentation middleware using Rack's Events module.
|
80
|
+
#
|
81
|
+
# A convenience wrapper around our {Events} middleware,
|
82
|
+
# modified to be compatible with streaming bodies,
|
83
|
+
# that automatically includes AppSignal's {EventHandler}.
|
84
|
+
#
|
85
|
+
# We recommend using this in combination with the
|
86
|
+
# {InstrumentationMiddleware}.
|
87
|
+
#
|
88
|
+
# This middleware will report the response status code as the
|
89
|
+
# `response_status` tag on the sample. It will also report the response
|
90
|
+
# status as the `response_status` metric.
|
91
|
+
#
|
92
|
+
# This middleware will ensure the AppSignal transaction is always completed
|
93
|
+
# for every request.
|
94
|
+
#
|
95
|
+
# @example Add EventMiddleware to a Rack app
|
96
|
+
# # Add this middleware as the first middleware of an app
|
97
|
+
# use Appsignal::Rack::EventMiddleware
|
98
|
+
#
|
99
|
+
# # Then add the InstrumentationMiddleware
|
100
|
+
# use Appsignal::Rack::InstrumentationMiddleware
|
101
|
+
#
|
102
|
+
# @see https://docs.appsignal.com/ruby/integrations/rack.html
|
103
|
+
# Rack integration documentation.
|
104
|
+
# @api public
|
105
|
+
class EventMiddleware < Events
|
106
|
+
def initialize(app)
|
107
|
+
super(app, [Appsignal::Rack::EventHandler.new])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -27,8 +27,8 @@ module Appsignal
|
|
27
27
|
# require "appsignal"
|
28
28
|
# # Configure and start AppSignal
|
29
29
|
#
|
30
|
-
# # Add the
|
31
|
-
# use
|
30
|
+
# # Add the EventMiddleware first
|
31
|
+
# use Appsignal::Rack::EventMiddleware
|
32
32
|
# # Add the instrumentation middleware second
|
33
33
|
# use Appsignal::Rack::InstrumentationMiddleware
|
34
34
|
#
|
data/lib/appsignal/version.rb
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -643,6 +643,7 @@ require "appsignal/rack/body_wrapper"
|
|
643
643
|
require "appsignal/rack/abstract_middleware"
|
644
644
|
require "appsignal/rack/instrumentation_middleware"
|
645
645
|
require "appsignal/rack/event_handler"
|
646
|
+
require "appsignal/rack/event_middleware"
|
646
647
|
require "appsignal/integrations/railtie" if defined?(::Rails)
|
647
648
|
require "appsignal/transaction"
|
648
649
|
require "appsignal/version"
|
data/sig/appsignal.rbi
CHANGED
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
8
8
|
- Thijs Cadier
|
9
9
|
- Tom de Bruijn
|
10
|
+
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2025-
|
13
|
+
date: 2025-08-29 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: logger
|
@@ -279,6 +280,7 @@ files:
|
|
279
280
|
- lib/appsignal/rack/abstract_middleware.rb
|
280
281
|
- lib/appsignal/rack/body_wrapper.rb
|
281
282
|
- lib/appsignal/rack/event_handler.rb
|
283
|
+
- lib/appsignal/rack/event_middleware.rb
|
282
284
|
- lib/appsignal/rack/grape_middleware.rb
|
283
285
|
- lib/appsignal/rack/hanami_middleware.rb
|
284
286
|
- lib/appsignal/rack/instrumentation_middleware.rb
|
@@ -317,6 +319,7 @@ metadata:
|
|
317
319
|
documentation_uri: https://docs.appsignal.com/ruby/
|
318
320
|
homepage_uri: https://docs.appsignal.com/ruby/
|
319
321
|
source_code_uri: https://github.com/appsignal/appsignal-ruby
|
322
|
+
post_install_message:
|
320
323
|
rdoc_options: []
|
321
324
|
require_paths:
|
322
325
|
- lib
|
@@ -332,7 +335,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
332
335
|
- !ruby/object:Gem::Version
|
333
336
|
version: '0'
|
334
337
|
requirements: []
|
335
|
-
rubygems_version: 3.
|
338
|
+
rubygems_version: 3.3.7
|
339
|
+
signing_key:
|
336
340
|
specification_version: 4
|
337
341
|
summary: Logs performance and exception data from your app to appsignal.com
|
338
342
|
test_files: []
|