solarwinds_apm 5.0.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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +5 -0
  3. data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
  4. data/.github/workflows/build_and_release_gem.yml +112 -0
  5. data/.github/workflows/build_for_packagecloud.yml +70 -0
  6. data/.github/workflows/docker-images.yml +47 -0
  7. data/.github/workflows/run_cpluplus_tests.yml +73 -0
  8. data/.github/workflows/run_tests.yml +155 -0
  9. data/.github/workflows/scripts/test_install.rb +23 -0
  10. data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
  11. data/.github/workflows/test_on_4_linux.yml +161 -0
  12. data/.gitignore +39 -0
  13. data/.rubocop.yml +29 -0
  14. data/.yardopts +7 -0
  15. data/CHANGELOG.md +769 -0
  16. data/CONFIG.md +31 -0
  17. data/Gemfile +14 -0
  18. data/LICENSE +202 -0
  19. data/README.md +383 -0
  20. data/bin/solarwinds_apm_config +15 -0
  21. data/examples/prepend.rb +13 -0
  22. data/examples/sdk_examples.rb +158 -0
  23. data/ext/oboe_metal/README.md +69 -0
  24. data/ext/oboe_metal/extconf.rb +141 -0
  25. data/ext/oboe_metal/extconf_local.rb +75 -0
  26. data/ext/oboe_metal/lib/.keep +0 -0
  27. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
  28. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
  29. data/ext/oboe_metal/noop/noop.c +8 -0
  30. data/ext/oboe_metal/src/README.md +6 -0
  31. data/ext/oboe_metal/src/VERSION +2 -0
  32. data/ext/oboe_metal/src/bson/bson.h +220 -0
  33. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  34. data/ext/oboe_metal/src/frames.cc +247 -0
  35. data/ext/oboe_metal/src/frames.h +40 -0
  36. data/ext/oboe_metal/src/init_solarwinds_apm.cc +21 -0
  37. data/ext/oboe_metal/src/logging.cc +95 -0
  38. data/ext/oboe_metal/src/logging.h +35 -0
  39. data/ext/oboe_metal/src/oboe.h +1169 -0
  40. data/ext/oboe_metal/src/oboe_api.cpp +658 -0
  41. data/ext/oboe_metal/src/oboe_api.hpp +433 -0
  42. data/ext/oboe_metal/src/oboe_debug.h +59 -0
  43. data/ext/oboe_metal/src/oboe_swig_wrap.cc +7562 -0
  44. data/ext/oboe_metal/src/profiling.cc +435 -0
  45. data/ext/oboe_metal/src/profiling.h +78 -0
  46. data/ext/oboe_metal/test/CMakeLists.txt +53 -0
  47. data/ext/oboe_metal/test/FindGMock.cmake +43 -0
  48. data/ext/oboe_metal/test/README.md +56 -0
  49. data/ext/oboe_metal/test/frames_test.cc +164 -0
  50. data/ext/oboe_metal/test/profiling_test.cc +93 -0
  51. data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
  52. data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
  53. data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
  54. data/ext/oboe_metal/test/test.h +11 -0
  55. data/ext/oboe_metal/test/test_main.cc +32 -0
  56. data/init.rb +4 -0
  57. data/lib/oboe.rb +7 -0
  58. data/lib/oboe_metal.rb +172 -0
  59. data/lib/rails/generators/solarwinds_apm/install_generator.rb +47 -0
  60. data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +424 -0
  61. data/lib/solarwinds_apm/api/layerinit.rb +41 -0
  62. data/lib/solarwinds_apm/api/logging.rb +356 -0
  63. data/lib/solarwinds_apm/api/memcache.rb +37 -0
  64. data/lib/solarwinds_apm/api/metrics.rb +63 -0
  65. data/lib/solarwinds_apm/api/util.rb +98 -0
  66. data/lib/solarwinds_apm/api.rb +21 -0
  67. data/lib/solarwinds_apm/base.rb +160 -0
  68. data/lib/solarwinds_apm/config.rb +301 -0
  69. data/lib/solarwinds_apm/frameworks/grape.rb +96 -0
  70. data/lib/solarwinds_apm/frameworks/padrino.rb +78 -0
  71. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller.rb +100 -0
  72. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  73. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  74. data/lib/solarwinds_apm/frameworks/rails/inst/action_view.rb +88 -0
  75. data/lib/solarwinds_apm/frameworks/rails/inst/active_record.rb +26 -0
  76. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
  77. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +22 -0
  78. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +103 -0
  79. data/lib/solarwinds_apm/frameworks/rails/inst/logger_formatters.rb +14 -0
  80. data/lib/solarwinds_apm/frameworks/rails.rb +100 -0
  81. data/lib/solarwinds_apm/frameworks/sinatra.rb +96 -0
  82. data/lib/solarwinds_apm/inst/bunny-client.rb +157 -0
  83. data/lib/solarwinds_apm/inst/bunny-consumer.rb +102 -0
  84. data/lib/solarwinds_apm/inst/curb.rb +288 -0
  85. data/lib/solarwinds_apm/inst/dalli.rb +89 -0
  86. data/lib/solarwinds_apm/inst/delayed_job.rb +100 -0
  87. data/lib/solarwinds_apm/inst/excon.rb +113 -0
  88. data/lib/solarwinds_apm/inst/faraday.rb +96 -0
  89. data/lib/solarwinds_apm/inst/graphql.rb +206 -0
  90. data/lib/solarwinds_apm/inst/grpc_client.rb +147 -0
  91. data/lib/solarwinds_apm/inst/grpc_server.rb +119 -0
  92. data/lib/solarwinds_apm/inst/httpclient.rb +181 -0
  93. data/lib/solarwinds_apm/inst/logger_formatter.rb +46 -0
  94. data/lib/solarwinds_apm/inst/logging_log_event.rb +24 -0
  95. data/lib/solarwinds_apm/inst/lumberjack_formatter.rb +9 -0
  96. data/lib/solarwinds_apm/inst/memcached.rb +86 -0
  97. data/lib/solarwinds_apm/inst/mongo.rb +246 -0
  98. data/lib/solarwinds_apm/inst/mongo2.rb +225 -0
  99. data/lib/solarwinds_apm/inst/moped.rb +466 -0
  100. data/lib/solarwinds_apm/inst/net_http.rb +60 -0
  101. data/lib/solarwinds_apm/inst/rack.rb +217 -0
  102. data/lib/solarwinds_apm/inst/rack_cache.rb +35 -0
  103. data/lib/solarwinds_apm/inst/redis.rb +273 -0
  104. data/lib/solarwinds_apm/inst/resque.rb +129 -0
  105. data/lib/solarwinds_apm/inst/rest-client.rb +43 -0
  106. data/lib/solarwinds_apm/inst/sequel.rb +241 -0
  107. data/lib/solarwinds_apm/inst/sidekiq-client.rb +63 -0
  108. data/lib/solarwinds_apm/inst/sidekiq-worker.rb +64 -0
  109. data/lib/solarwinds_apm/inst/typhoeus.rb +90 -0
  110. data/lib/solarwinds_apm/instrumentation.rb +22 -0
  111. data/lib/solarwinds_apm/loading.rb +65 -0
  112. data/lib/solarwinds_apm/logger.rb +14 -0
  113. data/lib/solarwinds_apm/noop/README.md +9 -0
  114. data/lib/solarwinds_apm/noop/context.rb +26 -0
  115. data/lib/solarwinds_apm/noop/metadata.rb +25 -0
  116. data/lib/solarwinds_apm/noop/profiling.rb +21 -0
  117. data/lib/solarwinds_apm/oboe_init_options.rb +191 -0
  118. data/lib/solarwinds_apm/ruby.rb +35 -0
  119. data/lib/solarwinds_apm/sdk/current_trace_info.rb +123 -0
  120. data/lib/solarwinds_apm/sdk/custom_metrics.rb +94 -0
  121. data/lib/solarwinds_apm/sdk/logging.rb +37 -0
  122. data/lib/solarwinds_apm/sdk/trace_context_headers.rb +69 -0
  123. data/lib/solarwinds_apm/sdk/tracing.rb +432 -0
  124. data/lib/solarwinds_apm/support/profiling.rb +22 -0
  125. data/lib/solarwinds_apm/support/trace_context.rb +53 -0
  126. data/lib/solarwinds_apm/support/trace_state.rb +69 -0
  127. data/lib/solarwinds_apm/support/trace_string.rb +89 -0
  128. data/lib/solarwinds_apm/support/transaction_metrics.rb +67 -0
  129. data/lib/solarwinds_apm/support/transaction_settings.rb +233 -0
  130. data/lib/solarwinds_apm/support/x_trace_options.rb +113 -0
  131. data/lib/solarwinds_apm/support.rb +12 -0
  132. data/lib/solarwinds_apm/support_report.rb +113 -0
  133. data/lib/solarwinds_apm/test.rb +165 -0
  134. data/lib/solarwinds_apm/thread_local.rb +26 -0
  135. data/lib/solarwinds_apm/util.rb +334 -0
  136. data/lib/solarwinds_apm/version.rb +17 -0
  137. data/lib/solarwinds_apm.rb +72 -0
  138. data/log/.keep +0 -0
  139. data/log/postgresql/.keep +0 -0
  140. data/solarwinds_apm.gemspec +52 -0
  141. data/yardoc_frontpage.md +24 -0
  142. metadata +228 -0
