appoptics_apm 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +43 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +23 -0
  5. data/.rubocop.yml +5 -0
  6. data/.travis.yml +82 -0
  7. data/CHANGELOG.md +769 -0
  8. data/CONFIG.md +33 -0
  9. data/Dockerfile +41 -0
  10. data/Dockerfile_test +66 -0
  11. data/Gemfile +41 -0
  12. data/LICENSE +193 -0
  13. data/README.md +351 -0
  14. data/Rakefile +202 -0
  15. data/Vagrantfile +67 -0
  16. data/appoptics_apm.gemspec +55 -0
  17. data/build_gems.sh +15 -0
  18. data/docker-compose.yml +73 -0
  19. data/examples/DNT.md +35 -0
  20. data/examples/carrying_context.rb +220 -0
  21. data/examples/instrumenting_metal_controller.rb +8 -0
  22. data/examples/puma_on_heroku_config.rb +17 -0
  23. data/examples/tracing_async_threads.rb +124 -0
  24. data/examples/tracing_background_jobs.rb +53 -0
  25. data/examples/tracing_forked_processes.rb +99 -0
  26. data/examples/unicorn_on_heroku_config.rb +28 -0
  27. data/ext/oboe_metal/extconf.rb +54 -0
  28. data/ext/oboe_metal/lib/.keep +0 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
  30. data/ext/oboe_metal/noop/noop.c +7 -0
  31. data/ext/oboe_metal/src/VERSION +1 -0
  32. data/ext/oboe_metal/src/bson/bson.h +221 -0
  33. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  34. data/ext/oboe_metal/src/oboe.h +883 -0
  35. data/ext/oboe_metal/src/oboe.hpp +793 -0
  36. data/ext/oboe_metal/src/oboe_debug.h +50 -0
  37. data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
  38. data/ext/oboe_metal/tests/test.rb +11 -0
  39. data/gemfiles/delayed_job.gemfile +36 -0
  40. data/gemfiles/frameworks.gemfile +44 -0
  41. data/gemfiles/instrumentation_mocked.gemfile +29 -0
  42. data/gemfiles/libraries.gemfile +85 -0
  43. data/gemfiles/rails23.gemfile +39 -0
  44. data/gemfiles/rails30.gemfile +42 -0
  45. data/gemfiles/rails31.gemfile +44 -0
  46. data/gemfiles/rails32.gemfile +54 -0
  47. data/gemfiles/rails40.gemfile +27 -0
  48. data/gemfiles/rails41.gemfile +27 -0
  49. data/gemfiles/rails42.gemfile +35 -0
  50. data/gemfiles/rails50.gemfile +44 -0
  51. data/gemfiles/rails51.gemfile +44 -0
  52. data/get_version.rb +5 -0
  53. data/init.rb +4 -0
  54. data/lib/appoptics_apm/api/layerinit.rb +39 -0
  55. data/lib/appoptics_apm/api/logging.rb +359 -0
  56. data/lib/appoptics_apm/api/memcache.rb +34 -0
  57. data/lib/appoptics_apm/api/profiling.rb +201 -0
  58. data/lib/appoptics_apm/api/tracing.rb +152 -0
  59. data/lib/appoptics_apm/api/util.rb +128 -0
  60. data/lib/appoptics_apm/api.rb +18 -0
  61. data/lib/appoptics_apm/base.rb +252 -0
  62. data/lib/appoptics_apm/config.rb +281 -0
  63. data/lib/appoptics_apm/frameworks/grape.rb +93 -0
  64. data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
  65. data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
  66. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
  67. data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
  68. data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
  75. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  76. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  77. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
  81. data/lib/appoptics_apm/frameworks/rails.rb +116 -0
  82. data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
  86. data/lib/appoptics_apm/inst/curb.rb +329 -0
  87. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  88. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  89. data/lib/appoptics_apm/inst/em-http-request.rb +105 -0
  90. data/lib/appoptics_apm/inst/excon.rb +130 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +77 -0
  92. data/lib/appoptics_apm/inst/http.rb +83 -0
  93. data/lib/appoptics_apm/inst/httpclient.rb +176 -0
  94. data/lib/appoptics_apm/inst/memcache.rb +102 -0
  95. data/lib/appoptics_apm/inst/memcached.rb +94 -0
  96. data/lib/appoptics_apm/inst/mongo.rb +242 -0
  97. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  98. data/lib/appoptics_apm/inst/moped.rb +466 -0
  99. data/lib/appoptics_apm/inst/rack.rb +146 -0
  100. data/lib/appoptics_apm/inst/redis.rb +275 -0
  101. data/lib/appoptics_apm/inst/resque.rb +151 -0
  102. data/lib/appoptics_apm/inst/rest-client.rb +50 -0
  103. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  104. data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
  105. data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
  106. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  107. data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
  108. data/lib/appoptics_apm/instrumentation.rb +22 -0
  109. data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
  110. data/lib/appoptics_apm/loading.rb +66 -0
  111. data/lib/appoptics_apm/logger.rb +41 -0
  112. data/lib/appoptics_apm/method_profiling.rb +33 -0
  113. data/lib/appoptics_apm/ruby.rb +35 -0
  114. data/lib/appoptics_apm/support.rb +135 -0
  115. data/lib/appoptics_apm/test.rb +94 -0
  116. data/lib/appoptics_apm/thread_local.rb +26 -0
  117. data/lib/appoptics_apm/util.rb +312 -0
  118. data/lib/appoptics_apm/version.rb +15 -0
  119. data/lib/appoptics_apm/xtrace.rb +103 -0
  120. data/lib/appoptics_apm.rb +72 -0
  121. data/lib/joboe_metal.rb +214 -0
  122. data/lib/oboe/README +2 -0
  123. data/lib/oboe/backward_compatibility.rb +80 -0
  124. data/lib/oboe/inst/rack.rb +11 -0
  125. data/lib/oboe.rb +7 -0
  126. data/lib/oboe_metal.rb +187 -0
  127. data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
  128. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
  129. data/ruby_setup.sh +47 -0
  130. data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
  131. data/run_tests_docker.rb +32 -0
  132. data/test/benchmark/README.md +65 -0
  133. data/test/benchmark/logging_bench.rb +54 -0
  134. data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
  135. data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
  136. data/test/frameworks/apps/grape_nested.rb +33 -0
  137. data/test/frameworks/apps/grape_simple.rb +80 -0
  138. data/test/frameworks/apps/padrino_simple.rb +80 -0
  139. data/test/frameworks/apps/sinatra_simple.rb +55 -0
  140. data/test/frameworks/grape_test.rb +286 -0
  141. data/test/frameworks/padrino_test.rb +222 -0
  142. data/test/frameworks/rails3x_test.rb +554 -0
  143. data/test/frameworks/rails4x_test.rb +570 -0
  144. data/test/frameworks/rails5x_api_test.rb +210 -0
  145. data/test/frameworks/rails5x_test.rb +376 -0
  146. data/test/frameworks/rails_shared_tests.rb +172 -0
  147. data/test/frameworks/sinatra_test.rb +140 -0
  148. data/test/instrumentation/bunny_client_test.rb +276 -0
  149. data/test/instrumentation/bunny_consumer_test.rb +204 -0
  150. data/test/instrumentation/curb_test.rb +398 -0
  151. data/test/instrumentation/dalli_test.rb +177 -0
  152. data/test/instrumentation/em_http_request_test.rb +89 -0
  153. data/test/instrumentation/excon_test.rb +231 -0
  154. data/test/instrumentation/faraday_test.rb +228 -0
  155. data/test/instrumentation/http_test.rb +143 -0
  156. data/test/instrumentation/httpclient_test.rb +320 -0
  157. data/test/instrumentation/memcache_test.rb +260 -0
  158. data/test/instrumentation/memcached_test.rb +229 -0
  159. data/test/instrumentation/mongo_v1_test.rb +479 -0
  160. data/test/instrumentation/mongo_v2_index_test.rb +124 -0
  161. data/test/instrumentation/mongo_v2_test.rb +584 -0
  162. data/test/instrumentation/mongo_v2_view_test.rb +435 -0
  163. data/test/instrumentation/moped_test.rb +517 -0
  164. data/test/instrumentation/rack_test.rb +165 -0
  165. data/test/instrumentation/redis_hashes_test.rb +268 -0
  166. data/test/instrumentation/redis_keys_test.rb +321 -0
  167. data/test/instrumentation/redis_lists_test.rb +310 -0
  168. data/test/instrumentation/redis_misc_test.rb +163 -0
  169. data/test/instrumentation/redis_sets_test.rb +296 -0
  170. data/test/instrumentation/redis_sortedsets_test.rb +328 -0
  171. data/test/instrumentation/redis_strings_test.rb +349 -0
  172. data/test/instrumentation/resque_test.rb +185 -0
  173. data/test/instrumentation/rest-client_test.rb +288 -0
  174. data/test/instrumentation/sequel_mysql2_test.rb +353 -0
  175. data/test/instrumentation/sequel_mysql_test.rb +334 -0
  176. data/test/instrumentation/sequel_pg_test.rb +336 -0
  177. data/test/instrumentation/sidekiq-client_test.rb +159 -0
  178. data/test/instrumentation/sidekiq-worker_test.rb +180 -0
  179. data/test/instrumentation/twitter-cassandra_test.rb +424 -0
  180. data/test/instrumentation/typhoeus_test.rb +284 -0
  181. data/test/jobs/delayed_job/db_worker_job.rb +29 -0
  182. data/test/jobs/delayed_job/error_worker_job.rb +10 -0
  183. data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
  184. data/test/jobs/resque/db_worker_job.rb +29 -0
  185. data/test/jobs/resque/error_worker_job.rb +10 -0
  186. data/test/jobs/resque/remote_call_worker_job.rb +20 -0
  187. data/test/jobs/sidekiq/db_worker_job.rb +29 -0
  188. data/test/jobs/sidekiq/error_worker_job.rb +10 -0
  189. data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
  190. data/test/minitest_helper.rb +276 -0
  191. data/test/mocked/curb_mocked_test.rb +311 -0
  192. data/test/mocked/excon_mocked_test.rb +166 -0
  193. data/test/mocked/faraday_mocked_test.rb +93 -0
  194. data/test/mocked/http_mocked_test.rb +129 -0
  195. data/test/mocked/httpclient_mocked_test.rb +245 -0
  196. data/test/mocked/rest_client_mocked_test.rb +103 -0
  197. data/test/mocked/typhoeus_mocked_test.rb +192 -0
  198. data/test/models/widget.rb +36 -0
  199. data/test/profiling/legacy_method_profiling_test.rb +201 -0
  200. data/test/profiling/method_profiling_test.rb +631 -0
  201. data/test/queues/delayed_job-client_test.rb +95 -0
  202. data/test/queues/delayed_job-worker_test.rb +91 -0
  203. data/test/reporter/reporter_test.rb +14 -0
  204. data/test/servers/delayed_job.rb +107 -0
  205. data/test/servers/rackapp_8101.rb +29 -0
  206. data/test/servers/rails3x_8140.rb +96 -0
  207. data/test/servers/rails4x_8140.rb +96 -0
  208. data/test/servers/rails5x_8140.rb +95 -0
  209. data/test/servers/rails5x_api_8150.rb +78 -0
  210. data/test/servers/sidekiq.rb +29 -0
  211. data/test/servers/sidekiq.yml +7 -0
  212. data/test/servers/sidekiq_initializer.rb +25 -0
  213. data/test/settings +0 -0
  214. data/test/support/auto_tracing_test.rb +50 -0
  215. data/test/support/backcompat_test.rb +276 -0
  216. data/test/support/config_test.rb +149 -0
  217. data/test/support/dnt_test.rb +98 -0
  218. data/test/support/init_report_test.rb +25 -0
  219. data/test/support/liboboe_settings_test.rb +110 -0
  220. data/test/support/logging_test.rb +130 -0
  221. data/test/support/noop_test.rb +88 -0
  222. data/test/support/sql_sanitize_test.rb +55 -0
  223. data/test/support/tracing_mode_test.rb +33 -0
  224. data/test/support/tvalias_test.rb +15 -0
  225. data/test/support/xtrace_test.rb +41 -0
  226. metadata +475 -0
