solarwinds_apm 5.1.2 → 5.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/CHANGELOG.md +14 -0
  4. data/README.md +4 -2
  5. data/ext/oboe_metal/extconf.rb +18 -5
  6. data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.0.0.0.sha256 +1 -0
  7. data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.0.0.0.sha256 +1 -0
  8. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -1
  9. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -1
  10. data/ext/oboe_metal/src/VERSION +1 -1
  11. data/ext/oboe_metal/src/oboe.h +2 -4
  12. data/ext/oboe_metal/src/oboe_api.cpp +7 -12
  13. data/ext/oboe_metal/src/oboe_api.h +1 -3
  14. data/ext/oboe_metal/src/oboe_swig_wrap.cc +3 -19
  15. data/lib/oboe_metal.rb +9 -0
  16. data/lib/solarwinds_apm/cert/star.appoptics.com.issuer.crt +24 -0
  17. data/lib/solarwinds_apm/inst/redis.rb +36 -29
  18. data/lib/solarwinds_apm/inst/redis_v4.rb +273 -0
  19. data/lib/solarwinds_apm/oboe_init_options.rb +23 -6
  20. data/lib/solarwinds_apm/util.rb +116 -42
  21. data/lib/solarwinds_apm/version.rb +1 -1
  22. data/solarwinds_apm.gemspec +5 -2
  23. metadata +6 -12
  24. data/.github/CODEOWNERS +0 -1
  25. data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +0 -16
  26. data/.github/workflows/build_and_release_gem.yml +0 -108
  27. data/.github/workflows/build_for_packagecloud.yml +0 -59
  28. data/.github/workflows/docker-images.yml +0 -53
  29. data/.github/workflows/run_cpluplus_tests.yml +0 -73
  30. data/.github/workflows/run_tests.yml +0 -154
  31. data/.github/workflows/scripts/test_install.rb +0 -28
  32. data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
  33. data/.github/workflows/test_on_4_linux.yml +0 -161
@@ -0,0 +1,273 @@
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
@@ -33,8 +33,8 @@ module SolarWindsAPM
33
33
 
34
34
  # the service key
35
35
  @service_key = read_and_validate_service_key
36
- # path to the SSL certificate (only for ssl)
37
- @trusted_path = ENV['SW_APM_TRUSTEDPATH'] || ''
36
+ # certificate content
37
+ @certificates = read_certificates
38
38
  # size of the message buffer
39
39
  @buffer_size = (ENV['SW_APM_BUFSIZE'] || -1).to_i
40
40
  # flag indicating if trace metrics reporting should be enabled (default) or disabled
@@ -74,7 +74,7 @@ module SolarWindsAPM
74
74
  @reporter, # 7
75
75
  @host, # 8
76
76
  @service_key, # 9
77
- @trusted_path, #10
77
+ @certificates, #10
78
78
  @buffer_size, #11
79
79
  @trace_metrics, #12
80
80
  @histogram_precision, #13
@@ -84,9 +84,7 @@ module SolarWindsAPM
84
84
  @ec2_md_timeout, #17
85
85
  @grpc_proxy, #18
86
86
  0, #19 arg for lambda (no lambda for ruby yet)
87
- 1, #20 arg for grpc hack, hardcoded to include hack
88
- 1, #21 arg for trace id format to use w3c format
89
- @metric_format #22
87
+ @metric_format #20
90
88
  ]
91
89
  end
92
90
 
@@ -190,6 +188,25 @@ module SolarWindsAPM
190
188
  proxy
191
189
  end
192
190
 
191
+ def read_certificates
192
+
193
+ file = ''
194
+ file = "#{File.expand_path File.dirname(__FILE__)}/cert/star.appoptics.com.issuer.crt" if ENV["SW_APM_COLLECTOR"]&.include? "appoptics.com"
195
+ file = ENV['SW_APM_TRUSTEDPATH'] if (!ENV['SW_APM_TRUSTEDPATH'].nil? && !ENV['SW_APM_TRUSTEDPATH']&.empty?)
196
+
197
+ return String.new if file.empty?
198
+
199
+ begin
200
+ certificate = File.open(file,"r").read
201
+ rescue StandardError => e
202
+ SolarWindsAPM.logger.error "[solarwinds_apm/oboe_options] certificates: #{file} doesn't exist or caused by #{e.message}."
203
+ certificate = String.new
204
+ end
205
+
206
+ return certificate
207
+
208
+ end
209
+
193
210
  def determine_the_metric_model
