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,63 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Support
5
+ module HTTPClients
6
+ class ExconHTTPResponse
7
+ def initialize(response)
8
+ @response = response
9
+ # Since HTTP headers are case-insensitive, we normalize all of them to
10
+ # upper case here, and then also in our [](key) implementation.
11
+ @normalized_headers = {}
12
+ headers = response.respond_to?(:headers) ? response.headers : response[:headers]
13
+ (headers || {}).each do |key, val|
14
+ @normalized_headers[key.upcase] = val
15
+ end
16
+ end
17
+
18
+ def [](key)
19
+ @normalized_headers[key.upcase]
20
+ end
21
+
22
+ def to_hash
23
+ @normalized_headers.dup
24
+ end
25
+ end
26
+
27
+ class ExconHTTPRequest
28
+ def initialize(datum)
29
+ @datum = datum
30
+ end
31
+
32
+ def type
33
+ "Excon"
34
+ end
35
+
36
+ def host
37
+ if hostname = (self['host'] || self['Host'])
38
+ hostname.split(':').first
39
+ else
40
+ @datum[:host]
41
+ end
42
+ end
43
+
44
+ def method
45
+ @datum[:method].to_s.upcase
46
+ end
47
+
48
+ def [](key)
49
+ @datum[:headers][key]
50
+ end
51
+
52
+ def []=(key, value)
53
+ @datum[:headers] ||= {}
54
+ @datum[:headers][key] = value
55
+ end
56
+
57
+ def uri
58
+ URI.parse("#{@datum[:scheme]}://#{@datum[:host]}:#{@datum[:port]}#{@datum[:path]}")
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Support
5
+ module HTTPClients
6
+ class HTTPClientResponse
7
+ attr_reader :response
8
+
9
+ def initialize(response)
10
+ @response = response
11
+ end
12
+
13
+ def [](key)
14
+ response.headers.each do |k,v|
15
+ if key.downcase == k.downcase
16
+ return v
17
+ end
18
+ end
19
+ nil
20
+ end
21
+
22
+ def to_hash
23
+ response.headers
24
+ end
25
+ end
26
+
27
+ class HTTPClientRequest
28
+ attr_reader :request, :uri
29
+
30
+ def initialize(request)
31
+ @request = request
32
+ @uri = request.header.request_uri
33
+ end
34
+
35
+ def type
36
+ "HTTPClient"
37
+ end
38
+
39
+ def method
40
+ request.header.request_method
41
+ end
42
+
43
+ def host
44
+ if hostname = (self['host'] || self['Host'])
45
+ hostname.split(':').first
46
+ else
47
+ uri.host.to_s
48
+ end
49
+ end
50
+
51
+ def [](key)
52
+ request.headers[key]
53
+ end
54
+
55
+ def []=(key, value)
56
+ request.http_header[key] = value
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Support
5
+ module HTTPClients
6
+ class NetHTTPRequest
7
+ def initialize(connection, request)
8
+ @connection = connection
9
+ @request = request
10
+ end
11
+
12
+ def type
13
+ 'Net::HTTP'
14
+ end
15
+
16
+ def host
17
+ if hostname = self['host']
18
+ hostname.split(':').first
19
+ else
20
+ @connection.address
21
+ end
22
+ end
23
+
24
+ def method
25
+ @request.method
26
+ end
27
+
28
+ def [](key)
29
+ @request[key]
30
+ end
31
+
32
+ def []=(key, value)
33
+ @request[key] = value
34
+ end
35
+
36
+ def uri
37
+ case @request.path
38
+ when /^https?:\/\//
39
+ URI(@request.path)
40
+ else
41
+ scheme = @connection.use_ssl? ? 'https' : 'http'
42
+ URI("#{scheme}://#{@connection.address}:#{@connection.port}#{@request.path}")
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Support
5
+ module HTTPClients
6
+ class TyphoeusHTTPResponse
7
+ def initialize(response)
8
+ @response = response
9
+ end
10
+
11
+ def [](key)
12
+ unless headers.nil?
13
+ result = headers[key]
14
+
15
+ # Typhoeus 0.5.3 has a bug where asking the headers hash for a
16
+ # non-existent header will return the hash itself, not what we want.
17
+ result == headers ? nil : result
18
+ end
19
+ end
20
+
21
+ def to_hash
22
+ hash = {}
23
+ headers.each do |(k,v)|
24
+ hash[k] = v
25
+ end
26
+ hash
27
+ end
28
+
29
+ private
30
+
31
+ def headers
32
+ @response.headers
33
+ end
34
+ end
35
+
36
+ class TyphoeusHTTPRequest
37
+ def initialize(request)
38
+ @request = request
39
+ @uri = case request.url
40
+ when ::URI then request.url
41
+ else OneApm::Support::HTTPClients::URIUtil.parse_url(request.url)
42
+ end
43
+ end
44
+
45
+ def type
46
+ "Typhoeus"
47
+ end
48
+
49
+ def host
50
+ self['host'] || self['Host'] || @uri.host
51
+ end
52
+
53
+ def method
54
+ (@request.options[:method] || 'GET').to_s.upcase
55
+ end
56
+
57
+ def [](key)
58
+ return nil unless @request.options && @request.options[:headers]
59
+ @request.options[:headers][key]
60
+ end
61
+
62
+ def []=(key, value)
63
+ @request.options[:headers] ||= {}
64
+ @request.options[:headers][key] = value
65
+ end
66
+
67
+ def uri
68
+ @uri
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ # This module includes utilities for manipulating URIs, particularly from the
4
+ # context of Net::HTTP requests. We don't always have direct access to the full
5
+ # URI from our instrumentation points in Net::HTTP, and we want to filter out
6
+ # some URI parts before saving URIs from instrumented calls - logic for that
7
+ # lives here.
8
+
9
+ module OneApm
10
+ module Support
11
+ module HTTPClients
12
+ module URIUtil
13
+
14
+ def self.filter_uri(original)
15
+ filtered = original.dup
16
+ filtered.user = nil
17
+ filtered.password = nil
18
+ filtered.query = nil
19
+ filtered.fragment = nil
20
+ filtered.to_s
21
+ end
22
+
23
+ # There are valid URI strings that some HTTP client libraries will
24
+ # accept that the stdlib URI module doesn't handle. If we find that
25
+ # Addressable is around, use that to normalize out our URL's.
26
+ def self.parse_url(url)
27
+ if defined?(::Addressable::URI)
28
+ address = ::Addressable::URI.parse(url)
29
+ address.normalize!
30
+ URI.parse(address.to_s)
31
+ else
32
+ URI.parse(url)
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/support/marshaller'
4
+
5
+ module OneApm
6
+ module Support
7
+ class JsonMarshaller < Marshaller
8
+
9
+ OK_YAJL_VERSION = OneApm::VersionNumber.new("1.2.1")
10
+
11
+ def initialize
12
+ ::OneApm::Agent.logger.info "Using JSON marshaller (#{OneApm::JSONWrapper.backend_name})"
13
+ warn_for_yajl
14
+ end
15
+
16
+ def warn_for_yajl
17
+ if defined?(::Yajl)
18
+ require 'yajl/version'
19
+ if OneApm::VersionNumber.new(::Yajl::VERSION) < OK_YAJL_VERSION
20
+ ::OneApm::Agent.logger.warn "Detected yajl-ruby version #{::Yajl::VERSION} which can cause segfaults with oneapm_rpm's thread profiling features. We strongly recommend you upgrade to the latest yajl-ruby version available."
21
+ end
22
+ end
23
+ rescue => err
24
+ ::OneApm::Agent.logger.warn "Failed trying to watch for problematic yajl-ruby version.", err
25
+ end
26
+
27
+ def dump(ruby, opts={})
28
+ prepared = prepare(ruby, opts)
29
+
30
+ if opts[:skip_normalization]
31
+ normalize_encodings = false
32
+ else
33
+ normalize_encodings = Agent.config[:normalize_json_string_encodings]
34
+ end
35
+
36
+ OneApm::JSONWrapper.dump prepared, :normalize => normalize_encodings
37
+ end
38
+
39
+ def load(data)
40
+ if data.nil? || data.empty?
41
+ ::OneApm::Agent.logger.error "Empty JSON response from collector: '#{data.inspect}'"
42
+ return nil
43
+ end
44
+
45
+ return_value OneApm::JSONWrapper.load(data)
46
+ rescue => e
47
+ ::OneApm::Agent.logger.debug "#{e.class.name} : #{e.message} encountered loading collector response: #{data}"
48
+ raise
49
+ end
50
+
51
+ def default_encoder
52
+ Encoders::Base64CompressedJSON
53
+ end
54
+
55
+ def self.is_supported?
56
+ OneApm::JSONWrapper.usable_for_collector_serialization?
57
+ end
58
+
59
+ def format
60
+ 'json'
61
+ end
62
+
63
+ def self.human_readable?
64
+ true # for some definitions of 'human'
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,130 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class JSONWrapper
5
+ def self.load_native_json
6
+ begin
7
+ require 'json' unless defined?(::JSON)
8
+
9
+ # yajl's replacement methods on ::JSON override both dump and generate.
10
+ # Because stdlib dump just calls generate, we end up calling into yajl
11
+ # when we don't want to. As such, we use generate directly instead of
12
+ # dump, although we have to fuss with defaults to make that ok.
13
+ generate_method = ::JSON.method(:generate)
14
+ if ::JSON.respond_to?(:dump_default_options)
15
+ options = ::JSON.dump_default_options
16
+ else
17
+ # These were the defaults from json 1.1.9 up to 1.6.1
18
+ options = { :allow_nan => true, :max_nesting => false }
19
+ end
20
+ @dump_method = Proc.new do |obj|
21
+ generate_method.call(obj, options)
22
+ end
23
+
24
+ @load_method = ::JSON.method(:load)
25
+ @backend_name = :json
26
+ return true
27
+ rescue StandardError, ScriptError
28
+ OneApm::Agent.logger.debug "%p while loading JSON library: %s" % [ err, err.message ] if
29
+ defined?( OneApm::Agent ) && OneApm::Agent.respond_to?( :logger )
30
+ end
31
+ end
32
+
33
+ def self.load_okjson
34
+ require 'one_apm/support/okjson'
35
+ @load_method = ::OneApm::Support::OkJson.method(:decode)
36
+ @dump_method = ::OneApm::Support::OkJson.method(:encode)
37
+ @backend_name = :okjson
38
+ end
39
+
40
+ load_native_json or load_okjson
41
+
42
+ def self.usable_for_collector_serialization?
43
+ @backend_name == :json
44
+ end
45
+
46
+ def self.backend_name
47
+ @backend_name
48
+ end
49
+
50
+ def self.normalize_string(s)
51
+ choose_normalizer unless @normalizer
52
+ @normalizer.normalize(s)
53
+ end
54
+
55
+ def self.choose_normalizer
56
+ if OneApm::LanguageSupport.supports_string_encodings?
57
+ @normalizer = EncodingNormalizer
58
+ else
59
+ @normalizer = IconvNormalizer
60
+ end
61
+ end
62
+
63
+ class EncodingNormalizer
64
+ def self.normalize(s)
65
+ encoding = s.encoding
66
+ if (encoding == Encoding::UTF_8 || encoding == Encoding::ISO_8859_1) && s.valid_encoding?
67
+ return s
68
+ end
69
+
70
+ # If the encoding is not valid, or it's ASCII-8BIT, we know conversion to
71
+ # UTF-8 is likely to fail, so treat it as ISO-8859-1 (byte-preserving).
72
+ normalized = s.dup
73
+ if encoding == Encoding::ASCII_8BIT || !s.valid_encoding?
74
+ normalized.force_encoding(Encoding::ISO_8859_1)
75
+ else
76
+ # Encoding is valid and non-binary, so it might be cleanly convertible
77
+ # to UTF-8. Give it a try and fall back to ISO-8859-1 if it fails.
78
+ begin
79
+ normalized.encode!(Encoding::UTF_8)
80
+ rescue
81
+ normalized.force_encoding(Encoding::ISO_8859_1)
82
+ end
83
+ end
84
+ normalized
85
+ end
86
+ end
87
+
88
+ class IconvNormalizer
89
+ def self.normalize(s)
90
+ if @iconv.nil?
91
+ require 'iconv'
92
+ @iconv = Iconv.new('utf-8', 'iso-8859-1')
93
+ end
94
+ @iconv.iconv(s)
95
+ end
96
+ end
97
+
98
+ def self.normalize(object)
99
+ case object
100
+ when String
101
+ normalize_string(object)
102
+ when Symbol
103
+ normalize_string(object.to_s)
104
+ when Array
105
+ return object if object.empty?
106
+ object.map { |x| normalize(x) }
107
+ when Hash
108
+ return object if object.empty?
109
+ hash = {}
110
+ object.each_pair do |k, v|
111
+ k = normalize_string(k) if k.is_a?(String)
112
+ k = normalize_string(k.to_s) if k.is_a?(Symbol)
113
+ hash[k] = normalize(v)
114
+ end
115
+ hash
116
+ else
117
+ object
118
+ end
119
+ end
120
+
121
+ def self.dump(object, options={})
122
+ object = normalize(object) if options[:normalize]
123
+ @dump_method.call(object)
124
+ end
125
+
126
+ def self.load(string)
127
+ @load_method.call(string)
128
+ end
129
+ end
130
+ end