solarwinds_apm 5.1.9 → 6.0.0.preV2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +28 -55
  3. data/ext/oboe_metal/extconf.rb +37 -41
  4. data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +1 -1
  5. data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +1 -1
  6. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +1 -1
  7. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +1 -1
  8. data/ext/oboe_metal/src/VERSION +1 -1
  9. data/ext/oboe_metal/src/init_solarwinds_apm.cc +0 -6
  10. data/ext/oboe_metal/src/oboe_debug.h +1 -0
  11. data/lib/oboe_metal.rb +116 -80
  12. data/lib/rails/generators/solarwinds_apm/install_generator.rb +1 -5
  13. data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +42 -267
  14. data/lib/solarwinds_apm/api/current_trace_info.rb +148 -0
  15. data/lib/solarwinds_apm/api/tracing.rb +30 -0
  16. data/lib/solarwinds_apm/api/transaction_name.rb +58 -0
  17. data/lib/solarwinds_apm/api.rb +8 -15
  18. data/lib/solarwinds_apm/base.rb +4 -131
  19. data/lib/solarwinds_apm/config.rb +101 -174
  20. data/lib/solarwinds_apm/constants.rb +32 -0
  21. data/lib/solarwinds_apm/logger.rb +1 -1
  22. data/lib/solarwinds_apm/noop/context.rb +2 -5
  23. data/lib/solarwinds_apm/noop/metadata.rb +1 -2
  24. data/lib/solarwinds_apm/oboe_init_options.rb +74 -38
  25. data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +204 -0
  26. data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +166 -0
  27. data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +92 -0
  28. data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +72 -0
  29. data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +335 -0
  30. data/lib/solarwinds_apm/opentelemetry.rb +8 -0
  31. data/lib/solarwinds_apm/otel_config.rb +161 -0
  32. data/lib/solarwinds_apm/{inst → support}/logger_formatter.rb +5 -6
  33. data/lib/solarwinds_apm/{inst → support}/logging_log_event.rb +3 -6
  34. data/lib/solarwinds_apm/{inst → support}/lumberjack_formatter.rb +1 -4
  35. data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +27 -0
  36. data/lib/solarwinds_apm/support/swomarginalia/LICENSE +20 -0
  37. data/lib/solarwinds_apm/support/swomarginalia/README.md +41 -0
  38. data/lib/solarwinds_apm/support/swomarginalia/comment.rb +205 -0
  39. data/lib/solarwinds_apm/support/swomarginalia/load_swomarginalia.rb +48 -0
  40. data/lib/solarwinds_apm/support/swomarginalia/railtie.rb +22 -0
  41. data/lib/solarwinds_apm/support/swomarginalia/swomarginalia.rb +86 -0
  42. data/lib/solarwinds_apm/support/transaction_cache.rb +24 -0
  43. data/lib/solarwinds_apm/support/transaction_settings.rb +26 -209
  44. data/lib/solarwinds_apm/support/transformer.rb +56 -0
  45. data/lib/solarwinds_apm/support/txn_name_manager.rb +25 -0
  46. data/lib/solarwinds_apm/support/x_trace_options.rb +42 -26
  47. data/lib/solarwinds_apm/support.rb +37 -10
  48. data/lib/solarwinds_apm/support_report.rb +10 -32
  49. data/lib/solarwinds_apm/thread_local.rb +1 -1
  50. data/lib/solarwinds_apm/version.rb +4 -4
  51. data/lib/solarwinds_apm.rb +29 -25
  52. metadata +63 -123
  53. data/.dockerignore +0 -5
  54. data/.gitignore +0 -58
  55. data/.rubocop.yml +0 -29
  56. data/.whitesource +0 -22
  57. data/.yardopts +0 -7
  58. data/CHANGELOG-appoptics.md +0 -766
  59. data/CHANGELOG.md +0 -82
  60. data/CONFIG.md +0 -31
  61. data/Gemfile +0 -15
  62. data/README.md +0 -385
  63. data/bin/solarwinds_apm_config +0 -15
  64. data/examples/prepend.rb +0 -13
  65. data/examples/sdk_examples.rb +0 -158
  66. data/ext/oboe_metal/README.md +0 -69
  67. data/ext/oboe_metal/extconf_local.rb +0 -75
  68. data/ext/oboe_metal/lib/.keep +0 -0
  69. data/ext/oboe_metal/noop/noop.c +0 -8
  70. data/ext/oboe_metal/src/README.md +0 -6
  71. data/ext/oboe_metal/src/frames.cc +0 -247
  72. data/ext/oboe_metal/src/frames.h +0 -40
  73. data/ext/oboe_metal/src/logging.cc +0 -97
  74. data/ext/oboe_metal/src/logging.h +0 -34
  75. data/ext/oboe_metal/src/profiling.cc +0 -435
  76. data/ext/oboe_metal/src/profiling.h +0 -78
  77. data/ext/oboe_metal/test/CMakeLists.txt +0 -53
  78. data/ext/oboe_metal/test/FindGMock.cmake +0 -43
  79. data/ext/oboe_metal/test/README.md +0 -56
  80. data/ext/oboe_metal/test/frames_test.cc +0 -164
  81. data/ext/oboe_metal/test/profiling_test.cc +0 -93
  82. data/ext/oboe_metal/test/ruby_inc_dir.rb +0 -8
  83. data/ext/oboe_metal/test/ruby_prefix.rb +0 -8
  84. data/ext/oboe_metal/test/ruby_test_helper.rb +0 -67
  85. data/ext/oboe_metal/test/test.h +0 -11
  86. data/ext/oboe_metal/test/test_main.cc +0 -32
  87. data/init.rb +0 -4
  88. data/lib/solarwinds_apm/api/layerinit.rb +0 -41
  89. data/lib/solarwinds_apm/api/logging.rb +0 -356
  90. data/lib/solarwinds_apm/api/memcache.rb +0 -37
  91. data/lib/solarwinds_apm/api/metrics.rb +0 -63
  92. data/lib/solarwinds_apm/api/util.rb +0 -98
  93. data/lib/solarwinds_apm/frameworks/grape.rb +0 -96
  94. data/lib/solarwinds_apm/frameworks/padrino.rb +0 -78
  95. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller.rb +0 -100
  96. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller5.rb +0 -50
  97. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller_api.rb +0 -50
  98. data/lib/solarwinds_apm/frameworks/rails/inst/action_view.rb +0 -88
  99. data/lib/solarwinds_apm/frameworks/rails/inst/active_record.rb +0 -26
  100. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +0 -29
  101. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +0 -22
  102. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +0 -103
  103. data/lib/solarwinds_apm/frameworks/rails/inst/logger_formatters.rb +0 -14
  104. data/lib/solarwinds_apm/frameworks/rails.rb +0 -100
  105. data/lib/solarwinds_apm/frameworks/sinatra.rb +0 -96
  106. data/lib/solarwinds_apm/inst/bunny-client.rb +0 -157
  107. data/lib/solarwinds_apm/inst/bunny-consumer.rb +0 -102
  108. data/lib/solarwinds_apm/inst/curb.rb +0 -289
  109. data/lib/solarwinds_apm/inst/dalli.rb +0 -89
  110. data/lib/solarwinds_apm/inst/delayed_job.rb +0 -100
  111. data/lib/solarwinds_apm/inst/excon.rb +0 -113
  112. data/lib/solarwinds_apm/inst/faraday.rb +0 -96
  113. data/lib/solarwinds_apm/inst/graphql.rb +0 -206
  114. data/lib/solarwinds_apm/inst/grpc_client.rb +0 -147
  115. data/lib/solarwinds_apm/inst/grpc_server.rb +0 -119
  116. data/lib/solarwinds_apm/inst/httpclient.rb +0 -182
  117. data/lib/solarwinds_apm/inst/memcached.rb +0 -86
  118. data/lib/solarwinds_apm/inst/mongo.rb +0 -246
  119. data/lib/solarwinds_apm/inst/mongo2.rb +0 -225
  120. data/lib/solarwinds_apm/inst/moped.rb +0 -466
  121. data/lib/solarwinds_apm/inst/net_http.rb +0 -60
  122. data/lib/solarwinds_apm/inst/rack.rb +0 -223
  123. data/lib/solarwinds_apm/inst/rack_cache.rb +0 -35
  124. data/lib/solarwinds_apm/inst/redis.rb +0 -280
  125. data/lib/solarwinds_apm/inst/redis_v4.rb +0 -273
  126. data/lib/solarwinds_apm/inst/resque.rb +0 -129
  127. data/lib/solarwinds_apm/inst/rest-client.rb +0 -43
  128. data/lib/solarwinds_apm/inst/sequel.rb +0 -241
  129. data/lib/solarwinds_apm/inst/sidekiq-client.rb +0 -63
  130. data/lib/solarwinds_apm/inst/sidekiq-worker.rb +0 -64
  131. data/lib/solarwinds_apm/inst/typhoeus.rb +0 -90
  132. data/lib/solarwinds_apm/instrumentation.rb +0 -22
  133. data/lib/solarwinds_apm/loading.rb +0 -65
  134. data/lib/solarwinds_apm/noop/profiling.rb +0 -21
  135. data/lib/solarwinds_apm/ruby.rb +0 -35
  136. data/lib/solarwinds_apm/sdk/current_trace_info.rb +0 -123
  137. data/lib/solarwinds_apm/sdk/custom_metrics.rb +0 -94
  138. data/lib/solarwinds_apm/sdk/logging.rb +0 -37
  139. data/lib/solarwinds_apm/sdk/trace_context_headers.rb +0 -69
  140. data/lib/solarwinds_apm/sdk/tracing.rb +0 -432
  141. data/lib/solarwinds_apm/support/profiling.rb +0 -25
  142. data/lib/solarwinds_apm/support/trace_context.rb +0 -53
  143. data/lib/solarwinds_apm/support/trace_state.rb +0 -69
  144. data/lib/solarwinds_apm/support/trace_string.rb +0 -89
  145. data/lib/solarwinds_apm/support/transaction_metrics.rb +0 -67
  146. data/lib/solarwinds_apm/test.rb +0 -165
  147. data/lib/solarwinds_apm/util.rb +0 -426
  148. data/log/.keep +0 -0
  149. data/log/postgresql/.keep +0 -0
  150. data/solarwinds_apm.gemspec +0 -55
  151. data/yardoc_frontpage.md +0 -24
