appsignal 2.5.0.alpha.1-java

Sign up to get free protection for your applications and to get access to all the features.
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,48 @@
1
+ module Appsignal
2
+ # {Appsignal::GarbageCollectionProfiler} wraps Ruby's `GC::Profiler` to be
3
+ # able to track garbage collection time for multiple transactions, while
4
+ # constantly clearing `GC::Profiler`'s total_time to make sure it doesn't
5
+ # leak memory by keeping garbage collection run samples in memory.
6
+ #
7
+ # @api private
8
+ class GarbageCollectionProfiler
9
+ def self.lock
10
+ @lock ||= Mutex.new
11
+ end
12
+
13
+ def initialize
14
+ @total_time = 0
15
+ end
16
+
17
+ # Whenever {#total_time} is called, the current `GC::Profiler#total_time`
18
+ # gets added to `@total_time`, after which `GC::Profiler.clear` is called
19
+ # to prevent it from leaking memory. A class-level lock is used to make
20
+ # sure garbage collection time is never counted more than once.
21
+ #
22
+ # Whenever `@total_time` gets above two billion milliseconds (about 23
23
+ # days), it's reset to make sure the result fits in a signed 32-bit
24
+ # integer.
25
+ #
26
+ # @return [Integer]
27
+ def total_time
28
+ lock.synchronize do
29
+ @total_time += (internal_profiler.total_time * 1000).round
30
+ internal_profiler.clear
31
+ end
32
+
33
+ @total_time = 0 if @total_time > 2_000_000_000
34
+
35
+ @total_time
36
+ end
37
+
38
+ private
39
+
40
+ def internal_profiler
41
+ GC::Profiler
42
+ end
43
+
44
+ def lock
45
+ self.class.lock
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,105 @@
1
+ module Appsignal
2
+ # @api private
3
+ class Hooks
4
+ class << self
5
+ def register(name, hook)
6
+ hooks[name] = hook
7
+ end
8
+
9
+ def load_hooks
10
+ hooks.each do |name, hook|
11
+ hook.try_to_install(name)
12
+ end
13
+ end
14
+
15
+ def hooks
16
+ @hooks ||= {}
17
+ end
18
+ end
19
+
20
+ class Hook
21
+ def self.register(name, hook = self)
22
+ Appsignal::Hooks.register(name, hook.new)
23
+ end
24
+
25
+ def initialize
26
+ @installed = false
27
+ end
28
+
29
+ def try_to_install(name)
30
+ if dependencies_present? && !installed?
31
+ Appsignal.logger.info("Installing #{name} hook")
32
+ begin
33
+ install
34
+ @installed = true
35
+ rescue => ex
36
+ Appsignal.logger.error("Error while installing #{name} hook: #{ex}")
37
+ end
38
+ end
39
+ end
40
+
41
+ def installed?
42
+ @installed
43
+ end
44
+
45
+ def dependencies_present?
46
+ raise NotImplementedError
47
+ end
48
+
49
+ def install
50
+ raise NotImplementedError
51
+ end
52
+ end
53
+
54
+ module Helpers
55
+ def string_or_inspect(string_or_other)
56
+ if string_or_other.is_a?(String)
57
+ string_or_other
58
+ else
59
+ string_or_other.inspect
60
+ end
61
+ end
62
+
63
+ def truncate(text)
64
+ text.size > 200 ? "#{text[0...197]}..." : text
65
+ end
66
+
67
+ def extract_value(object_or_hash, field, default_value = nil, convert_to_s = false)
68
+ value =
69
+ if object_or_hash.respond_to?(:[])
70
+ begin
71
+ object_or_hash[field]
72
+ rescue NameError
73
+ nil
74
+ end
75
+ elsif object_or_hash.respond_to?(field)
76
+ object_or_hash.send(field)
77
+ end || default_value
78
+
79
+ if convert_to_s
80
+ value.to_s
81
+ else
82
+ value
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ require "appsignal/hooks/action_cable"
90
+ require "appsignal/hooks/active_support_notifications"
91
+ require "appsignal/hooks/celluloid"
92
+ require "appsignal/hooks/delayed_job"
93
+ require "appsignal/hooks/net_http"
94
+ require "appsignal/hooks/passenger"
95
+ require "appsignal/hooks/puma"
96
+ require "appsignal/hooks/rake"
97
+ require "appsignal/hooks/redis"
98
+ require "appsignal/hooks/sequel"
99
+ require "appsignal/hooks/shoryuken"
100
+ require "appsignal/hooks/sidekiq"
101
+ require "appsignal/hooks/unicorn"
102
+ require "appsignal/hooks/mongo_ruby_driver"
103
+ require "appsignal/hooks/webmachine"
104
+ require "appsignal/hooks/data_mapper"
105
+ require "appsignal/hooks/que"
@@ -0,0 +1,113 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class ActionCableHook < Appsignal::Hooks::Hook
5
+ register :action_cable
6
+
7
+ REQUEST_ID = "_appsignal_action_cable.request_id".freeze
8
+
9
+ def dependencies_present?
10
+ defined?(::ActiveSupport::Notifications::Instrumenter) &&
11
+ defined?(::ActionCable)
12
+ end
13
+
14
+ def install
15
+ patch_perform_action
16
+ install_callbacks
17
+ end
18
+
19
+ private
20
+
21
+ def patch_perform_action
22
+ ActionCable::Channel::Base.class_eval do
23
+ alias_method :original_perform_action, :perform_action
24
+
25
+ def perform_action(*args, &block)
26
+ # The request is only the original websocket request
27
+ env = connection.env
28
+ request = ActionDispatch::Request.new(env)
29
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||=
30
+ request.request_id || SecureRandom.uuid
31
+
32
+ transaction = Appsignal::Transaction.create(
33
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID],
34
+ Appsignal::Transaction::ACTION_CABLE,
35
+ request
36
+ )
37
+
38
+ begin
39
+ original_perform_action(*args, &block)
40
+ rescue Exception => exception # rubocop:disable Lint/RescueException
41
+ transaction.set_error(exception)
42
+ raise exception
43
+ ensure
44
+ transaction.params = args.first
45
+ transaction.set_action_if_nil("#{self.class}##{args.first["action"]}")
46
+ transaction.set_metadata("path", request.path)
47
+ transaction.set_metadata("method", "websocket")
48
+ Appsignal::Transaction.complete_current!
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def install_callbacks
55
+ ActionCable::Channel::Base.set_callback :subscribe, :around, :prepend => true do |channel, inner|
56
+ # The request is only the original websocket request
57
+ env = channel.connection.env
58
+ request = ActionDispatch::Request.new(env)
59
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||=
60
+ request.request_id || SecureRandom.uuid
61
+
62
+ transaction = Appsignal::Transaction.create(
63
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID],
64
+ Appsignal::Transaction::ACTION_CABLE,
65
+ request
66
+ )
67
+
68
+ begin
69
+ Appsignal.instrument "subscribed.action_cable" do
70
+ inner.call
71
+ end
72
+ rescue Exception => exception # rubocop:disable Lint/RescueException
73
+ transaction.set_error(exception)
74
+ raise exception
75
+ ensure
76
+ transaction.set_action_if_nil("#{channel.class}#subscribed")
77
+ transaction.set_metadata("path", request.path)
78
+ transaction.set_metadata("method", "websocket")
79
+ Appsignal::Transaction.complete_current!
80
+ end
81
+ end
82
+
83
+ ActionCable::Channel::Base.set_callback :unsubscribe, :around, :prepend => true do |channel, inner|
84
+ # The request is only the original websocket request
85
+ env = channel.connection.env
86
+ request = ActionDispatch::Request.new(env)
87
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||=
88
+ request.request_id || SecureRandom.uuid
89
+
90
+ transaction = Appsignal::Transaction.create(
91
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID],
92
+ Appsignal::Transaction::ACTION_CABLE,
93
+ request
94
+ )
95
+
96
+ begin
97
+ Appsignal.instrument "unsubscribed.action_cable" do
98
+ inner.call
99
+ end
100
+ rescue Exception => exception # rubocop:disable Lint/RescueException
101
+ transaction.set_error(exception)
102
+ raise exception
103
+ ensure
104
+ transaction.set_action_if_nil("#{channel.class}#unsubscribed")
105
+ transaction.set_metadata("path", request.path)
106
+ transaction.set_metadata("method", "websocket")
107
+ Appsignal::Transaction.complete_current!
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,52 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class ActiveSupportNotificationsHook < Appsignal::Hooks::Hook
5
+ register :active_support_notifications
6
+
7
+ BANG = "!".freeze
8
+
9
+ def dependencies_present?
10
+ defined?(::ActiveSupport::Notifications::Instrumenter)
11
+ end
12
+
13
+ def install
14
+ ::ActiveSupport::Notifications.class_eval do
15
+ def self.instrument(name, payload = {})
16
+ # Don't check the notifier if any subscriber is listening:
17
+ # AppSignal is listening
18
+ instrumenter.instrument(name, payload) do
19
+ yield payload if block_given?
20
+ end
21
+ end
22
+ end
23
+
24
+ ::ActiveSupport::Notifications::Instrumenter.class_eval do
25
+ alias instrument_without_appsignal instrument
26
+
27
+ def instrument(name, payload = {}, &block)
28
+ # Events that start with a bang are internal to Rails
29
+ instrument_this = name[0] != BANG
30
+
31
+ if instrument_this
32
+ transaction = Appsignal::Transaction.current
33
+ transaction.start_event
34
+ end
35
+
36
+ instrument_without_appsignal(name, payload, &block)
37
+ ensure
38
+ if instrument_this
39
+ title, body, body_format = Appsignal::EventFormatter.format(name, payload)
40
+ transaction.finish_event(
41
+ name.to_s,
42
+ title,
43
+ body,
44
+ body_format
45
+ )
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,30 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class CelluloidHook < Appsignal::Hooks::Hook
5
+ register :celluloid
6
+
7
+ def dependencies_present?
8
+ defined?(::Celluloid)
9
+ end
10
+
11
+ def install
12
+ # Some versions of Celluloid have race conditions while exiting
13
+ # that can result in a dead lock. We stop appsignal before shutting
14
+ # down Celluloid so we're sure our thread does not aggravate this situation.
15
+ # This way we also make sure any outstanding transactions get flushed.
16
+
17
+ ::Celluloid.class_eval do
18
+ class << self
19
+ alias shutdown_without_appsignal shutdown
20
+
21
+ def shutdown
22
+ Appsignal.stop("celluloid")
23
+ shutdown_without_appsignal
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class DataMapperHook < Appsignal::Hooks::Hook
5
+ register :data_mapper
6
+
7
+ def dependencies_present?
8
+ defined?(::DataMapper) &&
9
+ defined?(::DataObjects::Connection)
10
+ end
11
+
12
+ def install
13
+ require "appsignal/integrations/data_mapper"
14
+ ::DataObjects::Connection.send(:include, Appsignal::Hooks::DataMapperLogListener)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class DelayedJobHook < Appsignal::Hooks::Hook
5
+ register :delayed_job
6
+
7
+ def dependencies_present?
8
+ defined?(::Delayed::Plugin)
9
+ end
10
+
11
+ def install
12
+ # The DJ plugin is a subclass of Delayed::Plugin, so we can only
13
+ # require this code if we're actually installing.
14
+ require "appsignal/integrations/delayed_job_plugin"
15
+ ::Delayed::Worker.plugins << Appsignal::Hooks::DelayedJobPlugin
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class MongoRubyDriverHook < Appsignal::Hooks::Hook
5
+ register :mongo_ruby_driver
6
+
7
+ def dependencies_present?
8
+ defined?(::Mongo::Monitoring::Global)
9
+ end
10
+
11
+ def install
12
+ require "appsignal/integrations/mongo_ruby_driver"
13
+
14
+ Mongo::Monitoring::Global.subscribe(
15
+ Mongo::Monitoring::COMMAND,
16
+ Appsignal::Hooks::MongoMonitorSubscriber.new
17
+ )
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ require "net/http"
2
+
3
+ module Appsignal
4
+ class Hooks
5
+ # @api private
6
+ class NetHttpHook < Appsignal::Hooks::Hook
7
+ register :net_http
8
+
9
+ def dependencies_present?
10
+ Appsignal.config && Appsignal.config[:instrument_net_http]
11
+ end
12
+
13
+ def install
14
+ Net::HTTP.class_eval do
15
+ alias request_without_appsignal request
16
+
17
+ def request(request, body = nil, &block)
18
+ Appsignal.instrument(
19
+ "request.net_http",
20
+ "#{request.method} #{use_ssl? ? "https" : "http"}://#{request["host"] || address}"
21
+ ) do
22
+ request_without_appsignal(request, body, &block)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class PassengerHook < Appsignal::Hooks::Hook
5
+ register :passenger
6
+
7
+ def dependencies_present?
8
+ defined?(::PhusionPassenger)
9
+ end
10
+
11
+ def install
12
+ ::PhusionPassenger.on_event(:starting_worker_process) do |_forked|
13
+ Appsignal.forked
14
+ end
15
+
16
+ ::PhusionPassenger.on_event(:stopping_worker_process) do
17
+ Appsignal.stop("passenger")
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end