appoptics_apm_mnfst 4.5.2
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.
- checksums.yaml +7 -0
- data/.dockerignore +5 -0
- data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
- data/.gitignore +29 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +121 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Gemfile +29 -0
- data/LICENSE +193 -0
- data/README.md +393 -0
- data/Rakefile +230 -0
- data/appoptics_apm.gemspec +61 -0
- data/bin/appoptics_apm_config +15 -0
- data/build_gem.sh +15 -0
- data/build_gem_upload_to_packagecloud.sh +20 -0
- data/examples/SDK/01_basic_tracing.rb +67 -0
- data/examples/carrying_context.rb +220 -0
- data/ext/oboe_metal/extconf.rb +114 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/VERSION +1 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm.rb +76 -0
- data/lib/appoptics_apm/api.rb +20 -0
- data/lib/appoptics_apm/api/layerinit.rb +41 -0
- data/lib/appoptics_apm/api/logging.rb +375 -0
- data/lib/appoptics_apm/api/memcache.rb +37 -0
- data/lib/appoptics_apm/api/metrics.rb +55 -0
- data/lib/appoptics_apm/api/profiling.rb +203 -0
- data/lib/appoptics_apm/api/tracing.rb +53 -0
- data/lib/appoptics_apm/api/util.rb +122 -0
- data/lib/appoptics_apm/base.rb +230 -0
- data/lib/appoptics_apm/config.rb +254 -0
- data/lib/appoptics_apm/frameworks/grape.rb +97 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +108 -0
- data/lib/appoptics_apm/frameworks/rails.rb +94 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +55 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +108 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +125 -0
- data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
- data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
- data/lib/appoptics_apm/inst/curb.rb +330 -0
- data/lib/appoptics_apm/inst/dalli.rb +85 -0
- data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
- data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
- data/lib/appoptics_apm/inst/excon.rb +125 -0
- data/lib/appoptics_apm/inst/faraday.rb +94 -0
- data/lib/appoptics_apm/inst/grpc_client.rb +162 -0
- data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
- data/lib/appoptics_apm/inst/http.rb +73 -0
- data/lib/appoptics_apm/inst/httpclient.rb +174 -0
- data/lib/appoptics_apm/inst/memcached.rb +86 -0
- data/lib/appoptics_apm/inst/mongo.rb +246 -0
- data/lib/appoptics_apm/inst/mongo2.rb +225 -0
- data/lib/appoptics_apm/inst/moped.rb +466 -0
- data/lib/appoptics_apm/inst/rack.rb +199 -0
- data/lib/appoptics_apm/inst/redis.rb +275 -0
- data/lib/appoptics_apm/inst/resque.rb +151 -0
- data/lib/appoptics_apm/inst/rest-client.rb +48 -0
- data/lib/appoptics_apm/inst/sequel.rb +178 -0
- data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
- data/lib/appoptics_apm/inst/sidekiq-worker.rb +65 -0
- data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
- data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
- data/lib/appoptics_apm/instrumentation.rb +22 -0
- data/lib/appoptics_apm/legacy_method_profiling.rb +90 -0
- data/lib/appoptics_apm/loading.rb +65 -0
- data/lib/appoptics_apm/logger.rb +42 -0
- data/lib/appoptics_apm/method_profiling.rb +33 -0
- data/lib/appoptics_apm/noop/README.md +9 -0
- data/lib/appoptics_apm/noop/context.rb +26 -0
- data/lib/appoptics_apm/noop/metadata.rb +22 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/sdk/custom_metrics.rb +92 -0
- data/lib/appoptics_apm/sdk/tracing.rb +315 -0
- data/lib/appoptics_apm/support.rb +119 -0
- data/lib/appoptics_apm/test.rb +94 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +319 -0
- data/lib/appoptics_apm/version.rb +15 -0
- data/lib/appoptics_apm/xtrace.rb +103 -0
- data/lib/joboe_metal.rb +212 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +80 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe_metal.rb +198 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +265 -0
- data/yardoc_frontpage.md +26 -0
- metadata +266 -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
|