194
211
  if ENV['SW_APM_COLLECTOR']&.include? "appoptics.com"
195
212
  return 1
@@ -265,57 +265,66 @@ module SolarWindsAPM
265
265
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
266
266
 
267
267
  ##
268
- # build_init_report
268
+ # build_legacy_ao_init_report
269
269
  #
270
270
  # Internal: Build a hash of KVs that reports on the status of the
271
271
  # running environment. This is used on stack boot in __Init reporting
272
272
  # and for SolarWindsAPM.support_report.
273
+ # On 2023-01-12, this is no longer used in new SWO endpoints
273
274
  #
274
275
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
275
- def build_init_report
276
+ def build_legacy_ao_init_report
276
277
  platform_info = { '__Init' => 1 }
277
-
278
278
  begin
279
- platform_info['Force'] = true
280
- platform_info['Ruby.Platform.Version'] = RUBY_PLATFORM
281
- platform_info['Ruby.Version'] = RUBY_VERSION
282
- platform_info['Ruby.SolarWindsAPM.Version'] = SolarWindsAPM::Version::STRING
283
-
284
- # oboe not loaded yet, can't use oboe_api function to read oboe VERSION
285
- clib_version_file = File.join(Gem::Specification.find_by_name('solarwinds_apm').gem_dir, 'ext', 'oboe_metal', 'src', 'VERSION')
286
- platform_info['Ruby.SolarWindsAPMExtension.Version'] = File.read(clib_version_file).strip
287
- platform_info['RubyHeroku.SolarWindsAPM.Version'] = SolarWindsAPMHeroku::Version::STRING if defined?(SolarWindsAPMHeroku)
288
- platform_info['Ruby.TraceMode.Version'] = SolarWindsAPM::Config[:tracing_mode]
289
-
290
- # Collect up the loaded gems
291
- if defined?(Gem) && Gem.respond_to?(:loaded_specs)
292
- Gem.loaded_specs.each_pair { |k, v|
293
- platform_info["Ruby.#{k}.Version"] = v.version.to_s
294
- }
295
- else
296
- platform_info.merge!(legacy_build_init_report)
297
- end
279
+ platform_info['Force'] = true
280
+ platform_info['Ruby.Platform.Version'] = RUBY_PLATFORM
281
+ platform_info['Ruby.Version'] = RUBY_VERSION
282
+ platform_info['Ruby.SolarWindsAPM.Version'] = SolarWindsAPM::Version::STRING
283
+ platform_info['Ruby.SolarWindsAPMExtension.Version'] = get_extension_lib_version
284
+ platform_info['RubyHeroku.SolarWindsAPM.Version'] = SolarWindsAPMHeroku::Version::STRING if defined?(SolarWindsAPMHeroku)
285
+ platform_info['Ruby.TraceMode.Version'] = SolarWindsAPM::Config[:tracing_mode]
286
+ platform_info.merge!(report_gem_in_use)
287
+ platform_info.merge!(report_server_in_use)
298
288
 
