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,206 @@
1
+ # encoding: utf-8
2
+
3
+ require 'logger'
4
+ require 'singleton'
5
+ require 'one_apm/support/hostname'
6
+
7
+ module OneApm
8
+ module Agent
9
+ class AgentLogger
10
+
11
+ attr_reader :already_logged
12
+
13
+ def initialize(root = "", override_logger=nil)
14
+ clear_already_logged
15
+ create_log(root, override_logger)
16
+ set_log_level!
17
+ set_log_format!
18
+
19
+ gather_startup_logs
20
+ end
21
+
22
+ def fatal(*msgs, &blk)
23
+ format_and_send(:fatal, msgs, &blk)
24
+ end
25
+
26
+ def error(*msgs, &blk)
27
+ format_and_send(:error, msgs, &blk)
28
+ end
29
+
30
+ def warn(*msgs, &blk)
31
+ format_and_send(:warn, msgs, &blk)
32
+ end
33
+
34
+ def info(*msgs, &blk)
35
+ format_and_send(:info, msgs, &blk)
36
+ end
37
+
38
+ def debug(*msgs, &blk)
39
+ format_and_send(:debug, msgs, &blk)
40
+ end
41
+
42
+ NUM_LOG_ONCE_KEYS = 1000
43
+
44
+ def log_once(level, key, *msgs)
45
+ # Since `already_logged` might change between calls, just grab it once
46
+ # and use it throughout this method.
47
+ logged = already_logged
48
+
49
+ return if logged.include?(key)
50
+
51
+ if logged.size >= NUM_LOG_ONCE_KEYS && key.kind_of?(String)
52
+ # The reason for preventing too many keys in `logged` is for
53
+ # memory concerns.
54
+ # The reason for checking the type of the key is that we always want
55
+ # to allow symbols to log, since there are very few of them.
56
+ # The assumption here is that you would NEVER pass dynamically-created
57
+ # symbols, because you would never create symbols dynamically in the
58
+ # first place, as that would already be a memory leak in most Rubies,
59
+ # even if we didn't hang on to them all here.
60
+ return
61
+ end
62
+
63
+ logged[key] = true
64
+ self.send(level, *msgs)
65
+ end
66
+
67
+ def is_startup_logger?
68
+ @log.is_a?(NullLogger)
69
+ end
70
+
71
+ # Use this when you want to log an exception with explicit control over
72
+ # the log level that the backtrace is logged at. If you just want the
73
+ # default behavior of backtraces logged at debug, use one of the methods
74
+ # above and pass an Exception as one of the args.
75
+ def log_exception(level, e, backtrace_level=level)
76
+ @log.send(level, "%p: %s" % [ e.class, e.message ])
77
+ @log.send(backtrace_level) do
78
+ backtrace = backtrace_from_exception(e)
79
+ if backtrace
80
+ "Debugging backtrace:\n" + backtrace.join("\n ")
81
+ else
82
+ "No backtrace available."
83
+ end
84
+ end
85
+ end
86
+
87
+ def backtrace_from_exception(e)
88
+ # We've seen that often the backtrace on a SystemStackError is bunk
89
+ # so massage the caller instead at a known depth.
90
+ #
91
+ # Tests keep us honest about minmum method depth our log calls add.
92
+ return caller.drop(5) if e.is_a?(SystemStackError)
93
+
94
+ e.backtrace
95
+ end
96
+
97
+ # Allows for passing exceptions in explicitly, which format with backtrace
98
+ def format_and_send(level, *msgs, &block)
99
+ if block
100
+ if @log.send("#{level}?")
101
+ msgs = Array(block.call)
102
+ else
103
+ msgs = []
104
+ end
105
+ end
106
+
107
+ msgs.flatten.each do |item|
108
+ case item
109
+ when Exception then log_exception(level, item, :debug)
110
+ else @log.send(level, item)
111
+ end
112
+ end
113
+ end
114
+
115
+ def create_log(root, override_logger)
116
+ if !override_logger.nil?
117
+ @log = override_logger
118
+ elsif ::OneApm::Agent.config[:agent_enabled] == false
119
+ create_null_logger
120
+ else
121
+ if wants_stdout?
122
+ @log = ::Logger.new(STDOUT)
123
+ else
124
+ create_log_to_file(root)
125
+ end
126
+ end
127
+ end
128
+
129
+ def create_log_to_file(root)
130
+ path = find_or_create_file_path(::OneApm::Agent.config[:log_file_path], root)
131
+ if path.nil?
132
+ @log = ::Logger.new(STDOUT)
133
+ warn("Error creating log directory #{::OneApm::Agent.config[:log_file_path]}, using standard out for logging.")
134
+ else
135
+ file_path = "#{path}/#{::OneApm::Agent.config[:log_file_name]}"
136
+ begin
137
+ @log = ::Logger.new(file_path)
138
+ rescue => e
139
+ @log = ::Logger.new(STDOUT)
140
+ warn("Failed creating logger for file #{file_path}, using standard out for logging.", e)
141
+ end
142
+ end
143
+ end
144
+
145
+ def create_null_logger
146
+ @log = ::OneApm::Agent::NullLogger.new
147
+ end
148
+
149
+ def clear_already_logged
150
+ @already_logged = {}
151
+ end
152
+
153
+ def wants_stdout?
154
+ ::OneApm::Agent.config[:log_file_path].upcase == "STDOUT"
155
+ end
156
+
157
+ def find_or_create_file_path(path_setting, root)
158
+ for abs_path in [ File.expand_path(path_setting),
159
+ File.expand_path(File.join(root, path_setting)) ] do
160
+ if File.directory?(abs_path) || (Dir.mkdir(abs_path) rescue nil)
161
+ return abs_path[%r{^(.*?)/?$}]
162
+ end
163
+ end
164
+ nil
165
+ end
166
+
167
+ def set_log_level!
168
+ @log.level = AgentLogger.log_level_for(::OneApm::Agent.config[:log_level])
169
+ end
170
+
171
+ LOG_LEVELS = {
172
+ "debug" => ::Logger::DEBUG,
173
+ "info" => ::Logger::INFO,
174
+ "warn" => ::Logger::WARN,
175
+ "error" => ::Logger::ERROR,
176
+ "fatal" => ::Logger::FATAL,
177
+ }
178
+
179
+ def self.log_level_for(level)
180
+ LOG_LEVELS.fetch(level.to_s.downcase, ::Logger::INFO)
181
+ end
182
+
183
+ def set_log_format!
184
+ @hostname = OneApm::Agent::Hostname.get
185
+ @prefix = wants_stdout? ? '** [OneApm]' : ''
186
+ @log.formatter = Proc.new do |severity, timestamp, progname, msg|
187
+ "#{@prefix}[#{timestamp.strftime("%m/%d/%y %H:%M:%S %z")} #{@hostname} (#{$$})] #{severity} : #{msg}\n"
188
+ end
189
+ end
190
+
191
+ def gather_startup_logs
192
+ StartupLogger.instance.dump(self)
193
+ end
194
+
195
+ def log_formatter=(formatter)
196
+ @log.formatter = formatter
197
+ end
198
+ end
199
+
200
+ # In an effort to not lose messages during startup, we trap them in memory
201
+ # The real logger will then dump its contents out when it arrives.
202
+ class StartupLogger < MemoryLogger
203
+ include Singleton
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ require 'logger'
4
+ require 'fileutils'
5
+ require 'one_apm/support/hostname'
6
+
7
+ module OneApm
8
+ module Agent
9
+ class AuditLogger
10
+ def initialize
11
+ @enabled = OneApm::Agent.config[:'audit_log.enabled']
12
+ @encoder = OneApm::Support::Encoders::Identity
13
+ end
14
+
15
+ attr_writer :enabled
16
+
17
+ def enabled?
18
+ @enabled
19
+ end
20
+
21
+ def setup?
22
+ !@log.nil?
23
+ end
24
+
25
+ def log_request(uri, data, marshaller)
26
+ if enabled?
27
+ setup_logger unless setup?
28
+ request_body = if marshaller.class.human_readable?
29
+ marshaller.dump(data, :encoder => @encoder)
30
+ else
31
+ marshaller.prepare(data, :encoder => @encoder).inspect
32
+ end
33
+ @log.info("REQUEST: #{uri}")
34
+ @log.info("REQUEST BODY: #{request_body}")
35
+ end
36
+ rescue StandardError, SystemStackError, SystemCallError => e
37
+ ::OneApm::Agent.logger.warn("Failed writing to audit log", e)
38
+ rescue Exception => e
39
+ ::OneApm::Agent.logger.warn("Failed writing to audit log with exception. Re-raising in case of interupt.", e)
40
+ raise
41
+ end
42
+
43
+ def setup_logger
44
+ path = ensure_log_path
45
+ if path
46
+ @log = ::Logger.new(path)
47
+ @log.formatter = create_log_formatter
48
+ ::OneApm::Agent.logger.info("Audit log enabled at '#{path}'")
49
+ else
50
+ @log = OneApm::Agent::NullLogger.new
51
+ end
52
+ end
53
+
54
+ def ensure_log_path
55
+ path = File.expand_path(OneApm::Agent.config[:'audit_log.path'])
56
+ log_dir = File.dirname(path)
57
+
58
+ begin
59
+ FileUtils.mkdir_p(log_dir)
60
+ FileUtils.touch(path)
61
+ rescue SystemCallError => e
62
+ msg = "Audit log disabled, failed opening log at '#{path}': #{e}"
63
+ ::OneApm::Agent.logger.warn(msg)
64
+ path = nil
65
+ end
66
+
67
+ path
68
+ end
69
+
70
+ def create_log_formatter
71
+ @hostname = OneApm::Agent::Hostname.get
72
+ Proc.new do |severity, time, progname, msg|
73
+ "[#{time} #{@hostname} (#{$$})] : #{msg}\n"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ # Base class for startup logging and testing in multiverse
4
+
5
+ module OneApm
6
+ module Agent
7
+ class MemoryLogger
8
+ def initialize
9
+ @messages = []
10
+ end
11
+
12
+ def is_startup_logger?
13
+ true
14
+ end
15
+
16
+ attr_accessor :messages, :level
17
+
18
+ def fatal(*msgs, &blk)
19
+ messages << [:fatal, msgs, blk]
20
+ end
21
+
22
+ def error(*msgs, &blk)
23
+ messages << [:error, msgs, blk]
24
+ end
25
+
26
+ def warn(*msgs, &blk)
27
+ messages << [:warn, msgs, blk]
28
+ end
29
+
30
+ def info(*msgs, &blk)
31
+ messages << [:info, msgs, blk]
32
+ end
33
+
34
+ def debug(*msgs, &blk)
35
+ messages << [:debug, msgs, blk]
36
+ end
37
+
38
+ def log_exception(level, e, backtrace_level=level)
39
+ messages << [:log_exception, [level, e, backtrace_level]]
40
+ end
41
+
42
+ def dump(logger)
43
+ messages.each do |(method, args, blk)|
44
+ logger.send(method, *args, &blk)
45
+ end
46
+ messages.clear
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ # A stub object that we can use in place of a real Logger instance when
4
+ # the agent is disabled.
5
+ module OneApm
6
+ module Agent
7
+ class NullLogger
8
+ def fatal(*args); end
9
+ def error(*args); end
10
+ def warn(*args); end
11
+ def info(*args); end
12
+ def debug(*args); end
13
+
14
+ def method_missing(method, *args, &blk)
15
+ nil
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/support/coerce'
4
+
5
+ module OneApm
6
+ class MetricData
7
+ # nil, or a OneApm::MetricSpec object if we have no cached ID
8
+ attr_accessor :metric_spec
9
+ # nil or a cached integer ID for the metric from the collector.
10
+ attr_accessor :metric_id
11
+ # the actual statistics object
12
+ attr_accessor :stats
13
+
14
+ def initialize(metric_spec, stats, metric_id)
15
+ @metric_spec = metric_spec
16
+ self.stats = stats
17
+ self.metric_id = metric_id
18
+ end
19
+
20
+ def eql?(o)
21
+ (metric_spec.eql? o.metric_spec) && (stats.eql? o.stats)
22
+ end
23
+
24
+ def original_spec
25
+ @original_spec || @metric_spec
26
+ end
27
+
28
+ # assigns a new metric spec, and retains the old metric spec as
29
+ # @original_spec if it exists currently
30
+ def metric_spec= new_spec
31
+ @original_spec = @metric_spec if @metric_spec
32
+ @metric_spec = new_spec
33
+ end
34
+
35
+ def hash
36
+ metric_spec.hash ^ stats.hash
37
+ end
38
+
39
+ # Serialize with all attributes, but if the metric id is not nil, then don't send the metric spec
40
+ def to_json(*a)
41
+ %Q[{"metric_spec":#{metric_id ? 'null' : metric_spec.to_json},"stats":{"total_exclusive_time":#{stats.total_exclusive_time},"min_call_time":#{stats.min_call_time},"call_count":#{stats.call_count},"sum_of_squares":#{stats.sum_of_squares},"total_call_time":#{stats.total_call_time},"max_call_time":#{stats.max_call_time}},"metric_id":#{metric_id ? metric_id : 'null'}}]
42
+ end
43
+
44
+ def to_s
45
+ if metric_spec
46
+ "#{metric_spec.name}(#{metric_spec.scope}): #{stats}"
47
+ else
48
+ "#{metric_id}: #{stats}"
49
+ end
50
+ end
51
+
52
+ def inspect
53
+ "#<MetricData metric_spec:#{metric_spec.inspect}, stats:#{stats.inspect}, metric_id:#{metric_id.inspect}>"
54
+ end
55
+
56
+ include OneApm::Coerce
57
+
58
+ def to_collector_array(encoder=nil)
59
+ stat_key = metric_id || { 'name' => metric_spec.name, 'scope' => metric_spec.scope }
60
+ [ stat_key,
61
+ [
62
+ int(stats.call_count, stat_key),
63
+ float(stats.total_call_time, stat_key),
64
+ float(stats.total_exclusive_time, stat_key),
65
+ float(stats.min_call_time, stat_key),
66
+ float(stats.max_call_time, stat_key),
67
+ float(stats.sum_of_squares, stat_key)
68
+ ]
69
+ ]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+
3
+ # this struct uniquely defines a metric, optionally inside
4
+ # the call scope of another metric
5
+ # the call scope of another metric
6
+ module OneApm
7
+ class MetricSpec
8
+ attr_reader :name, :scope
9
+
10
+ # the maximum length of a metric name or metric scope
11
+ MAX_LENGTH = 255
12
+ LENGTH_RANGE = (0...MAX_LENGTH)
13
+ EMPTY_SCOPE = ''.freeze
14
+
15
+ def initialize(metric_name='', metric_scope=nil)
16
+ if metric_name.to_s.length > MAX_LENGTH
17
+ @name = metric_name.to_s[LENGTH_RANGE]
18
+ else
19
+ @name = metric_name.to_s
20
+ end
21
+
22
+ if metric_scope
23
+ if metric_scope.to_s.length > MAX_LENGTH
24
+ @scope = metric_scope.to_s[LENGTH_RANGE]
25
+ else
26
+ @scope = metric_scope.to_s
27
+ end
28
+ else
29
+ @scope = EMPTY_SCOPE
30
+ end
31
+ end
32
+
33
+ def ==(o)
34
+ self.eql?(o)
35
+ end
36
+
37
+ def eql? o
38
+ @name == o.name && @scope == o.scope
39
+ end
40
+
41
+ def hash
42
+ @name.hash ^ @scope.hash
43
+ end
44
+
45
+ # return a new metric spec if the given regex
46
+ # matches the name or scope.
47
+ def sub(pattern, replacement, apply_to_scope = true)
48
+ ::OneApm::Agent.logger.warn("The sub method on metric specs is deprecated") rescue nil
49
+ return nil if name !~ pattern &&
50
+ (!apply_to_scope || scope.nil? || scope !~ pattern)
51
+ new_name = name.sub(pattern, replacement)[LENGTH_RANGE]
52
+
53
+ if apply_to_scope
54
+ new_scope = (scope && scope.sub(pattern, replacement)[LENGTH_RANGE])
55
+ else
56
+ new_scope = scope
57
+ end
58
+
59
+ self.class.new new_name, new_scope
60
+ end
61
+
62
+ def to_s
63
+ return name if scope.empty?
64
+ "#{name}:#{scope}"
65
+ end
66
+
67
+ def inspect
68
+ "#<OneApm::MetricSpec '#{name}':'#{scope}'>"
69
+ end
70
+
71
+ def to_json(*a)
72
+ {'name' => name,
73
+ 'scope' => scope}.to_json(*a)
74
+ end
75
+
76
+ def <=>(o)
77
+ namecmp = self.name <=> o.name
78
+ return namecmp if namecmp != 0
79
+ return (self.scope || '') <=> (o.scope || '')
80
+ end
81
+ end
82
+ end