appsignal 3.9.3-java → 3.11.0-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/.github/workflows/ci.yml +22 -19
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +180 -0
- data/Gemfile +1 -0
- data/README.md +0 -1
- data/Rakefile +1 -1
- data/benchmark.rake +99 -42
- data/build_matrix.yml +10 -12
- data/gemfiles/webmachine1.gemfile +5 -4
- data/lib/appsignal/cli/demo.rb +0 -1
- data/lib/appsignal/config.rb +57 -97
- data/lib/appsignal/demo.rb +15 -20
- data/lib/appsignal/environment.rb +6 -1
- data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
- data/lib/appsignal/event_formatter.rb +3 -2
- data/lib/appsignal/helpers/instrumentation.rb +490 -16
- data/lib/appsignal/hooks/action_cable.rb +21 -16
- data/lib/appsignal/hooks/active_job.rb +15 -14
- data/lib/appsignal/hooks/delayed_job.rb +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +3 -63
- data/lib/appsignal/integrations/action_cable.rb +5 -7
- data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
- data/lib/appsignal/integrations/data_mapper.rb +1 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
- data/lib/appsignal/integrations/dry_monitor.rb +1 -0
- data/lib/appsignal/integrations/excon.rb +1 -0
- data/lib/appsignal/integrations/http.rb +1 -0
- data/lib/appsignal/integrations/net_http.rb +1 -0
- data/lib/appsignal/integrations/object.rb +6 -0
- data/lib/appsignal/integrations/padrino.rb +21 -25
- data/lib/appsignal/integrations/que.rb +13 -20
- data/lib/appsignal/integrations/railtie.rb +1 -1
- data/lib/appsignal/integrations/rake.rb +45 -15
- data/lib/appsignal/integrations/redis.rb +1 -0
- data/lib/appsignal/integrations/redis_client.rb +1 -0
- data/lib/appsignal/integrations/resque.rb +2 -5
- data/lib/appsignal/integrations/shoryuken.rb +75 -0
- data/lib/appsignal/integrations/sidekiq.rb +7 -25
- data/lib/appsignal/integrations/unicorn.rb +1 -0
- data/lib/appsignal/integrations/webmachine.rb +12 -9
- data/lib/appsignal/logger.rb +7 -3
- data/lib/appsignal/probes/helpers.rb +1 -0
- data/lib/appsignal/probes/mri.rb +1 -0
- data/lib/appsignal/probes/sidekiq.rb +1 -0
- data/lib/appsignal/probes.rb +3 -0
- data/lib/appsignal/rack/abstract_middleware.rb +67 -24
- data/lib/appsignal/rack/body_wrapper.rb +143 -0
- data/lib/appsignal/rack/event_handler.rb +39 -8
- data/lib/appsignal/rack/generic_instrumentation.rb +6 -4
- data/lib/appsignal/rack/grape_middleware.rb +3 -2
- data/lib/appsignal/rack/hanami_middleware.rb +1 -1
- data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +1 -3
- data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
- data/lib/appsignal/rack/streaming_listener.rb +14 -59
- data/lib/appsignal/rack.rb +60 -0
- data/lib/appsignal/span.rb +1 -0
- data/lib/appsignal/transaction.rb +353 -104
- data/lib/appsignal/utils/data.rb +0 -1
- data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
- data/lib/appsignal/utils/integration_logger.rb +0 -13
- data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
- data/lib/appsignal/utils/json.rb +0 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
- data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
- data/lib/appsignal/utils.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +9 -6
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +139 -43
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
- data/spec/lib/appsignal/hooks/activejob_spec.rb +9 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
- data/spec/lib/appsignal/hooks/rake_spec.rb +100 -17
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
- data/spec/lib/appsignal/integrations/padrino_spec.rb +181 -131
- data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -4
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -2
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -17
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +144 -11
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -17
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +1 -1
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -120
- data/spec/lib/appsignal/rack_spec.rb +63 -0
- data/spec/lib/appsignal/transaction_spec.rb +1675 -953
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
- data/spec/lib/appsignal_spec.rb +517 -13
- data/spec/support/helpers/transaction_helpers.rb +44 -20
- data/spec/support/matchers/transaction.rb +15 -1
- data/spec/support/mocks/dummy_app.rb +1 -1
- data/spec/support/testing.rb +1 -1
- metadata +12 -4
- data/support/check_versions +0 -22
|
@@ -54,25 +54,13 @@ module Appsignal
|
|
|
54
54
|
# we do for Sidekiq.
|
|
55
55
|
#
|
|
56
56
|
# Prefer job_id from provider, instead of ActiveJob's internal ID.
|
|
57
|
-
Appsignal::Transaction.create(
|
|
58
|
-
job["provider_job_id"] || job["job_id"],
|
|
59
|
-
Appsignal::Transaction::BACKGROUND_JOB,
|
|
60
|
-
Appsignal::Transaction::GenericRequest.new({})
|
|
61
|
-
)
|
|
57
|
+
Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
|
|
62
58
|
end
|
|
63
59
|
|
|
64
60
|
if transaction
|
|
65
|
-
transaction.set_params_if_nil(
|
|
66
|
-
Appsignal::Utils::HashSanitizer.sanitize(
|
|
67
|
-
job["arguments"],
|
|
68
|
-
Appsignal.config[:filter_parameters]
|
|
69
|
-
)
|
|
70
|
-
)
|
|
61
|
+
transaction.set_params_if_nil(job["arguments"])
|
|
71
62
|
|
|
72
63
|
transaction_tags = ActiveJobHelpers.transaction_tags_for(job)
|
|
73
|
-
transaction_tags["active_job_id"] = job["job_id"]
|
|
74
|
-
provider_job_id = job["provider_job_id"]
|
|
75
|
-
transaction_tags[:provider_job_id] = provider_job_id if provider_job_id
|
|
76
64
|
transaction.set_tags(transaction_tags)
|
|
77
65
|
|
|
78
66
|
transaction.set_action(ActiveJobHelpers.action_name(job))
|
|
@@ -159,12 +147,25 @@ module Appsignal
|
|
|
159
147
|
|
|
160
148
|
def self.transaction_tags_for(job)
|
|
161
149
|
tags = {}
|
|
150
|
+
|
|
162
151
|
queue = job["queue_name"]
|
|
163
152
|
tags[:queue] = queue if queue
|
|
153
|
+
|
|
164
154
|
priority = job["priority"]
|
|
165
155
|
tags[:priority] = priority if priority
|
|
156
|
+
|
|
166
157
|
executions = job["executions"]
|
|
167
158
|
tags[:executions] = executions.to_i + 1 if executions
|
|
159
|
+
|
|
160
|
+
job_id = job["job_id"]
|
|
161
|
+
tags[:active_job_id] = job_id
|
|
162
|
+
|
|
163
|
+
provider_job_id = job["provider_job_id"]
|
|
164
|
+
tags[:provider_job_id] = provider_job_id if provider_job_id
|
|
165
|
+
|
|
166
|
+
request_id = provider_job_id || job_id
|
|
167
|
+
tags[:request_id] = request_id if request_id
|
|
168
|
+
|
|
168
169
|
tags
|
|
169
170
|
end
|
|
170
171
|
|
|
@@ -14,7 +14,7 @@ module Appsignal
|
|
|
14
14
|
# The DJ plugin is a subclass of Delayed::Plugin, so we can only
|
|
15
15
|
# require this code if we're actually installing.
|
|
16
16
|
require "appsignal/integrations/delayed_job_plugin"
|
|
17
|
-
::Delayed::Worker.plugins << Appsignal::
|
|
17
|
+
::Delayed::Worker.plugins << Appsignal::Integrations::DelayedJobPlugin
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
end
|
|
@@ -3,68 +3,6 @@
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
class Hooks
|
|
5
5
|
# @api private
|
|
6
|
-
class ShoryukenMiddleware
|
|
7
|
-
def call(worker_instance, queue, sqs_msg, body, &block)
|
|
8
|
-
batch = sqs_msg.is_a?(Array)
|
|
9
|
-
attributes =
|
|
10
|
-
if batch
|
|
11
|
-
# We can't instrument batched message separately, the `yield` will
|
|
12
|
-
# perform all the batched messages.
|
|
13
|
-
# To provide somewhat useful metadata, Get first message based on
|
|
14
|
-
# SentTimestamp, and use its attributes as metadata for the
|
|
15
|
-
# transaction. We can't combine them all because then they would
|
|
16
|
-
# overwrite each other and the last message (in an sorted order)
|
|
17
|
-
# would be used as the source of the metadata. With the
|
|
18
|
-
# oldest/first message at least some useful information is stored
|
|
19
|
-
# such as the first received time and the number of retries for the
|
|
20
|
-
# first message. The newer message should have lower values and
|
|
21
|
-
# timestamps in their metadata.
|
|
22
|
-
first_msg = sqs_msg.min do |a, b|
|
|
23
|
-
a.attributes["SentTimestamp"].to_i <=> b.attributes["SentTimestamp"].to_i
|
|
24
|
-
end
|
|
25
|
-
# Add batch => true metadata so people can recognize when a
|
|
26
|
-
# transaction is about a batch of messages.
|
|
27
|
-
first_msg.attributes.merge(:batch => true)
|
|
28
|
-
else
|
|
29
|
-
sqs_msg.attributes.merge(:message_id => sqs_msg.message_id)
|
|
30
|
-
end
|
|
31
|
-
metadata = { :queue => queue }.merge(attributes)
|
|
32
|
-
options = {
|
|
33
|
-
:class => worker_instance.class.name,
|
|
34
|
-
:method => "perform",
|
|
35
|
-
:metadata => metadata
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
args =
|
|
39
|
-
if batch
|
|
40
|
-
bodies = {}
|
|
41
|
-
sqs_msg.each_with_index do |msg, index|
|
|
42
|
-
# Store all separate bodies on a hash with the key being the
|
|
43
|
-
# message_id
|
|
44
|
-
bodies[msg.message_id] = body[index]
|
|
45
|
-
end
|
|
46
|
-
bodies
|
|
47
|
-
else
|
|
48
|
-
case body
|
|
49
|
-
when Hash
|
|
50
|
-
body
|
|
51
|
-
else
|
|
52
|
-
{ :params => body }
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
options[:params] = Appsignal::Utils::HashSanitizer.sanitize(
|
|
56
|
-
args,
|
|
57
|
-
Appsignal.config[:filter_parameters]
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
if attributes.key?("SentTimestamp")
|
|
61
|
-
options[:queue_start] = Time.at(attributes["SentTimestamp"].to_i / 1000)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
Appsignal.monitor_transaction("perform_job.shoryuken", options, &block)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
6
|
class ShoryukenHook < Appsignal::Hooks::Hook
|
|
69
7
|
register :shoryuken
|
|
70
8
|
|
|
@@ -73,9 +11,11 @@ module Appsignal
|
|
|
73
11
|
end
|
|
74
12
|
|
|
75
13
|
def install
|
|
14
|
+
require "appsignal/integrations/shoryuken"
|
|
15
|
+
|
|
76
16
|
::Shoryuken.configure_server do |config|
|
|
77
17
|
config.server_middleware do |chain|
|
|
78
|
-
chain.add Appsignal::
|
|
18
|
+
chain.add Appsignal::Integrations::ShoryukenMiddleware
|
|
79
19
|
end
|
|
80
20
|
end
|
|
81
21
|
end
|
|
@@ -2,19 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
module Integrations
|
|
5
|
+
# @api private
|
|
5
6
|
module ActionCableIntegration
|
|
6
7
|
def perform_action(*args, &block)
|
|
7
8
|
# The request is only the original websocket request
|
|
8
9
|
env = connection.env
|
|
9
10
|
request = ActionDispatch::Request.new(env)
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
request_id = request.request_id || SecureRandom.uuid
|
|
12
|
+
env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||= request_id
|
|
12
13
|
|
|
13
|
-
transaction = Appsignal::Transaction.create(
|
|
14
|
-
env[Appsignal::Hooks::ActionCableHook::REQUEST_ID],
|
|
15
|
-
Appsignal::Transaction::ACTION_CABLE,
|
|
16
|
-
request
|
|
17
|
-
)
|
|
14
|
+
transaction = Appsignal::Transaction.create(Appsignal::Transaction::ACTION_CABLE)
|
|
18
15
|
|
|
19
16
|
begin
|
|
20
17
|
super
|
|
@@ -26,6 +23,7 @@ module Appsignal
|
|
|
26
23
|
transaction.set_action_if_nil("#{self.class}##{args.first["action"]}")
|
|
27
24
|
transaction.set_metadata("path", request.path)
|
|
28
25
|
transaction.set_metadata("method", "websocket")
|
|
26
|
+
transaction.set_tags(:request_id => request_id) if request_id
|
|
29
27
|
Appsignal::Transaction.complete_current!
|
|
30
28
|
end
|
|
31
29
|
end
|
|
@@ -1,47 +1,48 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
module Integrations
|
|
5
|
+
# @api private
|
|
6
|
+
class Capistrano
|
|
7
|
+
def self.tasks(config)
|
|
8
|
+
config.load do # rubocop:disable Metrics/BlockLength
|
|
9
|
+
after "deploy", "appsignal:deploy"
|
|
10
|
+
after "deploy:migrations", "appsignal:deploy"
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
namespace :appsignal do
|
|
13
|
+
task :deploy do
|
|
14
|
+
env = fetch(:appsignal_env,
|
|
15
|
+
fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
|
|
16
|
+
user = fetch(:appsignal_user, ENV["USER"] || ENV.fetch("USERNAME", nil))
|
|
17
|
+
revision = fetch(:appsignal_revision, fetch(:current_revision))
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
appsignal_config = Appsignal::Config.new(
|
|
20
|
+
ENV.fetch("PWD", nil),
|
|
21
|
+
env,
|
|
22
|
+
{},
|
|
23
|
+
Appsignal::Utils::IntegrationLogger.new(StringIO.new)
|
|
24
|
+
).tap do |c|
|
|
25
|
+
fetch(:appsignal_config, {}).each do |key, value|
|
|
26
|
+
c[key] = value
|
|
27
|
+
end
|
|
28
|
+
c.validate
|
|
27
29
|
end
|
|
28
|
-
c.validate
|
|
29
|
-
end
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
if appsignal_config&.active?
|
|
32
|
+
marker_data = {
|
|
33
|
+
:revision => revision,
|
|
34
|
+
:user => user
|
|
35
|
+
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
marker = Marker.new(marker_data, appsignal_config)
|
|
38
|
+
if config.dry_run
|
|
39
|
+
puts "Dry run: AppSignal deploy marker not actually sent."
|
|
40
|
+
else
|
|
41
|
+
marker.transmit
|
|
42
|
+
end
|
|
40
43
|
else
|
|
41
|
-
|
|
44
|
+
puts "Not notifying of deploy, config is not active for environment: #{env}"
|
|
42
45
|
end
|
|
43
|
-
else
|
|
44
|
-
puts "Not notifying of deploy, config is not active for environment: #{env}"
|
|
45
46
|
end
|
|
46
47
|
end
|
|
47
48
|
end
|
|
@@ -51,5 +52,5 @@ module Appsignal
|
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
if ::Capistrano::Configuration.instance
|
|
54
|
-
Appsignal::Capistrano.tasks(::Capistrano::Configuration.instance)
|
|
55
|
+
Appsignal::Integrations::Capistrano.tasks(::Capistrano::Configuration.instance)
|
|
55
56
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
|
-
|
|
4
|
+
module Integrations
|
|
5
5
|
# @api private
|
|
6
6
|
class DelayedJobPlugin < ::Delayed::Plugin
|
|
7
7
|
extend Appsignal::Hooks::Helpers
|
|
@@ -17,52 +17,46 @@ module Appsignal
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def self.invoke_with_instrumentation(job, block)
|
|
20
|
-
|
|
20
|
+
transaction =
|
|
21
|
+
Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
|
|
21
22
|
|
|
23
|
+
Appsignal.instrument("perform_job.delayed_job") do
|
|
24
|
+
block.call(job)
|
|
25
|
+
end
|
|
26
|
+
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
27
|
+
transaction.set_error(error)
|
|
28
|
+
raise
|
|
29
|
+
ensure
|
|
30
|
+
payload = job.payload_object
|
|
22
31
|
if payload.respond_to? :job_data
|
|
23
32
|
# ActiveJob
|
|
24
33
|
job_data = payload.job_data
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
method_name = "perform"
|
|
34
|
+
transaction.set_action_if_nil("#{job_data["job_class"]}#perform")
|
|
35
|
+
transaction.set_params_if_nil(job_data.fetch("arguments", {}))
|
|
28
36
|
else
|
|
29
37
|
# Delayed Job
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
transaction.set_action_if_nil(action_name_from_payload(payload, job.name))
|
|
39
|
+
transaction.set_params_if_nil(extract_value(payload, :args, {}))
|
|
32
40
|
end
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
transaction.set_tags(
|
|
43
|
+
:id => extract_value(job, :id, nil, true),
|
|
44
|
+
:queue => extract_value(job, :queue),
|
|
45
|
+
:priority => extract_value(job, :priority, 0),
|
|
46
|
+
:attempts => extract_value(job, :attempts, 0)
|
|
37
47
|
)
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
:method => method_name,
|
|
43
|
-
:metadata => {
|
|
44
|
-
:id => extract_value(job, :id, nil, true),
|
|
45
|
-
:queue => extract_value(job, :queue),
|
|
46
|
-
:priority => extract_value(job, :priority, 0),
|
|
47
|
-
:attempts => extract_value(job, :attempts, 0)
|
|
48
|
-
},
|
|
49
|
-
:params => params,
|
|
50
|
-
:queue_start => extract_value(job, :run_at)
|
|
51
|
-
) do
|
|
52
|
-
block.call(job)
|
|
53
|
-
end
|
|
49
|
+
transaction.set_queue_start(extract_value(job, :run_at)&.to_i&.* 1_000)
|
|
50
|
+
|
|
51
|
+
Appsignal::Transaction.complete_current!
|
|
54
52
|
end
|
|
55
53
|
|
|
56
|
-
def self.
|
|
54
|
+
def self.action_name_from_payload(payload, default_name)
|
|
57
55
|
# Attempt to find appsignal_name override
|
|
58
56
|
class_and_method_name = extract_value(payload, :appsignal_name, nil)
|
|
59
|
-
return class_and_method_name
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return pound_split if pound_split.length == 2
|
|
63
|
-
|
|
64
|
-
dot_split = default_name.split(".")
|
|
65
|
-
return default_name if dot_split.length == 2
|
|
57
|
+
return class_and_method_name if class_and_method_name.is_a?(String)
|
|
58
|
+
return default_name if default_name.split("#").length == 2
|
|
59
|
+
return default_name if default_name.split(".").length == 2
|
|
66
60
|
|
|
67
61
|
"#{default_name}#perform"
|
|
68
62
|
end
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Appsignal::Environment.report_enabled("object_instrumentation") if defined?(Appsignal)
|
|
4
4
|
|
|
5
5
|
class Object
|
|
6
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html
|
|
7
|
+
# Method instrumentation documentation.
|
|
6
8
|
def self.appsignal_instrument_class_method(method_name, options = {})
|
|
7
9
|
singleton_class.send \
|
|
8
10
|
:alias_method, "appsignal_uninstrumented_#{method_name}", method_name
|
|
@@ -20,6 +22,8 @@ class Object
|
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
|
|
25
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html
|
|
26
|
+
# Method instrumentation documentation.
|
|
23
27
|
def self.appsignal_instrument_method(method_name, options = {})
|
|
24
28
|
alias_method "appsignal_uninstrumented_#{method_name}", method_name
|
|
25
29
|
define_method method_name do |*args, &block|
|
|
@@ -33,12 +37,14 @@ class Object
|
|
|
33
37
|
ruby2_keywords method_name if respond_to?(:ruby2_keywords, true)
|
|
34
38
|
end
|
|
35
39
|
|
|
40
|
+
# @api private
|
|
36
41
|
def self.appsignal_reverse_class_name
|
|
37
42
|
return "AnonymousClass" unless name
|
|
38
43
|
|
|
39
44
|
name.split("::").reverse.join(".")
|
|
40
45
|
end
|
|
41
46
|
|
|
47
|
+
# @api private
|
|
42
48
|
def appsignal_reverse_class_name
|
|
43
49
|
self.class.appsignal_reverse_class_name
|
|
44
50
|
end
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "appsignal"
|
|
4
|
+
require "appsignal/rack/sinatra_instrumentation"
|
|
4
5
|
|
|
5
6
|
module Appsignal
|
|
6
7
|
module Integrations
|
|
7
8
|
# @api private
|
|
8
9
|
module PadrinoPlugin
|
|
9
10
|
def self.init
|
|
10
|
-
|
|
11
|
+
Padrino::Application.prepend Appsignal::Integrations::PadrinoIntegration
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
Padrino.before_load do
|
|
14
|
+
Appsignal.internal_logger.debug("Loading Padrino (#{Padrino::VERSION}) integration")
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
unless Appsignal.active?
|
|
17
|
+
root = Padrino.mounted_root
|
|
18
|
+
Appsignal.config = Appsignal::Config.new(root, Padrino.env)
|
|
19
|
+
Appsignal.start
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
next unless Appsignal.active?
|
|
23
|
+
|
|
24
|
+
Padrino.use ::Rack::Events, [Appsignal::Rack::EventHandler.new]
|
|
25
|
+
Padrino.use Appsignal::Rack::SinatraBaseInstrumentation,
|
|
26
|
+
:instrument_event_name => "process_action.padrino"
|
|
27
|
+
end
|
|
16
28
|
end
|
|
17
29
|
end
|
|
18
30
|
end
|
|
@@ -20,35 +32,23 @@ end
|
|
|
20
32
|
|
|
21
33
|
module Appsignal
|
|
22
34
|
module Integrations
|
|
35
|
+
# @api private
|
|
23
36
|
module PadrinoIntegration
|
|
24
37
|
def route!(base = settings, pass_block = nil)
|
|
25
38
|
return super if !Appsignal.active? || env["sinatra.static_file"]
|
|
26
39
|
|
|
27
|
-
transaction = Appsignal::Transaction.create(
|
|
28
|
-
SecureRandom.uuid,
|
|
29
|
-
Appsignal::Transaction::HTTP_REQUEST,
|
|
30
|
-
request
|
|
31
|
-
)
|
|
32
40
|
begin
|
|
33
|
-
|
|
34
|
-
super
|
|
35
|
-
end
|
|
36
|
-
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
37
|
-
transaction.set_error(error)
|
|
38
|
-
raise error
|
|
41
|
+
super
|
|
39
42
|
ensure
|
|
43
|
+
transaction = Appsignal::Transaction.current
|
|
40
44
|
transaction.set_action_if_nil(get_payload_action(request))
|
|
41
|
-
transaction.set_metadata("path", request.path)
|
|
42
|
-
transaction.set_metadata("method", request.request_method)
|
|
43
|
-
transaction.set_http_or_background_queue_start
|
|
44
|
-
Appsignal::Transaction.complete_current!
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
private
|
|
49
49
|
|
|
50
50
|
def get_payload_action(request)
|
|
51
|
-
# Short-
|
|
51
|
+
# Short-circuit is there's no request object to obtain information from
|
|
52
52
|
return settings.name.to_s unless request
|
|
53
53
|
|
|
54
54
|
# Newer versions expose the action / controller on the request class.
|
|
@@ -75,8 +75,4 @@ module Appsignal
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Padrino.after_load do
|
|
81
|
-
Appsignal::Integrations::PadrinoPlugin.init
|
|
82
|
-
end
|
|
78
|
+
Appsignal::Integrations::PadrinoPlugin.init
|
|
@@ -2,27 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
module Integrations
|
|
5
|
+
# @api private
|
|
5
6
|
module QuePlugin
|
|
6
7
|
def _run(*)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
:metadata => {
|
|
10
|
-
:id => local_attrs[:job_id] || local_attrs[:id],
|
|
11
|
-
:queue => local_attrs[:queue],
|
|
12
|
-
:run_at => local_attrs[:run_at].to_s,
|
|
13
|
-
:priority => local_attrs[:priority],
|
|
14
|
-
:attempts => local_attrs[:error_count].to_i
|
|
15
|
-
},
|
|
16
|
-
:params => local_attrs[:args]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
request = Appsignal::Transaction::GenericRequest.new(env)
|
|
20
|
-
|
|
21
|
-
transaction = Appsignal::Transaction.create(
|
|
22
|
-
SecureRandom.uuid,
|
|
23
|
-
Appsignal::Transaction::BACKGROUND_JOB,
|
|
24
|
-
request
|
|
25
|
-
)
|
|
8
|
+
transaction =
|
|
9
|
+
Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
|
|
26
10
|
|
|
27
11
|
begin
|
|
28
12
|
Appsignal.instrument("perform_job.que") { super }
|
|
@@ -30,7 +14,16 @@ module Appsignal
|
|
|
30
14
|
transaction.set_error(error)
|
|
31
15
|
raise error
|
|
32
16
|
ensure
|
|
33
|
-
|
|
17
|
+
local_attrs = respond_to?(:que_attrs) ? que_attrs : attrs
|
|
18
|
+
transaction.set_action_if_nil("#{local_attrs[:job_class]}#run")
|
|
19
|
+
transaction.set_params_if_nil(local_attrs[:args])
|
|
20
|
+
transaction.set_tags(
|
|
21
|
+
"id" => local_attrs[:job_id] || local_attrs[:id],
|
|
22
|
+
"queue" => local_attrs[:queue],
|
|
23
|
+
"run_at" => local_attrs[:run_at].to_s,
|
|
24
|
+
"priority" => local_attrs[:priority],
|
|
25
|
+
"attempts" => local_attrs[:error_count].to_i
|
|
26
|
+
)
|
|
34
27
|
Appsignal::Transaction.complete_current!
|
|
35
28
|
end
|
|
36
29
|
end
|
|
@@ -69,7 +69,7 @@ module Appsignal
|
|
|
69
69
|
transaction.set_metadata("path", path)
|
|
70
70
|
transaction.set_metadata("method", method)
|
|
71
71
|
transaction.set_params_if_nil(params)
|
|
72
|
-
transaction.
|
|
72
|
+
transaction.set_custom_data(custom_data) if custom_data
|
|
73
73
|
|
|
74
74
|
tags[:severity] = severity
|
|
75
75
|
tags[:source] = source.to_s if source
|
|
@@ -2,26 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
module Integrations
|
|
5
|
+
# @api private
|
|
5
6
|
module RakeIntegration
|
|
6
7
|
def execute(*args)
|
|
7
|
-
|
|
8
|
+
transaction =
|
|
9
|
+
if Appsignal.config[:enable_rake_performance_instrumentation]
|
|
10
|
+
Appsignal::Integrations::RakeIntegrationHelper.register_at_exit_hook
|
|
11
|
+
_appsignal_create_transaction
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Appsignal.instrument "task.rake" do
|
|
15
|
+
super
|
|
16
|
+
end
|
|
8
17
|
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
params = params.to_hash if params.respond_to?(:to_hash)
|
|
12
|
-
|
|
13
|
-
transaction = Appsignal::Transaction.create(
|
|
14
|
-
SecureRandom.uuid,
|
|
15
|
-
Appsignal::Transaction::BACKGROUND_JOB,
|
|
16
|
-
Appsignal::Transaction::GenericRequest.new(
|
|
17
|
-
:params => params
|
|
18
|
-
)
|
|
19
|
-
)
|
|
20
|
-
transaction.set_action(name)
|
|
18
|
+
Appsignal::Integrations::RakeIntegrationHelper.register_at_exit_hook
|
|
19
|
+
transaction ||= _appsignal_create_transaction
|
|
21
20
|
transaction.set_error(error)
|
|
22
|
-
transaction.complete
|
|
23
|
-
Appsignal.stop("rake")
|
|
24
21
|
raise error
|
|
22
|
+
ensure
|
|
23
|
+
if transaction
|
|
24
|
+
# Format given arguments and cast to hash if possible
|
|
25
|
+
params, _ = args
|
|
26
|
+
params = params.to_hash if params.respond_to?(:to_hash)
|
|
27
|
+
transaction.set_params_if_nil(params)
|
|
28
|
+
transaction.set_action(name)
|
|
29
|
+
transaction.complete
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def _appsignal_create_transaction
|
|
36
|
+
Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @api private
|
|
41
|
+
module RakeIntegrationHelper
|
|
42
|
+
# Register an `at_exit` hook when a task is executed. This will stop
|
|
43
|
+
# AppSignal when _all_ tasks are executed and Rake exits.
|
|
44
|
+
def self.register_at_exit_hook
|
|
45
|
+
return if @register_at_exit_hook
|
|
46
|
+
|
|
47
|
+
Kernel.at_exit(&method(:at_exit_hook))
|
|
48
|
+
|
|
49
|
+
@register_at_exit_hook = true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# The at_exit hook itself
|
|
53
|
+
def self.at_exit_hook
|
|
54
|
+
Appsignal.stop("rake")
|
|
25
55
|
end
|
|
26
56
|
end
|
|
27
57
|
end
|