299
- # Report the server in use (if possible)
300
- if defined?(::Unicorn::Const::UNICORN_VERSION)
301
- platform_info['Ruby.AppContainer.Version'] = "Unicorn-#{::Unicorn::Const::UNICORN_VERSION}"
302
- elsif defined?(::Puma::Const::PUMA_VERSION)
303
- platform_info['Ruby.AppContainer.Version'] = "Puma-#{::Puma::Const::PUMA_VERSION} (#{::Puma::Const::CODE_NAME})"
304
- elsif defined?(::PhusionPassenger::PACKAGE_NAME)
305
- platform_info['Ruby.AppContainer.Version'] = "#{::PhusionPassenger::PACKAGE_NAME}-#{::PhusionPassenger::VERSION_STRING}"
306
- elsif defined?(::Thin::VERSION::STRING)
307
- platform_info['Ruby.AppContainer.Version'] = "Thin-#{::Thin::VERSION::STRING} (#{::Thin::VERSION::CODENAME})"
308
- elsif defined?(::Mongrel::Const::MONGREL_VERSION)
309
- platform_info['Ruby.AppContainer.Version'] = "Mongrel-#{::Mongrel::Const::MONGREL_VERSION}"
310
- elsif defined?(::Mongrel2::VERSION)
311
- platform_info['Ruby.AppContainer.Version'] = "Mongrel2-#{::Mongrel2::VERSION}"
312
- elsif defined?(::Trinidad::VERSION)
313
- platform_info['Ruby.AppContainer.Version'] = "Trinidad-#{::Trinidad::VERSION}"
314
- elsif defined?(::WEBrick::VERSION)
315
- platform_info['Ruby.AppContainer.Version'] = "WEBrick-#{::WEBrick::VERSION}"
316
- else
317
- platform_info['Ruby.AppContainer.Version'] = File.basename($PROGRAM_NAME)
318
- end
289
+ rescue StandardError, ScriptError => e
290
+ platform_info['Error'] = "Error in build_report: #{e.message}"
291
+ SolarWindsAPM.logger.warn "[solarwinds_apm/warn] Error in build_init_report: #{e.message}"
292
+ SolarWindsAPM.logger.debug e.backtrace
293
+ end
294
+ platform_info
295
+ end
296
+
297
+ ##
298
+ # build_swo_init_report
299
+ #
300
+ # Internal: Build a hash of KVs that reports on the status of the
301
+ # running environment for swo only. This is used on stack boot in __Init reporting
302
+ # and for SolarWindsAPM.support_report.
303
+ #
304
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
305
+ def build_init_report
306
+
307
+ platform_info = { '__Init' => true }
308
+
309
+ begin
310
+ platform_info['APM.Version'] = SolarWindsAPM::Version::STRING
311
+ platform_info['APM.Extension.Version'] = get_extension_lib_version
312
+
313
+ platform_info['process.pid'] = Process.pid
314
+ platform_info['process.command'] = $PROGRAM_NAME
315
+ platform_info['process.runtime.name'] = RUBY_ENGINE
316
+ platform_info['process.runtime.version'] = RUBY_VERSION
317
+ platform_info['process.runtime.description'] = RUBY_DESCRIPTION
318
+ platform_info['telemetry.sdk.language'] = 'ruby'
319
+
320
+ # Resource Attributes (Optional)
321
+ platform_info['process.executable.path'] = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']).sub(/.*\s.*/m, '"\&"')
322
+ platform_info['process.executable.name'] = RbConfig::CONFIG['ruby_install_name']
323
+ platform_info['process.command_line'] = $PROGRAM_NAME
324
+ platform_info['process.telemetry.path'] = Gem::Specification.find_by_name('solarwinds_apm')&.full_gem_path
325
+ platform_info['os.type'] = RUBY_PLATFORM
326
+
327
+ platform_info.merge!(report_gem_in_use)
319
328
 
320
329
  rescue StandardError, ScriptError => e
321
330
  # Also rescue ScriptError (aka SyntaxError) in case one of the expected
@@ -329,6 +338,71 @@ module SolarWindsAPM
329
338
  platform_info
330
339
  end
