appoptics_apm-zearn 4.13.1

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 (145) 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 +103 -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 +168 -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 +159 -0
  12. data/.gitignore +36 -0
  13. data/.rubocop.yml +29 -0
  14. data/.travis.yml +130 -0
  15. data/.yardopts +6 -0
  16. data/CHANGELOG.md +769 -0
  17. data/CONFIG.md +33 -0
  18. data/Gemfile +14 -0
  19. data/LICENSE +202 -0
  20. data/README.md +393 -0
  21. data/appoptics_apm.gemspec +70 -0
  22. data/bin/appoptics_apm_config +15 -0
  23. data/examples/prepend.rb +13 -0
  24. data/examples/sdk_examples.rb +158 -0
  25. data/ext/oboe_metal/README.md +69 -0
  26. data/ext/oboe_metal/extconf.rb +151 -0
  27. data/ext/oboe_metal/lib/.keep +0 -0
  28. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
  30. data/ext/oboe_metal/noop/noop.c +8 -0
  31. data/ext/oboe_metal/src/README.md +6 -0
  32. data/ext/oboe_metal/src/VERSION +2 -0
  33. data/ext/oboe_metal/src/bson/bson.h +220 -0
  34. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  35. data/ext/oboe_metal/src/frames.cc +246 -0
  36. data/ext/oboe_metal/src/frames.h +40 -0
  37. data/ext/oboe_metal/src/init_appoptics_apm.cc +21 -0
  38. data/ext/oboe_metal/src/logging.cc +95 -0
  39. data/ext/oboe_metal/src/logging.h +35 -0
  40. data/ext/oboe_metal/src/oboe.h +1156 -0
  41. data/ext/oboe_metal/src/oboe_api.cpp +652 -0
  42. data/ext/oboe_metal/src/oboe_api.hpp +431 -0
  43. data/ext/oboe_metal/src/oboe_debug.h +59 -0
  44. data/ext/oboe_metal/src/oboe_swig_wrap.cc +7329 -0
  45. data/ext/oboe_metal/src/profiling.cc +435 -0
  46. data/ext/oboe_metal/src/profiling.h +78 -0
  47. data/ext/oboe_metal/test/CMakeLists.txt +53 -0
  48. data/ext/oboe_metal/test/FindGMock.cmake +43 -0
  49. data/ext/oboe_metal/test/README.md +56 -0
  50. data/ext/oboe_metal/test/frames_test.cc +164 -0
  51. data/ext/oboe_metal/test/profiling_test.cc +93 -0
  52. data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
  53. data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
  54. data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
  55. data/ext/oboe_metal/test/test.h +11 -0
  56. data/ext/oboe_metal/test/test_main.cc +32 -0
  57. data/init.rb +4 -0
  58. data/lib/appoptics_apm/api/layerinit.rb +41 -0
  59. data/lib/appoptics_apm/api/logging.rb +381 -0
  60. data/lib/appoptics_apm/api/memcache.rb +37 -0
  61. data/lib/appoptics_apm/api/metrics.rb +63 -0
  62. data/lib/appoptics_apm/api/tracing.rb +57 -0
  63. data/lib/appoptics_apm/api/util.rb +120 -0
  64. data/lib/appoptics_apm/api.rb +21 -0
  65. data/lib/appoptics_apm/base.rb +231 -0
  66. data/lib/appoptics_apm/config.rb +299 -0
  67. data/lib/appoptics_apm/frameworks/grape.rb +98 -0
  68. data/lib/appoptics_apm/frameworks/padrino.rb +78 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_controller6.rb +50 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +88 -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 +29 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +114 -0
  81. data/lib/appoptics_apm/frameworks/rails/inst/logger_formatters.rb +27 -0
  82. data/lib/appoptics_apm/frameworks/rails.rb +100 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +96 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
  86. data/lib/appoptics_apm/inst/curb.rb +332 -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 +101 -0
  90. data/lib/appoptics_apm/inst/excon.rb +125 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +106 -0
  92. data/lib/appoptics_apm/inst/graphql.rb +240 -0
  93. data/lib/appoptics_apm/inst/grpc_client.rb +159 -0
  94. data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
  95. data/lib/appoptics_apm/inst/http.rb +81 -0
  96. data/lib/appoptics_apm/inst/httpclient.rb +174 -0
  97. data/lib/appoptics_apm/inst/logger_formatter.rb +50 -0
  98. data/lib/appoptics_apm/inst/logging_log_event.rb +28 -0
  99. data/lib/appoptics_apm/inst/lumberjack_formatter.rb +13 -0
  100. data/lib/appoptics_apm/inst/memcached.rb +86 -0
  101. data/lib/appoptics_apm/inst/mongo.rb +246 -0
  102. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  103. data/lib/appoptics_apm/inst/moped.rb +466 -0
  104. data/lib/appoptics_apm/inst/rack.rb +182 -0
  105. data/lib/appoptics_apm/inst/rack_cache.rb +35 -0
  106. data/lib/appoptics_apm/inst/redis.rb +274 -0
  107. data/lib/appoptics_apm/inst/resque.rb +151 -0
  108. data/lib/appoptics_apm/inst/rest-client.rb +48 -0
  109. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  110. data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
  111. data/lib/appoptics_apm/inst/sidekiq-worker.rb +66 -0
  112. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  113. data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
  114. data/lib/appoptics_apm/instrumentation.rb +22 -0
  115. data/lib/appoptics_apm/loading.rb +65 -0
  116. data/lib/appoptics_apm/logger.rb +14 -0
  117. data/lib/appoptics_apm/noop/README.md +9 -0
  118. data/lib/appoptics_apm/noop/context.rb +27 -0
  119. data/lib/appoptics_apm/noop/metadata.rb +25 -0
  120. data/lib/appoptics_apm/noop/profiling.rb +21 -0
  121. data/lib/appoptics_apm/oboe_init_options.rb +211 -0
  122. data/lib/appoptics_apm/ruby.rb +35 -0
  123. data/lib/appoptics_apm/sdk/current_trace.rb +77 -0
  124. data/lib/appoptics_apm/sdk/custom_metrics.rb +94 -0
  125. data/lib/appoptics_apm/sdk/logging.rb +37 -0
  126. data/lib/appoptics_apm/sdk/tracing.rb +434 -0
  127. data/lib/appoptics_apm/support/profiling.rb +18 -0
  128. data/lib/appoptics_apm/support/transaction_metrics.rb +67 -0
  129. data/lib/appoptics_apm/support/transaction_settings.rb +219 -0
  130. data/lib/appoptics_apm/support/x_trace_options.rb +110 -0
  131. data/lib/appoptics_apm/support_report.rb +119 -0
  132. data/lib/appoptics_apm/test.rb +95 -0
  133. data/lib/appoptics_apm/thread_local.rb +26 -0
  134. data/lib/appoptics_apm/util.rb +326 -0
  135. data/lib/appoptics_apm/version.rb +16 -0
  136. data/lib/appoptics_apm/xtrace.rb +115 -0
  137. data/lib/appoptics_apm.rb +77 -0
  138. data/lib/joboe_metal.rb +212 -0
  139. data/lib/oboe.rb +7 -0
  140. data/lib/oboe_metal.rb +172 -0
  141. data/lib/rails/generators/appoptics_apm/install_generator.rb +47 -0
  142. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +425 -0
  143. data/log/.keep +0 -0
  144. data/yardoc_frontpage.md +26 -0
  145. metadata +231 -0
