appsignal 3.9.2-java → 3.10.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 +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
|