331
340
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
341
+
342
+ private
343
+
344
+ ##
345
+ # Collect up the loaded gems
346
+ ##
347
+ def report_gem_in_use
348
+ platform_info = {}
349
+ if defined?(Gem) && Gem.respond_to?(:loaded_specs)
350
+ Gem.loaded_specs.each_pair { |k, v|
351
+ platform_info["Ruby.#{k}.Version"] = v.version.to_s
352
+ }
353
+ else
354
+ platform_info.merge!(legacy_build_init_report)
355
+ end
356
+ platform_info
357
+ end
358
+
359
+ ##
360
+ # get extension library version by looking at the VERSION file
361
+ # oboe not loaded yet, can't use oboe_api function to read oboe VERSION
362
+ ##
363
+ def get_extension_lib_version
364
+ version = '0.0.0'
365
+ begin
366
+ gem_location = Gem::Specification.find_by_name('solarwinds_apm')
367
+ clib_version_file = File.join(gem_location&.gem_dir, 'ext', 'oboe_metal', 'src', 'VERSION')
368
+ version = File.read(clib_version_file).strip
369
+ rescue
370
+ SolarWindsAPM.logger.warn "[solarwinds_apm/warn] Error in build_init_report: couldn't find installed solarwinds_apm gem #{e.message}"
371
+ end
372
+ version
373
+ end
374
+
375
+ ##
376
+ # build_init_report
377
+ #
378
+ # Internal: Build a hash of KVs that reports on the server in use
379
+ ##
380
+ def report_server_in_use
381
+ platform_info = {}
382
+ # Report the server in use (if possible)
383
+ if defined?(::Unicorn::Const::UNICORN_VERSION)
384
+ platform_info['Ruby.AppContainer.Version'] = "Unicorn-#{::Unicorn::Const::UNICORN_VERSION}"
385
+ elsif defined?(::Puma::Const::PUMA_VERSION)
386
+ platform_info['Ruby.AppContainer.Version'] = "Puma-#{::Puma::Const::PUMA_VERSION} (#{::Puma::Const::CODE_NAME})"
387
+ elsif defined?(::PhusionPassenger::PACKAGE_NAME)
388
+ platform_info['Ruby.AppContainer.Version'] = "#{::PhusionPassenger::PACKAGE_NAME}-#{::PhusionPassenger::VERSION_STRING}"
389
+ elsif defined?(::Thin::VERSION::STRING)
390
+ platform_info['Ruby.AppContainer.Version'] = "Thin-#{::Thin::VERSION::STRING} (#{::Thin::VERSION::CODENAME})"
391
+ elsif defined?(::Mongrel::Const::MONGREL_VERSION)
392
+ platform_info['Ruby.AppContainer.Version'] = "Mongrel-#{::Mongrel::Const::MONGREL_VERSION}"
393
+ elsif defined?(::Mongrel2::VERSION)
394
+ platform_info['Ruby.AppContainer.Version'] = "Mongrel2-#{::Mongrel2::VERSION}"
395
+ elsif defined?(::Trinidad::VERSION)
396
+ platform_info['Ruby.AppContainer.Version'] = "Trinidad-#{::Trinidad::VERSION}"
397
+ elsif defined?(::WEBrick::VERSION)
398
+ platform_info['Ruby.AppContainer.Version'] = "WEBrick-#{::WEBrick::VERSION}"
399
+ else
400
+ platform_info['Ruby.AppContainer.Version'] = File.basename($PROGRAM_NAME)
401
+ end
402
+ platform_info
403
+ end
404
+
332
405
  end
406
+
333
407
  end
334
408
  end
@@ -8,7 +8,7 @@ module SolarWindsAPM
8
8
  module Version
9
9
  MAJOR = 5 # breaking,
10
10
  MINOR = 1 # feature,
11
- PATCH = 2 # fix => BFF
11
+ PATCH = 4 # fix => BFF
12
12
  PRE = nil # for pre-releases into packagecloud, set to nil for production releases into rubygems
13
13
 
14
14
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
@@ -24,7 +24,7 @@ Automatic tracing and metrics for Ruby applications. Get started at cloud.solarw
24
24
  }
25
25
 
26
26
  s.extra_rdoc_files = ['LICENSE']
