oneapm_rpm 1.1.0

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 (234) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.rubocop.yml +725 -0
  4. data/Gemfile +3 -0
  5. data/Guardfile +7 -0
  6. data/LICENSE +1 -0
  7. data/README.md +3 -0
  8. data/config/cert/cacert.pem +1177 -0
  9. data/config/database.yml +5 -0
  10. data/lib/initializers/goliath.rb +11 -0
  11. data/lib/initializers/other.rb +1 -0
  12. data/lib/initializers/rails.rb +15 -0
  13. data/lib/one_apm/agent.rb +253 -0
  14. data/lib/one_apm/agent/agent.rb +283 -0
  15. data/lib/one_apm/agent/agent/connect.rb +175 -0
  16. data/lib/one_apm/agent/agent/container_data_manager.rb +218 -0
  17. data/lib/one_apm/agent/agent/forkable_dispatcher_functions.rb +96 -0
  18. data/lib/one_apm/agent/agent/helpers.rb +45 -0
  19. data/lib/one_apm/agent/agent/start.rb +226 -0
  20. data/lib/one_apm/agent/agent/start_worker_thread.rb +148 -0
  21. data/lib/one_apm/agent/busy_calculator.rb +115 -0
  22. data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +181 -0
  23. data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +336 -0
  24. data/lib/one_apm/agent/database.rb +308 -0
  25. data/lib/one_apm/agent/database/active_record_helper.rb +80 -0
  26. data/lib/one_apm/agent/database/obfuscation_helpers.rb +76 -0
  27. data/lib/one_apm/agent/database/obfuscator.rb +78 -0
  28. data/lib/one_apm/agent/database/postgres_explain_obfuscator.rb +45 -0
  29. data/lib/one_apm/agent/datastores.rb +175 -0
  30. data/lib/one_apm/agent/datastores/metric_helper.rb +83 -0
  31. data/lib/one_apm/agent/datastores/mongo.rb +27 -0
  32. data/lib/one_apm/agent/datastores/mongo/metric_translator.rb +189 -0
  33. data/lib/one_apm/agent/datastores/mongo/obfuscator.rb +37 -0
  34. data/lib/one_apm/agent/datastores/mongo/statement_formatter.rb +51 -0
  35. data/lib/one_apm/agent/event/event_listener.rb +40 -0
  36. data/lib/one_apm/agent/event/event_loop.rb +191 -0
  37. data/lib/one_apm/agent/event/worker_loop.rb +97 -0
  38. data/lib/one_apm/agent/harvester.rb +48 -0
  39. data/lib/one_apm/agent/inbound_request_monitor.rb +30 -0
  40. data/lib/one_apm/agent/javascript_instrumentor.rb +186 -0
  41. data/lib/one_apm/agent/pipe/pipe_channel_manager.rb +275 -0
  42. data/lib/one_apm/agent/pipe/pipe_service.rb +81 -0
  43. data/lib/one_apm/agent/sampler.rb +55 -0
  44. data/lib/one_apm/agent/sampler_collection.rb +65 -0
  45. data/lib/one_apm/agent/samplers/cpu_sampler.rb +49 -0
  46. data/lib/one_apm/agent/samplers/delayed_job_sampler.rb +109 -0
  47. data/lib/one_apm/agent/samplers/memory_sampler.rb +144 -0
  48. data/lib/one_apm/agent/samplers/object_sampler.rb +22 -0
  49. data/lib/one_apm/agent/samplers/vm_sampler.rb +124 -0
  50. data/lib/one_apm/agent/synthetics_monitor.rb +48 -0
  51. data/lib/one_apm/agent/threading/agent_thread.rb +74 -0
  52. data/lib/one_apm/agent/threading/backtrace_node.rb +133 -0
  53. data/lib/one_apm/agent/threading/backtrace_service.rb +259 -0
  54. data/lib/one_apm/agent/threading/thread_profile.rb +155 -0
  55. data/lib/one_apm/collector/collector/helper.rb +139 -0
  56. data/lib/one_apm/collector/collector/http_connection.rb +254 -0
  57. data/lib/one_apm/collector/collector/server_methods.rb +71 -0
  58. data/lib/one_apm/collector/collector_service.rb +123 -0
  59. data/lib/one_apm/collector/commands/agent_command.rb +17 -0
  60. data/lib/one_apm/collector/commands/thread_profiler_session.rb +108 -0
  61. data/lib/one_apm/collector/commands/xray_session.rb +53 -0
  62. data/lib/one_apm/collector/commands/xray_session_collection.rb +156 -0
  63. data/lib/one_apm/collector/containers/agent_command_router.rb +153 -0
  64. data/lib/one_apm/collector/containers/custom_event_aggregator.rb +94 -0
  65. data/lib/one_apm/collector/containers/error_collector.rb +349 -0
  66. data/lib/one_apm/collector/containers/sql_sampler.rb +331 -0
  67. data/lib/one_apm/collector/containers/stats_engine.rb +34 -0
  68. data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +249 -0
  69. data/lib/one_apm/collector/containers/transaction_sampler.rb +352 -0
  70. data/lib/one_apm/collector/containers/utilization_data.rb +36 -0
  71. data/lib/one_apm/collector/stats_engine/gc_profiler.rb +106 -0
  72. data/lib/one_apm/collector/stats_engine/metric_stats.rb +243 -0
  73. data/lib/one_apm/collector/stats_engine/stats_hash.rb +105 -0
  74. data/lib/one_apm/configuration.rb +429 -0
  75. data/lib/one_apm/configuration/autostart.rb +41 -0
  76. data/lib/one_apm/configuration/default_source.rb +1026 -0
  77. data/lib/one_apm/configuration/environment_source.rb +113 -0
  78. data/lib/one_apm/configuration/high_security_source.rb +56 -0
  79. data/lib/one_apm/configuration/manual_source.rb +13 -0
  80. data/lib/one_apm/configuration/server_source.rb +60 -0
  81. data/lib/one_apm/configuration/yaml_source.rb +134 -0
  82. data/lib/one_apm/errors/agent_errors.rb +26 -0
  83. data/lib/one_apm/errors/internal_agent_error.rb +16 -0
  84. data/lib/one_apm/errors/noticed_error.rb +79 -0
  85. data/lib/one_apm/frameworks/external.rb +15 -0
  86. data/lib/one_apm/frameworks/rails.rb +103 -0
  87. data/lib/one_apm/frameworks/rails3.rb +37 -0
  88. data/lib/one_apm/frameworks/rails4.rb +21 -0
  89. data/lib/one_apm/frameworks/ruby.rb +21 -0
  90. data/lib/one_apm/frameworks/sinatra.rb +12 -0
  91. data/lib/one_apm/inst/3rd/active_merchant.rb +35 -0
  92. data/lib/one_apm/inst/3rd/acts_as_solr.rb +70 -0
  93. data/lib/one_apm/inst/3rd/authlogic.rb +23 -0
  94. data/lib/one_apm/inst/3rd/sunspot.rb +31 -0
  95. data/lib/one_apm/inst/background_job/active_job.rb +88 -0
  96. data/lib/one_apm/inst/background_job/delayed_job.rb +52 -0
  97. data/lib/one_apm/inst/background_job/delayed_job_injection.rb +8 -0
  98. data/lib/one_apm/inst/background_job/resque.rb +107 -0
  99. data/lib/one_apm/inst/background_job/sidekiq.rb +64 -0
  100. data/lib/one_apm/inst/dispatcher/passenger.rb +25 -0
  101. data/lib/one_apm/inst/dispatcher/rainbows.rb +23 -0
  102. data/lib/one_apm/inst/framework/grape.rb +94 -0
  103. data/lib/one_apm/inst/framework/padrino.rb +30 -0
  104. data/lib/one_apm/inst/framework/sinatra.rb +185 -0
  105. data/lib/one_apm/inst/framework/sinatra/ignorer.rb +50 -0
  106. data/lib/one_apm/inst/framework/sinatra/transaction_namer.rb +54 -0
  107. data/lib/one_apm/inst/http_clients/curb.rb +189 -0
  108. data/lib/one_apm/inst/http_clients/excon.rb +70 -0
  109. data/lib/one_apm/inst/http_clients/excon/connection.rb +31 -0
  110. data/lib/one_apm/inst/http_clients/excon/middleware.rb +55 -0
  111. data/lib/one_apm/inst/http_clients/httpclient.rb +44 -0
  112. data/lib/one_apm/inst/http_clients/net.rb +34 -0
  113. data/lib/one_apm/inst/http_clients/typhoeus.rb +76 -0
  114. data/lib/one_apm/inst/nosql/memcache.rb +134 -0
  115. data/lib/one_apm/inst/nosql/mongo.rb +126 -0
  116. data/lib/one_apm/inst/nosql/mongo_moped.rb +85 -0
  117. data/lib/one_apm/inst/nosql/redis.rb +83 -0
  118. data/lib/one_apm/inst/orm/active_record.rb +99 -0
  119. data/lib/one_apm/inst/orm/active_record_4.rb +28 -0
  120. data/lib/one_apm/inst/orm/data_mapper.rb +180 -0
  121. data/lib/one_apm/inst/orm/sequel.rb +47 -0
  122. data/lib/one_apm/inst/rack.rb +38 -0
  123. data/lib/one_apm/inst/rack/rack.rb +44 -0
  124. data/lib/one_apm/inst/rack/rack_builder.rb +51 -0
  125. data/lib/one_apm/inst/rails/action_controller.rb +118 -0
  126. data/lib/one_apm/inst/rails/action_web_service.rb +44 -0
  127. data/lib/one_apm/inst/rails/errors.rb +43 -0
  128. data/lib/one_apm/inst/rails3/action_controller.rb +172 -0
  129. data/lib/one_apm/inst/rails3/errors.rb +43 -0
  130. data/lib/one_apm/inst/rails4/action_controller.rb +27 -0
  131. data/lib/one_apm/inst/rails4/action_controller_subscriber.rb +121 -0
  132. data/lib/one_apm/inst/rails4/action_view.rb +23 -0
  133. data/lib/one_apm/inst/rails4/action_view_subscriber.rb +93 -0
  134. data/lib/one_apm/inst/rails4/active_record_subscriber.rb +96 -0
  135. data/lib/one_apm/inst/rails4/errors.rb +42 -0
  136. data/lib/one_apm/inst/rails_middleware.rb +40 -0
  137. data/lib/one_apm/inst/support/evented_subscriber.rb +98 -0
  138. data/lib/one_apm/inst/support/ignore_actions.rb +39 -0
  139. data/lib/one_apm/inst/support/queue_time.rb +76 -0
  140. data/lib/one_apm/inst/transaction_base.rb +405 -0
  141. data/lib/one_apm/logger/agent_logger.rb +206 -0
  142. data/lib/one_apm/logger/audit_logger.rb +78 -0
  143. data/lib/one_apm/logger/memory_logger.rb +50 -0
  144. data/lib/one_apm/logger/null_logger.rb +19 -0
  145. data/lib/one_apm/metrics/metric_data.rb +72 -0
  146. data/lib/one_apm/metrics/metric_spec.rb +82 -0
  147. data/lib/one_apm/metrics/stats.rb +173 -0
  148. data/lib/one_apm/probe.rb +16 -0
  149. data/lib/one_apm/probe/framework_loader.rb +53 -0
  150. data/lib/one_apm/probe/instance_methods.rb +105 -0
  151. data/lib/one_apm/probe/instrumentation.rb +60 -0
  152. data/lib/one_apm/rack/browser_monitoring.rb +144 -0
  153. data/lib/one_apm/rack/middleware_base.rb +27 -0
  154. data/lib/one_apm/rack/middleware_hooks.rb +17 -0
  155. data/lib/one_apm/rack/middleware_tracing.rb +81 -0
  156. data/lib/one_apm/rack/middleware_wrapper.rb +86 -0
  157. data/lib/one_apm/support/chained_call.rb +15 -0
  158. data/lib/one_apm/support/coerce.rb +81 -0
  159. data/lib/one_apm/support/collection_helper.rb +79 -0
  160. data/lib/one_apm/support/dotted_hash.rb +45 -0
  161. data/lib/one_apm/support/encoders.rb +34 -0
  162. data/lib/one_apm/support/environment_report.rb +127 -0
  163. data/lib/one_apm/support/event_buffer.rb +82 -0
  164. data/lib/one_apm/support/event_buffer/sampled_buffer.rb +45 -0
  165. data/lib/one_apm/support/event_buffer/sized_buffer.rb +21 -0
  166. data/lib/one_apm/support/event_buffer/synthetics_event_buffer.rb +40 -0
  167. data/lib/one_apm/support/helper.rb +49 -0
  168. data/lib/one_apm/support/hostname.rb +13 -0
  169. data/lib/one_apm/support/http_clients/curb_wrappers.rb +65 -0
  170. data/lib/one_apm/support/http_clients/excon_wrappers.rb +63 -0
  171. data/lib/one_apm/support/http_clients/httpclient_wrappers.rb +61 -0
  172. data/lib/one_apm/support/http_clients/net_http_wrappers.rb +48 -0
  173. data/lib/one_apm/support/http_clients/typhoeus_wrappers.rb +73 -0
  174. data/lib/one_apm/support/http_clients/uri_util.rb +39 -0
  175. data/lib/one_apm/support/json_marshaller.rb +68 -0
  176. data/lib/one_apm/support/json_wrapper.rb +130 -0
  177. data/lib/one_apm/support/language_support.rb +142 -0
  178. data/lib/one_apm/support/library_detection.rb +119 -0
  179. data/lib/one_apm/support/local_environment.rb +196 -0
  180. data/lib/one_apm/support/marshaller.rb +62 -0
  181. data/lib/one_apm/support/method_tracer.rb +334 -0
  182. data/lib/one_apm/support/method_tracer/helpers.rb +92 -0
  183. data/lib/one_apm/support/method_tracer/traced_method_stack.rb +103 -0
  184. data/lib/one_apm/support/obfuscator.rb +47 -0
  185. data/lib/one_apm/support/okjson.rb +601 -0
  186. data/lib/one_apm/support/parameter_filtering.rb +35 -0
  187. data/lib/one_apm/support/rules_engine.rb +56 -0
  188. data/lib/one_apm/support/rules_engine/replacement_rule.rb +80 -0
  189. data/lib/one_apm/support/rules_engine/segment_terms_rule.rb +46 -0
  190. data/lib/one_apm/support/server.rb +11 -0
  191. data/lib/one_apm/support/supported_versions.rb +257 -0
  192. data/lib/one_apm/support/system_info.rb +211 -0
  193. data/lib/one_apm/support/timer_lib.rb +29 -0
  194. data/lib/one_apm/support/version_number.rb +51 -0
  195. data/lib/one_apm/support/vm.rb +30 -0
  196. data/lib/one_apm/support/vm/jruby_vm.rb +38 -0
  197. data/lib/one_apm/support/vm/monotonic_gc_profiler.rb +43 -0
  198. data/lib/one_apm/support/vm/mri_vm.rb +85 -0
  199. data/lib/one_apm/support/vm/rubinius_vm.rb +129 -0
  200. data/lib/one_apm/support/vm/snapshot.rb +18 -0
  201. data/lib/one_apm/transaction.rb +336 -0
  202. data/lib/one_apm/transaction/class_methods.rb +132 -0
  203. data/lib/one_apm/transaction/instance_helpers.rb +82 -0
  204. data/lib/one_apm/transaction/metric_constants.rb +42 -0
  205. data/lib/one_apm/transaction/sample_buffer/force_persist_sample_buffer.rb +21 -0
  206. data/lib/one_apm/transaction/sample_buffer/slowest_sample_buffer.rb +21 -0
  207. data/lib/one_apm/transaction/sample_buffer/synthetics_sample_buffer.rb +21 -0
  208. data/lib/one_apm/transaction/sample_buffer/transaction_sample_buffer.rb +101 -0
  209. data/lib/one_apm/transaction/sample_buffer/xray_sample_buffer.rb +60 -0
  210. data/lib/one_apm/transaction/segment.rb +193 -0
  211. data/lib/one_apm/transaction/segment_summary.rb +51 -0
  212. data/lib/one_apm/transaction/thread_local_access.rb +73 -0
  213. data/lib/one_apm/transaction/transaction_analysis.rb +78 -0
  214. data/lib/one_apm/transaction/transaction_apdex.rb +20 -0
  215. data/lib/one_apm/transaction/transaction_cpu.rb +22 -0
  216. data/lib/one_apm/transaction/transaction_finish_append.rb +67 -0
  217. data/lib/one_apm/transaction/transaction_ignore.rb +33 -0
  218. data/lib/one_apm/transaction/transaction_jruby_functions.rb +40 -0
  219. data/lib/one_apm/transaction/transaction_metrics.rb +53 -0
  220. data/lib/one_apm/transaction/transaction_name.rb +90 -0
  221. data/lib/one_apm/transaction/transaction_namer.rb +49 -0
  222. data/lib/one_apm/transaction/transaction_sample.rb +204 -0
  223. data/lib/one_apm/transaction/transaction_sample_builder.rb +168 -0
  224. data/lib/one_apm/transaction/transaction_state.rb +149 -0
  225. data/lib/one_apm/transaction/transaction_summary.rb +28 -0
  226. data/lib/one_apm/transaction/transaction_synthetics.rb +40 -0
  227. data/lib/one_apm/transaction/transaction_timings.rb +54 -0
  228. data/lib/one_apm/version.rb +13 -0
  229. data/lib/oneapm_rpm.rb +16 -0
  230. data/lib/sequel/extensions/oneapm_instrumentation.rb +84 -0
  231. data/lib/sequel/plugins/oneapm_instrumentation.rb +66 -0
  232. data/oneapm.yml +135 -0
  233. data/oneapm_rpm.gemspec +58 -0
  234. metadata +474 -0
