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,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