27
- s.files = `git ls-files`.split("\n").reject { |f| f.match(%r{^(test|gemfiles)/}) }
27
+ s.files = `git ls-files`.split("\n").reject { |f| f.match(%r{^(test|gemfiles|.github)/}) }
28
28
  s.files += ['ext/oboe_metal/src/oboe.h',
29
29
  'ext/oboe_metal/src/oboe_api.cpp',
30
30
  'ext/oboe_metal/src/oboe_api.h',
@@ -34,8 +34,11 @@ Automatic tracing and metrics for Ruby applications. Get started at cloud.solarw
34
34
  'ext/oboe_metal/src/bson/platform_hacks.h',
35
35
  'ext/oboe_metal/src/VERSION',
36
36
  'ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256',
37
- 'ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256'
37
+ 'ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256',
38
+ 'ext/oboe_metal/lib/liboboe-1.0-aarch64.so.0.0.0.sha256',
39
+ 'ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.0.0.0.sha256'
38
40
  ]
41
+ s.files += ['lib/solarwinds_apm/cert/star.appoptics.com.issuer.crt']
39
42
  s.files -= ['build_gem.sh',
40
43
  'build_gem_upload_to_packagecloud.sh',
41
44
  'Rakefile']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solarwinds_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.2
4
+ version: 5.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maia Engeli
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2022-10-13 00:00:00.000000000 Z
14
+ date: 2023-01-23 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: json
@@ -60,16 +60,6 @@ extra_rdoc_files:
60
60
  - LICENSE
61
61
  files:
62
62
  - ".dockerignore"
63
- - ".github/CODEOWNERS"
64
- - ".github/ISSUE_TEMPLATE/bug-or-feature-request.md"
65
- - ".github/workflows/build_and_release_gem.yml"
66
- - ".github/workflows/build_for_packagecloud.yml"
67
- - ".github/workflows/docker-images.yml"
68
- - ".github/workflows/run_cpluplus_tests.yml"
69
- - ".github/workflows/run_tests.yml"
70
- - ".github/workflows/scripts/test_install.rb"
71
- - ".github/workflows/swig/swig-v4.0.2.tar.gz"
72
- - ".github/workflows/test_on_4_linux.yml"
73
63
  - ".gitignore"
74
64
  - ".rubocop.yml"
75
65
  - ".whitesource"
@@ -87,6 +77,8 @@ files:
87
77
  - ext/oboe_metal/extconf.rb
88
78
  - ext/oboe_metal/extconf_local.rb
89
79
  - ext/oboe_metal/lib/.keep
80
+ - ext/oboe_metal/lib/liboboe-1.0-aarch64.so.0.0.0.sha256
81
+ - ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.0.0.0.sha256
90
82
  - ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256
91
83
  - ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256
92
84
  - ext/oboe_metal/noop/noop.c
@@ -129,6 +121,7 @@ files:
129
121
  - lib/solarwinds_apm/api/metrics.rb
130
122
  - lib/solarwinds_apm/api/util.rb
131
123
  - lib/solarwinds_apm/base.rb
124
+ - lib/solarwinds_apm/cert/star.appoptics.com.issuer.crt
132
125
  - lib/solarwinds_apm/config.rb
133
126
  - lib/solarwinds_apm/frameworks/grape.rb
134
127
  - lib/solarwinds_apm/frameworks/padrino.rb
@@ -165,6 +158,7 @@ files:
165
158
  - lib/solarwinds_apm/inst/rack.rb
166
159
  - lib/solarwinds_apm/inst/rack_cache.rb
167
160
  - lib/solarwinds_apm/inst/redis.rb
161
+ - lib/solarwinds_apm/inst/redis_v4.rb
168
162
  - lib/solarwinds_apm/inst/resque.rb
169
163
  - lib/solarwinds_apm/inst/rest-client.rb
170
164
  - lib/solarwinds_apm/inst/sequel.rb
data/.github/CODEOWNERS DELETED
@@ -1 +0,0 @@
1
- * @cheempz @xuan-cao-swi @tammy-baylis-swi
@@ -1,16 +0,0 @@
1
- ---
2
- name: Bug or Feature request
3
- about: general purpose template
4
- title: "[Bug] or [Feature request]"
5
- labels: ''
6
- assignees: ''
7
-
8
- ---
9
-
10
- # Description
11
-
12
- # How to reproduce or use case
13
-
14
- # Code Sample (if available)
15
-
16
- # OS, Ruby version, Gemfile, Gemfile.lock, log message ... (if relevant)