appsignal 3.9.0-java → 3.9.2-java
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 +28 -0
- data/lib/appsignal/helpers/instrumentation.rb +2 -2
- data/lib/appsignal/hooks/active_job.rb +2 -1
- data/lib/appsignal/integrations/action_cable.rb +1 -1
- data/lib/appsignal/integrations/hanami.rb +19 -34
- data/lib/appsignal/integrations/railtie.rb +1 -1
- data/lib/appsignal/integrations/resque.rb +1 -1
- data/lib/appsignal/integrations/sidekiq.rb +2 -4
- data/lib/appsignal/integrations/sinatra.rb +7 -1
- data/lib/appsignal/rack/abstract_middleware.rb +1 -2
- data/lib/appsignal/rack/event_handler.rb +28 -26
- data/lib/appsignal/rack/hanami_middleware.rb +30 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +1 -2
- data/lib/appsignal/transaction.rb +34 -12
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/integrations/hanami_spec.rb +66 -62
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +8 -2
- data/spec/lib/appsignal/rack/event_handler_spec.rb +83 -4
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +50 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +1 -1
- data/spec/lib/appsignal/transaction_spec.rb +87 -4
- data/spec/support/hanami/hanami_app.rb +1 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8242c596a38a842614a47cb94b88a666de659fad2b0c5270dc94747c0ec996c
|
4
|
+
data.tar.gz: e604b5e5acd710f2978579db85b3e274461d4c2c3b68065c9e4541b2a7f4b133
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 682a946ea99d3db5d552ad1c6afa1ed67493c71427dfd55172a03349f6dfdbbaaabf6459123c19598e6c66164293cd845431264e7b6d832b5cd40b870c642f67
|
7
|
+
data.tar.gz: ce4f0c6fdd313528c2b91ad3b0c4c50f3e05bb93b56d2f2a983da830ff4a0dfa8a1184ce6b8cad0c20091b7e1d07dedea4f259f8e528ecc86295b8ea3a375e0b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# AppSignal for Ruby gem Changelog
|
2
2
|
|
3
|
+
## 3.9.2
|
4
|
+
|
5
|
+
_Published on 2024-06-26._
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- Improve instrumentation of Hanami requests by making sure the transaction is always closed.
|
10
|
+
It will also report a `response_status` tag and metric for Hanami requests.
|
11
|
+
|
12
|
+
(patch [e79d4277](https://github.com/appsignal/appsignal-ruby/commit/e79d4277046bf4ec0d32263d06d4975ca8c426ee))
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
|
16
|
+
- Instrument the entire Sinatra request. Instrumenting Sinatra apps using `require "appsignal/integrations/sinatra"` will now report more of the request, if previously other middleware were not instrumented. It will also report the response status with the `response_status` tag and metric. (patch [15b3390b](https://github.com/appsignal/appsignal-ruby/commit/15b3390b5b54cdc7378d69c92d91ec51dab1b0e4))
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
|
20
|
+
- Fix deprecation warnings about `Transacation.params=` usage by updating how we record parameters in our instrumentations. (patch [b65d6674](https://github.com/appsignal/appsignal-ruby/commit/b65d6674c93afbc95e9cecee8c032e6949229aab))
|
21
|
+
- Fix error reporting for requests with an error that use the AppSignal EventHandler. (patch [0e48f19b](https://github.com/appsignal/appsignal-ruby/commit/0e48f19bb9f5c3ead96d21fbacdd5d7f221e2063))
|
22
|
+
|
23
|
+
## 3.9.1
|
24
|
+
|
25
|
+
_Published on 2024-06-24._
|
26
|
+
|
27
|
+
### Fixed
|
28
|
+
|
29
|
+
- [0a253aa1](https://github.com/appsignal/appsignal-ruby/commit/0a253aa16c00cd6172e35a4edaff34f76ac9cbe5) patch - Fix parameter reporting for Rack and Sinatra apps, especially POST payloads.
|
30
|
+
|
3
31
|
## 3.9.0
|
4
32
|
|
5
33
|
_Published on 2024-06-21._
|
@@ -176,7 +176,7 @@ module Appsignal
|
|
176
176
|
#
|
177
177
|
# @example Add more metadata to transaction
|
178
178
|
# Appsignal.send_error(e) do |transaction|
|
179
|
-
# transaction.
|
179
|
+
# transaction.set_params(:search_query => params[:search_query])
|
180
180
|
# transaction.set_action("my_action_name")
|
181
181
|
# transaction.set_tags(:key => "value")
|
182
182
|
# transaction.set_namespace("my_namespace")
|
@@ -273,7 +273,7 @@ module Appsignal
|
|
273
273
|
#
|
274
274
|
# @example Add more metadata to transaction
|
275
275
|
# Appsignal.set_error(e) do |transaction|
|
276
|
-
# transaction.
|
276
|
+
# transaction.set_params(:search_query => params[:search_query])
|
277
277
|
# transaction.set_action("my_action_name")
|
278
278
|
# transaction.set_tags(:key => "value")
|
279
279
|
# transaction.set_namespace("my_namespace")
|
@@ -62,11 +62,12 @@ module Appsignal
|
|
62
62
|
end
|
63
63
|
|
64
64
|
if transaction
|
65
|
-
transaction.
|
65
|
+
transaction.set_params_if_nil(
|
66
66
|
Appsignal::Utils::HashSanitizer.sanitize(
|
67
67
|
job["arguments"],
|
68
68
|
Appsignal.config[:filter_parameters]
|
69
69
|
)
|
70
|
+
)
|
70
71
|
|
71
72
|
transaction_tags = ActiveJobHelpers.transaction_tags_for(job)
|
72
73
|
transaction_tags["active_job_id"] = job["job_id"]
|
@@ -22,7 +22,7 @@ module Appsignal
|
|
22
22
|
transaction.set_error(exception)
|
23
23
|
raise exception
|
24
24
|
ensure
|
25
|
-
transaction.
|
25
|
+
transaction.set_params_if_nil(args.first)
|
26
26
|
transaction.set_action_if_nil("#{self.class}##{args.first["action"]}")
|
27
27
|
transaction.set_metadata("path", request.path)
|
28
28
|
transaction.set_metadata("method", "websocket")
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "appsignal"
|
4
|
+
require "appsignal/rack/hanami_middleware"
|
4
5
|
|
5
6
|
module Appsignal
|
6
7
|
module Integrations
|
8
|
+
# @api private
|
7
9
|
module HanamiPlugin
|
8
10
|
def self.init
|
9
11
|
Appsignal.internal_logger.debug("Loading Hanami integration")
|
@@ -17,44 +19,27 @@ module Appsignal
|
|
17
19
|
Appsignal.start_logger
|
18
20
|
Appsignal.start
|
19
21
|
|
20
|
-
|
22
|
+
return unless Appsignal.active?
|
23
|
+
|
24
|
+
hanami_app_config.middleware.use(
|
25
|
+
::Rack::Events,
|
26
|
+
[Appsignal::Rack::EventHandler.new]
|
27
|
+
)
|
28
|
+
hanami_app_config.middleware.use(Appsignal::Rack::HanamiMiddleware)
|
29
|
+
|
30
|
+
::Hanami::Action.prepend Appsignal::Integrations::HanamiIntegration
|
21
31
|
end
|
22
32
|
end
|
23
|
-
end
|
24
|
-
end
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
transaction = Appsignal::Transaction.create(
|
36
|
-
SecureRandom.uuid,
|
37
|
-
Appsignal::Transaction::HTTP_REQUEST,
|
38
|
-
request
|
39
|
-
)
|
40
|
-
|
41
|
-
begin
|
42
|
-
Appsignal.instrument("process_action.hanami") do
|
43
|
-
super.tap do |response|
|
44
|
-
transaction.set_metadata("status", response.status.to_s)
|
45
|
-
end
|
34
|
+
# @api private
|
35
|
+
module HanamiIntegration
|
36
|
+
def call(env)
|
37
|
+
super
|
38
|
+
ensure
|
39
|
+
transaction = env[::Appsignal::Rack::APPSIGNAL_TRANSACTION]
|
40
|
+
|
41
|
+
transaction&.set_action_if_nil(self.class.name)
|
46
42
|
end
|
47
|
-
rescue Exception => error # rubocop:disable Lint/RescueException
|
48
|
-
transaction.set_error(error)
|
49
|
-
transaction.set_metadata("status", "500")
|
50
|
-
raise error
|
51
|
-
ensure
|
52
|
-
transaction.params = request.params.to_h
|
53
|
-
transaction.set_action_if_nil(self.class.name)
|
54
|
-
transaction.set_metadata("path", request.path)
|
55
|
-
transaction.set_metadata("method", request.request_method)
|
56
|
-
transaction.set_http_or_background_queue_start
|
57
|
-
Appsignal::Transaction.complete_current!
|
58
43
|
end
|
59
44
|
end
|
60
45
|
end
|
@@ -71,7 +71,7 @@ module Appsignal
|
|
71
71
|
transaction.set_action(action_name) if action_name
|
72
72
|
transaction.set_metadata("path", path)
|
73
73
|
transaction.set_metadata("method", method)
|
74
|
-
transaction.params
|
74
|
+
transaction.set_params_if_nil(params)
|
75
75
|
transaction.set_sample_data("custom_data", custom_data) if custom_data
|
76
76
|
|
77
77
|
tags[:severity] = severity
|
@@ -25,7 +25,7 @@ module Appsignal
|
|
25
25
|
ResqueHelpers.arguments(payload),
|
26
26
|
Appsignal.config[:filter_parameters]
|
27
27
|
)
|
28
|
-
transaction.
|
28
|
+
transaction.set_params_if_nil(args)
|
29
29
|
transaction.set_tags("queue" => queue)
|
30
30
|
|
31
31
|
Appsignal::Transaction.complete_current!
|
@@ -45,7 +45,7 @@ module Appsignal
|
|
45
45
|
)
|
46
46
|
transaction.set_action_if_nil("SidekiqInternal")
|
47
47
|
transaction.set_metadata("sidekiq_error", sidekiq_context[:context])
|
48
|
-
transaction.
|
48
|
+
transaction.set_params_if_nil(:jobstr => sidekiq_context[:jobstr])
|
49
49
|
transaction.set_error(exception)
|
50
50
|
end
|
51
51
|
|
@@ -83,9 +83,7 @@ module Appsignal
|
|
83
83
|
raise exception
|
84
84
|
ensure
|
85
85
|
if transaction
|
86
|
-
|
87
|
-
transaction.params = params if params
|
88
|
-
|
86
|
+
transaction.set_params_if_nil(filtered_arguments(item))
|
89
87
|
transaction.set_http_or_background_queue_start
|
90
88
|
Appsignal::Transaction.complete_current! unless exception
|
91
89
|
|
@@ -16,4 +16,10 @@ unless Appsignal.active?
|
|
16
16
|
Appsignal.start
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
if Appsignal.active?
|
20
|
+
::Sinatra::Base.use(
|
21
|
+
::Rack::Events,
|
22
|
+
[Appsignal::Rack::EventHandler.new]
|
23
|
+
)
|
24
|
+
::Sinatra::Base.use(Appsignal::Rack::SinatraBaseInstrumentation)
|
25
|
+
end
|
@@ -91,8 +91,6 @@ module Appsignal
|
|
91
91
|
# Override this method to set metadata before the app is called.
|
92
92
|
# Call `super` to also include the default set metadata.
|
93
93
|
def add_transaction_metadata_before(transaction, request)
|
94
|
-
params = params_for(request)
|
95
|
-
transaction.params = params if params
|
96
94
|
end
|
97
95
|
|
98
96
|
# Add metadata to the transaction based on the request environment.
|
@@ -104,6 +102,7 @@ module Appsignal
|
|
104
102
|
transaction.set_action_if_nil(default_action)
|
105
103
|
transaction.set_metadata("path", request.path)
|
106
104
|
transaction.set_metadata("method", request.request_method)
|
105
|
+
transaction.set_params_if_nil(params_for(request))
|
107
106
|
transaction.set_http_or_background_queue_start
|
108
107
|
end
|
109
108
|
|
@@ -42,22 +42,22 @@ module Appsignal
|
|
42
42
|
|
43
43
|
request.env[RACK_AFTER_REPLY] ||= []
|
44
44
|
request.env[RACK_AFTER_REPLY] << proc do
|
45
|
+
next unless event_handler.request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
46
|
+
|
45
47
|
Appsignal::Rack::EventHandler
|
46
48
|
.safe_execution("Appsignal::Rack::EventHandler's after_reply") do
|
47
|
-
next unless event_handler.request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
48
|
-
|
49
49
|
transaction.finish_event("process_request.rack", "", "")
|
50
50
|
transaction.set_http_or_background_queue_start
|
51
|
-
|
52
|
-
# Make sure the current transaction is always closed when the request
|
53
|
-
# is finished. This is a fallback for in case the `on_finish`
|
54
|
-
# callback is not called. This is supported by servers like Puma and
|
55
|
-
# Unicorn.
|
56
|
-
#
|
57
|
-
# The EventHandler.on_finish callback should be called first, this is
|
58
|
-
# just a fallback if that doesn't get called.
|
59
|
-
Appsignal::Transaction.complete_current!
|
60
51
|
end
|
52
|
+
|
53
|
+
# Make sure the current transaction is always closed when the request
|
54
|
+
# is finished. This is a fallback for in case the `on_finish`
|
55
|
+
# callback is not called. This is supported by servers like Puma and
|
56
|
+
# Unicorn.
|
57
|
+
#
|
58
|
+
# The EventHandler.on_finish callback should be called first, this is
|
59
|
+
# just a fallback if that doesn't get called.
|
60
|
+
Appsignal::Transaction.complete_current!
|
61
61
|
end
|
62
62
|
transaction.start_event
|
63
63
|
end
|
@@ -75,26 +75,28 @@ module Appsignal
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def on_finish(request, response)
|
78
|
-
|
79
|
-
return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
78
|
+
return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
80
79
|
|
81
|
-
|
82
|
-
|
80
|
+
transaction = request.env[APPSIGNAL_TRANSACTION]
|
81
|
+
return unless transaction
|
83
82
|
|
83
|
+
self.class.safe_execution("Appsignal::Rack::EventHandler#on_finish") do
|
84
84
|
transaction.finish_event("process_request.rack", "", "")
|
85
|
-
transaction.set_tags(:response_status => response.status)
|
86
85
|
transaction.set_http_or_background_queue_start
|
87
|
-
|
88
|
-
:response_status
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
Appsignal::Transaction.complete_current!
|
86
|
+
if response
|
87
|
+
transaction.set_tags(:response_status => response.status)
|
88
|
+
Appsignal.increment_counter(
|
89
|
+
:response_status,
|
90
|
+
1,
|
91
|
+
:status => response.status,
|
92
|
+
:namespace => format_namespace(transaction.namespace)
|
93
|
+
)
|
94
|
+
end
|
97
95
|
end
|
96
|
+
|
97
|
+
# Make sure the current transaction is always closed when the request
|
98
|
+
# is finished
|
99
|
+
Appsignal::Transaction.complete_current!
|
98
100
|
end
|
99
101
|
|
100
102
|
private
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Rack
|
5
|
+
# @api private
|
6
|
+
class HanamiMiddleware < AbstractMiddleware
|
7
|
+
def initialize(app, options = {})
|
8
|
+
options[:request_class] ||= ::Hanami::Action::Request
|
9
|
+
options[:params_method] ||= :params
|
10
|
+
options[:instrument_span_name] ||= "process_action.hanami"
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def params_for(request)
|
17
|
+
super&.to_h
|
18
|
+
end
|
19
|
+
|
20
|
+
def request_for(env)
|
21
|
+
params = ::Hanami::Action.params_class.new(env)
|
22
|
+
@request_class.new(
|
23
|
+
:env => env,
|
24
|
+
:params => params,
|
25
|
+
:sessions_enabled => true
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -28,8 +28,6 @@ module Appsignal
|
|
28
28
|
)
|
29
29
|
|
30
30
|
begin
|
31
|
-
transaction.params = fetch_params(request)
|
32
|
-
|
33
31
|
@app.call(env)
|
34
32
|
rescue Exception => error # rubocop:disable Lint/RescueException
|
35
33
|
transaction.set_error(error)
|
@@ -39,6 +37,7 @@ module Appsignal
|
|
39
37
|
if controller
|
40
38
|
transaction.set_action_if_nil("#{controller.class}##{controller.action_name}")
|
41
39
|
end
|
40
|
+
transaction.set_params_if_nil(fetch_params(request))
|
42
41
|
request_id = fetch_request_id(env)
|
43
42
|
transaction.set_tags(:request_id => request_id) if request_id
|
44
43
|
transaction.set_metadata("path", request.path)
|
@@ -76,18 +76,6 @@ module Appsignal
|
|
76
76
|
attr_reader :ext, :transaction_id, :action, :namespace, :request, :paused, :tags, :options,
|
77
77
|
:discarded, :breadcrumbs
|
78
78
|
|
79
|
-
# @!attribute params
|
80
|
-
# Attribute for parameters of the transaction.
|
81
|
-
#
|
82
|
-
# When no parameters are set with {#params=} the parameters it will look
|
83
|
-
# for parameters on the {#request} environment.
|
84
|
-
#
|
85
|
-
# The parameters set using {#params=} are leading over those extracted
|
86
|
-
# from a request's environment.
|
87
|
-
#
|
88
|
-
# @return [Hash]
|
89
|
-
attr_writer :params
|
90
|
-
|
91
79
|
def initialize(transaction_id, namespace, request, options = {})
|
92
80
|
@transaction_id = transaction_id
|
93
81
|
@action = nil
|
@@ -156,6 +144,40 @@ module Appsignal
|
|
156
144
|
request_params
|
157
145
|
end
|
158
146
|
|
147
|
+
# Set parameters on the transaction.
|
148
|
+
#
|
149
|
+
# When no parameters are set this way, the transaction will look for
|
150
|
+
# parameters on the {#request} environment.
|
151
|
+
#
|
152
|
+
# The parameters set using {#set_params} are leading over those extracted
|
153
|
+
# from a request's environment.
|
154
|
+
#
|
155
|
+
# @param given_params [Hash] The parameters to set on the transaction.
|
156
|
+
# @return [void]
|
157
|
+
def set_params(given_params)
|
158
|
+
@params = given_params if given_params
|
159
|
+
end
|
160
|
+
|
161
|
+
# @deprecated Use {#set_params} or {#set_params_if_nil} instead.
|
162
|
+
def params=(given_params)
|
163
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning(
|
164
|
+
"Transaction#params= is deprecated." \
|
165
|
+
"Use Transaction#set_params or #set_params_if_nil instead."
|
166
|
+
)
|
167
|
+
set_params(given_params)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Set parameters on the transaction if not already set
|
171
|
+
#
|
172
|
+
# When no parameters are set this way, the transaction will look for
|
173
|
+
# parameters on the {#request} environment.
|
174
|
+
#
|
175
|
+
# @param given_params [Hash] The parameters to set on the transaction if none are already set.
|
176
|
+
# @return [void]
|
177
|
+
def set_params_if_nil(given_params)
|
178
|
+
set_params(given_params) unless @params
|
179
|
+
end
|
180
|
+
|
159
181
|
# Set tags on the transaction.
|
160
182
|
#
|
161
183
|
# @param given_tags [Hash] Collection of tags.
|
data/lib/appsignal/version.rb
CHANGED
@@ -5,32 +5,62 @@ if DependencyHelper.hanami2_present?
|
|
5
5
|
require "appsignal/integrations/hanami"
|
6
6
|
|
7
7
|
before do
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
uninstall_hanami_middleware
|
9
|
+
end
|
10
|
+
|
11
|
+
def uninstall_hanami_middleware
|
12
|
+
middleware_stack = ::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX]
|
13
|
+
middleware_stack.delete_if do |middleware|
|
14
|
+
middleware.first == Appsignal::Rack::HanamiMiddleware ||
|
15
|
+
middleware.first == Rack::Events
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
describe Appsignal::Integrations::HanamiPlugin do
|
14
20
|
it "starts AppSignal on init" do
|
15
21
|
expect(Appsignal).to receive(:start)
|
22
|
+
expect(Appsignal).to receive(:start_logger)
|
23
|
+
Appsignal::Integrations::HanamiPlugin.init
|
16
24
|
end
|
17
25
|
|
18
|
-
it "
|
19
|
-
|
26
|
+
it "prepends the integration to Hanami::Action" do
|
27
|
+
allow(Appsignal).to receive(:active?).and_return(true)
|
28
|
+
Appsignal::Integrations::HanamiPlugin.init
|
29
|
+
expect(::Hanami::Action.included_modules)
|
30
|
+
.to include(Appsignal::Integrations::HanamiIntegration)
|
20
31
|
end
|
21
32
|
|
22
|
-
it "
|
23
|
-
|
24
|
-
|
33
|
+
it "adds middleware to the Hanami app" do
|
34
|
+
allow(Appsignal).to receive(:active?).and_return(true)
|
35
|
+
Appsignal::Integrations::HanamiPlugin.init
|
36
|
+
|
37
|
+
expect(::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX])
|
38
|
+
.to include(
|
39
|
+
[Rack::Events, [[kind_of(Appsignal::Rack::EventHandler)]], nil],
|
40
|
+
[Appsignal::Rack::HanamiMiddleware, [], nil]
|
41
|
+
)
|
25
42
|
end
|
26
43
|
|
27
44
|
context "when not active" do
|
28
45
|
before { allow(Appsignal).to receive(:active?).and_return(false) }
|
29
46
|
|
30
|
-
it "does not prepend the integration" do
|
47
|
+
it "does not prepend the integration to Hanami::Action" do
|
48
|
+
Appsignal::Integrations::HanamiPlugin.init
|
31
49
|
expect(::Hanami::Action).to_not receive(:prepend)
|
32
50
|
.with(Appsignal::Integrations::HanamiIntegration)
|
33
51
|
end
|
52
|
+
|
53
|
+
it "does not add the middleware to the Hanami app" do
|
54
|
+
Appsignal::Integrations::HanamiPlugin.init
|
55
|
+
|
56
|
+
middleware_stack = ::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX]
|
57
|
+
expect(middleware_stack).to_not include(
|
58
|
+
[Rack::Events, [[kind_of(Appsignal::Rack::EventHandler)]], nil]
|
59
|
+
)
|
60
|
+
expect(middleware_stack).to_not include(
|
61
|
+
[Appsignal::Rack::HanamiMiddleware, [], nil]
|
62
|
+
)
|
63
|
+
end
|
34
64
|
end
|
35
65
|
|
36
66
|
context "when APPSIGNAL_APP_ENV ENV var is provided" do
|
@@ -52,71 +82,45 @@ if DependencyHelper.hanami2_present?
|
|
52
82
|
expect(Appsignal.config.env).to eq("test")
|
53
83
|
end
|
54
84
|
end
|
55
|
-
|
56
|
-
after { Appsignal::Integrations::HanamiPlugin.init }
|
57
85
|
end
|
58
86
|
|
59
|
-
describe
|
60
|
-
let(:
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
87
|
+
describe Appsignal::Integrations::HanamiIntegration do
|
88
|
+
let(:transaction) { http_request_transaction }
|
89
|
+
around { |example| keep_transactions { example.run } }
|
90
|
+
before(:context) { start_agent }
|
91
|
+
before do
|
92
|
+
allow(Appsignal).to receive(:active?).and_return(true)
|
93
|
+
Appsignal::Integrations::HanamiPlugin.init
|
66
94
|
end
|
67
95
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:params=).with(router_params)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "sets the action name" do
|
76
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil)
|
77
|
-
.with("HanamiApp::Actions::Books::Index")
|
78
|
-
end
|
79
|
-
|
80
|
-
it "sets the metadata" do
|
81
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
82
|
-
.with("status", "200")
|
83
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
84
|
-
.with("path", "/books")
|
85
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
86
|
-
.with("method", "GET")
|
87
|
-
end
|
96
|
+
def make_request(env, app: HanamiApp::Actions::Books::Index)
|
97
|
+
action = app.new
|
98
|
+
action.call(env)
|
99
|
+
end
|
88
100
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
101
|
+
describe "#call" do
|
102
|
+
context "without an active transaction" do
|
103
|
+
let(:env) { {} }
|
93
104
|
|
94
|
-
|
95
|
-
|
105
|
+
it "does not set the action name" do
|
106
|
+
make_request(env)
|
96
107
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
it "sets the status to 500" do
|
102
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
103
|
-
.with("status", "500")
|
104
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata).twice
|
108
|
+
expect(transaction.to_h).to include(
|
109
|
+
"action" => nil
|
110
|
+
)
|
105
111
|
end
|
106
112
|
end
|
107
113
|
|
108
|
-
|
109
|
-
Appsignal::
|
110
|
-
|
111
|
-
action = HanamiApp::Actions::Books::Index.new
|
112
|
-
action.call(env)
|
113
|
-
end
|
114
|
+
context "with an active transaction" do
|
115
|
+
let(:env) { { Appsignal::Rack::APPSIGNAL_TRANSACTION => transaction } }
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
+
it "sets action name on the transaction" do
|
118
|
+
make_request(env)
|
117
119
|
|
118
|
-
|
119
|
-
|
120
|
+
expect(transaction.to_h).to include(
|
121
|
+
"action" => "HanamiApp::Actions::Books::Index"
|
122
|
+
)
|
123
|
+
end
|
120
124
|
end
|
121
125
|
end
|
122
126
|
end
|
@@ -50,9 +50,13 @@ if DependencyHelper.sinatra_present?
|
|
50
50
|
context "when AppSignal is not active" do
|
51
51
|
it "does not add the instrumentation middleware to Sinatra::Base" do
|
52
52
|
install_sinatra_integration
|
53
|
-
|
53
|
+
middlewares = Sinatra::Base.middleware.to_a
|
54
|
+
expect(middlewares).to_not include(
|
54
55
|
[Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
|
55
56
|
)
|
57
|
+
expect(middlewares).to_not include(
|
58
|
+
[Rack::Events, [Appsignal::Rack::EventHandler], nil]
|
59
|
+
)
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
@@ -63,7 +67,9 @@ if DependencyHelper.sinatra_present?
|
|
63
67
|
ENV["APPSIGNAL_PUSH_API_KEY"] = "my-key"
|
64
68
|
|
65
69
|
install_sinatra_integration
|
66
|
-
|
70
|
+
middlewares = Sinatra::Base.middleware.to_a
|
71
|
+
expect(middlewares).to include(
|
72
|
+
[Rack::Events, [[Appsignal::Rack::EventHandler]], nil],
|
67
73
|
[Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
|
68
74
|
)
|
69
75
|
end
|
@@ -66,6 +66,30 @@ describe Appsignal::Rack::EventHandler do
|
|
66
66
|
expect(last_transaction.ext.queue_start).to eq(queue_start_time)
|
67
67
|
end
|
68
68
|
|
69
|
+
context "with error inside rack.after_reply handler" do
|
70
|
+
before do
|
71
|
+
on_start
|
72
|
+
# A random spot we can access to raise an error for this test
|
73
|
+
expect(request.env[Appsignal::Rack::APPSIGNAL_TRANSACTION])
|
74
|
+
.to receive(:finish_event)
|
75
|
+
.and_raise(ExampleStandardError, "oh no")
|
76
|
+
callback = request.env[Appsignal::Rack::RACK_AFTER_REPLY].first
|
77
|
+
callback.call
|
78
|
+
end
|
79
|
+
|
80
|
+
it "completes the transaction" do
|
81
|
+
expect(last_transaction).to be_completed
|
82
|
+
end
|
83
|
+
|
84
|
+
it "logs an error" do
|
85
|
+
expect(log).to contains_log(
|
86
|
+
:error,
|
87
|
+
"Error occurred in Appsignal::Rack::EventHandler's after_reply: " \
|
88
|
+
"ExampleStandardError: oh no"
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
69
93
|
it "logs errors from rack.after_reply callbacks" do
|
70
94
|
on_start
|
71
95
|
|
@@ -139,8 +163,8 @@ describe Appsignal::Rack::EventHandler do
|
|
139
163
|
describe "#on_finish" do
|
140
164
|
let(:response) { Rack::Events::BufferedResponse.new(200, {}, ["body"]) }
|
141
165
|
|
142
|
-
def on_finish
|
143
|
-
event_handler_instance.on_finish(
|
166
|
+
def on_finish(given_request = request, given_response = response)
|
167
|
+
event_handler_instance.on_finish(given_request, given_response)
|
144
168
|
end
|
145
169
|
|
146
170
|
it "doesn't do anything without a transaction" do
|
@@ -155,6 +179,7 @@ describe Appsignal::Rack::EventHandler do
|
|
155
179
|
"sample_data" => {},
|
156
180
|
"events" => []
|
157
181
|
)
|
182
|
+
expect(last_transaction).to_not be_completed
|
158
183
|
end
|
159
184
|
|
160
185
|
it "completes the transaction" do
|
@@ -176,6 +201,60 @@ describe Appsignal::Rack::EventHandler do
|
|
176
201
|
expect(last_transaction).to be_completed
|
177
202
|
end
|
178
203
|
|
204
|
+
context "without a response" do
|
205
|
+
it "completes the transaction" do
|
206
|
+
on_start
|
207
|
+
on_finish(request, nil)
|
208
|
+
|
209
|
+
expect(last_transaction.to_h).to include(
|
210
|
+
# The action is not set on purpose, as we can't set a normalized route
|
211
|
+
# It requires the app to set an action name
|
212
|
+
"action" => nil,
|
213
|
+
"sample_data" => hash_including(
|
214
|
+
"environment" => {
|
215
|
+
"REQUEST_METHOD" => "GET",
|
216
|
+
"PATH_INFO" => "/path"
|
217
|
+
}
|
218
|
+
)
|
219
|
+
)
|
220
|
+
expect(last_transaction.ext.queue_start).to eq(queue_start_time)
|
221
|
+
expect(last_transaction).to be_completed
|
222
|
+
end
|
223
|
+
|
224
|
+
it "does not set a response_status tag" do
|
225
|
+
on_start
|
226
|
+
on_finish(request, nil)
|
227
|
+
|
228
|
+
expect(last_transaction.to_h.dig("sample_data", "tags")).to_not have_key("response_status")
|
229
|
+
end
|
230
|
+
|
231
|
+
it "does not report a response_status counter metric" do
|
232
|
+
expect(Appsignal).to_not receive(:increment_counter)
|
233
|
+
.with(:response_status, anything, anything)
|
234
|
+
|
235
|
+
on_start
|
236
|
+
on_finish(request, nil)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context "with error inside on_finish handler" do
|
241
|
+
before do
|
242
|
+
on_start
|
243
|
+
# A random spot we can access to raise an error for this test
|
244
|
+
expect(Appsignal).to receive(:increment_counter).and_raise(ExampleStandardError, "oh no")
|
245
|
+
on_finish
|
246
|
+
end
|
247
|
+
|
248
|
+
it "completes the transaction" do
|
249
|
+
expect(last_transaction).to be_completed
|
250
|
+
end
|
251
|
+
|
252
|
+
it "logs an error" do
|
253
|
+
expect(log).to contains_log(:error,
|
254
|
+
"Error occurred in Appsignal::Rack::EventHandler#on_finish: ExampleStandardError: oh no")
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
179
258
|
context "when the handler is nested in another EventHandler" do
|
180
259
|
it "does not complete the transaction" do
|
181
260
|
on_start
|
@@ -237,8 +316,8 @@ describe Appsignal::Rack::EventHandler do
|
|
237
316
|
end
|
238
317
|
|
239
318
|
it "logs an error in case of an error" do
|
240
|
-
|
241
|
-
|
319
|
+
# A random spot we can access to raise an error for this test
|
320
|
+
expect(Appsignal).to receive(:increment_counter).and_raise(ExampleStandardError, "oh no")
|
242
321
|
|
243
322
|
on_start
|
244
323
|
on_finish
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "appsignal/rack/hanami_middleware"
|
2
|
+
|
3
|
+
if DependencyHelper.hanami2_present?
|
4
|
+
describe Appsignal::Rack::HanamiMiddleware do
|
5
|
+
let(:app) { double(:call => true) }
|
6
|
+
let(:router_params) { { "param1" => "value1", "param2" => "value2" } }
|
7
|
+
let(:env) do
|
8
|
+
Rack::MockRequest.env_for(
|
9
|
+
"/some/path",
|
10
|
+
"router.params" => router_params
|
11
|
+
)
|
12
|
+
end
|
13
|
+
let(:middleware) { Appsignal::Rack::HanamiMiddleware.new(app, {}) }
|
14
|
+
|
15
|
+
before(:context) { start_agent }
|
16
|
+
around { |example| keep_transactions { example.run } }
|
17
|
+
|
18
|
+
def make_request(env)
|
19
|
+
middleware.call(env)
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with params" do
|
23
|
+
it "sets request parameters on the transaction" do
|
24
|
+
make_request(env)
|
25
|
+
|
26
|
+
expect(last_transaction.to_h).to include(
|
27
|
+
"sample_data" => hash_including(
|
28
|
+
"params" => { "param1" => "value1", "param2" => "value2" }
|
29
|
+
)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "reports a process_action.hanami event" do
|
35
|
+
make_request(env)
|
36
|
+
|
37
|
+
expect(last_transaction.to_h).to include(
|
38
|
+
"events" => [
|
39
|
+
hash_including(
|
40
|
+
"body" => "",
|
41
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
42
|
+
"count" => 1,
|
43
|
+
"name" => "process_action.hanami",
|
44
|
+
"title" => ""
|
45
|
+
)
|
46
|
+
]
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -115,7 +115,7 @@ if DependencyHelper.rails_present?
|
|
115
115
|
context "with custom params" do
|
116
116
|
let(:app) do
|
117
117
|
lambda do |env|
|
118
|
-
env[Appsignal::Rack::APPSIGNAL_TRANSACTION].
|
118
|
+
env[Appsignal::Rack::APPSIGNAL_TRANSACTION].set_params("custom_param" => "yes")
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
@@ -328,7 +328,7 @@ describe Appsignal::Transaction do
|
|
328
328
|
|
329
329
|
context "with custom params set on transaction" do
|
330
330
|
before do
|
331
|
-
transaction.
|
331
|
+
transaction.set_params(:foo => "bar")
|
332
332
|
end
|
333
333
|
|
334
334
|
it "returns custom parameters" do
|
@@ -348,9 +348,92 @@ describe Appsignal::Transaction do
|
|
348
348
|
end
|
349
349
|
|
350
350
|
describe "#params=" do
|
351
|
+
around { |example| keep_transactions { example.run } }
|
352
|
+
|
351
353
|
it "sets params on the transaction" do
|
352
|
-
|
353
|
-
|
354
|
+
params = { "foo" => "bar" }
|
355
|
+
silence { transaction.params = params }
|
356
|
+
|
357
|
+
transaction.complete # Sample the data
|
358
|
+
expect(transaction.params).to eq(params)
|
359
|
+
expect(transaction.to_h.dig("sample_data", "params")).to eq(params)
|
360
|
+
end
|
361
|
+
|
362
|
+
it "logs a deprecation warning" do
|
363
|
+
transaction.params = { "foo" => "bar" }
|
364
|
+
|
365
|
+
expect(log_contents(log)).to contains_log(
|
366
|
+
:warn,
|
367
|
+
"Transaction#params= is deprecated." \
|
368
|
+
"Use Transaction#set_params or #set_params_if_nil instead."
|
369
|
+
)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "#set_params" do
|
374
|
+
around { |example| keep_transactions { example.run } }
|
375
|
+
|
376
|
+
context "when the params are set" do
|
377
|
+
it "updates the params on the transaction" do
|
378
|
+
params = { "key" => "value" }
|
379
|
+
transaction.set_params(params)
|
380
|
+
|
381
|
+
transaction.complete # Sample the data
|
382
|
+
expect(transaction.params).to eq(params)
|
383
|
+
expect(transaction.to_h.dig("sample_data", "params")).to eq(params)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
context "when the given params is nil" do
|
388
|
+
it "does not update the params on the transaction" do
|
389
|
+
params = { "key" => "value" }
|
390
|
+
transaction.set_params(params)
|
391
|
+
transaction.set_params(nil)
|
392
|
+
|
393
|
+
transaction.complete # Sample the data
|
394
|
+
expect(transaction.params).to eq(params)
|
395
|
+
expect(transaction.to_h.dig("sample_data", "params")).to eq(params)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
describe "#set_params_if_nil" do
|
401
|
+
around { |example| keep_transactions { example.run } }
|
402
|
+
|
403
|
+
context "when the params are not set" do
|
404
|
+
it "sets the params on the transaction" do
|
405
|
+
params = { "key" => "value" }
|
406
|
+
transaction.set_params_if_nil(params)
|
407
|
+
|
408
|
+
transaction.complete # Sample the data
|
409
|
+
expect(transaction.params).to eq(params)
|
410
|
+
expect(transaction.to_h.dig("sample_data", "params")).to eq(params)
|
411
|
+
end
|
412
|
+
|
413
|
+
context "when the given params is nil" do
|
414
|
+
it "does not update the params on the transaction" do
|
415
|
+
params = { "key" => "value" }
|
416
|
+
transaction.set_params(params)
|
417
|
+
transaction.set_params_if_nil(nil)
|
418
|
+
|
419
|
+
transaction.complete # Sample the data
|
420
|
+
expect(transaction.params).to eq(params)
|
421
|
+
expect(transaction.to_h.dig("sample_data", "params")).to eq(params)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
context "when the params are set" do
|
427
|
+
it "does not update the params on the transaction" do
|
428
|
+
preset_params = { "other" => "params" }
|
429
|
+
params = { "key" => "value" }
|
430
|
+
transaction.set_params(preset_params)
|
431
|
+
transaction.set_params_if_nil(params)
|
432
|
+
|
433
|
+
transaction.complete # Sample the data
|
434
|
+
expect(transaction.params).to eq(preset_params)
|
435
|
+
expect(transaction.to_h.dig("sample_data", "params")).to eq(preset_params)
|
436
|
+
end
|
354
437
|
end
|
355
438
|
end
|
356
439
|
|
@@ -1158,7 +1241,7 @@ describe Appsignal::Transaction do
|
|
1158
1241
|
|
1159
1242
|
context "with custom params" do
|
1160
1243
|
before do
|
1161
|
-
transaction.
|
1244
|
+
transaction.set_params(:foo => "bar", :baz => :bat)
|
1162
1245
|
end
|
1163
1246
|
|
1164
1247
|
it "returns custom params" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.9.
|
4
|
+
version: 3.9.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-06-
|
13
|
+
date: 2024-06-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -288,6 +288,7 @@ files:
|
|
288
288
|
- lib/appsignal/rack/abstract_middleware.rb
|
289
289
|
- lib/appsignal/rack/event_handler.rb
|
290
290
|
- lib/appsignal/rack/generic_instrumentation.rb
|
291
|
+
- lib/appsignal/rack/hanami_middleware.rb
|
291
292
|
- lib/appsignal/rack/rails_instrumentation.rb
|
292
293
|
- lib/appsignal/rack/sinatra_instrumentation.rb
|
293
294
|
- lib/appsignal/rack/streaming_listener.rb
|
@@ -390,6 +391,7 @@ files:
|
|
390
391
|
- spec/lib/appsignal/rack/abstract_middleware_spec.rb
|
391
392
|
- spec/lib/appsignal/rack/event_handler_spec.rb
|
392
393
|
- spec/lib/appsignal/rack/generic_instrumentation_spec.rb
|
394
|
+
- spec/lib/appsignal/rack/hanami_middleware_spec.rb
|
393
395
|
- spec/lib/appsignal/rack/rails_instrumentation_spec.rb
|
394
396
|
- spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb
|
395
397
|
- spec/lib/appsignal/rack/streaming_listener_spec.rb
|