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.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +66 -0
  5. data/.rubocop_todo.yml +124 -0
  6. data/.travis.yml +72 -0
  7. data/.yardopts +8 -0
  8. data/CHANGELOG.md +639 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +20 -0
  11. data/README.md +264 -0
  12. data/Rakefile +214 -0
  13. data/appsignal.gemspec +42 -0
  14. data/benchmark.rake +77 -0
  15. data/bin/appsignal +13 -0
  16. data/ext/Rakefile +27 -0
  17. data/ext/agent.yml +64 -0
  18. data/ext/appsignal_extension.c +692 -0
  19. data/ext/base.rb +79 -0
  20. data/ext/extconf.rb +35 -0
  21. data/gemfiles/capistrano2.gemfile +7 -0
  22. data/gemfiles/capistrano3.gemfile +7 -0
  23. data/gemfiles/grape.gemfile +7 -0
  24. data/gemfiles/no_dependencies.gemfile +5 -0
  25. data/gemfiles/padrino.gemfile +7 -0
  26. data/gemfiles/que.gemfile +5 -0
  27. data/gemfiles/rails-3.2.gemfile +6 -0
  28. data/gemfiles/rails-4.0.gemfile +6 -0
  29. data/gemfiles/rails-4.1.gemfile +6 -0
  30. data/gemfiles/rails-4.2.gemfile +10 -0
  31. data/gemfiles/rails-5.0.gemfile +5 -0
  32. data/gemfiles/rails-5.1.gemfile +5 -0
  33. data/gemfiles/resque.gemfile +12 -0
  34. data/gemfiles/sequel-435.gemfile +11 -0
  35. data/gemfiles/sequel.gemfile +11 -0
  36. data/gemfiles/sinatra.gemfile +6 -0
  37. data/gemfiles/webmachine.gemfile +5 -0
  38. data/lib/appsignal.rb +804 -0
  39. data/lib/appsignal/auth_check.rb +65 -0
  40. data/lib/appsignal/capistrano.rb +10 -0
  41. data/lib/appsignal/cli.rb +108 -0
  42. data/lib/appsignal/cli/demo.rb +63 -0
  43. data/lib/appsignal/cli/diagnose.rb +500 -0
  44. data/lib/appsignal/cli/helpers.rb +72 -0
  45. data/lib/appsignal/cli/install.rb +277 -0
  46. data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
  47. data/lib/appsignal/config.rb +287 -0
  48. data/lib/appsignal/demo.rb +107 -0
  49. data/lib/appsignal/event_formatter.rb +74 -0
  50. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
  51. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
  52. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
  53. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
  54. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
  55. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
  56. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  57. data/lib/appsignal/extension.rb +63 -0
  58. data/lib/appsignal/extension/jruby.rb +460 -0
  59. data/lib/appsignal/garbage_collection_profiler.rb +48 -0
  60. data/lib/appsignal/hooks.rb +105 -0
  61. data/lib/appsignal/hooks/action_cable.rb +113 -0
  62. data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
  63. data/lib/appsignal/hooks/celluloid.rb +30 -0
  64. data/lib/appsignal/hooks/data_mapper.rb +18 -0
  65. data/lib/appsignal/hooks/delayed_job.rb +19 -0
  66. data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
  67. data/lib/appsignal/hooks/net_http.rb +29 -0
  68. data/lib/appsignal/hooks/passenger.rb +22 -0
  69. data/lib/appsignal/hooks/puma.rb +35 -0
  70. data/lib/appsignal/hooks/que.rb +21 -0
  71. data/lib/appsignal/hooks/rake.rb +39 -0
  72. data/lib/appsignal/hooks/redis.rb +30 -0
  73. data/lib/appsignal/hooks/sequel.rb +60 -0
  74. data/lib/appsignal/hooks/shoryuken.rb +43 -0
  75. data/lib/appsignal/hooks/sidekiq.rb +144 -0
  76. data/lib/appsignal/hooks/unicorn.rb +40 -0
  77. data/lib/appsignal/hooks/webmachine.rb +23 -0
  78. data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
  79. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
  80. data/lib/appsignal/integrations/data_mapper.rb +33 -0
  81. data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
  82. data/lib/appsignal/integrations/grape.rb +53 -0
  83. data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
  84. data/lib/appsignal/integrations/object.rb +35 -0
  85. data/lib/appsignal/integrations/padrino.rb +84 -0
  86. data/lib/appsignal/integrations/que.rb +43 -0
  87. data/lib/appsignal/integrations/railtie.rb +41 -0
  88. data/lib/appsignal/integrations/rake.rb +2 -0
  89. data/lib/appsignal/integrations/resque.rb +20 -0
  90. data/lib/appsignal/integrations/resque_active_job.rb +30 -0
  91. data/lib/appsignal/integrations/sinatra.rb +17 -0
  92. data/lib/appsignal/integrations/webmachine.rb +38 -0
  93. data/lib/appsignal/js_exception_transaction.rb +54 -0
  94. data/lib/appsignal/marker.rb +63 -0
  95. data/lib/appsignal/minutely.rb +42 -0
  96. data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
  97. data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
  98. data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
  99. data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
  100. data/lib/appsignal/rack/streaming_listener.rb +73 -0
  101. data/lib/appsignal/system.rb +81 -0
  102. data/lib/appsignal/transaction.rb +498 -0
  103. data/lib/appsignal/transmitter.rb +107 -0
  104. data/lib/appsignal/utils.rb +127 -0
  105. data/lib/appsignal/utils/params_sanitizer.rb +59 -0
  106. data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
  107. data/lib/appsignal/version.rb +3 -0
  108. data/lib/sequel/extensions/appsignal_integration.rb +3 -0
  109. data/resources/appsignal.yml.erb +39 -0
  110. data/resources/cacert.pem +3866 -0
  111. data/spec/.rubocop.yml +7 -0
  112. data/spec/lib/appsignal/auth_check_spec.rb +80 -0
  113. data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
  114. data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
  115. data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
  116. data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
  117. data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
  118. data/spec/lib/appsignal/cli/install_spec.rb +632 -0
  119. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
  120. data/spec/lib/appsignal/cli_spec.rb +56 -0
  121. data/spec/lib/appsignal/config_spec.rb +637 -0
  122. data/spec/lib/appsignal/demo_spec.rb +87 -0
  123. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
  124. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
  125. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
  126. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
  127. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
  128. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
  129. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
  130. data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
  131. data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
  132. data/spec/lib/appsignal/extension_spec.rb +137 -0
  133. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
  134. data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
  135. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
  136. data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
  137. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
  138. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
  139. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
  140. data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
  141. data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
  142. data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
  143. data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
  144. data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
  145. data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
  146. data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
  147. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
  148. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
  149. data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
  150. data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
  151. data/spec/lib/appsignal/hooks_spec.rb +195 -0
  152. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
  153. data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
  154. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
  155. data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
  156. data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
  157. data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
  158. data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
  159. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
  160. data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
  161. data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
  162. data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
  163. data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
  164. data/spec/lib/appsignal/marker_spec.rb +51 -0
  165. data/spec/lib/appsignal/minutely_spec.rb +50 -0
  166. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
  167. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
  168. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
  169. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
  170. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
  171. data/spec/lib/appsignal/system_spec.rb +131 -0
  172. data/spec/lib/appsignal/transaction_spec.rb +1146 -0
  173. data/spec/lib/appsignal/transmitter_spec.rb +152 -0
  174. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
  175. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
  176. data/spec/lib/appsignal/utils_spec.rb +150 -0
  177. data/spec/lib/appsignal_spec.rb +1049 -0
  178. data/spec/spec_helper.rb +116 -0
  179. data/spec/support/fixtures/containers/cgroups/docker +14 -0
  180. data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
  181. data/spec/support/fixtures/containers/cgroups/lxc +10 -0
  182. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  183. data/spec/support/fixtures/containers/cgroups/none +1 -0
  184. data/spec/support/fixtures/generated_config.yml +24 -0
  185. data/spec/support/fixtures/uploaded_file.txt +0 -0
  186. data/spec/support/helpers/api_request_helper.rb +19 -0
  187. data/spec/support/helpers/cli_helpers.rb +26 -0
  188. data/spec/support/helpers/config_helpers.rb +21 -0
  189. data/spec/support/helpers/dependency_helper.rb +73 -0
  190. data/spec/support/helpers/directory_helper.rb +27 -0
  191. data/spec/support/helpers/env_helpers.rb +33 -0
  192. data/spec/support/helpers/example_exception.rb +13 -0
  193. data/spec/support/helpers/example_standard_error.rb +13 -0
  194. data/spec/support/helpers/log_helpers.rb +22 -0
  195. data/spec/support/helpers/std_streams_helper.rb +66 -0
  196. data/spec/support/helpers/system_helpers.rb +8 -0
  197. data/spec/support/helpers/time_helpers.rb +11 -0
  198. data/spec/support/helpers/transaction_helpers.rb +37 -0
  199. data/spec/support/matchers/contains_log.rb +7 -0
  200. data/spec/support/mocks/fake_gc_profiler.rb +19 -0
  201. data/spec/support/mocks/mock_extension.rb +6 -0
  202. data/spec/support/project_fixture/config/application.rb +0 -0
  203. data/spec/support/project_fixture/config/appsignal.yml +32 -0
  204. data/spec/support/project_fixture/config/environments/development.rb +0 -0
  205. data/spec/support/project_fixture/config/environments/production.rb +0 -0
  206. data/spec/support/project_fixture/config/environments/test.rb +0 -0
  207. data/spec/support/project_fixture/log/.gitkeep +0 -0
  208. data/spec/support/rails/my_app.rb +6 -0
  209. data/spec/support/shared_examples/instrument.rb +43 -0
  210. data/spec/support/stubs/delayed_job.rb +0 -0
  211. 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"