@@ -0,0 +1,466 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'json'
5
+
6
+ module SolarWindsAPM
7
+ module Inst
8
+ ##
9
+ # Moped
10
+ #
11
+ module Moped
12
+ FLAVOR = :mongodb
13
+
14
+ # Moped::Database
15
+ DB_OPS = [:command, :drop].freeze
16
+
17
+ # Moped::Indexes
18
+ INDEX_OPS = [:create, :drop].freeze
19
+
20
+ # Moped::Query
21
+ QUERY_OPS = [:count, :sort, :limit, :distinct, :update, :update_all, :upsert,
22
+ :explain, :modify, :remove, :remove_all].freeze
23
+
24
+ # Moped::Collection
25
+ COLLECTION_OPS = [:drop, :find, :indexes, :insert, :aggregate].freeze
26
+
27
+ ##
28
+ # remote_host
29
+ #
30
+ # This utility method converts the server into a host:port
31
+ # pair for reporting
32
+ #
33
+ def remote_host(server)
34
+ if ::Moped::VERSION < '2.0.0'
35
+ server
36
+ else
37
+ "#{server.address.host}:#{server.address.port}"
38
+ end
39
+ end
40
+ end
41
+
42
+ ##
43
+ # MopedDatabase
44
+ #
45
+ module MopedDatabase
46
+ include SolarWindsAPM::Inst::Moped
47
+
48
+ def self.included(klass)
49
+ SolarWindsAPM::Inst::Moped::DB_OPS.each do |m|
50
+ SolarWindsAPM::Util.method_alias(klass, m)
51
+ end
52
+ end
53
+
54
+ def extract_trace_details(op)
55
+ report_kvs = {}
56
+ report_kvs[:Flavor] = SolarWindsAPM::Inst::Moped::FLAVOR
57
+ # FIXME: We're only grabbing the first of potentially multiple servers here
58
+ report_kvs[:RemoteHost] = remote_host(session.cluster.seeds.first)
59
+ report_kvs[:Database] = name
60
+ report_kvs[:QueryOp] = op.to_s
61
+ report_kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:moped][:collect_backtraces]
62
+ rescue StandardError => e
63
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
64
+ ensure
65
+ return report_kvs
66
+ end
67
+
68
+ def command_with_sw_apm(command)
69
+ if SolarWindsAPM.tracing? && !SolarWindsAPM.layer_op && command.key?(:mapreduce)
70
+ begin
71
+ report_kvs = extract_trace_details(:map_reduce)
72
+ report_kvs[:Map_Function] = command[:map]
73
+ report_kvs[:Reduce_Function] = command[:reduce]
74
+ rescue => e
75
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
76
+ end
77
+
78
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
79
+ command_without_sw_apm(command)
80
+ end
81
+ else
82
+ command_without_sw_apm(command)
83
+ end
84
+ end
85
+
86
+ def drop_with_sw_apm
87
+ return drop_without_sw_apm unless SolarWindsAPM.tracing?
88
+
89
+ report_kvs = extract_trace_details(:drop_database)
90
+
91
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
92
+ drop_without_sw_apm
93
+ end
94
+ end
95
+ end
96
+
97
+ ##
98
+ # MopedIndexes
99
+ #
100
+ module MopedIndexes
101
+ include SolarWindsAPM::Inst::Moped
102
+
103
+ def self.included(klass)
104
+ SolarWindsAPM::Inst::Moped::INDEX_OPS.each do |m|
105
+ SolarWindsAPM::Util.method_alias(klass, m)
106
+ end
107
+ end
108
+
109
+ def extract_trace_details(op)
110
+ report_kvs = {}
111
+ report_kvs[:Flavor] = SolarWindsAPM::Inst::Moped::FLAVOR
112
+
113
+ # FIXME: We're only grabbing the first of potentially multiple servers here
114
+ first = database.session.cluster.seeds.first
115
+ if ::Moped::VERSION < '2.0.0'
116
+ report_kvs[:RemoteHost] = first
117
+ else
118
+ report_kvs[:RemoteHost] = "#{first.address.host}:#{first.address.port}"
119
+ end
120
+ report_kvs[:Database] = database.name
121
+ report_kvs[:QueryOp] = op.to_s
122
+ report_kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:moped][:collect_backtraces]
123
+ rescue StandardError => e
124
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
125
+ ensure
126
+ return report_kvs
127
+ end
128
+
129
+ def create_with_sw_apm(key, options = {})
130
+ return create_without_sw_apm(key, options) unless SolarWindsAPM.tracing?
131
+
132
+ begin
133
+ # We report :create_index here to be consistent
134
+ # with other mongo implementations
135
+ report_kvs = extract_trace_details(:create_index)
136
+ report_kvs[:Key] = key.to_json
137
+ report_kvs[:Options] = options.to_json
138
+ rescue StandardError => e
139
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
140
+ end
141
+
142
+ SolarWindsAPM::API.trace(:mongo, kvs: report_kvs, protect_op: :create_index) do
143
+ create_without_sw_apm(key, options = {})
144
+ end
145
+ end
146
+
147
+ def drop_with_sw_apm(key = nil)
148
+ return drop_without_sw_apm(key) unless SolarWindsAPM.tracing?
149
+
150
+ begin
151
+ # We report :drop_indexes here to be consistent
152
+ # with other mongo implementations
153
+ report_kvs = extract_trace_details(:drop_indexes)
154
+ report_kvs[:Key] = key.nil? ? :all : key.to_json
155
+ rescue StandardError => e
156
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
157
+ end
158
+
159
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
160
+ drop_without_sw_apm(key)
161
+ end
162
+ end
163
+ end
164
+
165
+ ##
166
+ # MopedQuery
167
+ #
168
+ module MopedQuery
169
+ include SolarWindsAPM::Inst::Moped
170
+
171
+ def self.included(klass)
172
+ SolarWindsAPM::Inst::Moped::QUERY_OPS.each do |m|
173
+ SolarWindsAPM::Util.method_alias(klass, m)
174
+ end
175
+ end
176
+
177
+ def extract_trace_details(op)
178
+ report_kvs = {}
179
+ report_kvs[:Flavor] = SolarWindsAPM::Inst::Moped::FLAVOR
180
+ # FIXME: We're only grabbing the first of potentially multiple servers here
181
+ first = collection.database.session.cluster.seeds.first
182
+ report_kvs[:RemoteHost] = remote_host(first)
183
+ report_kvs[:Database] = collection.database.name
184
+ report_kvs[:Collection] = collection.name
185
+ report_kvs[:QueryOp] = op.to_s
186
+ report_kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:moped][:collect_backtraces]
187
+ rescue StandardError => e
188
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
189
+ ensure
190
+ return report_kvs
191
+ end
192
+
193
+ def count_with_sw_apm
194
+ return count_without_sw_apm unless SolarWindsAPM.tracing?
195
+
196
+ begin
197
+ report_kvs = extract_trace_details(:count)
198
+ report_kvs[:Query] = selector.empty? ? :all : selector.to_json
199
+ rescue StandardError => e
200
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
201
+ end
202
+
203
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
204
+ count_without_sw_apm
205
+ end
206
+ end
207
+
208
+ def sort_with_sw_apm(sort)
209
+ return sort_without_sw_apm(sort) unless SolarWindsAPM.tracing?
210
+
211
+ begin
212
+ report_kvs = extract_trace_details(:sort)
213
+ report_kvs[:Query] = selector.empty? ? :all : selector.to_json
214
+ report_kvs[:Order] = sort.to_s
215
+ rescue StandardError => e
216
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
217
+ end
218
+
219
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
220
+ sort_without_sw_apm(sort)
221
+ end
222
+ end
223
+
224
+ def limit_with_sw_apm(limit)
225
+ if SolarWindsAPM.tracing? && !SolarWindsAPM.tracing_layer_op?(:explain)
226
+ begin
227
+ report_kvs = extract_trace_details(:limit)
228
+ report_kvs[:Query] = selector.empty? ? :all : selector.to_json
229
+ report_kvs[:Limit] = limit.to_s
230
+ rescue StandardError => e
231
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
232
+ end
233
+
234
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
235
+ limit_without_sw_apm(limit)
236
+ end
237
+ else
238
+ limit_without_sw_apm(limit)
239
+ end
240
+ end
241
+
242
+ def distinct_with_sw_apm(key)
243
+ return distinct_without_sw_apm(key) unless SolarWindsAPM.tracing?
244
+
245
+ begin
246
+ report_kvs = extract_trace_details(:distinct)
247
+ report_kvs[:Query] = selector.empty? ? :all : selector.to_json
248
+ report_kvs[:Key] = key.to_s
249
+ rescue StandardError => e
250
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
251
+ end
252
+
253
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
254
+ distinct_without_sw_apm(key)
255
+ end
256
+ end
257
+
258
+ def update_with_sw_apm(change, flags = nil)
259
+ if SolarWindsAPM.tracing? && !SolarWindsAPM.tracing_layer_op?(:update_all) && !SolarWindsAPM.tracing_layer_op?(:upsert)
260
+ begin
261
+ report_kvs = extract_trace_details(:update)
262
+ report_kvs[:Flags] = flags.to_s if flags
263
+ report_kvs[:Update_Document] = change.to_json
264
+ rescue StandardError => e
265
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
266
+ end
267
+
268
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
269
+ update_without_sw_apm(change, flags)
270
+ end
271
+ else
272
+ update_without_sw_apm(change, flags)
273
+ end
274
+ end
275
+
276
+ def update_all_with_sw_apm(change)
277
+ return update_all_without_sw_apm(change) unless SolarWindsAPM.tracing?
278
+
279
+ begin
280
+ report_kvs = extract_trace_details(:update_all)
281
+ report_kvs[:Update_Document] = change.to_json
282
+ rescue StandardError => e
283
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
284
+ end
285
+
286
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs, protect_op: :update_all) do
287
+ update_all_without_sw_apm(change)
288
+ end
289
+ end
290
+
291
+ def upsert_with_sw_apm(change)
292
+ return upsert_without_sw_apm(change) unless SolarWindsAPM.tracing?
293
+
294
+ begin
295
+ report_kvs = extract_trace_details(:upsert)
296
+ report_kvs[:Query] = selector.to_json
297
+ report_kvs[:Update_Document] = change.to_json
298
+ rescue StandardError => e
299
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
300
+ end
301
+
302
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs, protect_op: :upsert) do
303
+ upsert_without_sw_apm(change)
304
+ end
305
+ end
306
+
307
+ def explain_with_sw_apm
308
+ return explain_without_sw_apm unless SolarWindsAPM.tracing?
309
+
310
+ begin
311
+ report_kvs = extract_trace_details(:explain)
312
+ report_kvs[:Query] = selector.empty? ? :all : selector.to_json
313
+ rescue StandardError => e
314
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
315
+ end
316
+
317
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs, protect_op: :explain) do
318
+ explain_without_sw_apm
319
+ end
320
+ end
321
+
322
+ def modify_with_sw_apm(change, options = {})
323
+ return modify_without_sw_apm(change, options) unless SolarWindsAPM.tracing?
324
+
325
+ begin
326
+ report_kvs = extract_trace_details(:modify)
327
+ report_kvs[:Update_Document] = selector.empty? ? :all : selector.to_json
328
+ report_kvs[:Change] = change.to_json
329
+ report_kvs[:Options] = options.to_json
330
+ rescue StandardError => e
331
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
332
+ end
333
+
334
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
335
+ modify_without_sw_apm(change, options)
336
+ end
337
+ end
338
+
339
+ def remove_with_sw_apm
340
+ return remove_without_sw_apm unless SolarWindsAPM.tracing?
341
+
342
+ begin
343
+ report_kvs = extract_trace_details(:remove)
344
+ report_kvs[:Query] = selector.to_json
345
+ rescue StandardError => e
346
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
347
+ end
348
+
349
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
350
+ remove_without_sw_apm
351
+ end
352
+ end
353
+
354
+ def remove_all_with_sw_apm
355
+ return remove_all_without_sw_apm unless SolarWindsAPM.tracing?
356
+
357
+ begin
358
+ report_kvs = extract_trace_details(:remove_all)
359
+ report_kvs[:Query] = selector.to_json
360
+ rescue StandardError => e
361
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
362
+ end
363
+
364
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
365
+ remove_all_without_sw_apm
366
+ end
367
+ end
368
+ end
369
+
370
+ ##
371
+ # MopedCollection
372
+ #
373
+ module MopedCollection
374
+ include SolarWindsAPM::Inst::Moped
375
+
376
+ def self.included(klass)
377
+ SolarWindsAPM::Inst::Moped::COLLECTION_OPS.each do |m|
378
+ SolarWindsAPM::Util.method_alias(klass, m)
379
+ end
380
+ end
381
+
382
+ def extract_trace_details(op)
383
+ report_kvs = {}
384
+ report_kvs[:Flavor] = SolarWindsAPM::Inst::Moped::FLAVOR
385
+ # FIXME: We're only grabbing the first of potentially multiple servers here
386
+ report_kvs[:RemoteHost] = remote_host(database.session.cluster.seeds.first)
387
+ report_kvs[:Database] = database.name
388
+ report_kvs[:Collection] = name
389
+ report_kvs[:QueryOp] = op.to_s
390
+ report_kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:moped][:collect_backtraces]
391
+ rescue StandardError => e
392
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
393
+ ensure
394
+ return report_kvs
395
+ end
396
+
397
+ def drop_with_sw_apm
398
+ return drop_without_sw_apm unless SolarWindsAPM.tracing?
399
+
400
+ # We report :drop_collection here to be consistent
401
+ # with other mongo implementations
402
+ report_kvs = extract_trace_details(:drop_collection)
403
+
404
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
405
+ drop_without_sw_apm
406
+ end
407
+ end
408
+
409
+ def find_with_sw_apm(selector = {})
410
+ return find_without_sw_apm(selector) unless SolarWindsAPM.tracing?
411
+
412
+ begin
413
+ report_kvs = extract_trace_details(:find)
414
+ report_kvs[:Query] = selector.empty? ? 'all' : selector.to_json
415
+ rescue StandardError => e
416
+ SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
417
+ end
418
+
419
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
420
+ find_without_sw_apm(selector)
421
+ end
422
+ end
423
+
424
+ def indexes_with_sw_apm
425
+ return indexes_without_sw_apm unless SolarWindsAPM.tracing?
426
+
427
+ report_kvs = extract_trace_details(:indexes)
428
+
429
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
430
+ indexes_without_sw_apm
431
+ end
432
+ end
433
+
434
+ def insert_with_sw_apm(documents, flags = nil)
435
+ if SolarWindsAPM.tracing? && !SolarWindsAPM.tracing_layer_op?(:create_index)
436
+ report_kvs = extract_trace_details(:insert)
437
+
438
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
439
+ insert_without_sw_apm(documents, flags)
440
+ end
441
+ else
442
+ insert_without_sw_apm(documents, flags)
443
+ end
444
+ end
445
+
446
+ def aggregate_with_sw_apm(*pipeline)
447
+ return aggregate_without_sw_apm(*pipeline) unless SolarWindsAPM.tracing?
448
+
449
+ report_kvs = extract_trace_details(:aggregate)
450
+ report_kvs[:Query] = pipeline
451
+
452
+ SolarWindsAPM::SDK.trace(:mongo, kvs: report_kvs) do
453
+ aggregate_without_sw_apm(pipeline)
454
+ end
455
+ end
456
+ end
457
+ end
458
+ end
459
+
460
+ if defined?(Moped) && SolarWindsAPM::Config[:moped][:enabled]
461
+ SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting moped' if SolarWindsAPM::Config[:verbose]
462
+ SolarWindsAPM::Util.send_include(Moped::Database, SolarWindsAPM::Inst::MopedDatabase)
463
+ SolarWindsAPM::Util.send_include(Moped::Collection, SolarWindsAPM::Inst::MopedCollection)
464
+ SolarWindsAPM::Util.send_include(Moped::Query, SolarWindsAPM::Inst::MopedQuery)
465
+ SolarWindsAPM::Util.send_include(Moped::Indexes, SolarWindsAPM::Inst::MopedIndexes)
466
+ end
@@ -0,0 +1,60 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'net/http'
5
+
6
+ if SolarWindsAPM::Config[:nethttp][:enabled]
7
+ module SolarWindsAPM
8
+ module Inst
9
+ module NetHttp
10
+ include SolarWindsAPM::SDK::TraceContextHeaders
11
+
12
+ # Net::HTTP.class_eval do
13
+ # def request_with_sw_apm(*args, &block)
14
+ def request(*args, &block)
15
+ # If we're not tracing, just do a fast return. Since
16
+ # net/http.request calls itself, only trace
17
+ # once the http session has been started.
18
+ if !SolarWindsAPM.tracing? || !started?
19
+ add_tracecontext_headers(args[0])
20
+ return super
21
+ end
22
+
23
+ kvs = {}
24
+ SolarWindsAPM::SDK.trace(:'net-http', kvs: kvs) do
25
+ # Collect KVs to report in the exit event
26
+ if args.respond_to?(:first) && args.first
27
+ req = args.first
28
+
29
+ kvs[:Spec] = 'rsc'
30
+ kvs[:IsService] = 1
31
+ kvs[:RemoteURL] = "#{use_ssl? ? 'https' : 'http'}://#{addr_port}"
32
+ kvs[:RemoteURL] << (SolarWindsAPM::Config[:nethttp][:log_args] ? req.path : req.path.split('?').first)
33
+ kvs[:HTTPMethod] = req.method
34
+ kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:nethttp][:collect_backtraces]
35
+ end
36
+
37
+ begin
38
+ add_tracecontext_headers(args[0])
39
+ # The actual net::http call
40
+ resp = super
41
+
42
+ kvs[:HTTPStatus] = resp.code
43
+
44
+ # If we get a redirect, report the location header
45
+ if ((300..308).to_a.include? resp.code.to_i) && resp.header["Location"]
46
+ kvs[:Location] = resp.header["Location"]
47
+ end
48
+
49
+ resp
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+
58
+ Net::HTTP.prepend(SolarWindsAPM::Inst::NetHttp)
59
+ SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting net/http' if SolarWindsAPM::Config[:verbose]
60
+ end