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,113 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Configuration
5
+ class EnvironmentSource < OneApm::Support::DottedHash
6
+
7
+ SUPPORTED_PREFIXES = /^one_apm_|^oneapm_/i
8
+ SPECIAL_CASE_KEYS = [
9
+ 'ONE_APM_ENV', # read by OneApm::Probe::Frameworks::Ruby
10
+ 'ONE_APM_LOG' # read by set_log_file
11
+ ]
12
+
13
+ attr_accessor :alias_map, :type_map
14
+
15
+ def initialize
16
+ set_log_file
17
+ set_config_file
18
+
19
+ @alias_map = {}
20
+ @type_map = {}
21
+
22
+ DEFAULTS.each do |config_setting, value|
23
+ self.type_map[config_setting] = value[:type]
24
+ set_aliases(config_setting, value)
25
+ end
26
+
27
+ set_values_from_one_apm_environment_variables
28
+ end
29
+
30
+ def set_aliases(config_setting, value)
31
+ set_dotted_alias(config_setting)
32
+
33
+ return unless value[:aliases]
34
+ value[:aliases].each do |config_alias|
35
+ self.alias_map[config_alias] = config_setting
36
+ end
37
+ end
38
+
39
+ def set_dotted_alias(original_config_setting)
40
+ config_setting = original_config_setting.to_s
41
+
42
+ if config_setting.include? '.'
43
+ config_alias = config_setting.gsub(/\./,'_').to_sym
44
+ self.alias_map[config_alias] = original_config_setting
45
+ end
46
+ end
47
+
48
+ def set_log_file
49
+ if ENV['ONE_APM_LOG']
50
+ if ENV['ONE_APM_LOG'].upcase == 'STDOUT'
51
+ self[:log_file_path] = self[:log_file_name] = 'STDOUT'
52
+ else
53
+ self[:log_file_path] = File.dirname(ENV['ONE_APM_LOG'])
54
+ self[:log_file_name] = File.basename(ENV['ONE_APM_LOG'])
55
+ end
56
+ end
57
+ end
58
+
59
+ def set_config_file
60
+ self[:config_path] = ENV['OACONFIG'] if ENV['OACONFIG']
61
+ end
62
+
63
+ def set_values_from_one_apm_environment_variables
64
+ nr_env_var_keys = collect_one_apm_environment_variable_keys
65
+
66
+ nr_env_var_keys.each do |key|
67
+ next if SPECIAL_CASE_KEYS.include?(key.upcase)
68
+ set_value_from_environment_variable(key)
69
+ end
70
+ end
71
+
72
+ def set_value_from_environment_variable(key)
73
+ config_key = convert_environment_key_to_config_key(key)
74
+ set_key_by_type(config_key, key)
75
+ end
76
+
77
+ def set_key_by_type(config_key, environment_key)
78
+ value = ENV[environment_key]
79
+ type = self.type_map[config_key]
80
+
81
+ if type == String
82
+ self[config_key] = value
83
+ elsif type == Fixnum
84
+ self[config_key] = value.to_i
85
+ elsif type == Float
86
+ self[config_key] = value.to_f
87
+ elsif type == Symbol
88
+ self[config_key] = value.to_sym
89
+ elsif type == OneApm::Configuration::Boolean
90
+ if value =~ /false|off|no/i
91
+ self[config_key] = false
92
+ elsif value != nil
93
+ self[config_key] = true
94
+ end
95
+ else
96
+ ::OneApm::Agent.logger.info("#{environment_key} does not have a corresponding configuration setting (#{config_key} does not exist).")
97
+ ::OneApm::Agent.logger.info("Run `rake oneapm:config:docs` or visit https://oneapm.com/docs/ruby/ruby-agent-configuration to see a list of available configuration settings.")
98
+ self[config_key] = value
99
+ end
100
+ end
101
+
102
+ def convert_environment_key_to_config_key(key)
103
+ stripped_key = key.gsub(SUPPORTED_PREFIXES, '').downcase.to_sym
104
+ self.alias_map[stripped_key] || stripped_key
105
+ end
106
+
107
+ def collect_one_apm_environment_variable_keys
108
+ ENV.keys.select { |key| key.match(SUPPORTED_PREFIXES) }
109
+ end
110
+
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/configuration'
4
+
5
+ module OneApm
6
+ module Configuration
7
+ class HighSecuritySource < OneApm::Support::DottedHash
8
+
9
+ OFF = "off".freeze
10
+ RAW = "raw".freeze
11
+ OBFUSCATED = "obfuscated".freeze
12
+
13
+ SET_TO_OBFUSCATED = [RAW, OBFUSCATED]
14
+
15
+ def initialize(local_settings)
16
+ super({
17
+ :ssl => true,
18
+
19
+ :capture_params => false,
20
+ :'resque.capture_params' => false,
21
+ :'sidekiq.capture_params' => false,
22
+
23
+ # These aren't strictly necessary as add_custom_parameters is
24
+ # directly responsible for ignoring incoming param, but we disallow
25
+ # attributes by these settings just to be safe
26
+ :'transaction_tracer.capture_attributes' => false,
27
+ :'error_collector.capture_attributes' => false,
28
+ :'browser_monitoring.capture_attributes' => false,
29
+ :'analytics_events.capture_attributes' => false,
30
+
31
+ :'transaction_tracer.record_sql' => record_sql_setting(local_settings, :'transaction_tracer.record_sql'),
32
+ :'slow_sql.record_sql' => record_sql_setting(local_settings, :'slow_sql.record_sql'),
33
+ :'mongo.obfuscate_queries' => true,
34
+
35
+ :'custom_insights_events.enabled' => false,
36
+ :'strip_exception_messages.enabled' => true
37
+ })
38
+ end
39
+
40
+ def record_sql_setting(local_settings, key)
41
+ original_value = local_settings[key]
42
+ result = if SET_TO_OBFUSCATED.include?(original_value)
43
+ OBFUSCATED
44
+ else
45
+ OFF
46
+ end
47
+
48
+ if result != original_value
49
+ OneApm::Agent.logger.info("Disabling setting #{key}='#{original_value}' because high security mode is enabled. Value will be '#{result}'")
50
+ end
51
+
52
+ result
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/support/dotted_hash'
4
+
5
+ module OneApm
6
+ module Configuration
7
+ class ManualSource < OneApm::Support::DottedHash
8
+ def initialize(hash)
9
+ super(hash, true)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Configuration
5
+ class ServerSource < OneApm::Support::DottedHash
6
+
7
+ def initialize(hash, existing_config = {})
8
+ if hash['transaction_tracer']
9
+ transaction_threshold = hash['transaction_tracer']['transaction_threshold']
10
+ if transaction_threshold =~ /apdex_f/i
11
+ # when value is "apdex_f" remove the config and defer to default
12
+ hash['transaction_tracer'].delete('transaction_threshold')
13
+ else
14
+ hash['transaction_tracer']['transaction_threshold'] = transaction_threshold.to_f
15
+ end
16
+ end
17
+
18
+ if hash['browser_monitoring']
19
+ hash['browser_monitoring']['auto_instrument'] = hash['browser_monitoring']['transform']
20
+ end
21
+
22
+ if hash['web_transactions_apdex']
23
+ self[:web_transactions_apdex] = hash.delete('web_transactions_apdex')
24
+ end
25
+
26
+ dotted_hash = OneApm::Support::DottedHash.new(hash).to_hash
27
+ apply_feature_gates(dotted_hash, existing_config)
28
+
29
+ super(dotted_hash)
30
+ end
31
+
32
+ # These feature gates are not intended to be bullet-proof, but only to
33
+ # avoid the overhead of collecting and transmitting additional data if
34
+ # the user's subscription level precludes its use. The server is the
35
+ # ultimate authority regarding subscription levels, so we expect it to
36
+ # do the real enforcement there.
37
+ def apply_feature_gates(server_config, existing_config)
38
+ gated_features = {
39
+ :'transaction_tracer.enabled' => :collect_traces,
40
+ :'slow_sql.enabled' => :collect_traces,
41
+ :'error_collector.enabled' => :collect_errors,
42
+ :'analytics_events.enabled' => :collect_analytics_events,
43
+ :'custom_insights_events.enabled' => :collect_custom_events
44
+ }
45
+ gated_features.each do |feature, gate_key|
46
+ if server_config.has_key?(gate_key)
47
+ allowed_by_server = server_config[gate_key]
48
+ requested_value = ungated_value(feature, server_config, existing_config)
49
+ effective_value = (allowed_by_server && requested_value)
50
+ server_config[feature] = effective_value
51
+ end
52
+ end
53
+ end
54
+
55
+ def ungated_value(key, server_config, existing_config)
56
+ server_config.has_key?(key) ? server_config[key] : existing_config[key]
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,134 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/configuration'
4
+ require 'yaml'
5
+ require 'erb'
6
+
7
+ module OneApm
8
+ module Configuration
9
+ class YamlSource < OneApm::Support::DottedHash
10
+
11
+ attr_accessor :file_path
12
+
13
+ def initialize(path, env)
14
+ config = {}
15
+
16
+ begin
17
+ @file_path = validate_config_file_path(path)
18
+ return unless @file_path
19
+
20
+ OneApm::Agent.logger.info("Reading configuration from #{path} (#{Dir.pwd})")
21
+ raw_file = File.read(@file_path)
22
+ erb_file = process_erb(raw_file)
23
+ config = process_yaml(erb_file, env, config, @file_path)
24
+ rescue ScriptError, StandardError => e
25
+ ::OneApm::Agent.logger.error("Failed to read or parse configuration file at #{path}", e)
26
+ end
27
+
28
+ substitute_transaction_threshold(config)
29
+ booleanify_values(config, 'agent_enabled', 'enabled', 'monitor_daemons')
30
+
31
+ super(config, true)
32
+ end
33
+
34
+ protected
35
+
36
+ def validate_config_file_path(path)
37
+ expanded_path = File.expand_path(path)
38
+
39
+ if path.empty? || !File.exists?(expanded_path)
40
+ warn_missing_config_file(expanded_path)
41
+ return
42
+ end
43
+
44
+ expanded_path
45
+ end
46
+
47
+ def warn_missing_config_file(path)
48
+ based_on = 'unknown'
49
+ source = ::OneApm::Agent.config.source(:config_path)
50
+ candidate_paths = [path]
51
+
52
+ case source
53
+ when DefaultSource
54
+ based_on = 'defaults'
55
+ candidate_paths = OneApm::Agent.config[:config_search_paths].map do |p|
56
+ File.expand_path(p)
57
+ end
58
+ when EnvironmentSource
59
+ based_on = 'environment variable'
60
+ when ManualSource
61
+ based_on = 'API call'
62
+ end
63
+
64
+ OneApm::Agent.logger.warn(
65
+ "No configuration file found. Working directory = #{Dir.pwd}",
66
+ "Looked in these locations (based on #{based_on}): #{candidate_paths.join(", ")}"
67
+ )
68
+ end
69
+
70
+ def process_erb(file)
71
+ begin
72
+ # Exclude lines that are commented out so failing Ruby code in an
73
+ # ERB template commented at the YML level is fine. Leave the line,
74
+ # though, so ERB line numbers remain correct.
75
+ file.gsub!(/^\s*#.*$/, '#')
76
+
77
+ # Next two are for populating the oneapm.yml via erb binding, necessary
78
+ # when using the default oneapm.yml file
79
+ generated_for_user = ''
80
+ license_key = ''
81
+
82
+ ERB.new(file).result(binding)
83
+ rescue ScriptError, StandardError => e
84
+ ::OneApm::Agent.logger.error("Failed ERB processing configuration file. This is typically caused by a Ruby error in <% %> templating blocks in your oneapm.yml file.", e)
85
+ nil
86
+ end
87
+ end
88
+
89
+ def process_yaml(file, env, config, path)
90
+ if file
91
+ confighash = with_yaml_engine { YAML.load(file) }
92
+ ::OneApm::Agent.logger.error("Config file at #{path} doesn't include a '#{env}' section!") unless confighash.key?(env)
93
+
94
+ config = confighash[env] || {}
95
+ end
96
+
97
+ config
98
+ end
99
+
100
+ def substitute_transaction_threshold(config)
101
+ if config['transaction_tracer'] &&
102
+ config['transaction_tracer']['transaction_threshold'] =~ /apdex_f/i
103
+ # when value is "apdex_f" remove the config and defer to default
104
+ config['transaction_tracer'].delete('transaction_threshold')
105
+ end
106
+ end
107
+
108
+ def with_yaml_engine
109
+ return yield unless OneApm::LanguageSupport.needs_syck?
110
+
111
+ yamler = ::YAML::ENGINE.yamler
112
+ ::YAML::ENGINE.yamler = 'syck'
113
+ result = yield
114
+ ::YAML::ENGINE.yamler = yamler
115
+ result
116
+ end
117
+
118
+ def booleanify_values(config, *keys)
119
+ # auto means defer ro default
120
+ keys.each do |option|
121
+ if config[option] == 'auto'
122
+ config.delete(option)
123
+ elsif !config[option].nil? && !is_boolean?(config[option])
124
+ config[option] = !!(config[option] =~ /yes|on|true/i)
125
+ end
126
+ end
127
+ end
128
+
129
+ def is_boolean?(value)
130
+ value == !!value
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,26 @@
1
+ module OneApm
2
+ # An exception that is thrown by the server if the agent license is invalid.
3
+ class LicenseException < StandardError; end
4
+
5
+ # An exception that forces an agent to stop reporting until its mongrel is restarted.
6
+ class ForceDisconnectException < StandardError; end
7
+
8
+ # An exception that forces an agent to restart.
9
+ class ForceRestartException < StandardError; end
10
+
11
+ # Used to blow out of a periodic task without logging a an error, such as for routine
12
+ # failures.
13
+ class ServerConnectionException < StandardError; end
14
+
15
+ # When a post is either too large or poorly formatted we should
16
+ # drop it and not try to resend
17
+ class UnrecoverableServerException < ServerConnectionException; end
18
+
19
+ # An unrecoverable client-side error that prevents the agent from continuing
20
+ class UnrecoverableAgentException < ServerConnectionException; end
21
+
22
+ # An error while serializing data for the collector
23
+ class SerializationError < StandardError; end
24
+
25
+ class BackgroundLoadingError < StandardError; end
26
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ # This is the base class for all errors that we want to record through the
4
+ # OneApm::Collector::ErrorCollector#notice_agent_error API. It provides the
5
+ # standard support text at the front of the message, and is used for flagging
6
+ # agent errors when checking queue limits.
7
+
8
+ module OneApm
9
+ module Agent
10
+ class InternalAgentError < StandardError
11
+ def initialize(msg=nil)
12
+ super("Ruby agent internal error. Please contact support referencing this error.\n #{msg}")
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/support/helper'
4
+
5
+ # This class encapsulates an error that was noticed by OneApm in a managed app.
6
+ class OneApm::NoticedError
7
+ extend OneApm::CollectionHelper
8
+ include OneApm::Coerce
9
+
10
+ attr_accessor :path, :timestamp, :params, :message, :exception_class_name
11
+ attr_reader :exception_id, :is_internal
12
+
13
+ STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE = "Message removed by OneApm 'strip_exception_messages' setting"
14
+
15
+ def initialize(path, data, exception, timestamp = Time.now)
16
+ @exception_id = exception.object_id
17
+ @path = path
18
+ @params = OneApm::NoticedError.normalize_params(data)
19
+
20
+ @exception_class_name = exception.is_a?(Exception) ? exception.class.name : 'Error'
21
+
22
+ # It's critical that we not hold onto the exception class constant in this
23
+ # class. These objects get serialized for Resque to a process that might
24
+ # not have the original exception class loaded, so do all processing now
25
+ # while we have the actual exception!
26
+ @is_internal = (exception.class < OneApm::Agent::InternalAgentError)
27
+
28
+ if exception.nil?
29
+ @message = '<no message>'
30
+ elsif exception.respond_to?('original_exception')
31
+ @message = (exception.original_exception || exception).to_s
32
+ else # exception is not nil, but does not respond to original_exception
33
+ @message = exception.to_s
34
+ end
35
+
36
+
37
+ unless @message.is_a?(String)
38
+ # In pre-1.9.3, Exception.new({}).to_s.class != String
39
+ # That is, Exception#to_s may not return a String instance if one wasn't
40
+ # passed in upon creation of the Exception. So, try to generate a useful
41
+ # String representation of the exception message, falling back to failsafe
42
+ @message = String(@message.inspect) rescue '<unknown message type>'
43
+ end
44
+
45
+ # clamp long messages to 4k so that we don't send a lot of
46
+ # overhead across the wire
47
+ @message = @message[0..4095] if @message.length > 4096
48
+
49
+ # replace error message if enabled
50
+ if OneApm::Agent.config[:'strip_exception_messages.enabled'] &&
51
+ !self.class.passes_message_whitelist(exception.class)
52
+ @message = STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE
53
+ end
54
+
55
+ @timestamp = timestamp
56
+ end
57
+
58
+ def ==(other)
59
+ if other.respond_to?(:exception_id)
60
+ exception_id == other.exception_id
61
+ else
62
+ false
63
+ end
64
+ end
65
+
66
+ def self.passes_message_whitelist(exception_class)
67
+ OneApm::Agent.config.stripped_exceptions_whitelist.any? do |klass|
68
+ exception_class <= klass
69
+ end
70
+ end
71
+
72
+ def to_collector_array(encoder=nil)
73
+ [ OneApm::Helper.time_to_millis(timestamp),
74
+ string(path),
75
+ string(message),
76
+ string(exception_class_name),
77
+ params ]
78
+ end
79
+ end