@@ -0,0 +1,142 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm::LanguageSupport
4
+ extend self
5
+
6
+ # need to use syck rather than psych when possible
7
+ def needs_syck?
8
+ !OneApm::LanguageSupport.using_engine?('jruby') &&
9
+ OneApm::LanguageSupport.using_version?('1.9.2')
10
+ end
11
+
12
+ @@forkable = nil
13
+ def can_fork?
14
+ # this is expensive to check, so we should only check once
15
+ return @@forkable if @@forkable != nil
16
+
17
+ if Process.respond_to?(:fork)
18
+ # if this is not 1.9.2 or higher, we have to make sure
19
+ @@forkable = ::RUBY_VERSION < '1.9.2' ? test_forkability : true
20
+ else
21
+ @@forkable = false
22
+ end
23
+
24
+ @@forkable
25
+ end
26
+
27
+ def using_engine?(engine)
28
+ if defined?(::RUBY_ENGINE)
29
+ ::RUBY_ENGINE == engine
30
+ else
31
+ engine == 'ruby'
32
+ end
33
+ end
34
+
35
+ def broken_gc?
36
+ OneApm::LanguageSupport.using_version?('1.8.7') &&
37
+ RUBY_PATCHLEVEL < 348 &&
38
+ !OneApm::LanguageSupport.using_engine?('jruby') &&
39
+ !OneApm::LanguageSupport.using_engine?('rbx')
40
+ end
41
+
42
+ def with_disabled_gc
43
+ if defined?(::GC) && ::GC.respond_to?(:disable)
44
+ val = nil
45
+ begin
46
+ ::GC.disable
47
+ val = yield
48
+ ensure
49
+ ::GC.enable
50
+ end
51
+ val
52
+ else
53
+ yield
54
+ end
55
+ end
56
+
57
+ def with_cautious_gc
58
+ if broken_gc?
59
+ with_disabled_gc { yield }
60
+ else
61
+ yield
62
+ end
63
+ end
64
+
65
+ def gc_profiler_usable?
66
+ if defined?(::GC::Profiler) && !jruby?
67
+ true
68
+ else
69
+ false
70
+ end
71
+ end
72
+
73
+ def gc_profiler_enabled?
74
+ if gc_profiler_usable? && ::GC::Profiler.enabled? && !::OneApm::Agent.config[:disable_gc_profiler]
75
+ true
76
+ else
77
+ false
78
+ end
79
+ end
80
+
81
+ def object_space_usable?
82
+ if defined?(::JRuby) && JRuby.respond_to?(:runtime)
83
+ JRuby.runtime.is_object_space_enabled
84
+ elsif defined?(::ObjectSpace) && !rubinius?
85
+ true
86
+ else
87
+ false
88
+ end
89
+ end
90
+
91
+ def jruby?
92
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
93
+ end
94
+
95
+ def rubinius?
96
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
97
+ end
98
+
99
+ def ree?
100
+ defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /Ruby Enterprise Edition/
101
+ end
102
+
103
+ def using_version?(version)
104
+ numbers = version.split('.')
105
+ numbers == ::RUBY_VERSION.split('.')[0, numbers.size]
106
+ end
107
+
108
+ def supports_string_encodings?
109
+ RUBY_VERSION >= '1.9.0'
110
+ end
111
+
112
+ def test_forkability
113
+ child = Process.fork { exit! }
114
+ # calling wait here doesn't seem like it should necessary, but it seems to
115
+ # resolve some weird edge cases with resque forking.
116
+ Process.wait child
117
+ true
118
+ rescue NotImplementedError
119
+ false
120
+ end
121
+
122
+ def constant_is_defined?(const_name)
123
+ const_name.to_s.sub(/\A::/,'').split('::').inject(Object) do |namespace, name|
124
+ begin
125
+ result = namespace.const_get(name)
126
+
127
+ # const_get looks up the inheritence chain, so if it's a class
128
+ # in the constant make sure we found the one in our namespace.
129
+ #
130
+ # Can't help if the constant isn't a class...
131
+ if result.is_a?(Module)
132
+ expected_name = "#{namespace}::#{name}".gsub(/^Object::/, "")
133
+ return false unless expected_name == result.to_s
134
+ end
135
+
136
+ result
137
+ rescue NameError
138
+ false
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,119 @@
1
+ # encoding: utf-8
2
+
3
+ module LibraryDetection
4
+
5
+ module_function
6
+
7
+ @items = []
8
+
9
+ def defer(&block)
10
+ item = Dependent.new
11
+ item.instance_eval(&block)
12
+
13
+ if item.name
14
+ seen_names = @items.map { |i| i.name }.compact
15
+ if seen_names.include?(item.name)
16
+ OneApm::Agent.logger.warn("Refusing to re-register LibraryDetection block with name '#{item.name}'")
17
+ return @items
18
+ end
19
+ end
20
+
21
+ @items << item
22
+ end
23
+
24
+ def detect!
25
+ @items.each do |item|
26
+ if item.dependencies_satisfied?
27
+ item.execute
28
+ end
29
+ end
30
+ end
31
+
32
+ def dependency_by_name(name)
33
+ @items.find {|i| i.name == name }
34
+ end
35
+
36
+ def installed?(name)
37
+ item = dependency_by_name(name)
38
+ item && item.executed
39
+ end
40
+
41
+ def items
42
+ @items
43
+ end
44
+
45
+ def items=(new_items)
46
+ @items = new_items
47
+ end
48
+
49
+ class Dependent
50
+ attr_reader :executed
51
+ attr_accessor :name
52
+ def executed!
53
+ @executed = true
54
+ end
55
+
56
+ attr_reader :dependencies
57
+
58
+ def initialize
59
+ @dependencies = []
60
+ @executes = []
61
+ @name = nil
62
+ end
63
+
64
+ def dependencies_satisfied?
65
+ !executed and check_dependencies
66
+ end
67
+
68
+ def execute
69
+ @executes.each do |x|
70
+ begin
71
+ x.call
72
+ rescue => err
73
+ OneApm::Agent.logger.error( "Error while installing #{self.name} instrumentation:", err )
74
+ break
75
+ end
76
+ end
77
+ ensure
78
+ executed!
79
+ end
80
+
81
+ def check_dependencies
82
+ return false unless allowed_by_config? && dependencies
83
+
84
+ dependencies.all? do |dep|
85
+ begin
86
+ dep.call
87
+ rescue => err
88
+ OneApm::Agent.logger.error( "Error while detecting #{self.name}:", err )
89
+ false
90
+ end
91
+ end
92
+ end
93
+
94
+ def depends_on
95
+ @dependencies << Proc.new
96
+ end
97
+
98
+ def allowed_by_config?
99
+ # If we don't have a name, can't check config so allow it
100
+ return true if self.name.nil?
101
+
102
+ key = "disable_#{self.name}".to_sym
103
+ if (::OneApm::Agent.config[key] == true)
104
+ ::OneApm::Agent.logger.debug("Not installing #{self.name} instrumentation because of configuration #{key}")
105
+ false
106
+ else
107
+ true
108
+ end
109
+ end
110
+
111
+ def named(new_name)
112
+ self.name = new_name
113
+ end
114
+
115
+ def executes
116
+ @executes << Proc.new
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,196 @@
1
+ # encoding: utf-8
2
+
3
+ require 'set'
4
+ require 'one_apm/version'
5
+
6
+ module OneApm
7
+ # This class is responsible for determining the 'dispatcher' in use by the
8
+ # current process. The dispatcher might be a recognized web server such as
9
+ # unicorn or passenger, a background job processor such as resque or sidekiq,
10
+ # or nil for unknown.
11
+ #
12
+ # Dispatcher detection is best-effort, and serves two purposes:
13
+ #
14
+ # 1. For some dispatchers, we need to apply specific workarounds in order for
15
+ # the agent to work correctly.
16
+ # 2. When reading logs, since multiple processes on a given host might write
17
+ # into the same log, it's useful to be able to identify what kind of
18
+ # process a given PID mapped to.
19
+ #
20
+ # Overriding the dispatcher is possible via the ONE_APM_DISPATCHER
21
+ # environment variable, but this should not generally be necessary unless
22
+ # you're on a dispatcher that falls into category 1 above, and our detection
23
+ # logic isn't working correctly.
24
+ #
25
+ # If the environment can't be determined, it will be set to nil.
26
+ #
27
+ # OneApm::LocalEnvironment should be accessed through OneApm::Probe#env (via the OneApm::Probe singleton).
28
+ class LocalEnvironment
29
+ def discovered_dispatcher
30
+ discover_dispatcher unless @discovered_dispatcher
31
+ @discovered_dispatcher
32
+ end
33
+
34
+ def initialize
35
+ # Extend self with any any submodules of LocalEnvironment. These can override
36
+ # the discover methods to discover new framworks and dispatchers.
37
+ OneApm::LocalEnvironment.constants.each do | const |
38
+ mod = OneApm::LocalEnvironment.const_get const
39
+ self.extend mod if mod.instance_of? Module
40
+ end
41
+
42
+ discover_dispatcher
43
+ end
44
+
45
+ # Runs through all the objects in ObjectSpace to find the first one that
46
+ # match the provided class
47
+ def find_class_in_object_space(klass)
48
+ if OneApm::LanguageSupport.object_space_usable?
49
+ ObjectSpace.each_object(klass) do |x|
50
+ return x
51
+ end
52
+ end
53
+ return nil
54
+ end
55
+
56
+ private
57
+
58
+ def discover_dispatcher
59
+ dispatchers = %w[
60
+ passenger
61
+ torquebox
62
+ trinidad
63
+ glassfish
64
+ resque
65
+ sidekiq
66
+ delayed_job
67
+ puma
68
+ thin
69
+ mongrel
70
+ fastcgi
71
+ rainbows
72
+ unicorn
73
+ goliath
74
+ webrick
75
+ ]
76
+ while dispatchers.any? && @discovered_dispatcher.nil?
77
+ send 'check_for_'+(dispatchers.shift)
78
+ end
79
+ end
80
+
81
+ def check_for_torquebox
82
+ return unless defined?(::JRuby) &&
83
+ ( org.torquebox::TorqueBox rescue nil)
84
+ @discovered_dispatcher = :torquebox
85
+ end
86
+
87
+ def check_for_glassfish
88
+ return unless defined?(::JRuby) &&
89
+ (((com.sun.grizzly.jruby.rack.DefaultRackApplicationFactory rescue nil) &&
90
+ defined?(com::sun::grizzly::jruby::rack::DefaultRackApplicationFactory)) ||
91
+ (jruby_rack? && defined?(::GlassFish::Server)))
92
+ @discovered_dispatcher = :glassfish
93
+ end
94
+
95
+ def check_for_trinidad
96
+ return unless defined?(::JRuby) && jruby_rack? && defined?(::Trinidad::Server)
97
+ @discovered_dispatcher = :trinidad
98
+ end
99
+
100
+ def jruby_rack?
101
+ defined?(JRuby::Rack::VERSION)
102
+ end
103
+
104
+ def check_for_webrick
105
+ return unless defined?(::WEBrick) && defined?(::WEBrick::VERSION)
106
+ @discovered_dispatcher = :webrick
107
+ end
108
+
109
+ def check_for_fastcgi
110
+ return unless defined?(::FCGI)
111
+ @discovered_dispatcher = :fastcgi
112
+ end
113
+
114
+ # this case covers starting by mongrel_rails
115
+ def check_for_mongrel
116
+ return unless defined?(::Mongrel) && defined?(::Mongrel::HttpServer)
117
+ @discovered_dispatcher = :mongrel
118
+ end
119
+
120
+ def check_for_unicorn
121
+ if (defined?(::Unicorn) && defined?(::Unicorn::HttpServer)) && OneApm::LanguageSupport.object_space_usable?
122
+ v = find_class_in_object_space(::Unicorn::HttpServer)
123
+ @discovered_dispatcher = :unicorn if v
124
+ end
125
+ end
126
+
127
+ def check_for_rainbows
128
+ if (defined?(::Rainbows) && defined?(::Rainbows::HttpServer)) && OneApm::LanguageSupport.object_space_usable?
129
+ v = find_class_in_object_space(::Rainbows::HttpServer)
130
+ @discovered_dispatcher = :rainbows if v
131
+ end
132
+ end
133
+
134
+ def check_for_puma
135
+ if defined?(::Puma) && File.basename($0) == 'puma'
136
+ @discovered_dispatcher = :puma
137
+ end
138
+ end
139
+
140
+ def check_for_delayed_job
141
+ if $0 =~ /delayed_job$/ || (File.basename($0) == 'rake' && ARGV.include?('jobs:work'))
142
+ @discovered_dispatcher = :delayed_job
143
+ end
144
+ end
145
+
146
+ def check_for_resque
147
+ has_queue = ENV['QUEUE'] || ENV['QUEUES']
148
+ resque_rake = executable == 'rake' && ARGV.include?('resque:work')
149
+ resque_pool_rake = executable == 'rake' && ARGV.include?('resque:pool')
150
+ resque_pool_executable = executable == 'resque-pool' && defined?(::Resque::Pool)
151
+
152
+ using_resque = defined?(::Resque) &&
153
+ (has_queue && resque_rake) ||
154
+ (resque_pool_executable || resque_pool_rake)
155
+
156
+ @discovered_dispatcher = :resque if using_resque
157
+ end
158
+
159
+ def check_for_sidekiq
160
+ if defined?(::Sidekiq) && File.basename($0) == 'sidekiq'
161
+ @discovered_dispatcher = :sidekiq
162
+ end
163
+ end
164
+
165
+ def check_for_thin
166
+ if defined?(::Thin) && defined?(::Thin::Server)
167
+ @discovered_dispatcher = :thin
168
+ end
169
+ end
170
+
171
+ def check_for_passenger
172
+ if defined?(::PhusionPassenger)
173
+ @discovered_dispatcher = :passenger
174
+ end
175
+ end
176
+
177
+ def check_for_goliath
178
+ if defined?(::Goliath) && defined?(::Goliath::API)
179
+ @discovered_dispatcher = :goliath
180
+ end
181
+ end
182
+
183
+ public
184
+ # outputs a human-readable description
185
+ def to_s
186
+ s = "LocalEnvironment["
187
+ s << ";dispatcher=#{@discovered_dispatcher}" if @discovered_dispatcher
188
+ s << "]"
189
+ end
190
+
191
+ def executable
192
+ File.basename($0)
193
+ end
194
+
195
+ end
196
+ end