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,211 @@
1
+ # encoding: utf-8
2
+
3
+ # This module is intended to provide access to information about the host OS and
4
+ # [virtual] machine. It intentionally does no caching and maintains no state -
5
+ # caching should be handled by clients if needed. Methods should return nil if
6
+ # the requested information is unavailable.
7
+
8
+ require 'rbconfig'
9
+
10
+ module OneApm
11
+ module Agent
12
+ module SystemInfo
13
+ def self.ruby_os_identifier
14
+ RbConfig::CONFIG['target_os']
15
+ end
16
+
17
+ def self.clear_processor_info
18
+ @processor_info = nil
19
+ end
20
+
21
+ def self.get_processor_info
22
+ if @processor_info.nil?
23
+ case ruby_os_identifier
24
+
25
+ when /darwin/
26
+ @processor_info = {
27
+ :num_physical_packages => sysctl_value('hw.packages').to_i,
28
+ :num_physical_cores => sysctl_value('hw.physicalcpu_max').to_i,
29
+ :num_logical_processors => sysctl_value('hw.logicalcpu_max').to_i
30
+ }
31
+ # in case those don't work, try backup values
32
+ if @processor_info[:num_physical_cores] <= 0
33
+ @processor_info[:num_physical_cores] = sysctl_value('hw.physicalcpu').to_i
34
+ end
35
+ if @processor_info[:num_logical_processors] <= 0
36
+ @processor_info[:num_logical_processors] = sysctl_value('hw.logicalcpu').to_i
37
+ end
38
+ if @processor_info[:num_logical_processors] <= 0
39
+ @processor_info[:num_logical_processors] = sysctl_value('hw.ncpu').to_i
40
+ end
41
+
42
+ when /linux/
43
+ cpuinfo = proc_try_read('/proc/cpuinfo')
44
+ @processor_info = cpuinfo ? parse_cpuinfo(cpuinfo) : {}
45
+
46
+ when /freebsd/
47
+ @processor_info = {
48
+ :num_physical_packages => nil,
49
+ :num_physical_cores => nil,
50
+ :num_logical_processors => sysctl_value('hw.ncpu').to_i
51
+ }
52
+ end
53
+
54
+ # give nils for obviously wrong values
55
+ @processor_info.keys.each do |key|
56
+ value = @processor_info[key]
57
+ if value.is_a?(Numeric) && value <= 0
58
+ @processor_info[key] = nil
59
+ end
60
+ end
61
+ end
62
+
63
+ @processor_info
64
+ rescue
65
+ {}
66
+ end
67
+
68
+ def self.sysctl_value(name)
69
+ # make sure to redirect stderr so we don't spew if the name is unknown
70
+ `sysctl -n #{name} 2>/dev/null`
71
+ end
72
+
73
+ def self.parse_cpuinfo(cpuinfo)
74
+ # Build a hash of the form
75
+ # { [phys_id, core_id] => num_logical_processors_on_this_core }
76
+ cores = Hash.new(0)
77
+ phys_id = core_id = nil
78
+
79
+ total_processors = 0
80
+
81
+ cpuinfo.split("\n").map(&:strip).each do |line|
82
+ case line
83
+ when /^processor\s*:/
84
+ cores[[phys_id, core_id]] += 1 if phys_id && core_id
85
+ phys_id = core_id = nil # reset these values
86
+ total_processors += 1
87
+ when /^physical id\s*:(.*)/
88
+ phys_id = $1.strip.to_i
89
+ when /^core id\s*:(.*)/
90
+ core_id = $1.strip.to_i
91
+ end
92
+ end
93
+ cores[[phys_id, core_id]] += 1 if phys_id && core_id
94
+
95
+ num_physical_packages = cores.keys.map(&:first).uniq.size
96
+ num_physical_cores = cores.size
97
+ num_logical_processors = cores.values.reduce(0,:+)
98
+
99
+ if num_physical_cores == 0
100
+ num_logical_processors = total_processors
101
+
102
+ if total_processors == 1
103
+ # Some older, single-core processors might not list ids,
104
+ # so we'll just mark them all 1.
105
+ num_physical_packages = 1
106
+ num_physical_cores = 1
107
+ else
108
+ # We have no way of knowing how many packages or cores
109
+ # we have, even though we know how many processors there are.
110
+ num_physical_packages = nil
111
+ num_physical_cores = nil
112
+ end
113
+ end
114
+
115
+ {
116
+ :num_physical_packages => num_physical_packages,
117
+ :num_physical_cores => num_physical_cores,
118
+ :num_logical_processors => num_logical_processors
119
+ }
120
+ end
121
+
122
+ def self.num_physical_packages ; get_processor_info[:num_physical_packages ] end
123
+ def self.num_physical_cores ; get_processor_info[:num_physical_cores ] end
124
+ def self.num_logical_processors
125
+ processor_count = get_processor_info[:num_logical_processors]
126
+
127
+ if processor_count.nil?
128
+ OneApm::Agent.logger.warn("Failed to determine processor count, assuming 1")
129
+ processor_count = 1
130
+ end
131
+
132
+ processor_count
133
+ end
134
+
135
+ def self.processor_arch
136
+ RbConfig::CONFIG['target_cpu']
137
+ end
138
+
139
+ def self.os_version
140
+ proc_try_read('/proc/version')
141
+ end
142
+
143
+ def self.docker_container_id
144
+ return unless ruby_os_identifier =~ /linux/
145
+
146
+ cgroup_info = proc_try_read('/proc/self/cgroup')
147
+ return unless cgroup_info
148
+
149
+ parse_docker_container_id(cgroup_info)
150
+ end
151
+
152
+ def self.parse_docker_container_id(cgroup_info)
153
+ cpu_cgroup = parse_cgroup_ids(cgroup_info)['cpu']
154
+ return unless cpu_cgroup
155
+
156
+ case cpu_cgroup
157
+ # docker native driver w/out systemd (fs)
158
+ when %r{^/docker/([0-9a-f]+)$} then $1
159
+ # docker native driver with systemd
160
+ when %r{^/system\.slice/docker-([0-9a-f]+)\.scope$} then $1
161
+ # docker lxc driver
162
+ when %r{^/lxc/([0-9a-f]+)$} then $1
163
+ # not in any cgroup
164
+ when '/' then nil
165
+ # in a cgroup, but we don't recognize its format
166
+ else
167
+ ::OneApm::Agent.logger.debug("Ignoring unrecognized cgroup ID format: '#{cpu_cgroup}'")
168
+ nil
169
+ end
170
+ end
171
+
172
+ def self.parse_cgroup_ids(cgroup_info)
173
+ cgroup_ids = {}
174
+
175
+ cgroup_info.split("\n").each do |line|
176
+ parts = line.split(':')
177
+ next unless parts.size == 3
178
+ _, subsystems, cgroup_id = parts
179
+ subsystems = subsystems.split(',')
180
+ subsystems.each do |subsystem|
181
+ cgroup_ids[subsystem] = cgroup_id
182
+ end
183
+ end
184
+
185
+ cgroup_ids
186
+ end
187
+
188
+ # A File.read against /(proc|sysfs)/* can hang with some older Linuxes.
189
+ # See https://bugzilla.redhat.com/show_bug.cgi?id=604887, RUBY-736, and
190
+ # https://github.com/opscode/ohai/commit/518d56a6cb7d021b47ed3d691ecf7fba7f74a6a7
191
+ # for details on why we do it this way.
192
+ def self.proc_try_read(path)
193
+ return nil unless File.exist?(path)
194
+ content = ''
195
+ File.open(path) do |f|
196
+ loop do
197
+ begin
198
+ content << f.read_nonblock(4096)
199
+ rescue EOFError
200
+ break
201
+ rescue Errno::EWOULDBLOCK, Errno::EAGAIN
202
+ content = nil
203
+ break # don't select file handle, just give up
204
+ end
205
+ end
206
+ end
207
+ content
208
+ end
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ # Copyright: (C) 2008 David Vollbracht & Philippe Hanrigou
4
+
5
+ # This code was borrowed from the system_timer gem under the terms
6
+ # of the Ruby license. It has been slightly modified.
7
+
8
+ # Defines the constant TimerLib to the appropriate timeout library
9
+ module OneApm
10
+
11
+ begin
12
+ # Try to use the SystemTimer gem instead of Ruby's timeout library
13
+ # when running on Ruby 1.8.x. See:
14
+ # http://ph7spot.com/articles/system_timer
15
+ # We don't want to bother trying to load SystemTimer on jruby,
16
+ # ruby 1.9+ and rbx.
17
+ if !defined?(RUBY_ENGINE) || (RUBY_ENGINE == 'ruby' && RUBY_VERSION < '1.9.0')
18
+ require 'system_timer'
19
+ TimerLib = SystemTimer
20
+ else
21
+ require 'timeout'
22
+ TimerLib = Timeout
23
+ end
24
+ rescue LoadError
25
+ require 'timeout'
26
+ TimerLib = Timeout
27
+ end
28
+
29
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class VersionNumber
5
+ include Comparable
6
+
7
+ attr_reader :parts
8
+
9
+ def initialize(version_string)
10
+ version_string ||= '1.0.0'
11
+ @parts = version_string.split('.').map{|n| n =~ /^\d+$/ ? n.to_i : n}
12
+ end
13
+
14
+ def major_version; @parts[0]; end
15
+ def minor_version; @parts[1]; end
16
+ def tiny_version; @parts[2]; end
17
+
18
+ def <=>(other)
19
+ other = self.class.new(other) if other.is_a? String
20
+ self.class.compare(self.parts, other.parts)
21
+ end
22
+
23
+ def to_s
24
+ @parts.join(".")
25
+ end
26
+
27
+ def hash
28
+ @parts.hash
29
+ end
30
+
31
+ def eql? other
32
+ (self <=> other) == 0
33
+ end
34
+
35
+ private
36
+
37
+ def self.compare(parts1, parts2)
38
+ a, b = parts1.first, parts2.first
39
+ case
40
+ when a.nil? && b.nil? then 0
41
+ when a.nil? then b.is_a?(Fixnum) ? -1 : 1
42
+ when b.nil? then -compare(parts2, parts1)
43
+ when a.to_s == b.to_s then compare(parts1[1..-1], parts2[1..-1])
44
+ when a.is_a?(String) then b.is_a?(Fixnum) ? -1 : (a <=> b)
45
+ when b.is_a?(String) then -compare(parts2, parts1)
46
+ else # they are both fixnums, not nil
47
+ a <=> b
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/support/language_support'
4
+ require 'one_apm/support/vm/mri_vm'
5
+ require 'one_apm/support/vm/jruby_vm'
6
+ require 'one_apm/support/vm/rubinius_vm'
7
+
8
+ module OneApm
9
+ module Support
10
+ module VM
11
+ def self.snapshot
12
+ vm.snapshot
13
+ end
14
+
15
+ def self.vm
16
+ @vm ||= create_vm
17
+ end
18
+
19
+ def self.create_vm
20
+ if OneApm::LanguageSupport.using_engine?('jruby')
21
+ JRubyVM.new
22
+ elsif OneApm::LanguageSupport.using_engine?('rbx')
23
+ RubiniusVM.new
24
+ else
25
+ MriVM.new
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require 'thread'
4
+ require 'one_apm/support/vm/snapshot'
5
+
6
+ module OneApm
7
+ module Support
8
+ module VM
9
+ class JRubyVM
10
+ def snapshot
11
+ snap = Snapshot.new
12
+ gather_stats(snap)
13
+ snap
14
+ end
15
+
16
+ def gather_stats(snap)
17
+ if supports?(:gc_runs)
18
+ gc_stats = GC.stat
19
+ snap.gc_runs = gc_stats[:count]
20
+ end
21
+
22
+ snap.thread_count = Thread.list.size
23
+ end
24
+
25
+ def supports?(key)
26
+ case key
27
+ when :gc_runs
28
+ RUBY_VERSION >= "1.9.2"
29
+ when :thread_count
30
+ true
31
+ else
32
+ false
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ # The GC::Profiler class available on MRI has to be reset periodically to avoid
4
+ # memory "leaking" in the underlying implementation. However, it's a major
5
+ # bummer for how we want to gather those statistics.
6
+ #
7
+ # This class comes to the rescue. It relies on being the only party to reset
8
+ # the underlying GC::Profiler, but otherwise gives us a steadily increasing
9
+ # total time.
10
+
11
+ module OneApm
12
+ module Support
13
+ module VM
14
+ class MonotonicGCProfiler
15
+ def initialize
16
+ @total_time_s = 0
17
+ @lock = Mutex.new
18
+ end
19
+
20
+ def total_time_s
21
+ if OneApm::LanguageSupport.gc_profiler_enabled?
22
+ # There's a race here if the next two lines don't execute as an atomic
23
+ # unit - we may end up double-counting some GC time in that scenario.
24
+ # Locking around them guarantees atomicity of the read/increment/reset
25
+ # sequence.
26
+ @lock.synchronize do
27
+ # The Ruby 1.9.x docs claim that GC::Profiler.total_time returns
28
+ # a value in milliseconds. They are incorrect - both 1.9.x and 2.x
29
+ # return values in seconds.
30
+ @total_time_s += ::GC::Profiler.total_time
31
+ ::GC::Profiler.clear
32
+ end
33
+ else
34
+ OneApm::Agent.logger.log_once(:warn, :gc_profiler_disabled,
35
+ "Tried to measure GC time, but GC::Profiler was not enabled.")
36
+ end
37
+
38
+ @total_time_s
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ require 'thread'
4
+ require 'one_apm/support/vm/snapshot'
5
+
6
+ module OneApm
7
+ module Support
8
+ module VM
9
+ class MriVM
10
+ def snapshot
11
+ snap = Snapshot.new
12
+ gather_stats(snap)
13
+ snap
14
+ end
15
+
16
+ def gather_stats(snap)
17
+ gather_gc_stats(snap)
18
+ gather_ruby_vm_stats(snap)
19
+ gather_thread_stats(snap)
20
+ gather_gc_time(snap)
21
+ end
22
+
23
+ def gather_gc_stats(snap)
24
+ if supports?(:gc_runs)
25
+ snap.gc_runs = GC.count
26
+ end
27
+
28
+ if GC.respond_to?(:stat)
29
+ gc_stats = GC.stat
30
+ snap.total_allocated_object = gc_stats[:total_allocated_objects] || gc_stats[:total_allocated_object]
31
+ snap.major_gc_count = gc_stats[:major_gc_count]
32
+ snap.minor_gc_count = gc_stats[:minor_gc_count]
33
+ snap.heap_live = gc_stats[:heap_live_slots] || gc_stats[:heap_live_slot] || gc_stats[:heap_live_num]
34
+ snap.heap_free = gc_stats[:heap_free_slots] || gc_stats[:heap_free_slot] || gc_stats[:heap_free_num]
35
+ end
36
+ end
37
+
38
+ def gather_gc_time(snap)
39
+ if supports?(:gc_total_time)
40
+ snap.gc_total_time = OneApm::Agent.instance.monotonic_gc_profiler.total_time_s
41
+ end
42
+ end
43
+
44
+ def gather_ruby_vm_stats(snap)
45
+ if supports?(:method_cache_invalidations)
46
+ vm_stats = RubyVM.stat
47
+ snap.method_cache_invalidations = vm_stats[:global_method_state]
48
+ snap.constant_cache_invalidations = vm_stats[:global_constant_state]
49
+ end
50
+ end
51
+
52
+ def gather_thread_stats(snap)
53
+ snap.thread_count = Thread.list.size
54
+ end
55
+
56
+ def supports?(key)
57
+ case key
58
+ when :gc_runs
59
+ RUBY_VERSION >= '1.9.2'
60
+ when :gc_total_time
61
+ OneApm::LanguageSupport.gc_profiler_enabled?
62
+ when :total_allocated_object
63
+ RUBY_VERSION >= '2.0.0'
64
+ when :major_gc_count
65
+ RUBY_VERSION >= '2.1.0'
66
+ when :minor_gc_count
67
+ RUBY_VERSION >= '2.1.0'
68
+ when :heap_live
69
+ RUBY_VERSION >= '1.9.3'
70
+ when :heap_free
71
+ RUBY_VERSION >= '1.9.3'
72
+ when :method_cache_invalidations
73
+ RUBY_VERSION >= '2.1.0'
74
+ when :constant_cache_invalidations
75
+ RUBY_VERSION >= '2.1.0'
76
+ when :thread_count
77
+ true
78
+ else
79
+ false
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end