@@ -0,0 +1,214 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module Oboe_metal
5
+ include_package 'com.tracelytics.joboe'
6
+ java_import 'com.tracelytics.joboe.LayerUtil'
7
+ java_import 'com.tracelytics.joboe.SettingsReader'
8
+ java_import 'com.tracelytics.joboe.Context'
9
+ java_import 'com.tracelytics.joboe.Event'
10
+ java_import 'com.tracelytics.agent.Agent'
11
+
12
+ class Context
13
+ class << self
14
+ def toString
15
+ getMetadata.toHexString
16
+ end
17
+
18
+ def fromString(xtrace)
19
+ Context.setMetadata(xtrace)
20
+ end
21
+
22
+ def clear
23
+ clearMetadata
24
+ end
25
+
26
+ def get
27
+ getMetadata
28
+ end
29
+ end
30
+ end
31
+
32
+ module EventUtil
33
+ def self.metadataString(evt)
34
+ evt.getMetadata.toHexString
35
+ end
36
+ end
37
+
38
+ def UdpReporter
39
+ Java::ComTracelyticsJoboe
40
+ end
41
+
42
+ module Metadata
43
+ Java::ComTracelyticsJoboeMetaData
44
+ end
45
+
46
+ module Reporter
47
+ class << self
48
+ ##
49
+ # start
50
+ #
51
+ # Start the AppOpticsAPM Reporter
52
+ #
53
+ def start
54
+ return unless AppOpticsAPM.loaded
55
+
56
+ if ENV.key?('APPOPTICS_GEM_TEST')
57
+ AppOpticsAPM.reporter = Java::ComTracelyticsJoboe::ReporterFactory.getInstance.buildTestReporter(false)
58
+ else
59
+ AppOpticsAPM.reporter = Java::ComTracelyticsJoboe::ReporterFactory.getInstance.buildUdpReporter
60
+ end
61
+
62
+ begin
63
+ # Import the tracing mode and sample rate settings
64
+ # from the Java agent (user configured in
65
+ # /usr/local/tracelytics/javaagent.json when under JRuby)
66
+ cfg = LayerUtil.getLocalSampleRate(nil, nil)
67
+
68
+ if cfg.hasSampleStartFlag
69
+ AppOpticsAPM::Config.tracing_mode = :always
70
+ else
71
+ AppOpticsAPM::Config.tracing_mode = :never
72
+ end
73
+
74
+ AppOpticsAPM.sample_rate = cfg.getSampleRate
75
+ AppOpticsAPM::Config.sample_rate = cfg.sampleRate
76
+ AppOpticsAPM::Config.sample_source = cfg.sampleRateSourceValue
77
+ rescue => e
78
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] Couldn't retrieve/acces joboe sampleRateCfg"
79
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{e.message}"
80
+ end
81
+
82
+ # Only report __Init from here if we are not instrumenting a framework.
83
+ # Otherwise, frameworks will handle reporting __Init after full initialization
84
+ unless defined?(::Rails) || defined?(::Sinatra) || defined?(::Padrino) || defined?(::Grape)
85
+ AppOpticsAPM::API.report_init unless ENV.key?('APPOPTICS_GEM_TEST')
86
+ end
87
+ end
88
+
89
+ ##
90
+ # restart
91
+ #
92
+ # This is a nil method for AppOpticsAPM under Java. It is maintained only
93
+ # for compability across interfaces.
94
+ #
95
+ def restart
96
+ AppOpticsAPM.logger.warn "[appoptics_apm/reporter] Reporter.restart isn't supported under JRuby"
97
+ end
98
+
99
+ ##
100
+ # clear_all_traces
101
+ #
102
+ # Truncates the trace output file to zero
103
+ #
104
+ def clear_all_traces
105
+ AppOpticsAPM.reporter.reset if AppOpticsAPM.loaded
106
+ end
107
+
108
+ ##
109
+ # get_all_traces
110
+ #
111
+ # Retrieves all traces written to the trace file
112
+ #
113
+ def get_all_traces
114
+ return [] unless AppOpticsAPM.loaded
115
+
116
+ # Joboe TestReporter returns a Java::ComTracelyticsExtEbson::DefaultDocument
117
+ # document for traces which doesn't correctly support things like has_key? which
118
+ # raises an unhandled exception on non-existent key (duh). Here we convert
119
+ # the Java::ComTracelyticsExtEbson::DefaultDocument doc to a pure array of Ruby
120
+ # hashes
121
+ traces = []
122
+ AppOpticsAPM.reporter.getSentEventsAsBsonDocument.to_a.each do |e|
123
+ t = {}
124
+ e.each_pair { |k, v|
125
+ t[k] = v
126
+ }
127
+ traces << t
128
+ end
129
+ traces
130
+ end
131
+
132
+ def sendReport(evt)
133
+ evt.report(AppOpticsAPM.reporter)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ module AppOpticsAPM
140
+ extend AppOpticsAPMBase
141
+ include Oboe_metal
142
+
143
+ class << self
144
+ def sample?(opts = {})
145
+ begin
146
+ # Return false if no-op mode
147
+ return false unless AppOpticsAPM.loaded
148
+
149
+ return true if ENV.key?('APPOPTICS_GEM_TEST')
150
+
151
+ # Validation to make Joboe happy. Assure that we have the KVs and that they
152
+ # are not empty strings.
153
+ opts[:layer] = nil if opts[:layer].is_a?(String) && opts[:layer].empty?
154
+ opts[:xtrace] = nil if opts[:xtrace].is_a?(String) && opts[:xtrace].empty?
155
+
156
+ opts[:layer] ||= nil
157
+ opts[:xtrace] ||= nil
158
+
159
+ sr_cfg = Java::ComTracelyticsJoboe::LayerUtil.shouldTraceRequest(opts[:layer], { 'X-Trace' => opts[:xtrace] })
160
+
161
+ # Store the returned SampleRateConfig into AppOpticsAPM::Config
162
+ if sr_cfg
163
+ begin
164
+ AppOpticsAPM::Config.sample_rate = sr_cfg.sampleRate
165
+ AppOpticsAPM::Config.sample_source = sr_cfg.sampleRateSourceValue
166
+ # If we fail here, we do so quietly. This was we don't spam logs
167
+ # on every request
168
+ end
169
+ else
170
+ AppOpticsAPM.sample_rate = -1
171
+ AppOpticsAPM.sample_source = -1
172
+ end
173
+
174
+ sr_cfg ? true : false
175
+ rescue => e
176
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{e.message}"
177
+ false
178
+ end
179
+ end
180
+
181
+ def set_tracing_mode(_mode)
182
+ AppOpticsAPM.logger.warn 'When using JRuby set the tracing mode in /usr/local/tracelytics/javaagent.json instead'
183
+ end
184
+
185
+ def set_sample_rate(_rate)
186
+ # N/A
187
+ end
188
+ end
189
+ end
190
+
191
+ # Assure that the Joboe Java Agent was loaded via premain
192
+ case Java::ComTracelyticsAgent::Agent.getStatus
193
+ when Java::ComTracelyticsAgent::Agent::AgentStatus::INITIALIZED_SUCCESSFUL
194
+ AppOpticsAPM.loaded = true
195
+
196
+ when Java::ComTracelyticsAgent::Agent::AgentStatus::INITIALIZED_FAILED
197
+ AppOpticsAPM.loaded = false
198
+ $stderr.puts '=============================================================='
199
+ $stderr.puts 'AppOpticsAPM Java Agent not initialized properly.'
200
+ $stderr.puts 'Possibly misconfigured? Going into no-op mode.'
201
+ $stderr.puts 'http://docs.appoptics.solarwinds.com/Instrumentation/other-instrumentation-modules.html#jruby'
202
+ $stderr.puts '=============================================================='
203
+
204
+ when Java::ComTracelyticsAgent::Agent::AgentStatus::UNINITIALIZED
205
+ AppOpticsAPM.loaded = false
206
+ $stderr.puts '=============================================================='
207
+ $stderr.puts 'AppOpticsAPM Java Agent not loaded. Going into no-op mode.'
208
+ $stderr.puts 'To preload the AppOpticsAPM java agent see:'
209
+ $stderr.puts 'http://docs.appoptics.solarwinds.com/Instrumentation/other-instrumentation-modules.html#jruby'
210
+ $stderr.puts '=============================================================='
211
+
212
+ else
213
+ AppOpticsAPM.loaded = false
214
+ end
data/lib/oboe/README ADDED
@@ -0,0 +1,2 @@
1
+ This directory is kept for backward compatibility for applications
2
+ making calls to Oboe modules.
@@ -0,0 +1,80 @@
1
+ require 'appoptics_apm/thread_local'
2
+
3
+ module Oboe
4
+ extend AppOpticsAPMBase
5
+ if AppOpticsAPM.loaded
6
+ include Oboe_metal
7
+ end
8
+
9
+ #
10
+ # Support for Oboe::API calls
11
+ #
12
+ module API
13
+ include AppOpticsAPM::API
14
+ extend ::AppOpticsAPM::ThreadLocal
15
+ thread_local :deprecation_notified
16
+
17
+ def self.method_missing(sym, *args, &blk)
18
+ # Notify of deprecation only once
19
+ unless @deprecated_notified
20
+ AppOpticsAPM.logger.warn "[appoptics_apm/warn] Note that Oboe::API has been renamed to AppOpticsAPM::API. (#{sym}:#{args})"
21
+ AppOpticsAPM.logger.warn '[appoptics_apm/warn] Oboe::API will be deprecated in a future version.'
22
+ AppOpticsAPM.logger.warn "[appoptics_apm/warn] Caller: #{Kernel.caller[0]}"
23
+ @deprecated_notified = true
24
+ end
25
+ AppOpticsAPM::API.send(sym, *args, &blk)
26
+ end
27
+ end
28
+
29
+
30
+ #
31
+ # Support for Oboe::Config calls
32
+ #
33
+ module Config
34
+ extend ::AppOpticsAPM::ThreadLocal
35
+ thread_local :deprecation_notified
36
+
37
+ def self.method_missing(sym, *args)
38
+ # Notify of deprecation only once
39
+ unless @deprecated_notified
40
+ AppOpticsAPM.logger.warn "[appoptics_apm/warn] Note that Oboe::Config has been renamed to AppOpticsAPM::Config. (#{sym}:#{args})"
41
+ AppOpticsAPM.logger.warn '[appoptics_apm/warn] Oboe::Config will be deprecated in a future version.'
42
+ AppOpticsAPM.logger.warn "[appoptics_apm/warn] Caller: #{Kernel.caller[0]}"
43
+ @deprecated_notified = true
44
+ end
45
+ AppOpticsAPM::Config.send(sym, *args)
46
+ end
47
+ end
48
+
49
+ #
50
+ # Support for legacy Oboe::Ruby.load calls
51
+ #
52
+ module Ruby
53
+ extend ::AppOpticsAPM::ThreadLocal
54
+ thread_local :deprecation_notified
55
+
56
+ def self.method_missing(sym, *args)
57
+ # Notify of deprecation only once
58
+ unless @deprecated_notified
59
+ AppOpticsAPM.logger.warn "[appoptics_apm/warn] Note that Oboe::Ruby has been renamed to AppOpticsAPM::Ruby. (#{sym}:#{args})"
60
+ AppOpticsAPM.logger.warn '[appoptics_apm/warn] Oboe::Ruby will be deprecated in a future version.'
61
+ AppOpticsAPM.logger.warn "[appoptics_apm/warn] Caller: #{Kernel.caller[0]}"
62
+ @deprecated_notified = true
63
+ end
64
+ AppOpticsAPM::Ruby.send(sym, *args)
65
+ end
66
+ end
67
+ end
68
+
69
+ #
70
+ # Support for OboeMethodProfiling
71
+ #
72
+ module OboeMethodProfiling
73
+ def self.included(klass)
74
+ klass.extend ClassMethods
75
+ end
76
+
77
+ module ClassMethods
78
+ include AppOpticsAPMMethodProfiling::ClassMethods
79
+ end
80
+ end
@@ -0,0 +1,11 @@
1
+ require 'appoptics_apm/inst/rack'
2
+
3
+ module Oboe
4
+ class Rack < AppOpticsAPM::Rack
5
+ # This simply makes Oboe::Rack available (and a clone of AppOpticsAPM::Rack) for
6
+ # backward compatibility
7
+ #
8
+ # Provided for pre-existing apps (sinatra, padrino, grape etc..) that may still
9
+ # call `use Oboe::Rack`
10
+ end
11
+ end
data/lib/oboe.rb ADDED
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ # This module is provided for backward compatibility.
5
+ # It simply redirects to the appoptics_apm module which will
6
+ # also load backward compatibility support.
7
+ require 'appoptics_apm'
data/lib/oboe_metal.rb ADDED
@@ -0,0 +1,187 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'thread'
5
+
6
+ # Disable docs and Camelcase warns since we're implementing
7
+ # an interface here. See OboeBase for details.
8
+ # rubocop:disable Style/Documentation, Style/MethodName
9
+ module AppOpticsAPM
10
+ extend AppOpticsAPMBase
11
+ include Oboe_metal
12
+
13
+ class Reporter
14
+ class << self
15
+ ##
16
+ # start
17
+ #
18
+ # Start the AppOpticsAPM Reporter
19
+ #
20
+ def start
21
+ return unless AppOpticsAPM.loaded
22
+
23
+ begin
24
+ protocol = ENV.key?('APPOPTICS_GEM_TEST') ? 'file' :
25
+ ENV['TRACELYTICS_REPORTER'] || 'ssl'
26
+
27
+ case protocol
28
+ when 'file'
29
+ options = "file=#{TRACE_FILE}"
30
+ when 'udp'
31
+ options = "addr=#{AppOpticsAPM::Config[:reporter_host]},port=#{AppOpticsAPM::Config[:reporter_port]}"
32
+ else
33
+ if ENV['APPOPTICS_SERVICE_KEY'].to_s == ''
34
+ AppOpticsAPM.logger.warn "[appoptics_apm/warn] APPOPTICS_SERVICE_KEY not set. Cannot submit data."
35
+ AppOpticsAPM.loaded = false
36
+ return
37
+ end
38
+ # ssl reporter requires the service key passed in as arg "cid"
39
+ options = "cid=#{ENV['APPOPTICS_SERVICE_KEY']}"
40
+ end
41
+
42
+ AppOpticsAPM.reporter = Oboe_metal::Reporter.new(protocol, options)
43
+
44
+ # Only report __Init from here if we are not instrumenting a framework.
45
+ # Otherwise, frameworks will handle reporting __Init after full initialization
46
+ unless defined?(::Rails) || defined?(::Sinatra) || defined?(::Padrino) || defined?(::Grape)
47
+ AppOpticsAPM::API.report_init
48
+ end
49
+
50
+ rescue => e
51
+ $stderr.puts e.message
52
+ raise
53
+ end
54
+ end
55
+ alias :restart :start
56
+
57
+ ##
58
+ # sendReport
59
+ #
60
+ # Send the report for the given event
61
+ #
62
+ def sendReport(evt)
63
+ AppOpticsAPM.reporter.sendReport(evt)
64
+ end
65
+
66
+ ##
67
+ # sendStatus
68
+ #
69
+ # Send the report for the given event
70
+ #
71
+ def sendStatus(evt, context = nil)
72
+ AppOpticsAPM.reporter.sendStatus(evt, context)
73
+ end
74
+
75
+ ##
76
+ # clear_all_traces
77
+ #
78
+ # Truncates the trace output file to zero
79
+ #
80
+ def clear_all_traces
81
+ File.truncate(TRACE_FILE, 0)
82
+ end
83
+
84
+ ##
85
+ # get_all_traces
86
+ #
87
+ # Retrieves all traces written to the trace file
88
+ #
89
+ def get_all_traces
90
+ io = File.open(TRACE_FILE, 'r')
91
+ contents = io.readlines(nil)
92
+
93
+ return contents if contents.empty?
94
+
95
+ traces = []
96
+
97
+ #
98
+ # We use Gem.loaded_spec because older versions of the bson
99
+ # gem didn't even have a version embedded in the gem. If the
100
+ # gem isn't in the bundle, it should rightfully error out
101
+ # anyways.
102
+ #
103
+ if Gem.loaded_specs['bson'].version.to_s < '4.0'
104
+ s = StringIO.new(contents[0])
105
+
106
+ until s.eof?
107
+ traces << if ::BSON.respond_to? :read_bson_document
108
+ BSON.read_bson_document(s)
109
+ else
110
+ BSON::Document.from_bson(s)
111
+ end
112
+ end
113
+ else
114
+ bbb = BSON::ByteBuffer.new(contents[0])
115
+ until bbb.length == 0
116
+ traces << Hash.from_bson(bbb)
117
+ end
118
+ end
119
+
120
+ traces
121
+ end
122
+ end
123
+ end
124
+
125
+ module EventUtil
126
+ def self.metadataString(evt)
127
+ evt.metadataString
128
+ end
129
+ end
130
+
131
+ class << self
132
+ def sample?(opts = {})
133
+ # Return false if no-op mode
134
+ return false unless AppOpticsAPM.loaded
135
+
136
+ # Assure defaults since SWIG enforces Strings
137
+ layer = opts[:layer] ? opts[:layer].to_s.strip.freeze : APPOPTICS_STR_BLANK
138
+ xtrace = opts[:xtrace] ? opts[:xtrace].to_s.strip : APPOPTICS_STR_BLANK
139
+
140
+ rv = AppOpticsAPM::Context.sampleRequest(layer, xtrace)
141
+
142
+ if rv == 0
143
+ AppOpticsAPM.sample_rate = -1
144
+ AppOpticsAPM.sample_source = -1
145
+ false
146
+ else
147
+ # liboboe version > 1.3.1 returning a bit masked integer with SampleRate and
148
+ # source embedded
149
+ AppOpticsAPM.sample_rate = (rv & SAMPLE_RATE_MASK)
150
+ AppOpticsAPM.sample_source = (rv & SAMPLE_SOURCE_MASK) >> 24
151
+ true
152
+ end
153
+ rescue StandardError => e
154
+ AppOpticsAPM.logger.debug "[oboe/error] sample? error: #{e.inspect}"
155
+ false
156
+ end
157
+
158
+ def set_tracing_mode(mode)
159
+ return unless AppOpticsAPM.loaded
160
+
161
+ value = mode.to_sym
162
+
163
+ case value
164
+ when :never
165
+ AppOpticsAPM::Context.setTracingMode(OBOE_TRACE_NEVER)
166
+
167
+ when :always
168
+ AppOpticsAPM::Context.setTracingMode(OBOE_TRACE_ALWAYS)
169
+
170
+ else
171
+ AppOpticsAPM.logger.fatal "[oboe/error] Invalid tracing mode set: #{mode}"
172
+ AppOpticsAPM::Context.setTracingMode(OBOE_TRACE_NEVER)
173
+ end
174
+ end
175
+
176
+ def set_sample_rate(rate)
177
+ return unless AppOpticsAPM.loaded
178
+
179
+ # Update liboboe with the new SampleRate value
180
+ AppOpticsAPM::Context.setDefaultSampleRate(rate.to_i)
181
+ end
182
+ end
183
+ end
184
+ # rubocop:enable Style/Documentation
185
+
186
+ AppOpticsAPM.loaded = true
187
+ AppOpticsAPM.config_lock = Mutex.new
@@ -0,0 +1,45 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.join(File.dirname(__FILE__), 'templates')
7
+ desc "Copies a AppOpticsAPM gem initializer file to your application."
8
+
9
+ @namespace = "appoptics_apm:install"
10
+
11
+ def copy_initializer
12
+ # Set defaults
13
+ @verbose = 'false'
14
+
15
+ print_header
16
+ print_footer
17
+
18
+ template "appoptics_apm_initializer.rb", "config/initializers/appoptics_apm.rb"
19
+ end
20
+
21
+ private
22
+
23
+ def print_header
24
+ say ""
25
+ say shell.set_color "Welcome to the AppOpticsAPM Ruby instrumentation setup.", :green, :bold
26
+ say ""
27
+ say shell.set_color "Documentation Links", :magenta
28
+ say "-------------------"
29
+ say ""
30
+ say "AppOpticsAPM Installation Overview:"
31
+ say "http://docs.appoptics.solarwinds.com/AppOpticsAPM/install-instrumentation.html"
32
+ say ""
33
+ say "More information on instrumenting Ruby applications can be found here:"
34
+ say "http://docs.appoptics.solarwinds.com/Instrumentation/ruby.html#installing-ruby-instrumentation"
35
+ end
36
+
37
+ def print_footer
38
+ say ""
39
+ say "You can change configuration values in the future by modifying config/initializers/appoptics_apm.rb"
40
+ say ""
41
+ say "Thanks! Creating the AppOpticsAPM initializer..."
42
+ say ""
43
+ end
44
+ end
45
+ end