appsignal 2.5.0.alpha.1-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 +7 -0
- data/.gitignore +33 -0
- data/.rspec +4 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +124 -0
- data/.travis.yml +72 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +639 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +264 -0
- data/Rakefile +214 -0
- data/appsignal.gemspec +42 -0
- data/benchmark.rake +77 -0
- data/bin/appsignal +13 -0
- data/ext/Rakefile +27 -0
- data/ext/agent.yml +64 -0
- data/ext/appsignal_extension.c +692 -0
- data/ext/base.rb +79 -0
- data/ext/extconf.rb +35 -0
- data/gemfiles/capistrano2.gemfile +7 -0
- data/gemfiles/capistrano3.gemfile +7 -0
- data/gemfiles/grape.gemfile +7 -0
- data/gemfiles/no_dependencies.gemfile +5 -0
- data/gemfiles/padrino.gemfile +7 -0
- data/gemfiles/que.gemfile +5 -0
- data/gemfiles/rails-3.2.gemfile +6 -0
- data/gemfiles/rails-4.0.gemfile +6 -0
- data/gemfiles/rails-4.1.gemfile +6 -0
- data/gemfiles/rails-4.2.gemfile +10 -0
- data/gemfiles/rails-5.0.gemfile +5 -0
- data/gemfiles/rails-5.1.gemfile +5 -0
- data/gemfiles/resque.gemfile +12 -0
- data/gemfiles/sequel-435.gemfile +11 -0
- data/gemfiles/sequel.gemfile +11 -0
- data/gemfiles/sinatra.gemfile +6 -0
- data/gemfiles/webmachine.gemfile +5 -0
- data/lib/appsignal.rb +804 -0
- data/lib/appsignal/auth_check.rb +65 -0
- data/lib/appsignal/capistrano.rb +10 -0
- data/lib/appsignal/cli.rb +108 -0
- data/lib/appsignal/cli/demo.rb +63 -0
- data/lib/appsignal/cli/diagnose.rb +500 -0
- data/lib/appsignal/cli/helpers.rb +72 -0
- data/lib/appsignal/cli/install.rb +277 -0
- data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
- data/lib/appsignal/config.rb +287 -0
- data/lib/appsignal/demo.rb +107 -0
- data/lib/appsignal/event_formatter.rb +74 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
- data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
- data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
- data/lib/appsignal/extension.rb +63 -0
- data/lib/appsignal/extension/jruby.rb +460 -0
- data/lib/appsignal/garbage_collection_profiler.rb +48 -0
- data/lib/appsignal/hooks.rb +105 -0
- data/lib/appsignal/hooks/action_cable.rb +113 -0
- data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
- data/lib/appsignal/hooks/celluloid.rb +30 -0
- data/lib/appsignal/hooks/data_mapper.rb +18 -0
- data/lib/appsignal/hooks/delayed_job.rb +19 -0
- data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
- data/lib/appsignal/hooks/net_http.rb +29 -0
- data/lib/appsignal/hooks/passenger.rb +22 -0
- data/lib/appsignal/hooks/puma.rb +35 -0
- data/lib/appsignal/hooks/que.rb +21 -0
- data/lib/appsignal/hooks/rake.rb +39 -0
- data/lib/appsignal/hooks/redis.rb +30 -0
- data/lib/appsignal/hooks/sequel.rb +60 -0
- data/lib/appsignal/hooks/shoryuken.rb +43 -0
- data/lib/appsignal/hooks/sidekiq.rb +144 -0
- data/lib/appsignal/hooks/unicorn.rb +40 -0
- data/lib/appsignal/hooks/webmachine.rb +23 -0
- data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
- data/lib/appsignal/integrations/data_mapper.rb +33 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
- data/lib/appsignal/integrations/grape.rb +53 -0
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
- data/lib/appsignal/integrations/object.rb +35 -0
- data/lib/appsignal/integrations/padrino.rb +84 -0
- data/lib/appsignal/integrations/que.rb +43 -0
- data/lib/appsignal/integrations/railtie.rb +41 -0
- data/lib/appsignal/integrations/rake.rb +2 -0
- data/lib/appsignal/integrations/resque.rb +20 -0
- data/lib/appsignal/integrations/resque_active_job.rb +30 -0
- data/lib/appsignal/integrations/sinatra.rb +17 -0
- data/lib/appsignal/integrations/webmachine.rb +38 -0
- data/lib/appsignal/js_exception_transaction.rb +54 -0
- data/lib/appsignal/marker.rb +63 -0
- data/lib/appsignal/minutely.rb +42 -0
- data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
- data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
- data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
- data/lib/appsignal/rack/streaming_listener.rb +73 -0
- data/lib/appsignal/system.rb +81 -0
- data/lib/appsignal/transaction.rb +498 -0
- data/lib/appsignal/transmitter.rb +107 -0
- data/lib/appsignal/utils.rb +127 -0
- data/lib/appsignal/utils/params_sanitizer.rb +59 -0
- data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
- data/lib/appsignal/version.rb +3 -0
- data/lib/sequel/extensions/appsignal_integration.rb +3 -0
- data/resources/appsignal.yml.erb +39 -0
- data/resources/cacert.pem +3866 -0
- data/spec/.rubocop.yml +7 -0
- data/spec/lib/appsignal/auth_check_spec.rb +80 -0
- data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
- data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
- data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
- data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
- data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
- data/spec/lib/appsignal/cli/install_spec.rb +632 -0
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
- data/spec/lib/appsignal/cli_spec.rb +56 -0
- data/spec/lib/appsignal/config_spec.rb +637 -0
- data/spec/lib/appsignal/demo_spec.rb +87 -0
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
- data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
- data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
- data/spec/lib/appsignal/extension_spec.rb +137 -0
- data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
- data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
- data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
- data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
- data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
- data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
- data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
- data/spec/lib/appsignal/hooks_spec.rb +195 -0
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
- data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
- data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
- data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
- data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
- data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
- data/spec/lib/appsignal/marker_spec.rb +51 -0
- data/spec/lib/appsignal/minutely_spec.rb +50 -0
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
- data/spec/lib/appsignal/system_spec.rb +131 -0
- data/spec/lib/appsignal/transaction_spec.rb +1146 -0
- data/spec/lib/appsignal/transmitter_spec.rb +152 -0
- data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
- data/spec/lib/appsignal/utils_spec.rb +150 -0
- data/spec/lib/appsignal_spec.rb +1049 -0
- data/spec/spec_helper.rb +116 -0
- data/spec/support/fixtures/containers/cgroups/docker +14 -0
- data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
- data/spec/support/fixtures/containers/cgroups/lxc +10 -0
- data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
- data/spec/support/fixtures/containers/cgroups/none +1 -0
- data/spec/support/fixtures/generated_config.yml +24 -0
- data/spec/support/fixtures/uploaded_file.txt +0 -0
- data/spec/support/helpers/api_request_helper.rb +19 -0
- data/spec/support/helpers/cli_helpers.rb +26 -0
- data/spec/support/helpers/config_helpers.rb +21 -0
- data/spec/support/helpers/dependency_helper.rb +73 -0
- data/spec/support/helpers/directory_helper.rb +27 -0
- data/spec/support/helpers/env_helpers.rb +33 -0
- data/spec/support/helpers/example_exception.rb +13 -0
- data/spec/support/helpers/example_standard_error.rb +13 -0
- data/spec/support/helpers/log_helpers.rb +22 -0
- data/spec/support/helpers/std_streams_helper.rb +66 -0
- data/spec/support/helpers/system_helpers.rb +8 -0
- data/spec/support/helpers/time_helpers.rb +11 -0
- data/spec/support/helpers/transaction_helpers.rb +37 -0
- data/spec/support/matchers/contains_log.rb +7 -0
- data/spec/support/mocks/fake_gc_profiler.rb +19 -0
- data/spec/support/mocks/mock_extension.rb +6 -0
- data/spec/support/project_fixture/config/application.rb +0 -0
- data/spec/support/project_fixture/config/appsignal.yml +32 -0
- data/spec/support/project_fixture/config/environments/development.rb +0 -0
- data/spec/support/project_fixture/config/environments/production.rb +0 -0
- data/spec/support/project_fixture/config/environments/test.rb +0 -0
- data/spec/support/project_fixture/log/.gitkeep +0 -0
- data/spec/support/rails/my_app.rb +6 -0
- data/spec/support/shared_examples/instrument.rb +43 -0
- data/spec/support/stubs/delayed_job.rb +0 -0
- metadata +483 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class PumaHook < Appsignal::Hooks::Hook
|
|
5
|
+
register :puma
|
|
6
|
+
|
|
7
|
+
def dependencies_present?
|
|
8
|
+
defined?(::Puma) &&
|
|
9
|
+
::Puma.respond_to?(:cli_config) &&
|
|
10
|
+
::Puma.cli_config
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def install
|
|
14
|
+
::Puma.cli_config.options[:before_worker_boot] ||= []
|
|
15
|
+
::Puma.cli_config.options[:before_worker_boot] << proc do |_id|
|
|
16
|
+
Appsignal.forked
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
::Puma.cli_config.options[:before_worker_shutdown] ||= []
|
|
20
|
+
::Puma.cli_config.options[:before_worker_shutdown] << proc do |_id|
|
|
21
|
+
Appsignal.stop("puma before_worker_shutdown")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
::Puma::Cluster.class_eval do
|
|
25
|
+
alias stop_workers_without_appsignal stop_workers
|
|
26
|
+
|
|
27
|
+
def stop_workers
|
|
28
|
+
Appsignal.stop("puma cluster")
|
|
29
|
+
stop_workers_without_appsignal
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class QueHook < Appsignal::Hooks::Hook
|
|
5
|
+
register :que
|
|
6
|
+
|
|
7
|
+
def dependencies_present?
|
|
8
|
+
defined?(::Que::Job)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def install
|
|
12
|
+
require "appsignal/integrations/que"
|
|
13
|
+
::Que::Job.send(:include, Appsignal::Integrations::QuePlugin)
|
|
14
|
+
|
|
15
|
+
::Que.error_notifier = proc do |error, _job|
|
|
16
|
+
Appsignal::Transaction.current.set_error(error)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class RakeHook < Appsignal::Hooks::Hook
|
|
5
|
+
register :rake
|
|
6
|
+
|
|
7
|
+
def dependencies_present?
|
|
8
|
+
defined?(::Rake::Task)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def install
|
|
12
|
+
::Rake::Task.class_eval do
|
|
13
|
+
alias :execute_without_appsignal :execute
|
|
14
|
+
|
|
15
|
+
def execute(*args)
|
|
16
|
+
execute_without_appsignal(*args)
|
|
17
|
+
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
18
|
+
# Format given arguments and cast to hash if possible
|
|
19
|
+
params, _ = args
|
|
20
|
+
params = params.to_hash if params.respond_to?(:to_hash)
|
|
21
|
+
|
|
22
|
+
transaction = Appsignal::Transaction.create(
|
|
23
|
+
SecureRandom.uuid,
|
|
24
|
+
Appsignal::Transaction::BACKGROUND_JOB,
|
|
25
|
+
Appsignal::Transaction::GenericRequest.new(
|
|
26
|
+
:params => params
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
transaction.set_action(name)
|
|
30
|
+
transaction.set_error(error)
|
|
31
|
+
transaction.complete
|
|
32
|
+
Appsignal.stop("rake")
|
|
33
|
+
raise error
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class RedisHook < Appsignal::Hooks::Hook
|
|
5
|
+
register :redis
|
|
6
|
+
|
|
7
|
+
def dependencies_present?
|
|
8
|
+
defined?(::Redis) &&
|
|
9
|
+
Appsignal.config &&
|
|
10
|
+
Appsignal.config[:instrument_redis]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def install
|
|
14
|
+
::Redis::Client.class_eval do
|
|
15
|
+
alias process_without_appsignal process
|
|
16
|
+
|
|
17
|
+
def process(commands, &block)
|
|
18
|
+
sanitized_commands = commands.map do |command, *args|
|
|
19
|
+
"#{command}#{" ?" * args.size}"
|
|
20
|
+
end.join("\n")
|
|
21
|
+
|
|
22
|
+
Appsignal.instrument "query.redis", id, sanitized_commands do
|
|
23
|
+
process_without_appsignal(commands, &block)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
module SequelLogExtension
|
|
5
|
+
# Add query instrumentation
|
|
6
|
+
def log_yield(sql, args = nil)
|
|
7
|
+
Appsignal.instrument(
|
|
8
|
+
"sql.sequel",
|
|
9
|
+
nil,
|
|
10
|
+
sql,
|
|
11
|
+
Appsignal::EventFormatter::SQL_BODY_FORMAT
|
|
12
|
+
) do
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module SequelLogConnectionExtension
|
|
19
|
+
# Add query instrumentation
|
|
20
|
+
def log_connection_yield(sql, conn, args = nil)
|
|
21
|
+
Appsignal.instrument(
|
|
22
|
+
"sql.sequel",
|
|
23
|
+
nil,
|
|
24
|
+
sql,
|
|
25
|
+
Appsignal::EventFormatter::SQL_BODY_FORMAT
|
|
26
|
+
) do
|
|
27
|
+
super
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class SequelHook < Appsignal::Hooks::Hook
|
|
33
|
+
register :sequel
|
|
34
|
+
|
|
35
|
+
def dependencies_present?
|
|
36
|
+
defined?(::Sequel::Database) &&
|
|
37
|
+
Appsignal.config &&
|
|
38
|
+
Appsignal.config[:instrument_sequel]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def install
|
|
42
|
+
# Register the extension...
|
|
43
|
+
if ::Sequel::MAJOR >= 4 && ::Sequel::MINOR >= 35
|
|
44
|
+
::Sequel::Database.register_extension(
|
|
45
|
+
:appsignal_integration,
|
|
46
|
+
Appsignal::Hooks::SequelLogConnectionExtension
|
|
47
|
+
)
|
|
48
|
+
else
|
|
49
|
+
::Sequel::Database.register_extension(
|
|
50
|
+
:appsignal_integration,
|
|
51
|
+
Appsignal::Hooks::SequelLogExtension
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# ... and automatically add it to future instances.
|
|
56
|
+
::Sequel::Database.extension(:appsignal_integration)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class ShoryukenMiddleware
|
|
5
|
+
def call(worker_instance, queue, sqs_msg, body)
|
|
6
|
+
metadata = { :queue => queue }.merge(sqs_msg.attributes)
|
|
7
|
+
options = {
|
|
8
|
+
:class => worker_instance.class.name,
|
|
9
|
+
:method => "perform",
|
|
10
|
+
:metadata => metadata
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
args = body.is_a?(Hash) ? body : { :params => body }
|
|
14
|
+
options[:params] = Appsignal::Utils::ParamsSanitizer.sanitize args,
|
|
15
|
+
:filter_parameters => Appsignal.config[:filter_parameters]
|
|
16
|
+
|
|
17
|
+
if sqs_msg.attributes.key?("SentTimestamp")
|
|
18
|
+
options[:queue_start] = Time.at(sqs_msg.attributes["SentTimestamp"].to_i / 1000)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Appsignal.monitor_transaction("perform_job.shoryuken", options) do
|
|
22
|
+
yield
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class ShoryukenHook < Appsignal::Hooks::Hook
|
|
28
|
+
register :shoryuken
|
|
29
|
+
|
|
30
|
+
def dependencies_present?
|
|
31
|
+
defined?(::Shoryuken)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def install
|
|
35
|
+
::Shoryuken.configure_server do |config|
|
|
36
|
+
config.server_middleware do |chain|
|
|
37
|
+
chain.add Appsignal::Hooks::ShoryukenMiddleware
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
require "yaml"
|
|
2
|
+
|
|
3
|
+
module Appsignal
|
|
4
|
+
class Hooks
|
|
5
|
+
class SidekiqHook < Appsignal::Hooks::Hook
|
|
6
|
+
register :sidekiq
|
|
7
|
+
|
|
8
|
+
def dependencies_present?
|
|
9
|
+
defined?(::Sidekiq)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def install
|
|
13
|
+
::Sidekiq.configure_server do |config|
|
|
14
|
+
config.server_middleware do |chain|
|
|
15
|
+
chain.add Appsignal::Hooks::SidekiqPlugin
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
class SidekiqPlugin
|
|
23
|
+
include Appsignal::Hooks::Helpers
|
|
24
|
+
|
|
25
|
+
JOB_KEYS = %w[
|
|
26
|
+
args backtrace class created_at enqueued_at error_backtrace error_class
|
|
27
|
+
error_message failed_at jid retried_at retry wrapped
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
30
|
+
def call(_worker, item, _queue)
|
|
31
|
+
transaction = Appsignal::Transaction.create(
|
|
32
|
+
SecureRandom.uuid,
|
|
33
|
+
Appsignal::Transaction::BACKGROUND_JOB,
|
|
34
|
+
Appsignal::Transaction::GenericRequest.new(
|
|
35
|
+
:queue_start => item["enqueued_at"]
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
Appsignal.instrument "perform_job.sidekiq" do
|
|
40
|
+
begin
|
|
41
|
+
yield
|
|
42
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
|
43
|
+
transaction.set_error(exception)
|
|
44
|
+
raise exception
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
ensure
|
|
48
|
+
if transaction
|
|
49
|
+
transaction.set_action_if_nil(formatted_action_name(item))
|
|
50
|
+
transaction.params = filtered_arguments(item)
|
|
51
|
+
formatted_metadata(item).each do |key, value|
|
|
52
|
+
transaction.set_metadata key, value
|
|
53
|
+
end
|
|
54
|
+
transaction.set_http_or_background_queue_start
|
|
55
|
+
Appsignal::Transaction.complete_current!
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def formatted_action_name(job)
|
|
62
|
+
sidekiq_action_name = parse_action_name(job)
|
|
63
|
+
return sidekiq_action_name if sidekiq_action_name =~ /\.|#/
|
|
64
|
+
"#{sidekiq_action_name}#perform"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def filtered_arguments(job)
|
|
68
|
+
Appsignal::Utils::ParamsSanitizer.sanitize(
|
|
69
|
+
parse_arguments(job),
|
|
70
|
+
:filter_parameters => Appsignal.config[:filter_parameters]
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def formatted_metadata(item)
|
|
75
|
+
{}.tap do |hash|
|
|
76
|
+
(item || {}).each do |key, value|
|
|
77
|
+
next if JOB_KEYS.include?(key)
|
|
78
|
+
hash[key] = truncate(string_or_inspect(value))
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Based on: https://github.com/mperham/sidekiq/blob/63ee43353bd3b753beb0233f64865e658abeb1c3/lib/sidekiq/api.rb#L316-L334
|
|
84
|
+
def parse_action_name(job)
|
|
85
|
+
args = job["args"]
|
|
86
|
+
case job["class"]
|
|
87
|
+
when /\ASidekiq::Extensions::Delayed/
|
|
88
|
+
safe_load(job["args"][0], job["class"]) do |target, method, _|
|
|
89
|
+
"#{target}.#{method}"
|
|
90
|
+
end
|
|
91
|
+
when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
|
92
|
+
job_class = job["wrapped"] || args[0]
|
|
93
|
+
if job_class == "ActionMailer::DeliveryJob"
|
|
94
|
+
# MailerClass#mailer_method
|
|
95
|
+
args[0]["arguments"][0..1].join("#")
|
|
96
|
+
else
|
|
97
|
+
job_class
|
|
98
|
+
end
|
|
99
|
+
else
|
|
100
|
+
job["class"]
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Based on: https://github.com/mperham/sidekiq/blob/63ee43353bd3b753beb0233f64865e658abeb1c3/lib/sidekiq/api.rb#L336-L358
|
|
105
|
+
def parse_arguments(job)
|
|
106
|
+
args = job["args"]
|
|
107
|
+
case job["class"]
|
|
108
|
+
when /\ASidekiq::Extensions::Delayed/
|
|
109
|
+
safe_load(args[0], args) do |_, _, arg|
|
|
110
|
+
arg
|
|
111
|
+
end
|
|
112
|
+
when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
|
113
|
+
is_wrapped = job["wrapped"]
|
|
114
|
+
job_args = is_wrapped ? args[0]["arguments"] : []
|
|
115
|
+
if (is_wrapped || args[0]) == "ActionMailer::DeliveryJob"
|
|
116
|
+
# Remove MailerClass, mailer_method and "deliver_now"
|
|
117
|
+
job_args.drop(3)
|
|
118
|
+
else
|
|
119
|
+
job_args
|
|
120
|
+
end
|
|
121
|
+
else
|
|
122
|
+
# Sidekiq Enterprise argument encryption.
|
|
123
|
+
# More information: https://github.com/mperham/sidekiq/wiki/Ent-Encryption
|
|
124
|
+
if job["encrypt".freeze]
|
|
125
|
+
# No point in showing 150+ bytes of random garbage
|
|
126
|
+
args[-1] = "[encrypted data]".freeze
|
|
127
|
+
end
|
|
128
|
+
args
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Based on: https://github.com/mperham/sidekiq/blob/63ee43353bd3b753beb0233f64865e658abeb1c3/lib/sidekiq/api.rb#L403-L412
|
|
133
|
+
def safe_load(content, default)
|
|
134
|
+
yield(*YAML.load(content))
|
|
135
|
+
rescue => error
|
|
136
|
+
# Sidekiq issue #1761: in dev mode, it's possible to have jobs enqueued
|
|
137
|
+
# which haven't been loaded into memory yet so the YAML can't be
|
|
138
|
+
# loaded.
|
|
139
|
+
Appsignal.logger.warn "Unable to load YAML: #{error.message}"
|
|
140
|
+
default
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class UnicornHook < Appsignal::Hooks::Hook
|
|
5
|
+
register :unicorn
|
|
6
|
+
|
|
7
|
+
def dependencies_present?
|
|
8
|
+
defined?(::Unicorn::HttpServer) &&
|
|
9
|
+
defined?(::Unicorn::Worker)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def install
|
|
13
|
+
# Make sure that appsignal is started and the last transaction
|
|
14
|
+
# in a worker gets flushed.
|
|
15
|
+
#
|
|
16
|
+
# We'd love to be able to hook this into Unicorn in a less
|
|
17
|
+
# intrusive way, but this is the best we can do given the
|
|
18
|
+
# options we have.
|
|
19
|
+
|
|
20
|
+
::Unicorn::HttpServer.class_eval do
|
|
21
|
+
alias worker_loop_without_appsignal worker_loop
|
|
22
|
+
|
|
23
|
+
def worker_loop(worker)
|
|
24
|
+
Appsignal.forked
|
|
25
|
+
worker_loop_without_appsignal(worker)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
::Unicorn::Worker.class_eval do
|
|
30
|
+
alias close_without_appsignal close
|
|
31
|
+
|
|
32
|
+
def close
|
|
33
|
+
Appsignal.stop("unicorn")
|
|
34
|
+
close_without_appsignal
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class WebmachineHook < Appsignal::Hooks::Hook
|
|
5
|
+
register :webmachine
|
|
6
|
+
|
|
7
|
+
def dependencies_present?
|
|
8
|
+
defined?(::Webmachine)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def install
|
|
12
|
+
require "appsignal/integrations/webmachine"
|
|
13
|
+
::Webmachine::Decision::FSM.class_eval do
|
|
14
|
+
include Appsignal::Integrations::WebmachinePlugin::FSM
|
|
15
|
+
alias run_without_appsignal run
|
|
16
|
+
alias run run_with_appsignal
|
|
17
|
+
alias handle_exceptions_without_appsignal handle_exceptions
|
|
18
|
+
alias handle_exceptions handle_exceptions_with_appsignal
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
namespace :appsignal do
|
|
2
|
+
task :deploy do
|
|
3
|
+
appsignal_env = fetch(:appsignal_env, fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
|
|
4
|
+
user = fetch(:appsignal_user, ENV["USER"] || ENV["USERNAME"])
|
|
5
|
+
revision = fetch(:appsignal_revision, fetch(:current_revision))
|
|
6
|
+
|
|
7
|
+
appsignal_config = Appsignal::Config.new(
|
|
8
|
+
ENV["PWD"],
|
|
9
|
+
appsignal_env,
|
|
10
|
+
{},
|
|
11
|
+
Logger.new(StringIO.new)
|
|
12
|
+
).tap do |c|
|
|
13
|
+
fetch(:appsignal_config, {}).each do |key, value|
|
|
14
|
+
c[key] = value
|
|
15
|
+
end
|
|
16
|
+
c.validate
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if appsignal_config && appsignal_config.active?
|
|
20
|
+
marker_data = {
|
|
21
|
+
:revision => revision,
|
|
22
|
+
:user => user
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
marker = Appsignal::Marker.new(marker_data, appsignal_config)
|
|
26
|
+
# {#dry_run?} helper was added in Capistrano 3.5.0
|
|
27
|
+
# https://github.com/capistrano/capistrano/commit/38d8d6d2c8485f1b5643857465b16ff01da57aff
|
|
28
|
+
if respond_to?(:dry_run?) && dry_run?
|
|
29
|
+
puts "Dry run: AppSignal deploy marker not actually sent."
|
|
30
|
+
else
|
|
31
|
+
marker.transmit
|
|
32
|
+
end
|
|
33
|
+
else
|
|
34
|
+
puts "Not notifying of deploy, config is not active for environment: #{appsignal_env}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
after "deploy:finished", "appsignal:deploy"
|