solarwinds_apm 5.1.2 → 5.1.4
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 +4 -4
- data/.gitignore +15 -0
- data/CHANGELOG.md +14 -0
- data/README.md +4 -2
- data/ext/oboe_metal/extconf.rb +18 -5
- data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.0.0.0.sha256 +1 -0
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.0.0.0.sha256 +1 -0
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -1
- data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -1
- data/ext/oboe_metal/src/VERSION +1 -1
- data/ext/oboe_metal/src/oboe.h +2 -4
- data/ext/oboe_metal/src/oboe_api.cpp +7 -12
- data/ext/oboe_metal/src/oboe_api.h +1 -3
- data/ext/oboe_metal/src/oboe_swig_wrap.cc +3 -19
- data/lib/oboe_metal.rb +9 -0
- data/lib/solarwinds_apm/cert/star.appoptics.com.issuer.crt +24 -0
- data/lib/solarwinds_apm/inst/redis.rb +36 -29
- data/lib/solarwinds_apm/inst/redis_v4.rb +273 -0
- data/lib/solarwinds_apm/oboe_init_options.rb +23 -6
- data/lib/solarwinds_apm/util.rb +116 -42
- data/lib/solarwinds_apm/version.rb +1 -1
- data/solarwinds_apm.gemspec +5 -2
- metadata +6 -12
- data/.github/CODEOWNERS +0 -1
- data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +0 -16
- data/.github/workflows/build_and_release_gem.yml +0 -108
- data/.github/workflows/build_for_packagecloud.yml +0 -59
- data/.github/workflows/docker-images.yml +0 -53
- data/.github/workflows/run_cpluplus_tests.yml +0 -73
- data/.github/workflows/run_tests.yml +0 -154
- data/.github/workflows/scripts/test_install.rb +0 -28
- data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
- 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
|
-
#
|
37
|
-
@
|
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
|
-
@
|
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
|
-
|
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
|
data/lib/solarwinds_apm/util.rb
CHANGED
@@ -265,57 +265,66 @@ module SolarWindsAPM
|
|
265
265
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
|
266
266
|
|
267
267
|
##
|
268
|
-
#
|
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
|
276
|
+
def build_legacy_ao_init_report
|
276
277
|
platform_info = { '__Init' => 1 }
|
277
|
-
|
278
278
|
begin
|
279
|
-
platform_info['Force']
|
280
|
-
platform_info['Ruby.Platform.Version']
|
281
|
-
platform_info['Ruby.Version']
|
282
|
-
platform_info['Ruby.SolarWindsAPM.Version']
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
platform_info
|
287
|
-
platform_info
|
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
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
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 =
|
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('.')
|
data/solarwinds_apm.gemspec
CHANGED
@@ -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.
|
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:
|
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)
|