appsignal 3.9.2-java → 3.10.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +3138 -0
- data/.rubocop.yml +28 -20
- data/.rubocop_todo.yml +7 -33
- data/CHANGELOG.md +130 -0
- data/README.md +0 -1
- data/Rakefile +80 -65
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +112 -184
- data/ext/base.rb +1 -1
- data/gemfiles/hanami-2.1.gemfile +7 -0
- data/gemfiles/webmachine1.gemfile +5 -4
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +5 -1
- data/lib/appsignal/demo.rb +0 -1
- data/lib/appsignal/environment.rb +11 -2
- data/lib/appsignal/extension/jruby.rb +1 -1
- data/lib/appsignal/helpers/instrumentation.rb +164 -2
- data/lib/appsignal/hooks/active_job.rb +1 -6
- data/lib/appsignal/integrations/grape.rb +19 -47
- data/lib/appsignal/integrations/hanami.rb +8 -7
- data/lib/appsignal/integrations/padrino.rb +51 -52
- data/lib/appsignal/integrations/railtie.rb +0 -3
- data/lib/appsignal/integrations/rake.rb +46 -12
- data/lib/appsignal/integrations/sidekiq.rb +1 -11
- data/lib/appsignal/integrations/sinatra.rb +0 -1
- data/lib/appsignal/integrations/webmachine.rb +15 -9
- data/lib/appsignal/probes/gvl.rb +24 -2
- data/lib/appsignal/probes/sidekiq.rb +1 -1
- data/lib/appsignal/probes.rb +1 -1
- data/lib/appsignal/rack/abstract_middleware.rb +104 -33
- data/lib/appsignal/rack/body_wrapper.rb +143 -0
- data/lib/appsignal/rack/event_handler.rb +12 -3
- data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
- data/lib/appsignal/rack/grape_middleware.rb +40 -0
- data/lib/appsignal/rack/hanami_middleware.rb +2 -12
- data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +14 -57
- data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
- data/lib/appsignal/rack/streaming_listener.rb +13 -59
- data/lib/appsignal/rack.rb +31 -0
- data/lib/appsignal/transaction.rb +50 -8
- data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
- data/lib/appsignal/utils.rb +1 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +36 -33
- data/spec/.rubocop.yml +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
- data/spec/lib/appsignal/cli/install_spec.rb +3 -3
- data/spec/lib/appsignal/config_spec.rb +8 -5
- data/spec/lib/appsignal/demo_spec.rb +38 -41
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
- data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
- data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
- data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
- data/spec/lib/appsignal/hooks/rake_spec.rb +107 -34
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
- data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
- data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
- data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
- data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
- data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
- data/spec/lib/appsignal/integrations/padrino_spec.rb +190 -163
- data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
- data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -3
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -40
- data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
- data/spec/lib/appsignal/probes_spec.rb +7 -4
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +302 -105
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -27
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +44 -139
- data/spec/lib/appsignal/transaction_spec.rb +239 -94
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
- data/spec/lib/appsignal_spec.rb +556 -344
- data/spec/support/helpers/dependency_helper.rb +6 -1
- data/spec/support/helpers/std_streams_helper.rb +1 -1
- data/spec/support/helpers/transaction_helpers.rb +8 -0
- data/spec/support/matchers/transaction.rb +185 -0
- data/spec/support/mocks/dummy_app.rb +20 -0
- data/spec/support/shared_examples/instrument.rb +17 -12
- data/spec/support/testing.rb +18 -9
- metadata +20 -11
- data/.semaphore/semaphore.yml +0 -2347
- data/script/lint_git +0 -22
- data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
- data/spec/support/matchers/be_completed.rb +0 -5
- data/support/check_versions +0 -22
- /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Appsignal
|
4
4
|
module Helpers
|
5
|
-
module Instrumentation
|
5
|
+
module Instrumentation
|
6
6
|
include Appsignal::Utils::StdoutAndLoggerMessage
|
7
7
|
|
8
8
|
# Creates an AppSignal transaction for the given block.
|
@@ -195,6 +195,7 @@ module Appsignal
|
|
195
195
|
# used to send the error.
|
196
196
|
# @return [void]
|
197
197
|
#
|
198
|
+
# @see Transaction#report_error
|
198
199
|
# @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
|
199
200
|
# Exception handling guide
|
200
201
|
# @see https://docs.appsignal.com/ruby/instrumentation/tagging.html
|
@@ -294,6 +295,7 @@ module Appsignal
|
|
294
295
|
# @return [void]
|
295
296
|
#
|
296
297
|
# @see Transaction#set_error
|
298
|
+
# @see Transaction#report_error
|
297
299
|
# @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
|
298
300
|
# Exception handling guide
|
299
301
|
# @since 0.6.6
|
@@ -334,6 +336,74 @@ module Appsignal
|
|
334
336
|
alias :set_exception :set_error
|
335
337
|
alias :add_exception :set_error
|
336
338
|
|
339
|
+
# Report an error.
|
340
|
+
#
|
341
|
+
# If a transaction is currently active, it will report the error on the
|
342
|
+
# current transaction. If no transaction is active, it will report the
|
343
|
+
# error on a new transaction.
|
344
|
+
#
|
345
|
+
# **Note**: If AppSignal is not active, no error is reported.
|
346
|
+
#
|
347
|
+
# **Note**: If the given exception argument is not an Exception subclass,
|
348
|
+
# it will not be reported.
|
349
|
+
#
|
350
|
+
# @example
|
351
|
+
# class SomeController < ApplicationController
|
352
|
+
# def create
|
353
|
+
# # Do something that breaks
|
354
|
+
# rescue => error
|
355
|
+
# Appsignal.report_error(error)
|
356
|
+
# end
|
357
|
+
# end
|
358
|
+
#
|
359
|
+
# @example Add more metadata to transaction
|
360
|
+
# Appsignal.report_error(error) do |transaction|
|
361
|
+
# transaction.set_namespace("my_namespace")
|
362
|
+
# transaction.set_action("my_action_name")
|
363
|
+
# transaction.set_params(:search_query => params[:search_query])
|
364
|
+
# transaction.set_tags(:key => "value")
|
365
|
+
# end
|
366
|
+
#
|
367
|
+
# @param exception [Exception] The error to add to the current
|
368
|
+
# transaction.
|
369
|
+
# @yield [transaction] yields block to allow modification of the
|
370
|
+
# transaction.
|
371
|
+
# @yieldparam transaction [Transaction] yields the AppSignal transaction
|
372
|
+
# used to report the error.
|
373
|
+
# @return [void]
|
374
|
+
#
|
375
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
|
376
|
+
# Exception handling guide
|
377
|
+
# @since 3.10.0
|
378
|
+
def report_error(exception)
|
379
|
+
unless exception.is_a?(Exception)
|
380
|
+
internal_logger.error "Appsignal.report_error: Cannot set error. " \
|
381
|
+
"The given value is not an exception: #{exception.inspect}"
|
382
|
+
return
|
383
|
+
end
|
384
|
+
return unless active?
|
385
|
+
|
386
|
+
has_parent_transaction = Appsignal::Transaction.current?
|
387
|
+
transaction =
|
388
|
+
if has_parent_transaction
|
389
|
+
Appsignal::Transaction.current
|
390
|
+
else
|
391
|
+
Appsignal::Transaction.new(
|
392
|
+
SecureRandom.uuid,
|
393
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
394
|
+
Appsignal::Transaction::GenericRequest.new({})
|
395
|
+
)
|
396
|
+
end
|
397
|
+
|
398
|
+
transaction.set_error(exception)
|
399
|
+
yield transaction if block_given?
|
400
|
+
|
401
|
+
return if has_parent_transaction
|
402
|
+
|
403
|
+
transaction.complete
|
404
|
+
end
|
405
|
+
alias :report_exception :report_error
|
406
|
+
|
337
407
|
# Set a custom action name for the current transaction.
|
338
408
|
#
|
339
409
|
# When using an integration such as the Rails or Sinatra AppSignal will
|
@@ -404,13 +474,44 @@ module Appsignal
|
|
404
474
|
Appsignal::Transaction.current.set_namespace(namespace)
|
405
475
|
end
|
406
476
|
|
477
|
+
# Set custom data on the current transaction.
|
478
|
+
#
|
479
|
+
# Add extra information about the request or background that cannot be
|
480
|
+
# expressed in tags, like nested data structures.
|
481
|
+
#
|
482
|
+
# When this method is called multiple times, it will overwrite the
|
483
|
+
# previously set value.
|
484
|
+
#
|
485
|
+
# @example
|
486
|
+
# Appsignal.set_custom_data(:user => { :locale => "en" })
|
487
|
+
# Appsignal.set_custom_data([
|
488
|
+
# "array with data",
|
489
|
+
# :options => { :verbose => true }
|
490
|
+
# ])
|
491
|
+
#
|
492
|
+
# @since 3.10.0
|
493
|
+
# @see Transaction#set_custom_data
|
494
|
+
# @see https://docs.appsignal.com/guides/custom-data/sample-data.html
|
495
|
+
# Sample data guide
|
496
|
+
# @param data [Hash/Array]
|
497
|
+
# @return [void]
|
498
|
+
def set_custom_data(data)
|
499
|
+
return unless active?
|
500
|
+
return unless Appsignal::Transaction.current?
|
501
|
+
|
502
|
+
transaction = Appsignal::Transaction.current
|
503
|
+
transaction.set_custom_data(data)
|
504
|
+
end
|
505
|
+
|
407
506
|
# Set tags on the current transaction.
|
408
507
|
#
|
409
508
|
# Tags are extra bits of information that are added to transaction and
|
410
509
|
# appear on sample details pages on AppSignal.com.
|
411
510
|
#
|
511
|
+
# When this method is called multiple times, it will merge the tags.
|
512
|
+
#
|
412
513
|
# @example
|
413
|
-
# Appsignal.tag_request(:locale => "en")
|
514
|
+
# Appsignal.tag_request(:locale => "en", :user_id => 1)
|
414
515
|
# Appsignal.tag_request("locale" => "en")
|
415
516
|
# Appsignal.tag_request("user_id" => 1)
|
416
517
|
#
|
@@ -445,6 +546,67 @@ module Appsignal
|
|
445
546
|
transaction.set_tags(tags)
|
446
547
|
end
|
447
548
|
alias :tag_job :tag_request
|
549
|
+
alias :set_tags :tag_request
|
550
|
+
|
551
|
+
# Set parameters on the current transaction.
|
552
|
+
#
|
553
|
+
# Parameters are automatically set by most of our integrations. It should
|
554
|
+
# not be necessary to call this method unless you want to report
|
555
|
+
# different parameters.
|
556
|
+
#
|
557
|
+
# To filter parameters, see our parameter filtering guide.
|
558
|
+
#
|
559
|
+
# When this method is called multiple times, it will overwrite the
|
560
|
+
# previously set value.
|
561
|
+
#
|
562
|
+
# When no parameters are set this way, the transaction will look for
|
563
|
+
# parameters in its request environment.
|
564
|
+
#
|
565
|
+
# A block can be given to this method to defer the fetching and parsing
|
566
|
+
# of the parameters until and only when the transaction is sampled.
|
567
|
+
#
|
568
|
+
# When both the `params` and a block is given to this method, the
|
569
|
+
# `params` argument is leading and the block will _not_ be called.
|
570
|
+
#
|
571
|
+
# @example Set parameters
|
572
|
+
# Appsignal.set_params("param1" => "value1")
|
573
|
+
#
|
574
|
+
# @example Calling `set_params` multiple times will only keep the last call
|
575
|
+
# Appsignal.set_params("param1" => "value1")
|
576
|
+
# Appsignal.set_params("param2" => "value2")
|
577
|
+
# # The parameters are: { "param2" => "value2" }
|
578
|
+
#
|
579
|
+
# @example Calling `set_params` with a block
|
580
|
+
# Appsignal.set_params do
|
581
|
+
# # Some slow code to parse parameters
|
582
|
+
# JSON.parse('{"param1": "value1"}')
|
583
|
+
# end
|
584
|
+
# # The parameters are: { "param1" => "value1" }
|
585
|
+
#
|
586
|
+
# @example Calling `set_params` with a parameter and a block
|
587
|
+
# Appsignal.set_params("argument" => "argument value") do
|
588
|
+
# # Some slow code to parse parameters
|
589
|
+
# JSON.parse('{"param1": "value1"}')
|
590
|
+
# end
|
591
|
+
# # The parameters are: { "argument" => "argument value" }
|
592
|
+
#
|
593
|
+
# @since 3.10.0
|
594
|
+
# @param params [Hash] The parameters to set on the transaction.
|
595
|
+
# @yield This block is called when the transaction is sampled. The block's
|
596
|
+
# return value will become the new parameters.
|
597
|
+
# @see https://docs.appsignal.com/guides/custom-data/sample-data.html
|
598
|
+
# Sample data guide
|
599
|
+
# @see https://docs.appsignal.com/guides/filter-data/filter-parameters.html
|
600
|
+
# Parameter filtering guide
|
601
|
+
# @see Transaction#set_params
|
602
|
+
# @return [void]
|
603
|
+
def set_params(params = nil, &block)
|
604
|
+
return unless active?
|
605
|
+
return unless Appsignal::Transaction.current?
|
606
|
+
|
607
|
+
transaction = Appsignal::Transaction.current
|
608
|
+
transaction.set_params(params, &block)
|
609
|
+
end
|
448
610
|
|
449
611
|
# Add breadcrumbs to the transaction.
|
450
612
|
#
|
@@ -62,12 +62,7 @@ module Appsignal
|
|
62
62
|
end
|
63
63
|
|
64
64
|
if transaction
|
65
|
-
transaction.set_params_if_nil(
|
66
|
-
Appsignal::Utils::HashSanitizer.sanitize(
|
67
|
-
job["arguments"],
|
68
|
-
Appsignal.config[:filter_parameters]
|
69
|
-
)
|
70
|
-
)
|
65
|
+
transaction.set_params_if_nil(job["arguments"])
|
71
66
|
|
72
67
|
transaction_tags = ActiveJobHelpers.transaction_tags_for(job)
|
73
68
|
transaction_tags["active_job_id"] = job["job_id"]
|
@@ -1,55 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "appsignal"
|
4
|
+
require "appsignal/rack/grape_middleware"
|
5
|
+
|
6
|
+
Appsignal.internal_logger.debug("Loading Grape integration")
|
7
|
+
|
3
8
|
module Appsignal
|
4
|
-
# @todo Move to sub-namespace
|
5
9
|
# @api private
|
6
10
|
module Grape
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
request
|
22
|
-
)
|
23
|
-
begin
|
24
|
-
app.call(env)
|
25
|
-
rescue Exception => error # rubocop:disable Lint/RescueException
|
26
|
-
# Do not set error if "grape.skip_appsignal_error" is set to `true`.
|
27
|
-
transaction.set_error(error) unless env["grape.skip_appsignal_error"]
|
28
|
-
raise error
|
29
|
-
ensure
|
30
|
-
request_method = request.request_method.to_s.upcase
|
31
|
-
path = request.path # Path without namespaces
|
32
|
-
endpoint = env["api.endpoint"]
|
33
|
-
|
34
|
-
if endpoint&.options
|
35
|
-
options = endpoint.options
|
36
|
-
request_method = options[:method].first.to_s.upcase
|
37
|
-
klass = options[:for]
|
38
|
-
namespace = endpoint.namespace
|
39
|
-
namespace = "" if namespace == "/"
|
40
|
-
|
41
|
-
path = options[:path].first.to_s
|
42
|
-
path = "/#{path}" if path[0] != "/"
|
43
|
-
path = "#{namespace}#{path}"
|
44
|
-
|
45
|
-
transaction.set_action_if_nil("#{request_method}::#{klass}##{path}")
|
46
|
-
end
|
47
|
-
|
48
|
-
transaction.set_http_or_background_queue_start
|
49
|
-
transaction.set_metadata("path", path)
|
50
|
-
transaction.set_metadata("method", request_method)
|
51
|
-
Appsignal::Transaction.complete_current!
|
52
|
-
end
|
11
|
+
# Alias constants that have moved with a warning message that points to the
|
12
|
+
# place to update the reference.
|
13
|
+
def self.const_missing(name)
|
14
|
+
case name
|
15
|
+
when :Middleware
|
16
|
+
callers = caller
|
17
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
18
|
+
"The constant Appsignal::Grape::Middleware has been deprecated. " \
|
19
|
+
"Please update the constant name to " \
|
20
|
+
"Appsignal::Rack::GrapeMiddleware in the following file to " \
|
21
|
+
"remove this message.\n#{callers.first}"
|
22
|
+
Appsignal::Rack::GrapeMiddleware
|
23
|
+
else
|
24
|
+
super
|
53
25
|
end
|
54
26
|
end
|
55
27
|
end
|
@@ -11,13 +11,14 @@ module Appsignal
|
|
11
11
|
Appsignal.internal_logger.debug("Loading Hanami integration")
|
12
12
|
|
13
13
|
hanami_app_config = ::Hanami.app.config
|
14
|
-
Appsignal.config = Appsignal::Config.new(
|
15
|
-
hanami_app_config.root || Dir.pwd,
|
16
|
-
hanami_app_config.env
|
17
|
-
)
|
18
14
|
|
19
|
-
Appsignal.
|
20
|
-
|
15
|
+
unless Appsignal.active?
|
16
|
+
Appsignal.config = Appsignal::Config.new(
|
17
|
+
hanami_app_config.root || Dir.pwd,
|
18
|
+
hanami_app_config.env
|
19
|
+
)
|
20
|
+
Appsignal.start
|
21
|
+
end
|
21
22
|
|
22
23
|
return unless Appsignal.active?
|
23
24
|
|
@@ -44,4 +45,4 @@ module Appsignal
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
Appsignal::Integrations::HanamiPlugin.init
|
48
|
+
Appsignal::Integrations::HanamiPlugin.init unless Appsignal.testing?
|
@@ -1,79 +1,78 @@
|
|
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
|
-
|
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
|
17
28
|
end
|
18
29
|
end
|
19
30
|
end
|
20
31
|
end
|
21
32
|
|
22
|
-
module Appsignal
|
23
|
-
|
24
|
-
|
33
|
+
module Appsignal
|
34
|
+
module Integrations
|
35
|
+
# @api private
|
36
|
+
module PadrinoIntegration
|
37
|
+
def route!(base = settings, pass_block = nil)
|
38
|
+
return super if !Appsignal.active? || env["sinatra.static_file"]
|
25
39
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
Appsignal.instrument("process_action.padrino") do
|
33
|
-
super
|
40
|
+
begin
|
41
|
+
super
|
42
|
+
ensure
|
43
|
+
transaction = Appsignal::Transaction.current
|
44
|
+
transaction.set_action_if_nil(get_payload_action(request))
|
45
|
+
end
|
34
46
|
end
|
35
|
-
rescue Exception => error # rubocop:disable Lint/RescueException
|
36
|
-
transaction.set_error(error)
|
37
|
-
raise error
|
38
|
-
ensure
|
39
|
-
transaction.set_action_if_nil(get_payload_action(request))
|
40
|
-
transaction.set_metadata("path", request.path)
|
41
|
-
transaction.set_metadata("method", request.request_method)
|
42
|
-
transaction.set_http_or_background_queue_start
|
43
|
-
Appsignal::Transaction.complete_current!
|
44
|
-
end
|
45
|
-
end
|
46
47
|
|
47
|
-
|
48
|
+
private
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
def get_payload_action(request)
|
51
|
+
# Short-circuit is there's no request object to obtain information from
|
52
|
+
return settings.name.to_s unless request
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
# Newer versions expose the action / controller on the request class.
|
55
|
+
# Newer versions also still expose a route_obj so we must prioritize the
|
56
|
+
# action/fullpath methods.
|
57
|
+
# The `request.action` and `request.controller` values are `nil` when a
|
58
|
+
# endpoint is not found, `""` if not specified by the user.
|
59
|
+
controller_name = request.controller if request.respond_to?(:controller)
|
60
|
+
action_name = request.action if request.respond_to?(:action)
|
61
|
+
action_name ||= ""
|
61
62
|
|
62
|
-
|
63
|
+
return "#{settings.name}:#{controller_name}##{action_name}" unless action_name.empty?
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
# Older versions of Padrino work with a route object
|
66
|
+
if request.respond_to?(:route_obj) && request.route_obj
|
67
|
+
return "#{settings.name}:#{request.route_obj.original_path}"
|
68
|
+
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
# Fall back to the application name if we haven't found an action name in
|
71
|
+
# any previous methods.
|
72
|
+
"#{settings.name}#unknown"
|
73
|
+
end
|
74
|
+
end
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
75
|
-
|
76
|
-
|
77
|
-
Padrino.after_load do
|
78
|
-
Appsignal::Integrations::PadrinoPlugin.init
|
79
|
-
end
|
78
|
+
Appsignal::Integrations::PadrinoPlugin.init
|
@@ -2,26 +2,60 @@
|
|
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
|
-
|
18
|
+
Appsignal::Integrations::RakeIntegrationHelper.register_at_exit_hook
|
19
|
+
transaction ||= _appsignal_create_transaction
|
20
|
+
transaction.set_error(error)
|
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
|
12
32
|
|
13
|
-
|
33
|
+
private
|
34
|
+
|
35
|
+
def _appsignal_create_transaction
|
36
|
+
Appsignal::Transaction.create(
|
14
37
|
SecureRandom.uuid,
|
15
38
|
Appsignal::Transaction::BACKGROUND_JOB,
|
16
|
-
Appsignal::Transaction::GenericRequest.new(
|
17
|
-
:params => params
|
18
|
-
)
|
39
|
+
Appsignal::Transaction::GenericRequest.new({})
|
19
40
|
)
|
20
|
-
|
21
|
-
|
22
|
-
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# @api private
|
45
|
+
module RakeIntegrationHelper
|
46
|
+
# Register an `at_exit` hook when a task is executed. This will stop
|
47
|
+
# AppSignal when _all_ tasks are executed and Rake exits.
|
48
|
+
def self.register_at_exit_hook
|
49
|
+
return if @register_at_exit_hook
|
50
|
+
|
51
|
+
Kernel.at_exit(&method(:at_exit_hook))
|
52
|
+
|
53
|
+
@register_at_exit_hook = true
|
54
|
+
end
|
55
|
+
|
56
|
+
# The at_exit hook itself
|
57
|
+
def self.at_exit_hook
|
23
58
|
Appsignal.stop("rake")
|
24
|
-
raise error
|
25
59
|
end
|
26
60
|
end
|
27
61
|
end
|
@@ -83,7 +83,7 @@ module Appsignal
|
|
83
83
|
raise exception
|
84
84
|
ensure
|
85
85
|
if transaction
|
86
|
-
transaction.set_params_if_nil(
|
86
|
+
transaction.set_params_if_nil(parse_arguments(item))
|
87
87
|
transaction.set_http_or_background_queue_start
|
88
88
|
Appsignal::Transaction.complete_current! unless exception
|
89
89
|
|
@@ -115,16 +115,6 @@ module Appsignal
|
|
115
115
|
"#{sidekiq_action_name}#perform"
|
116
116
|
end
|
117
117
|
|
118
|
-
def filtered_arguments(job)
|
119
|
-
arguments = parse_arguments(job)
|
120
|
-
return unless arguments
|
121
|
-
|
122
|
-
Appsignal::Utils::HashSanitizer.sanitize(
|
123
|
-
arguments,
|
124
|
-
Appsignal.config[:filter_parameters]
|
125
|
-
)
|
126
|
-
end
|
127
|
-
|
128
118
|
def formatted_metadata(item)
|
129
119
|
{}.tap do |hash|
|
130
120
|
(item || {}).each do |key, value|
|
@@ -5,20 +5,26 @@ module Appsignal
|
|
5
5
|
# @api private
|
6
6
|
module WebmachineIntegration
|
7
7
|
def run
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
has_parent_transaction = Appsignal::Transaction.current?
|
9
|
+
transaction =
|
10
|
+
if has_parent_transaction
|
11
|
+
Appsignal::Transaction.current
|
12
|
+
else
|
13
|
+
Appsignal::Transaction.create(
|
14
|
+
SecureRandom.uuid,
|
15
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
16
|
+
request
|
17
|
+
)
|
18
|
+
end
|
16
19
|
|
17
20
|
Appsignal.instrument("process_action.webmachine") do
|
18
21
|
super
|
19
22
|
end
|
23
|
+
ensure
|
24
|
+
transaction.set_action_if_nil("#{resource.class.name}##{request.method}")
|
25
|
+
transaction.set_params_if_nil(request.query)
|
20
26
|
|
21
|
-
Appsignal::Transaction.complete_current!
|
27
|
+
Appsignal::Transaction.complete_current! unless has_parent_transaction
|
22
28
|
end
|
23
29
|
|
24
30
|
private
|
data/lib/appsignal/probes/gvl.rb
CHANGED
@@ -25,6 +25,11 @@ module Appsignal
|
|
25
25
|
Appsignal.internal_logger.debug("Initializing GVL probe")
|
26
26
|
@appsignal = appsignal
|
27
27
|
@gvl_tools = gvl_tools
|
28
|
+
|
29
|
+
# Store the process name and ID at initialization time
|
30
|
+
# to avoid picking up changes to the process name at runtime
|
31
|
+
@process_name = File.basename($PROGRAM_NAME).split.first || "[unknown process]"
|
32
|
+
@process_id = Process.pid
|
28
33
|
end
|
29
34
|
|
30
35
|
def call
|
@@ -39,13 +44,30 @@ module Appsignal
|
|
39
44
|
gauge_delta :gvl_global_timer, monotonic_time_ns do |time_delta_ns|
|
40
45
|
if time_delta_ns > 0
|
41
46
|
time_delta_ms = time_delta_ns / 1_000_000
|
42
|
-
|
47
|
+
set_gauges_with_hostname_and_process(
|
48
|
+
"gvl_global_timer",
|
49
|
+
time_delta_ms
|
50
|
+
)
|
43
51
|
end
|
44
52
|
end
|
45
53
|
end
|
46
54
|
|
47
55
|
def probe_waiting_threads
|
48
|
-
|
56
|
+
set_gauges_with_hostname_and_process(
|
57
|
+
"gvl_waiting_threads",
|
58
|
+
@gvl_tools::WaitingThreads.count
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_gauges_with_hostname_and_process(name, value)
|
63
|
+
set_gauge_with_hostname(name, value, {
|
64
|
+
:process_name => @process_name,
|
65
|
+
:process_id => @process_id
|
66
|
+
})
|
67
|
+
|
68
|
+
# Also set the gauge without the process name and ID for
|
69
|
+
# compatibility with existing automated dashboards
|
70
|
+
set_gauge_with_hostname(name, value)
|
49
71
|
end
|
50
72
|
end
|
51
73
|
end
|
@@ -47,7 +47,7 @@ module Appsignal
|
|
47
47
|
# @api private
|
48
48
|
def self.dependencies_present?
|
49
49
|
return true if sidekiq7_and_greater?
|
50
|
-
return unless defined?(::Redis::VERSION) # Sidekiq <= 6
|
50
|
+
return false unless defined?(::Redis::VERSION) # Sidekiq <= 6
|
51
51
|
|
52
52
|
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("3.3.5")
|
53
53
|
end
|