@@ -0,0 +1,246 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'json'
5
+
6
+ module AppOpticsAPM
7
+ module Inst
8
+ module Mongo
9
+ FLAVOR = 'mongodb'
10
+
11
+ # Operations for Mongo::DB
12
+ DB_OPS = [:create_collection, :drop_collection]
13
+
14
+ # Operations for Mongo::Cursor
15
+ CURSOR_OPS = [:count]
16
+
17
+ # Operations for Mongo::Collection
18
+ COLL_WRITE_OPS = [:find_and_modify, :insert, :map_reduce, :remove, :rename, :update]
19
+ COLL_QUERY_OPS = [:distinct, :find, :group]
20
+ COLL_INDEX_OPS = [:create_index, :drop_index, :drop_indexes, :ensure_index, :index_information]
21
+ end
22
+ end
23
+ end
24
+
25
+ # TODO find out if we still need to support mongo < '2.0.0', we don't run tests for it. 1.12.5 was released Dec 2015
26
+ if defined?(Mongo) && (Gem.loaded_specs['mongo'].version.to_s < '2.0.0') && AppOpticsAPM::Config[:mongo][:enabled]
27
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting mongo' if AppOpticsAPM::Config[:verbose]
28
+
29
+ if defined?(Mongo::DB)
30
+ module Mongo
31
+ class DB
32
+ include AppOpticsAPM::Inst::Mongo
33
+
34
+ # Instrument DB operations
35
+ AppOpticsAPM::Inst::Mongo::DB_OPS.reject { |m| !method_defined?(m) }.each do |m|
36
+ define_method("#{m}_with_appoptics") do |*args|
37
+ report_kvs = {}
38
+
39
+ begin
40
+ report_kvs[:Flavor] = AppOpticsAPM::Inst::Mongo::FLAVOR
41
+
42
+ report_kvs[:Database] = @name
43
+
44
+ # Mongo >= 1.10 uses @client instead of @connection
45
+ # Avoid the nil
46
+ if @connection
47
+ report_kvs[:RemoteHost] = @connection.host
48
+ report_kvs[:RemotePort] = @connection.port
49
+ elsif @client
50
+ report_kvs[:RemoteHost] = @client.host
51
+ report_kvs[:RemotePort] = @client.port
52
+ end
53
+
54
+ report_kvs[:QueryOp] = m
55
+
56
+ report_kvs[:New_Collection_Name] = args[0] if m == :create_collection
57
+ report_kvs[:Collection] = args[0] if m == :drop_collection
58
+
59
+ rescue => e
60
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
61
+ end
62
+
63
+ AppOpticsAPM::API.trace(:mongo, report_kvs) do
64
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
65
+ send("#{m}_without_appoptics", *args)
66
+ end
67
+ end
68
+
69
+ class_eval "alias #{m}_without_appoptics #{m}"
70
+ class_eval "alias #{m} #{m}_with_appoptics"
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ if defined?(Mongo::Cursor)
77
+ module Mongo
78
+ class Cursor
79
+ include AppOpticsAPM::Inst::Mongo
80
+
81
+ # Instrument DB cursor operations
82
+ AppOpticsAPM::Inst::Mongo::CURSOR_OPS.reject { |m| !method_defined?(m) }.each do |m|
83
+ define_method("#{m}_with_appoptics") do |*args|
84
+ report_kvs = {}
85
+
86
+ begin
87
+ report_kvs[:Flavor] = AppOpticsAPM::Inst::Mongo::FLAVOR
88
+
89
+ report_kvs[:Database] = @db.name
90
+ report_kvs[:RemoteHost] = @connection.host
91
+ report_kvs[:RemotePort] = @connection.port
92
+
93
+ report_kvs[:QueryOp] = m
94
+ if m == :count
95
+ unless @selector.empty?
96
+ report_kvs[:Query] = @selector.to_json
97
+ else
98
+ report_kvs[:Query] = :all
99
+ end
100
+ report_kvs[:Limit] = @limit if @limit != 0
101
+ end
102
+ rescue => e
103
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
104
+ end
105
+
106
+ AppOpticsAPM::API.trace(:mongo, report_kvs) do
107
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
108
+ send("#{m}_without_appoptics", *args)
109
+ end
110
+ end
111
+
112
+ class_eval "alias #{m}_without_appoptics #{m}"
113
+ class_eval "alias #{m} #{m}_with_appoptics"
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ if defined?(Mongo::Collection)
120
+ module Mongo
121
+ class Collection
122
+ include AppOpticsAPM::Inst::Mongo
123
+
124
+ def appoptics_collect(m, args)
125
+ kvs = {}
126
+ kvs[:Flavor] = AppOpticsAPM::Inst::Mongo::FLAVOR
127
+
128
+ kvs[:Database] = @db.name
129
+ kvs[:RemoteHost] = @db.connection.host
130
+ kvs[:RemotePort] = @db.connection.port
131
+ kvs[:Collection] = @name
132
+
133
+ kvs[:QueryOp] = m
134
+ kvs[:Query] = args[0].to_json if args && !args.empty? && args[0].class == Hash
135
+ rescue StandardError => e
136
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] Exception in appoptics_collect KV collection: #{e.inspect}"
137
+ ensure
138
+ return kvs
139
+ end
140
+
141
+ # Instrument Collection write operations
142
+ AppOpticsAPM::Inst::Mongo::COLL_WRITE_OPS.reject { |m| !method_defined?(m) }.each do |m|
143
+ define_method("#{m}_with_appoptics") do |*args|
144
+ report_kvs = appoptics_collect(m, args)
145
+ args_length = args.length
146
+
147
+ begin
148
+ if m == :find_and_modify && args[0] && args[0].key?(:update)
149
+ report_kvs[:Update_Document] = args[0][:update].inspect
150
+ end
151
+
152
+ if m == :map_reduce
153
+ report_kvs[:Map_Function] = args[0]
154
+ report_kvs[:Reduce_Function] = args[1]
155
+ report_kvs[:Limit] = args[2][:limit] if args[2] && args[2].key?(:limit)
156
+ end
157
+
158
+ report_kvs[:New_Collection_Name] = args[0] if m == :rename
159
+
160
+ if m == :update
161
+ if args_length >= 3
162
+ report_kvs[:Update_Document] = args[1].to_json
163
+ report_kvs[:Multi] = args[2][:multi] if args[2] && args[2].key?(:multi)
164
+ end
165
+ end
166
+ rescue => e
167
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
168
+ end
169
+
170
+ AppOpticsAPM::API.trace(:mongo, report_kvs) do
171
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
172
+ send("#{m}_without_appoptics", *args)
173
+ end
174
+ end
175
+
176
+ class_eval "alias #{m}_without_appoptics #{m}"
177
+ class_eval "alias #{m} #{m}_with_appoptics"
178
+ end
179
+
180
+ # Instrument Collection query operations
181
+ AppOpticsAPM::Inst::Mongo::COLL_QUERY_OPS.reject { |m| !method_defined?(m) }.each do |m|
182
+ define_method("#{m}_with_appoptics") do |*args, &blk|
183
+ report_kvs = {}
184
+ begin
185
+ report_kvs = appoptics_collect(m, args)
186
+ args_length = args.length
187
+
188
+ if m == :distinct && args_length >= 2
189
+ report_kvs[:Key] = args[0]
190
+ report_kvs[:Query] = args[1].to_json if args[1] && args[1].class == Hash
191
+ end
192
+
193
+ if m == :find && args_length > 0
194
+ report_kvs[:Limit] = args[0][:limit] if !args[0].nil? && args[0].key?(:limit)
195
+ end
196
+
197
+ if m == :group
198
+ unless args.empty?
199
+ if args[0].is_a?(Hash)
200
+ report_kvs[:Group_Key] = args[0][:key].to_json if args[0].key?(:key)
201
+ report_kvs[:Group_Condition] = args[0][:cond].to_json if args[0].key?(:cond)
202
+ report_kvs[:Group_Initial] = args[0][:initial].to_json if args[0].key?(:initial)
203
+ report_kvs[:Group_Reduce] = args[0][:reduce] if args[0].key?(:reduce)
204
+ end
205
+ end
206
+ end
207
+ rescue => e
208
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
209
+ end
210
+
211
+ AppOpticsAPM::API.trace(:mongo, report_kvs) do
212
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
213
+ send("#{m}_without_appoptics", *args, &blk)
214
+ end
215
+ end
216
+
217
+ class_eval "alias #{m}_without_appoptics #{m}"
218
+ class_eval "alias #{m} #{m}_with_appoptics"
219
+ end
220
+
221
+ # Instrument Collection index operations
222
+ AppOpticsAPM::Inst::Mongo::COLL_INDEX_OPS.reject { |m| !method_defined?(m) }.each do |m|
223
+ define_method("#{m}_with_appoptics") do |*args|
224
+ report_kvs = appoptics_collect(m, args)
225
+
226
+ begin
227
+ if [:create_index, :ensure_index, :drop_index].include?(m) && !args.empty?
228
+ report_kvs[:Index] = args[0].to_json
229
+ end
230
+ rescue => e
231
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
232
+ end
233
+
234
+ AppOpticsAPM::API.trace(:mongo, report_kvs) do
235
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
236
+ send("#{m}_without_appoptics", *args)
237
+ end
238
+ end
239
+
240
+ class_eval "alias #{m}_without_appoptics #{m}"
241
+ class_eval "alias #{m} #{m}_with_appoptics"
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,225 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'json'
5
+
6
+ if AppOpticsAPM::Config[:mongo][:enabled]
7
+ if defined?(Mongo) && (Gem.loaded_specs['mongo'].version.to_s >= '2.0.0')
8
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting mongo' if AppOpticsAPM::Config[:verbose]
9
+
10
+ # Collection Related Operations
11
+ COLL_OTHER_OPS = [:create, :drop, :insert_one, :insert_many, :bulk_write, :map_reduce].freeze
12
+
13
+ # Mongo 2.2 only ops
14
+ if Mongo::VERSION >= '2.1'
15
+ COLL_QUERY_OPS = [:find, :find_one_and_delete, :find_one_and_update, :find_one_and_replace, :update_one, :update_many, :delete_one, :delete_many, :replace_one].freeze
16
+ else
17
+ COLL_QUERY_OPS = [:find, :update_many, :delete_one].freeze
18
+ end
19
+
20
+ COLL_OPS = COLL_QUERY_OPS + COLL_OTHER_OPS
21
+
22
+ module Mongo
23
+ class Collection
24
+ ##
25
+ # collect_kvs
26
+ #
27
+ # Used to collect up information to report and build a hash
28
+ # with the Keys/Values to report.
29
+ #
30
+ def collect_kvs(op, args)
31
+ kvs = { :Flavor => :mongodb, :Database => @database.name }
32
+
33
+ kvs[:QueryOp] = op
34
+
35
+ if op == :create
36
+ kvs[:New_Collection_Name] = @name
37
+ else
38
+ kvs[:Collection] = @name
39
+ end
40
+
41
+ if op == :map_reduce
42
+ kvs[:Map_Function] = args[0]
43
+ kvs[:Reduce_Function] = args[1]
44
+ kvs[:Limit] = args[2][:limit] if args[2].is_a?(Hash) && args[2].key?(:limit)
45
+ end
46
+
47
+ if AppOpticsAPM::Config[:mongo][:log_args]
48
+ if COLL_QUERY_OPS.include?(op)
49
+ kvs[:Query] = args.first.to_json
50
+ end
51
+ end
52
+
53
+ kvs[:RemoteHost] = @database.client.cluster.addresses.first.to_s
54
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
55
+ rescue => e
56
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
57
+ ensure
58
+ return kvs
59
+ end
60
+
61
+ ##
62
+ # Here we dynamically define wrapper methods for the operations
63
+ # we want to instrument in mongo
64
+ #
65
+ COLL_OPS.reject { |m| !method_defined?(m) }.each do |m|
66
+ define_method("#{m}_with_appoptics") do |*args|
67
+ begin
68
+ if !AppOpticsAPM.tracing? || AppOpticsAPM.tracing_layer?(:mongo)
69
+ mongo_skipped = true
70
+ return send("#{m}_without_appoptics", *args)
71
+ end
72
+
73
+ kvs = collect_kvs(m, args)
74
+ AppOpticsAPM::API.log_entry(:mongo, kvs)
75
+
76
+ send("#{m}_without_appoptics", *args)
77
+ rescue => e
78
+ AppOpticsAPM::API.log_exception(:mongo, e)
79
+ raise e
80
+ ensure
81
+ AppOpticsAPM::API.log_exit(:mongo) unless mongo_skipped
82
+ end
83
+ end
84
+ AppOpticsAPM::Util.method_alias(Mongo::Collection, m)
85
+ end
86
+ end
87
+ end
88
+
89
+ ##
90
+ # Mongo Collection View Instrumentation
91
+ #
92
+
93
+ # Collection View Related Operations
94
+ VIEW_QUERY_OPS = [:delete_one, :delete_many, :count, :distinct, :find_one_and_delete, :find_one_and_update,
95
+ :replace_one, :update_one, :update_many].freeze
96
+ VIEW_OTHER_OPS = [:aggregate, :map_reduce ].freeze
97
+ VIEW_OPS = VIEW_QUERY_OPS + VIEW_OTHER_OPS
98
+
99
+ module Mongo
100
+ class Collection
101
+ class View
102
+ ##
103
+ # collect_kvs
104
+ #
105
+ # Used to collect up information to report and build a hash
106
+ # with the Keys/Values to report.
107
+ #
108
+ def collect_kvs(op, args)
109
+ kvs = { :Flavor => :mongodb, :Database => @collection.database.name }
110
+
111
+ kvs[:QueryOp] = op
112
+ kvs[:Collection] = @collection.name
113
+
114
+ if op == :map_reduce
115
+ kvs[:Map_Function] = args[0]
116
+ kvs[:Reduce_Function] = args[1]
117
+ kvs[:Limit] = args[2][:limit] if args[2].is_a?(Hash) && args[2].key?(:limit)
118
+ end
119
+
120
+ if AppOpticsAPM::Config[:mongo][:log_args]
121
+ if VIEW_QUERY_OPS.include?(op)
122
+ if defined?(filter)
123
+ kvs[:Query] = filter.to_json
124
+ elsif defined?(selector)
125
+ kvs[:Query] = selector.to_json
126
+ end
127
+ end
128
+ end
129
+
130
+ kvs[:RemoteHost] = @collection.database.client.cluster.addresses.first.to_s
131
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
132
+ rescue => e
133
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
134
+ ensure
135
+ return kvs
136
+ end
137
+
138
+ ##
139
+ # Here we dynamically define wrapper methods for the operations
140
+ # we want to instrument in mongo
141
+ #
142
+ VIEW_OPS.reject { |m| !method_defined?(m) }.each do |m|
143
+ define_method("#{m}_with_appoptics") do |*args|
144
+ begin
145
+ if !AppOpticsAPM.tracing? || AppOpticsAPM.tracing_layer?(:mongo)
146
+ mongo_skipped = true
147
+ return send("#{m}_without_appoptics", *args)
148
+ end
149
+
150
+ kvs = collect_kvs(m, args)
151
+ AppOpticsAPM::API.log_entry(:mongo, kvs)
152
+
153
+ send("#{m}_without_appoptics", *args)
154
+ rescue => e
155
+ AppOpticsAPM::API.log_exception(:mongo, e)
156
+ raise e
157
+ ensure
158
+ AppOpticsAPM::API.log_exit(:mongo) unless mongo_skipped
159
+ end
160
+ end
161
+ AppOpticsAPM::Util.method_alias(Mongo::Collection::View, m)
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ ##
168
+ # Mongo Collection Index View Instrumentation
169
+ #
170
+
171
+ # Collection Index View Related Operations
172
+ INDEX_OPS = [:create_one, :create_many, :drop_one, :drop_all].freeze
173
+
174
+ module Mongo
175
+ module Index
176
+ class View
177
+ ##
178
+ # collect_kvs
179
+ #
180
+ # Used to collect up information to report and build a hash
181
+ # with the Keys/Values to report.
182
+ #
183
+ def collect_index_kvs(op, args)
184
+ kvs = { :Flavor => :mongodb, :Database => @collection.database.name }
185
+
186
+ kvs[:QueryOp] = op
187
+ kvs[:Collection] = @collection.name
188
+ kvs[:RemoteHost] = @collection.database.client.cluster.addresses.first.to_s
189
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:mongo][:collect_backtraces]
190
+ rescue => e
191
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
192
+ ensure
193
+ return kvs
194
+ end
195
+
196
+ ##
197
+ # Here we dynamically define wrapper methods for the operations
198
+ # we want to instrument in mongo
199
+ #
200
+ INDEX_OPS.reject { |m| !method_defined?(m) }.each do |m|
201
+ define_method("#{m}_with_appoptics") do |*args|
202
+ begin
203
+ if !AppOpticsAPM.tracing? || AppOpticsAPM.tracing_layer?(:mongo)
204
+ mongo_skipped = true
205
+ return send("#{m}_without_appoptics", *args)
206
+ end
207
+
208
+ kvs = collect_index_kvs(m, args)
209
+ AppOpticsAPM::API.log_entry(:mongo, kvs)
210
+
211
+ send("#{m}_without_appoptics", *args)
212
+ rescue => e
213
+ AppOpticsAPM::API.log_exception(:mongo, e)
214
+ raise e
215
+ ensure
216
+ AppOpticsAPM::API.log_exit(:mongo) unless mongo_skipped
217
+ end
218
+ end
219
+ AppOpticsAPM::Util.method_alias(Mongo::Index::View, m)
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end