@@ -1,273 +0,0 @@
1
- # Copyright (c) 2016 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- module SolarWindsAPM
5
- module Inst
6
- module RedisV4
7
- module Client
8
- # The operations listed in this constant skip collecting KVKey
9
- NO_KEY_OPS = [:auth, :keys, :randomkey, :scan, :sdiff, :sdiffstore, :sinter,
10
- :sinterstore, :smove, :sunion, :sunionstore, :zinterstore,
11
- :zunionstore, :publish, :select, :eval, :evalsha, :script].freeze
12
-
13
- # Instead of a giant switch statement, we use a hash constant to map out what
14
- # KVs need to be collected for each of the many many Redis operations
15
- # Hash formatting by undiagnosed OCD
16
- KV_COLLECT_MAP = {
17
- :brpoplpush => { :destination => 2 }, :rpoplpush => { :destination => 2 },
18
- :sdiffstore => { :destination => 1 }, :sinterstore => { :destination => 1 },
19
- :sunionstore => { :destination => 1 }, :zinterstore => { :destination => 1 },
20
- :zunionstore => { :destination => 1 }, :publish => { :channel => 1 },
21
- :incrby => { :increment => 2 }, :incrbyfloat => { :increment => 2 },
22
- :pexpire => { :milliseconds => 2 }, :pexpireat => { :milliseconds => 2 },
23
- :expireat => { :timestamp => 2 }, :decrby => { :decrement => 2 },
24
- :psetex => { :ttl => 2 }, :restore => { :ttl => 2 },
25
- :setex => { :ttl => 2 }, :setnx => { :ttl => 2 },
26
- :move => { :db => 2 }, :select => { :db => 1 },
27
- :lindex => { :index => 2 }, :getset => { :value => 2 },
28
- :keys => { :pattern => 1 }, :expire => { :seconds => 2 },
29
- :rename => { :newkey => 2 }, :renamenx => { :newkey => 2 },
30
- :getbit => { :offset => 2 }, :setbit => { :offset => 2 },
31
- :setrange => { :offset => 2 }, :evalsha => { :sha => 1 },
32
- :getrange => { :start => 2, :end => 3 },
33
- :zrange => { :start => 2, :end => 3 },
34
- :bitcount => { :start => 2, :stop => 3 },
35
- :lrange => { :start => 2, :stop => 3 },
36
- :zrevrange => { :start => 2, :stop => 3 },
37
- :hincrby => { :field => 2, :increment => 3 },
38
- :smove => { :source => 1, :destination => 2 },
39
- :bitop => { :operation => 1, :destkey => 2 },
40
- :hincrbyfloat => { :field => 2, :increment => 3 },
41
- :zremrangebyrank => { :start => 2, :stop => 3 }
42
- }.freeze
43
-
44
- # The following operations don't require any special handling. For these,
45
- # we only collect KVKey and KVOp
46
- #
47
- # :append, :blpop, :brpop, :decr, :del, :dump, :exists,
48
- # :hgetall, :hkeys, :hlen, :hvals, :hmset, :incr, :linsert,
49
- # :llen, :lpop, :lpush, :lpushx, :lrem, :lset, :ltrim,
50
- # :persist, :pttl, :hscan, :rpop, :rpush, :rpushx, :sadd,
51
- # :scard, :sismember, :smembers, :strlen, :sort, :spop,
52
- # :srandmember, :srem, :sscan, :ttl, :type, :zadd, :zcard,
53
- # :zcount, :zincrby, :zrangebyscore, :zrank, :zrem,
54
- # :zremrangebyscore, :zrevrank, :zrevrangebyscore, :zscore
55
- #
56
- # For the operations in NO_KEY_OPS (above) we only collect
57
- # KVOp (no KVKey)
58
-
59
- def self.included(klass)
60
- # We wrap two of the Redis methods to instrument
61
- # operations
62
- SolarWindsAPM::Util.method_alias(klass, :call, ::Redis::Client)
63
- SolarWindsAPM::Util.method_alias(klass, :call_pipeline, ::Redis::Client)
64
- end
65
-
66
- # Given any Redis operation command array, this method
67
- # extracts the Key/Values to report to the SolarWinds # dashboard.
68
- #
69
- # @param command [Array] the Redis operation array
70
- # @param r [Return] the return value from the operation
71
- # @return [Hash] the Key/Values to report
72
- def extract_trace_details(command, r)
73
- kvs = {}
74
- op = command.first
75
-
76
- kvs[:KVOp] = command[0]
77
- kvs[:RemoteHost] = @options[:host]
78
- unless NO_KEY_OPS.include?(op) || op == :del && command[1..-1].flatten.count > 1
79
- if command[1].is_a?(Array)
80
- kvs[:KVKey] = command[1].first
81
- else
82
- kvs[:KVKey] = command[1]
83
- end
84
- end
85
-
86
- if KV_COLLECT_MAP[op]
87
- # Extract KVs from command for this op
88
- KV_COLLECT_MAP[op].each { |k, v| kvs[k] = command[v] }
89
- else
90
- # This case statement handle special cases not handled
91
- # by KV_COLLECT_MAP
92
- case op
93
- when :set
94
- if command.count > 3
95
- if command[3].is_a?(Hash)
96
- options = command[3]
97
- kvs[:ex] = options[:ex] if options.key?(:ex)
98
- kvs[:px] = options[:px] if options.key?(:px)
99
- kvs[:nx] = options[:nx] if options.key?(:nx)
100
- kvs[:xx] = options[:xx] if options.key?(:xx)
101
- else
102
- options = command[3..-1]
103
- until (opts = options.shift(2)).empty?
104
- case opts[0]
105
- when 'EX' then; kvs[:ex] = opts[1]
106
- when 'PX' then; kvs[:px] = opts[1]
107
- when 'NX' then; kvs[:nx] = opts[1]
108
- when 'XX' then; kvs[:xx] = opts[1]
109
- end
110
- end
111
- end
112
- end
113
-
114
- when :get
115
- kvs[:KVHit] = r.nil? ? 0 : 1
116
-
117
- when :hdel, :hexists, :hget, :hset, :hsetnx
118
- kvs[:field] = command[2] unless command[2].is_a?(Array)
119
- if op == :hget
120
- kvs[:KVHit] = r.nil? ? 0 : 1
121
- end
122
-
123
- when :eval
124
- if command[1].length > 1024
125
- kvs[:Script] = command[1][0..1023] + '(...snip...)'
126
- else
127
- kvs[:Script] = command[1]
128
- end
129
-
130
- when :script
131
- kvs[:subcommand] = command[1]
132
- kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:redis][:collect_backtraces]
133
- if command[1] == 'load'
134
- if command[1].length > 1024
135
- kvs[:Script] = command[2][0..1023] + '(...snip...)'
136
- else
137
- kvs[:Script] = command[2]
138
- end
139
- elsif command[1] == :exists
140
- if command[2].is_a?(Array)
141
- kvs[:KVKey] = command[2].inspect
142
- else
143
- kvs[:KVKey] = command[2]
144
- end
145
- end
146
-
147
- when :mget
148
- if command[1].is_a?(Array)
149
- kvs[:KVKeyCount] = command[1].count
150
- else
151
- kvs[:KVKeyCount] = command.count - 1
152
- end
153
- values = r.select { |i| i }
154
- kvs[:KVHitCount] = values.count
155
-
156
- when :hmget
157
- kvs[:KVKeyCount] = command.count - 2
158
- values = r.select { |i| i }
159
- kvs[:KVHitCount] = values.count
160
-
161
- when :mset, :msetnx
162
- if command[1].is_a?(Array)
163
- kvs[:KVKeyCount] = command[1].count / 2
164
- else
165
- kvs[:KVKeyCount] = (command.count - 1) / 2
166
- end
167
- end # case op
168
- end # if KV_COLLECT_MAP[op]
169
- rescue StandardError => e
170
- SolarWindsAPM.logger.debug "[solarwinds_apm/redis] Error collecting redis KVs: #{e.message}"
171
- SolarWindsAPM.logger.debug e.backtrace.join('\n')
172
- ensure
173
- return kvs
174
- end
175
-
176
- # Extracts the Key/Values to report from a pipelined
177
- # call to the SolarWinds dashboard.
178
- #
179
- # @param pipeline [Redis::Pipeline] the Redis pipeline instance
180
- # @return [Hash] the Key/Values to report
181
- def extract_pipeline_details(pipeline)
182
- kvs = {}
183
-
184
- kvs[:RemoteHost] = @options[:host]
185
- kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:redis][:collect_backtraces]
186
-
187
- command_count = pipeline.commands.count
188
- kvs[:KVOpCount] = command_count
189
-
190
- kvs[:KVOp] = if pipeline.commands.first == :multi
191
- :multi
192
- else
193
- :pipeline
194
- end
195
-
196
- # Report pipelined operations if the number
197
- # of ops is reasonable
198
- if command_count < 12
199
- ops = []
200
- pipeline.commands.each do |c|
201
- ops << c.first
202
- end
203
- kvs[:KVOps] = ops.join(', ')
204
- end
205
- rescue StandardError => e
206
- SolarWindsAPM.logger.debug "[solarwinds_apm/debug] Error extracting pipelined commands: #{e.message}"
207
- SolarWindsAPM.logger.debug e.backtrace
208
- ensure
209
- return kvs
210
- end
211
-
212
- #
213
- # The wrapper method for Redis::Client.call. Here
214
- # (when tracing) we capture KVs to report and pass
215
- # the call along
216
- #
217
- def call_with_sw_apm(command, &block)
218
- if SolarWindsAPM.tracing?
219
- SolarWindsAPM::API.log_entry(:redis, {})
220
-
221
- begin
222
- r = call_without_sw_apm(command, &block)
223
- report_kvs = extract_trace_details(command, r)
224
- r
225
- rescue StandardError => e
226
- SolarWindsAPM::API.log_exception(:redis, e)
227
- raise
228
- ensure
229
- SolarWindsAPM::API.log_exit(:redis, report_kvs)
230
- end
231
-
232
- else
233
- call_without_sw_apm(command, &block)
234
- end
235
- end
236
-
237
- #
238
- # The wrapper method for Redis::Client.call_pipeline. Here
239
- # (when tracing) we capture KVs to report and pass the call along
240
- #
241
- def call_pipeline_with_sw_apm(pipeline)
242
- if SolarWindsAPM.tracing?
243
- # Fall back to the raw tracing API so we can pass KVs
244
- # back on exit (a limitation of the SolarWindsAPM::API.trace
245
- # block method) This removes the need for an info
246
- # event to send additonal KVs
247
- SolarWindsAPM::API.log_entry(:redis, {})
248
-
249
- report_kvs = extract_pipeline_details(pipeline)
250
-
251
- begin
252
- call_pipeline_without_sw_apm(pipeline)
253
- rescue StandardError => e
254
- SolarWindsAPM::API.log_exception(:redis, e)
255
- raise
256
- ensure
257
- SolarWindsAPM::API.log_exit(:redis, report_kvs)
258
- end
259
- else
260
- call_pipeline_without_sw_apm(pipeline)
261
- end
262
- end
263
- end
264
- end
265
- end
266
- end
267
-
268
- if SolarWindsAPM::Config[:redis][:enabled]
269
- if defined?(::Redis) && ::Redis::VERSION < '5' && ::Redis::VERSION > '3'
270
- SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting redis' if SolarWindsAPM::Config[:verbose]
271
- SolarWindsAPM::Util.send_include(::Redis::Client, SolarWindsAPM::Inst::RedisV4::Client)
272
- end
273
- end
@@ -1,129 +0,0 @@
1
- # Copyright (c) 2016 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- require 'socket'
5
- require 'json'
6
-
7
- module SolarWindsAPM
8
- module Inst
9
- module ResqueClient
10
-
11
- self.include SolarWindsAPM::SDK::TraceContextHeaders
12
-
13
- def extract_trace_details(klass, args)
14
- report_kvs = {}
15
-
16
- begin
17
- report_kvs[:Spec] = :pushq
18
- report_kvs[:Flavor] = :resque
19
- report_kvs[:JobName] = klass.to_s
20
-
21
- if SolarWindsAPM::Config[:resqueclient][:log_args]
22
- kv_args = args.to_json
23
-
24
- # Limit the argument json string to 1024 bytes
25
- if kv_args.length > 1024
26
- report_kvs[:Args] = kv_args[0..1023] + '...[snipped]'
27
- else
28
- report_kvs[:Args] = kv_args
29
- end
30
- end
31
- report_kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:resqueclient][:collect_backtraces]
32
- report_kvs[:Queue] = klass.instance_variable_get(:@queue)
33
- rescue => e
34
- SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if SolarWindsAPM::Config[:verbose]
35
- end
36
-
37
- report_kvs
38
- end
39
-
40
- def push(queue, item)
41
- if SolarWindsAPM.tracing?
42
- report_kvs = extract_trace_details(item[:class], item[:args])
43
- report_kvs[:Queue] = queue.to_s if queue
44
-
45
- SolarWindsAPM::SDK.trace(:'resque-client', kvs: report_kvs) do
46
- add_tracecontext_headers(item)
47
- super
48
- end
49
- else
50
- super
51
- end
52
- end
53
-
54
- def dequeue(klass, *args)
55
- if SolarWindsAPM.tracing?
56
- report_kvs = extract_trace_details(klass, args)
57
- SolarWindsAPM::SDK.trace(:'resque-client', kvs: report_kvs) do
58
- super(klass, *args)
59
- end
60
- else
61
- super(klass, *args)
62
- end
63
- end
64
- end
65
-
66
- module ResqueJob
67
-
68
- def perform
69
- report_kvs = {}
70
-
71
- begin
72
- report_kvs[:Spec] = :job
73
- report_kvs[:Flavor] = :resque
74
- report_kvs[:JobName] = payload['class'].to_s
75
- report_kvs[:Queue] = queue.to_s
76
-
77
- # Set these keys for the ability to separate out
78
- # background tasks into a separate app on the server-side UI
79
-
80
- report_kvs[:'HTTP-Host'] = Socket.gethostname
81
- report_kvs[:Controller] = "Resque_#{queue}"
82
- report_kvs[:Action] = payload['class'].to_s
83
- report_kvs[:URL] = "/resque/#{queue}/#{payload['class']}"
84
-
85
- if SolarWindsAPM::Config[:resqueworker][:log_args]
86
- kv_args = payload['args'].to_json
87
-
88
- # Limit the argument json string to 1024 bytes
89
- if kv_args.length > 1024
90
- report_kvs[:Args] = kv_args[0..1023] + '...[snipped]'
91
- else
92
- report_kvs[:Args] = kv_args
93
- end
94
- end
95
-
96
- report_kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:resqueworker][:collect_backtraces]
97
- rescue => e
98
- SolarWindsAPM.logger.debug "[solarwinds_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if SolarWindsAPM::Config[:verbose]
99
- end
100
-
101
- SolarWindsAPM::SDK.start_trace('resque-worker', kvs: report_kvs, headers: payload) do
102
- super
103
- end
104
-
105
- def fail(exception)
106
- if SolarWindsAPM.tracing?
107
- SolarWindsAPM::API.log_exception(:resque, exception)
108
- end
109
- super(exception)
110
- end
111
- end
112
- end
113
- end
114
- end
115
-
116
- if defined?(::Resque)
117
- SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting resque' if SolarWindsAPM::Config[:verbose]
118
-
119
- if SolarWindsAPM::Config[:resqueclient][:enabled]
120
- ::Resque.singleton_class.prepend(SolarWindsAPM::Inst::ResqueClient)
121
- ::Resque.singleton_class.prepend(SolarWindsAPM::Inst::ResqueClient)
122
- end
123
-
124
- if SolarWindsAPM::Config[:resqueclient][:enabled] || SolarWindsAPM::Config[:resqueworker][:enabled]
125
- Resque::Job.prepend(SolarWindsAPM::Inst::ResqueJob)
126
- end
127
- end
128
-
129
-
@@ -1,43 +0,0 @@
1
- # Copyright (c) 2016 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- module SolarWindsAPM
5
- module Inst
6
- module RestClientRequest
7
- include SolarWindsAPM::SDK::TraceContextHeaders
8
-
9
- ##
10
- # execute
11
- #
12
- # The wrapper method for RestClient::Request.execute
13
- #
14
- def execute(&block)
15
- unless SolarWindsAPM.tracing?
16
- add_tracecontext_headers(@processed_headers)
17
- return super(&block)
18
- end
19
-
20
- begin
21
- kvs = {}
22
- kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:rest_client][:collect_backtraces]
23
- SolarWindsAPM::API.log_entry('rest-client', kvs)
24
-
25
- add_tracecontext_headers(@processed_headers)
26
-
27
- # The core rest-client call
28
- super(&block)
29
- rescue => e
30
- SolarWindsAPM::API.log_exception('rest-client', e)
31
- raise e
32
- ensure
33
- SolarWindsAPM::API.log_exit('rest-client')
34
- end
35
- end
36
- end
37
- end
38
- end
39
-
40
- if defined?(RestClient) && SolarWindsAPM::Config[:rest_client][:enabled]
41
- SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting rest-client' if SolarWindsAPM::Config[:verbose]
42
- RestClient::Request.prepend(SolarWindsAPM::Inst::RestClientRequest)
43
- end
@@ -1,241 +0,0 @@
1
- # Copyright (c) 2016 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- module SolarWindsAPM
5
- module Inst
6
- ##
7
- # SolarWindsAPM::Inst::Sequel
8
- #
9
- # The common (shared) methods used by the SolarWindsAPM Sequel instrumentation
10
- # across multiple modules/classes.
11
- #
12
- module Sequel
13
- ##
14
- # assign_kvs
15
- #
16
- # Given SQL and the options hash, this method extracts the interesting
17
- # bits for reporting to the SolarWinds dashboard.
18
- #
19
- # kvs is a hash and we are taking advantage of using it by reference to
20
- # assign kvs to the exit event (important for trace injection)
21
- #
22
- def assign_kvs(sql, opts, kvs)
23
- unless sql.is_a?(String)
24
- kvs[:IsPreparedStatement] = true
25
- end
26
-
27
- if ::Sequel::VERSION > '4.36.0' && !sql.is_a?(String)
28
- # TODO check if this is true for all sql
29
- # In 4.37.0, sql was converted to a prepared statement object
30
- sql = sql.prepared_sql unless sql.is_a?(Symbol)
31
- end
32
-
33
- if SolarWindsAPM::Config[:sanitize_sql]
34
- # Sanitize SQL and don't report binds
35
- if sql.is_a?(Symbol)
36
- kvs[:Query] = sql
37
- else
38
- sql = SolarWindsAPM::Util.remove_traceparent(sql)
39
- kvs[:Query] = SolarWindsAPM::Util.sanitize_sql(sql)
40
- end
41
- else
42
- # Report raw SQL and any binds if they exist
43
- kvs[:Query] = SolarWindsAPM::Util.remove_traceparent(sql.to_s)
44
- kvs[:QueryArgs] = opts[:arguments] if opts.is_a?(Hash) && opts.key?(:arguments)
45
- end
46
-
47
- kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:sequel][:collect_backtraces]
48
-
49
- if ::Sequel::VERSION < '3.41.0' && !(self.class.to_s =~ /Dataset$/)
50
- db_opts = @opts
51
- elsif @pool
52
- db_opts = @pool.db.opts
53
- else
54
- db_opts = @db.opts
55
- end
56
-
57
- kvs[:Database] = db_opts[:database]
58
- kvs[:RemoteHost] = db_opts[:host]
59
- kvs[:RemotePort] = db_opts[:port] if db_opts.key?(:port)
60
- kvs[:Flavor] = db_opts[:adapter]
61
- rescue => e
62
- SolarWindsAPM.logger.debug "[solarwinds_apm/debug Error capturing Sequel KVs: #{e.message}" if SolarWindsAPM::Config[:verbose]
63
- end
64
-
65
- ##
66
- # exec_with_sw_apm
67
- #
68
- # This method wraps and routes the call to the specified
69
- # original method call
70
- #
71
- def exec_with_sw_apm(method, sql, opts = ::Sequel::OPTS, &block)
72
- kvs = {}
73
- SolarWindsAPM::SDK.trace(:sequel, kvs: kvs) do
74
- new_sql = add_traceparent(sql, kvs)
75
- assign_kvs(new_sql, opts, kvs) if SolarWindsAPM.tracing?
76
- send(method, new_sql, opts, &block)
77
- end
78
- end
79
-
80
- def add_traceparent(sql, kvs)
81
- return sql unless SolarWindsAPM.tracing? && SolarWindsAPM::Config[:tag_sql]
82
-
83
- case sql
84
- when String
85
- return SolarWindsAPM::SDK.current_trace_info.add_traceparent_to_sql(sql, kvs)
86
- when Symbol
87
- if defined?(prepared_statement) # for mysql2
88
- ps = prepared_statement(sql)
89
- new_ps = add_traceparent_to_ps(ps, kvs)
90
- set_prepared_statement(sql, new_ps)
91
- return sql # related query may have been modified
92
- elsif self.is_a?(::Sequel::Dataset) # for postgresql
93
- ps = self
94
- new_ps = add_traceparent_to_ps(ps, kvs)
95
- self.db.set_prepared_statement(sql, new_ps)
96
- return sql
97
- end
98
- when ::Sequel::Dataset::ArgumentMapper # for mysql2
99
- new_sql = add_traceparent_to_ps(sql, kvs)
100
- return new_sql # related query may have been modified
101
- end
102
- sql # return original when none of the cases match
103
- end
104
-
105
- # this method uses some non-api methods partially copied from
106
- # `execute_prepared_statement` in `mysql2.rb`
107
- # and `prepare` in `prepared_statements.rb` in the sequel gem
108
- def add_traceparent_to_ps(ps, kvs)
109
- sql = ps.prepared_sql
110
- new_sql = SolarWindsAPM::SDK.current_trace_info.add_traceparent_to_sql(sql, kvs)
111
-
112
- unless new_sql == sql
113
- new_ps = ps.clone(:prepared_sql=>new_sql, :sql=>new_sql)
114
- return new_ps
115
- end
116
-
117
- ps # no change, no trace context added
118
- end
119
- end
120
-
121
- module SequelDatabase
122
- include SolarWindsAPM::Inst::Sequel
123
-
124
- def self.included(klass)
125
- SolarWindsAPM::Util.method_alias(klass, :run, ::Sequel::Database)
126
- SolarWindsAPM::Util.method_alias(klass, :execute_ddl, ::Sequel::Database)
127
- SolarWindsAPM::Util.method_alias(klass, :execute_dui, ::Sequel::Database)
128
- SolarWindsAPM::Util.method_alias(klass, :execute_insert, ::Sequel::Database)
129
- end
130
-
131
- def run_with_sw_apm(sql, opts = ::Sequel::OPTS)
132
- kvs = {}
133
- SolarWindsAPM::SDK.trace(:sequel, kvs: kvs) do
134
- new_sql = add_traceparent(sql, kvs)
135
- assign_kvs(new_sql, opts, kvs) if SolarWindsAPM.tracing?
136
- run_without_sw_apm(new_sql, opts)
137
- end
138
- end
139
-
140
- def execute_ddl_with_sw_apm(sql, opts = ::Sequel::OPTS, &block)
141
- # If we're already tracing a sequel operation, then this call likely came
142
- # from Sequel::Dataset. In this case, just pass it on.
143
- return execute_ddl_without_sw_apm(sql, opts, &block) if SolarWindsAPM.tracing_layer?(:sequel)
144
-
145
- exec_with_sw_apm(:execute_ddl_without_sw_apm, sql, opts, &block)
146
- end
147
-
148
- def execute_dui_with_sw_apm(sql, opts = ::Sequel::OPTS, &block)
149
- # If we're already tracing a sequel operation, then this call likely came
150
- # from Sequel::Dataset. In this case, just pass it on.
151
- return execute_dui_without_sw_apm(sql, opts, &block) if SolarWindsAPM.tracing_layer?(:sequel)
152
-
153
- exec_with_sw_apm(:execute_dui_without_sw_apm, sql, opts, &block)
154
- end
155
-
156
- def execute_insert_with_sw_apm(sql, opts = ::Sequel::OPTS, &block)
157
- # If we're already tracing a sequel operation, then this call likely came
158
- # from Sequel::Dataset. In this case, just pass it on.
159
- return execute_insert_without_sw_apm(sql, opts, &block) if SolarWindsAPM.tracing_layer?(:sequel)
160
-
161
- exec_with_sw_apm(:execute_insert_without_sw_apm, sql, opts, &block)
162
- end
163
- end # module SequelDatabase
164
-
165
- module AdapterDatabase
166
- include SolarWindsAPM::Inst::Sequel
167
-
168
- def self.included(klass)
169
- if defined?(::Sequel::MySQL::MysqlMysql2::DatabaseMethods)
170
- SolarWindsAPM::Util.method_alias(klass, :execute, ::Sequel::MySQL::MysqlMysql2::DatabaseMethods)
171
- end
172
- if defined?(::Sequel::Postgres::Database)
173
- SolarWindsAPM::Util.method_alias(klass, :execute, ::Sequel::Postgres::Database)
174
- end
175
- end
176
-
177
- def execute_with_sw_apm(*args, &block)
178
- # if this is called via a dataset it is already being traced
179
- return execute_without_sw_apm(*args, &block) if SolarWindsAPM.tracing_layer?(:sequel)
180
-
181
- kvs = {}
182
- SolarWindsAPM::SDK.trace(:sequel, kvs: kvs) do
183
- new_sql = add_traceparent(args[0], kvs)
184
- args[0] = new_sql
185
- assign_kvs(args[0], args[1], kvs) if SolarWindsAPM.tracing?
186
- execute_without_sw_apm(*args, &block)
187
- end
188
- end
189
- end
190
-
191
- module SequelDataset
192
- include SolarWindsAPM::Inst::Sequel
193
-
194
- def self.included(klass)
195
- SolarWindsAPM::Util.method_alias(klass, :execute, ::Sequel::Dataset)
196
- SolarWindsAPM::Util.method_alias(klass, :execute_ddl, ::Sequel::Dataset)
197
- SolarWindsAPM::Util.method_alias(klass, :execute_dui, ::Sequel::Dataset)
198
- SolarWindsAPM::Util.method_alias(klass, :execute_insert, ::Sequel::Dataset)
199
- end
200
-
201
- def execute_with_sw_apm(sql, opts = ::Sequel::OPTS, &block)
202
- exec_with_sw_apm(:execute_without_sw_apm, sql, opts, &block)
203
- end
204
-
205
- def execute_ddl_with_sw_apm(sql, opts = ::Sequel::OPTS, &block)
206
- exec_with_sw_apm(:execute_ddl_without_sw_apm, sql, opts, &block)
207
- end
208
-
209
- def execute_dui_with_sw_apm(sql, opts = ::Sequel::OPTS, &block)
210
- exec_with_sw_apm(:execute_dui_without_sw_apm, sql, opts, &block)
211
- end
212
-
213
- def execute_insert_with_sw_apm(sql, opts = ::Sequel::OPTS, &block)
214
- exec_with_sw_apm(:execute_insert_without_sw_apm, sql, opts, &block)
215
- end
216
-
217
- end # module SequelDataset
218
- end # module Inst
219
- end # module SolarWindsAPM
220
-
221
- if SolarWindsAPM::Config[:sequel][:enabled]
222
- if defined?(::Sequel) && ::Sequel::VERSION < '4.0.0'
223
- # For versions before 4.0.0, Sequel::OPTS wasn't defined.
224
- # Define it as an empty hash for backwards compatibility.
225
- module ::Sequel
226
- OPTS = {}
227
- end
228
- end
229
-
230
- if defined?(::Sequel)
231
- SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting sequel' if SolarWindsAPM::Config[:verbose]
232
- SolarWindsAPM::Util.send_include(::Sequel::Database, SolarWindsAPM::Inst::SequelDatabase)
233
- SolarWindsAPM::Util.send_include(::Sequel::Dataset, SolarWindsAPM::Inst::SequelDataset)
234
-
235
- # TODO this is temporary, we need to instrument `require`, see NH-9711
236
- require 'sequel/adapters/mysql2'
237
- SolarWindsAPM::Util.send_include(::Sequel::MySQL::MysqlMysql2::DatabaseMethods, SolarWindsAPM::Inst::AdapterDatabase)
238
- require 'sequel/adapters/postgres'
239
- SolarWindsAPM::Util.send_include(::Sequel::Postgres::Database, SolarWindsAPM::Inst::AdapterDatabase)
240
- end
241
- end