solarwinds_apm 6.0.0 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/oboe_metal/extconf.rb +42 -41
- data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +1 -1
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +1 -1
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +1 -1
- data/ext/oboe_metal/lib/liboboe-1.0-lambda-aarch64.so.sha256 +1 -0
- data/ext/oboe_metal/lib/liboboe-1.0-lambda-x86_64.so.sha256 +1 -0
- data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +1 -1
- data/ext/oboe_metal/src/VERSION +1 -1
- data/ext/oboe_metal/src/oboe.h +3 -0
- data/ext/oboe_metal/src/oboe_api.cpp +1 -1
- data/lib/oboe_metal.rb +30 -27
- data/lib/rails/generators/solarwinds_apm/install_generator.rb +21 -19
- data/lib/solarwinds_apm/api/current_trace_info.rb +16 -9
- data/lib/solarwinds_apm/api/custom_metrics.rb +6 -4
- data/lib/solarwinds_apm/api/opentelemetry.rb +8 -4
- data/lib/solarwinds_apm/api/tracing.rb +6 -4
- data/lib/solarwinds_apm/api/transaction_name.rb +21 -11
- data/lib/solarwinds_apm/api.rb +7 -5
- data/lib/solarwinds_apm/config.rb +70 -46
- data/lib/solarwinds_apm/constants.rb +25 -23
- data/lib/solarwinds_apm/logger.rb +2 -0
- data/lib/solarwinds_apm/noop/api.rb +3 -1
- data/lib/solarwinds_apm/noop/context.rb +2 -0
- data/lib/solarwinds_apm/noop/metadata.rb +2 -0
- data/lib/solarwinds_apm/noop/span.rb +2 -0
- data/lib/solarwinds_apm/noop.rb +8 -6
- data/lib/solarwinds_apm/oboe_init_options.rb +47 -39
- data/lib/solarwinds_apm/opentelemetry/otlp_processor.rb +135 -0
- data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +66 -41
- data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +49 -51
- data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +30 -22
- data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +29 -16
- data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +135 -98
- data/lib/solarwinds_apm/opentelemetry.rb +8 -5
- data/lib/solarwinds_apm/otel_config.rb +32 -25
- data/lib/solarwinds_apm/otel_lambda_config.rb +53 -0
- data/lib/solarwinds_apm/patch.rb +2 -0
- data/lib/solarwinds_apm/support/logger_formatter.rb +4 -2
- data/lib/solarwinds_apm/support/logging_log_event.rb +2 -0
- data/lib/solarwinds_apm/support/lumberjack_formatter.rb +2 -0
- data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +2 -0
- data/lib/solarwinds_apm/support/service_key_checker.rb +18 -6
- data/lib/solarwinds_apm/support/support_report.rb +5 -3
- data/lib/solarwinds_apm/support/swomarginalia/comment.rb +18 -17
- data/lib/solarwinds_apm/support/swomarginalia/load_swomarginalia.rb +13 -12
- data/lib/solarwinds_apm/support/swomarginalia/railtie.rb +4 -2
- data/lib/solarwinds_apm/support/swomarginalia/swomarginalia.rb +3 -1
- data/lib/solarwinds_apm/support/transaction_cache.rb +6 -4
- data/lib/solarwinds_apm/support/transaction_settings.rb +7 -3
- data/lib/solarwinds_apm/support/txn_name_manager.rb +8 -3
- data/lib/solarwinds_apm/support/utils.rb +12 -9
- data/lib/solarwinds_apm/support/x_trace_options.rb +23 -17
- data/lib/solarwinds_apm/support.rb +28 -24
- data/lib/solarwinds_apm/version.rb +3 -1
- data/lib/solarwinds_apm.rb +44 -34
- metadata +14 -23
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -35,35 +37,43 @@ module SolarWindsAPM
|
|
35
37
|
# === Returns:
|
36
38
|
# * Boolean
|
37
39
|
#
|
38
|
-
def set_transaction_name(custom_name=nil)
|
40
|
+
def set_transaction_name(custom_name = nil)
|
39
41
|
status = true
|
40
42
|
if ENV.fetch('SW_APM_ENABLED', 'true') == 'false' ||
|
41
43
|
SolarWindsAPM::Context.toString == '99-00000000000000000000000000000000-0000000000000000-00'
|
42
44
|
# library disabled or noop, just log and skip work.
|
43
45
|
# TODO: can we have a single indicator that the API is in noop mode?
|
44
|
-
SolarWindsAPM.logger.debug {"[#{name}/#{__method__}] SolarWindsAPM is in disabled or noop mode."}
|
46
|
+
SolarWindsAPM.logger.debug { "[#{name}/#{__method__}] SolarWindsAPM is in disabled or noop mode." }
|
45
47
|
elsif custom_name.nil? || custom_name.empty?
|
46
|
-
SolarWindsAPM.logger.warn
|
48
|
+
SolarWindsAPM.logger.warn do
|
49
|
+
"[#{name}/#{__method__}] Set transaction name failed: custom_name is either nil or empty string."
|
50
|
+
end
|
47
51
|
status = false
|
48
|
-
elsif SolarWindsAPM::OTelConfig
|
49
|
-
SolarWindsAPM.logger.warn
|
52
|
+
elsif SolarWindsAPM::OTelConfig[:metrics_processor].nil?
|
53
|
+
SolarWindsAPM.logger.warn do
|
54
|
+
"[#{name}/#{__method__}] Set transaction name failed: Solarwinds processor is missing."
|
55
|
+
end
|
50
56
|
status = false
|
51
57
|
else
|
52
|
-
solarwinds_processor = SolarWindsAPM::OTelConfig
|
53
|
-
current_span
|
58
|
+
solarwinds_processor = SolarWindsAPM::OTelConfig[:metrics_processor]
|
59
|
+
current_span = ::OpenTelemetry::Trace.current_span
|
54
60
|
|
55
61
|
if current_span.context.valid?
|
56
62
|
current_trace_id = current_span.context.hex_trace_id
|
57
63
|
entry_span_id, trace_flags = solarwinds_processor.txn_manager.get_root_context_h(current_trace_id)&.split('-')
|
58
64
|
if entry_span_id.to_s.empty? || trace_flags.to_s.empty?
|
59
|
-
SolarWindsAPM.logger.warn
|
65
|
+
SolarWindsAPM.logger.warn do
|
66
|
+
"[#{name}/#{__method__}] Set transaction name failed: record not found in the transaction manager."
|
67
|
+
end
|
60
68
|
status = false
|
61
69
|
else
|
62
|
-
solarwinds_processor.txn_manager.set("#{current_trace_id}-#{entry_span_id}",custom_name)
|
63
|
-
SolarWindsAPM.logger.debug
|
70
|
+
solarwinds_processor.txn_manager.set("#{current_trace_id}-#{entry_span_id}", custom_name)
|
71
|
+
SolarWindsAPM.logger.debug do
|
72
|
+
"[#{name}/#{__method__}] Cached custom transaction name for #{current_trace_id}-#{entry_span_id} as #{custom_name}"
|
73
|
+
end
|
64
74
|
end
|
65
75
|
else
|
66
|
-
SolarWindsAPM.logger.warn {"[#{name}/#{__method__}] Set transaction name failed: invalid span context."}
|
76
|
+
SolarWindsAPM.logger.warn { "[#{name}/#{__method__}] Set transaction name failed: invalid span context." }
|
67
77
|
status = false
|
68
78
|
end
|
69
79
|
end
|
data/lib/solarwinds_apm/api.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
4
6
|
#
|
5
7
|
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
6
8
|
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
9
|
-
require_relative '
|
10
|
-
require_relative '
|
11
|
-
require_relative '
|
9
|
+
require_relative 'api/transaction_name'
|
10
|
+
require_relative 'api/current_trace_info'
|
11
|
+
require_relative 'api/tracing'
|
12
|
+
require_relative 'api/opentelemetry'
|
13
|
+
require_relative 'api/custom_metrics'
|
12
14
|
|
13
15
|
module SolarWindsAPM
|
14
16
|
module API
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -12,24 +14,24 @@ module SolarWindsAPM
|
|
12
14
|
# Use SolarWindsAPM::Config.show to view the entire nested hash.
|
13
15
|
#
|
14
16
|
module Config
|
15
|
-
SW_LOG_LEVEL_MAPPING = {-1 => {:
|
16
|
-
0 => {:
|
17
|
-
1 => {:
|
18
|
-
2 => {:
|
19
|
-
3 => {:
|
20
|
-
4 => {:
|
21
|
-
5 => {:
|
22
|
-
6 => {:
|
17
|
+
SW_LOG_LEVEL_MAPPING = { -1 => { stdlib: ::Logger::FATAL, otel: 'fatal' },
|
18
|
+
0 => { stdlib: ::Logger::FATAL, otel: 'fatal' },
|
19
|
+
1 => { stdlib: ::Logger::ERROR, otel: 'error' },
|
20
|
+
2 => { stdlib: ::Logger::WARN, otel: 'warn' },
|
21
|
+
3 => { stdlib: ::Logger::INFO, otel: 'info' },
|
22
|
+
4 => { stdlib: ::Logger::DEBUG, otel: 'debug' },
|
23
|
+
5 => { stdlib: ::Logger::DEBUG, otel: 'debug' },
|
24
|
+
6 => { stdlib: ::Logger::DEBUG, otel: 'debug' } }.freeze
|
23
25
|
|
24
26
|
@@config = {}
|
25
|
-
@@instrumentation = [
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
@@instrumentation = %i[action_controller action_controller_api action_view
|
28
|
+
active_record bunnyclient bunnyconsumer curb
|
29
|
+
dalli delayed_jobclient delayed_jobworker
|
30
|
+
excon faraday graphql grpc_client grpc_server grape
|
31
|
+
httpclient nethttp memcached mongo moped padrino rack redis
|
32
|
+
resqueclient resqueworker rest_client
|
33
|
+
sequel sidekiqclient sidekiqworker sinatra typhoeus
|
34
|
+
curb excon faraday httpclient nethttp rest_client typhoeus]
|
33
35
|
|
34
36
|
##
|
35
37
|
# load_config_file
|
@@ -53,26 +55,32 @@ module SolarWindsAPM
|
|
53
55
|
config_files << config_file if File.exist?(config_file)
|
54
56
|
|
55
57
|
# Check for file set by env variable
|
56
|
-
config_files << config_file_from_env if ENV.
|
58
|
+
config_files << config_file_from_env if ENV.key?('SW_APM_CONFIG_RUBY')
|
57
59
|
|
58
60
|
# Check for default config file
|
59
61
|
config_file = File.join(Dir.pwd, 'solarwinds_apm_config.rb')
|
60
62
|
config_files << config_file if File.exist?(config_file)
|
61
63
|
|
62
|
-
SolarWindsAPM.logger.debug {"[#{name}/#{__method__}] Available config_files: #{config_files.join(', ')}" }
|
63
|
-
|
64
|
-
|
64
|
+
SolarWindsAPM.logger.debug { "[#{name}/#{__method__}] Available config_files: #{config_files.join(', ')}" }
|
65
|
+
if config_files.size > 1
|
66
|
+
SolarWindsAPM.logger.warn do
|
67
|
+
"[#{name}/#{__method__}] Multiple configuration files configured, using the first one listed: #{config_files.join(', ')}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
load(config_files[0]) if config_files.size.positive?
|
65
71
|
|
66
|
-
set_log_level
|
72
|
+
set_log_level # sets SolarWindsAPM::Config[:debug_level], SolarWindsAPM.logger.level
|
67
73
|
end
|
68
74
|
|
69
75
|
def self.config_file_from_env
|
70
|
-
if File.exist?(ENV
|
71
|
-
config_file = ENV
|
72
|
-
elsif File.exist?(File.join(ENV
|
73
|
-
config_file = File.join(ENV
|
76
|
+
if File.exist?(ENV.fetch('SW_APM_CONFIG_RUBY', nil)) && !File.directory?(ENV.fetch('SW_APM_CONFIG_RUBY', nil))
|
77
|
+
config_file = ENV.fetch('SW_APM_CONFIG_RUBY', nil)
|
78
|
+
elsif File.exist?(File.join(ENV.fetch('SW_APM_CONFIG_RUBY', nil), 'solarwinds_apm_config.rb'))
|
79
|
+
config_file = File.join(ENV.fetch('SW_APM_CONFIG_RUBY', nil), 'solarwinds_apm_config.rb')
|
74
80
|
else
|
75
|
-
SolarWindsAPM.logger.warn
|
81
|
+
SolarWindsAPM.logger.warn do
|
82
|
+
"[#{name}/#{__method__}] Could not find the configuration file set by the SW_APM_CONFIG_RUBY environment variable: #{ENV.fetch('SW_APM_CONFIG_RUBY', nil)}"
|
83
|
+
end
|
76
84
|
end
|
77
85
|
config_file
|
78
86
|
end
|
@@ -92,7 +100,7 @@ module SolarWindsAPM
|
|
92
100
|
if env_var && valid_env_values.include?(env_value)
|
93
101
|
value = bool ? true?(env_value) : env_value.to_sym
|
94
102
|
elsif env_var && !env_value.to_s.empty?
|
95
|
-
SolarWindsAPM.logger.warn("[#{name}/#{__method__}] #{env_var} must be #{valid_env_values.join('/')} (current setting is #{ENV
|
103
|
+
SolarWindsAPM.logger.warn("[#{name}/#{__method__}] #{env_var} must be #{valid_env_values.join('/')} (current setting is #{ENV.fetch(env_var, nil)}). Using default value: #{default}.")
|
96
104
|
return @@config[key.to_sym] = default
|
97
105
|
end
|
98
106
|
|
@@ -103,7 +111,7 @@ module SolarWindsAPM
|
|
103
111
|
end
|
104
112
|
|
105
113
|
def self.true?(obj)
|
106
|
-
obj.to_s.casecmp(
|
114
|
+
obj.to_s.casecmp('true').zero?
|
107
115
|
end
|
108
116
|
|
109
117
|
def self.boolean?(obj)
|
@@ -111,7 +119,7 @@ module SolarWindsAPM
|
|
111
119
|
end
|
112
120
|
|
113
121
|
def self.symbol?(obj)
|
114
|
-
[
|
122
|
+
%i[enabled disabled].include?(obj)
|
115
123
|
end
|
116
124
|
|
117
125
|
##
|
@@ -121,9 +129,13 @@ module SolarWindsAPM
|
|
121
129
|
# to create an output similar to the content of the config file
|
122
130
|
#
|
123
131
|
def self.print_config
|
124
|
-
SolarWindsAPM.logger.debug {"[#{name}/#{__method__}] General configurations list blow:"}
|
125
|
-
@@config.each do |k,v|
|
126
|
-
|
132
|
+
SolarWindsAPM.logger.debug { "[#{name}/#{__method__}] General configurations list blow:" }
|
133
|
+
@@config.each do |k, v|
|
134
|
+
next if @@instrumentation.include?(k)
|
135
|
+
|
136
|
+
SolarWindsAPM.logger.debug do
|
137
|
+
"[#{name}/#{__method__}] Config Key/Value: #{k}, #{v.inspect}"
|
138
|
+
end
|
127
139
|
end
|
128
140
|
nil
|
129
141
|
end
|
@@ -137,12 +149,18 @@ module SolarWindsAPM
|
|
137
149
|
#
|
138
150
|
def self.initialize
|
139
151
|
# for config file backward compatibility
|
140
|
-
@@instrumentation.each {|inst| @@config[inst] = {}}
|
152
|
+
@@instrumentation.each { |inst| @@config[inst] = {} }
|
141
153
|
@@config[:transaction_name] = {}
|
142
154
|
|
143
155
|
# Always load the template, it has all the keys and defaults defined,
|
144
156
|
# no guarantee of completeness in the user's config file
|
145
|
-
|
157
|
+
|
158
|
+
load(File.join(File.dirname(File.dirname(__FILE__)),
|
159
|
+
'rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb'))
|
160
|
+
|
161
|
+
load_config_file
|
162
|
+
|
163
|
+
print_config if SolarWindsAPM.logger.level.zero?
|
146
164
|
end
|
147
165
|
|
148
166
|
def self.update!(data)
|
@@ -164,7 +182,7 @@ module SolarWindsAPM
|
|
164
182
|
#
|
165
183
|
# Config variable assignment method. Here we validate and store the
|
166
184
|
# assigned value(s) and trigger any secondary action needed.
|
167
|
-
# ENV always have higher precedence
|
185
|
+
# ENV always have higher precedence
|
168
186
|
#
|
169
187
|
def self.[]=(key, value)
|
170
188
|
key = key.to_sym
|
@@ -172,18 +190,24 @@ module SolarWindsAPM
|
|
172
190
|
|
173
191
|
case key
|
174
192
|
when :sampling_rate
|
175
|
-
SolarWindsAPM.logger.warn
|
193
|
+
SolarWindsAPM.logger.warn do
|
194
|
+
"[#{name}/#{__method__}] sampling_rate is not a supported setting for SolarWindsAPM::Config. Please use :sample_rate."
|
195
|
+
end
|
176
196
|
|
177
197
|
when :sample_rate
|
178
198
|
unless value.is_a?(Integer) || value.is_a?(Float)
|
179
|
-
SolarWindsAPM.logger.warn
|
199
|
+
SolarWindsAPM.logger.warn do
|
200
|
+
"[#{name}/#{__method__}] :sample_rate must be a number between 0 and 1000000 (1m) (provided: #{value}), corrected to 0"
|
201
|
+
end
|
180
202
|
value = 0
|
181
203
|
end
|
182
204
|
|
183
205
|
# Validate :sample_rate value
|
184
206
|
unless value.between?(0, 1e6)
|
185
|
-
new_value = value
|
186
|
-
SolarWindsAPM.logger.warn
|
207
|
+
new_value = value.negative? ? 0 : 1_000_000
|
208
|
+
SolarWindsAPM.logger.warn do
|
209
|
+
"[#{name}/#{__method__}] :sample_rate must be between 0 and 1000000 (1m) (provided: #{value}), corrected to #{new_value}"
|
210
|
+
end
|
187
211
|
end
|
188
212
|
|
189
213
|
# Assure value is an integer
|
@@ -217,7 +241,7 @@ module SolarWindsAPM
|
|
217
241
|
end
|
218
242
|
|
219
243
|
# `tracing: disabled` is the default
|
220
|
-
disabled = settings.select { |v| !v.
|
244
|
+
disabled = settings.select { |v| !v.key?(:tracing) || v[:tracing] == :disabled }
|
221
245
|
enabled = settings.select { |v| v[:tracing] == :enabled }
|
222
246
|
|
223
247
|
SolarWindsAPM::Config[:enabled_regexps] = compile_regexp(enabled)
|
@@ -234,18 +258,18 @@ module SolarWindsAPM
|
|
234
258
|
|
235
259
|
def self.compile_settings_regexp(value)
|
236
260
|
regexps = value.select do |v|
|
237
|
-
v.
|
261
|
+
v.key?(:regexp) &&
|
238
262
|
!(v[:regexp].is_a?(String) && v[:regexp].empty?) &&
|
239
263
|
!(v[:regexp].is_a?(Regexp) && v[:regexp].inspect == '//')
|
240
264
|
end
|
241
265
|
|
242
266
|
regexps.map! do |v|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
nil
|
267
|
+
v[:regexp].is_a?(String) ? Regexp.new(v[:regexp], v[:opts]) : Regexp.new(v[:regexp])
|
268
|
+
rescue StandardError => e
|
269
|
+
SolarWindsAPM.logger.warn do
|
270
|
+
"[#{name}/#{__method__}] Problem compiling transaction_settings item #{v}, will ignore. Error: #{e.message}"
|
248
271
|
end
|
272
|
+
nil
|
249
273
|
end
|
250
274
|
regexps.keep_if { |v| !v.nil? }
|
251
275
|
regexps.empty? ? nil : regexps
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -7,28 +9,28 @@
|
|
7
9
|
module SolarWindsAPM
|
8
10
|
# Constants
|
9
11
|
module Constants
|
10
|
-
HTTP_METHOD =
|
11
|
-
HTTP_ROUTE =
|
12
|
-
HTTP_STATUS_CODE =
|
13
|
-
HTTP_URL =
|
14
|
-
INTL_SWO_AO_COLLECTOR =
|
15
|
-
INTL_SWO_AO_STG_COLLECTOR =
|
16
|
-
INTL_SWO_COMMA =
|
17
|
-
INTL_SWO_COMMA_W3C_SANITIZED =
|
18
|
-
INTL_SWO_EQUALS =
|
19
|
-
INTL_SWO_EQUALS_W3C_SANITIZED =
|
20
|
-
INTL_SWO_TRACESTATE_KEY =
|
21
|
-
INTL_SWO_X_OPTIONS_KEY =
|
22
|
-
INTL_SWO_SIGNATURE_KEY =
|
23
|
-
INTL_SWO_DEFAULT_TRACES_EXPORTER =
|
24
|
-
INTL_SWO_TRACECONTEXT_PROPAGATOR =
|
25
|
-
INTL_SWO_PROPAGATOR =
|
26
|
-
INTL_SWO_DEFAULT_PROPAGATORS = [INTL_SWO_TRACECONTEXT_PROPAGATOR,
|
27
|
-
INTL_SWO_SUPPORT_EMAIL =
|
28
|
-
INTL_SWO_OTEL_SCOPE_NAME =
|
29
|
-
INTL_SWO_OTEL_SCOPE_VERSION =
|
30
|
-
INTL_SWO_OTEL_STATUS =
|
31
|
-
INTL_SWO_OTEL_STATUS_DESCRIPTION =
|
32
|
-
INTERNAL_TRIGGERED_TRACE =
|
12
|
+
HTTP_METHOD = 'http.method'
|
13
|
+
HTTP_ROUTE = 'http.route'
|
14
|
+
HTTP_STATUS_CODE = 'http.status_code'
|
15
|
+
HTTP_URL = 'http.url'
|
16
|
+
INTL_SWO_AO_COLLECTOR = 'collector.appoptics.com'
|
17
|
+
INTL_SWO_AO_STG_COLLECTOR = 'collector-stg.appoptics.com'
|
18
|
+
INTL_SWO_COMMA = ','
|
19
|
+
INTL_SWO_COMMA_W3C_SANITIZED = '....'
|
20
|
+
INTL_SWO_EQUALS = '='
|
21
|
+
INTL_SWO_EQUALS_W3C_SANITIZED = '####'
|
22
|
+
INTL_SWO_TRACESTATE_KEY = 'sw'
|
23
|
+
INTL_SWO_X_OPTIONS_KEY = 'sw_xtraceoptions'
|
24
|
+
INTL_SWO_SIGNATURE_KEY = 'sw_signature'
|
25
|
+
INTL_SWO_DEFAULT_TRACES_EXPORTER = 'solarwinds_exporter'
|
26
|
+
INTL_SWO_TRACECONTEXT_PROPAGATOR = 'tracecontext'
|
27
|
+
INTL_SWO_PROPAGATOR = 'solarwinds_propagator'
|
28
|
+
INTL_SWO_DEFAULT_PROPAGATORS = [INTL_SWO_TRACECONTEXT_PROPAGATOR, 'baggage', INTL_SWO_PROPAGATOR].freeze
|
29
|
+
INTL_SWO_SUPPORT_EMAIL = 'SWO-support@solarwinds.com'
|
30
|
+
INTL_SWO_OTEL_SCOPE_NAME = 'otel.scope.name'
|
31
|
+
INTL_SWO_OTEL_SCOPE_VERSION = 'otel.scope.version'
|
32
|
+
INTL_SWO_OTEL_STATUS = 'otel.status'
|
33
|
+
INTL_SWO_OTEL_STATUS_DESCRIPTION = 'otel.status_description'
|
34
|
+
INTERNAL_TRIGGERED_TRACE = 'TriggeredTrace'
|
33
35
|
end
|
34
36
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -9,7 +11,7 @@
|
|
9
11
|
#
|
10
12
|
module SolarWindsAPM
|
11
13
|
# API
|
12
|
-
module API
|
14
|
+
module API
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
data/lib/solarwinds_apm/noop.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
4
6
|
#
|
5
7
|
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
6
8
|
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
9
|
-
require_relative '
|
10
|
-
require_relative '
|
9
|
+
require_relative 'noop/context'
|
10
|
+
require_relative 'noop/metadata'
|
11
|
+
require_relative 'noop/span'
|
12
|
+
require_relative 'noop/api'
|
11
13
|
|
12
14
|
module SolarWindsAPM
|
13
15
|
include Oboe_metal
|
@@ -21,11 +23,11 @@ module SolarWindsAPM
|
|
21
23
|
##
|
22
24
|
# noop version of :send_status
|
23
25
|
#
|
24
|
-
def self.send_status(event, context=nil, with_system_timestamp: false); end
|
26
|
+
def self.send_status(event, context = nil, with_system_timestamp: false); end
|
25
27
|
|
26
28
|
##
|
27
29
|
# noop version of :start
|
28
30
|
#
|
29
31
|
def self.start; end
|
30
32
|
end
|
31
|
-
end
|
33
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
|
@@ -7,16 +9,18 @@
|
|
7
9
|
require 'singleton'
|
8
10
|
require 'uri'
|
9
11
|
|
10
|
-
require_relative '
|
12
|
+
require_relative 'support/service_key_checker'
|
11
13
|
|
12
14
|
module SolarWindsAPM
|
13
15
|
# OboeInitOptions
|
14
16
|
class OboeInitOptions
|
15
17
|
include Singleton
|
16
18
|
|
17
|
-
attr_reader :reporter, :host, :service_name, :ec2_md_timeout, :grpc_proxy # exposing these mainly for testing
|
19
|
+
attr_reader :reporter, :host, :service_name, :ec2_md_timeout, :grpc_proxy, :lambda_env # exposing these mainly for testing
|
18
20
|
|
19
21
|
def initialize
|
22
|
+
# determining the lambda env based on env var (not used in array_for_oboe for oboe initialization)
|
23
|
+
@lambda_env = determine_lambda
|
20
24
|
# optional hostname alias
|
21
25
|
@hostname_alias = ENV['SW_APM_HOSTNAME_ALIAS'] || SolarWindsAPM::Config[:hostname_alias] || ''
|
22
26
|
# level at which log messages will be written to log file (0-6)
|
@@ -82,18 +86,18 @@ module SolarWindsAPM
|
|
82
86
|
@reporter, # 7
|
83
87
|
@host, # 8
|
84
88
|
@service_key, # 9
|
85
|
-
@certificates, #10
|
86
|
-
@buffer_size, #11
|
87
|
-
@trace_metrics, #12
|
88
|
-
@histogram_precision, #13
|
89
|
-
@token_bucket_capacity, #14
|
90
|
-
@token_bucket_rate, #15
|
91
|
-
@file_single, #16
|
92
|
-
@ec2_md_timeout, #17
|
93
|
-
@grpc_proxy, #18
|
94
|
-
0, #19 arg for lambda (no lambda for ruby yet)
|
95
|
-
@metric_format, #20
|
96
|
-
@log_type #21
|
89
|
+
@certificates, # 10
|
90
|
+
@buffer_size, # 11
|
91
|
+
@trace_metrics, # 12
|
92
|
+
@histogram_precision, # 13
|
93
|
+
@token_bucket_capacity, # 14
|
94
|
+
@token_bucket_rate, # 15
|
95
|
+
@file_single, # 16
|
96
|
+
@ec2_md_timeout, # 17
|
97
|
+
@grpc_proxy, # 18
|
98
|
+
0, # 19 arg for lambda (no lambda for ruby yet)
|
99
|
+
@metric_format, # 20
|
100
|
+
@log_type # 21
|
97
101
|
]
|
98
102
|
end
|
99
103
|
|
@@ -104,32 +108,23 @@ module SolarWindsAPM
|
|
104
108
|
private
|
105
109
|
|
106
110
|
def reporter_and_host
|
107
|
-
|
108
111
|
reporter = ENV['SW_APM_REPORTER'] || 'ssl'
|
109
112
|
|
110
|
-
host =
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
# TODO: decide what to do
|
117
|
-
# ____ SolarWindsAPM::Config[:reporter_host] and
|
118
|
-
# ____ SolarWindsAPM::Config[:reporter_port] were moved here from
|
119
|
-
# ____ oboe_metal.rb and are not documented anywhere
|
120
|
-
# ____ udp is for internal use only
|
121
|
-
when 'null'
|
122
|
-
host = ''
|
123
|
-
end
|
113
|
+
host = case reporter
|
114
|
+
when 'ssl', 'file'
|
115
|
+
ENV['SW_APM_COLLECTOR'] || ''
|
116
|
+
else
|
117
|
+
''
|
118
|
+
end
|
124
119
|
|
125
120
|
host = sanitize_collector_uri(host) unless reporter == 'file'
|
126
121
|
[reporter, host]
|
127
122
|
end
|
128
123
|
|
129
124
|
def read_and_validate_service_key
|
130
|
-
service_key_checker = SolarWindsAPM::ServiceKeyChecker.new(@reporter)
|
125
|
+
service_key_checker = SolarWindsAPM::ServiceKeyChecker.new(@reporter, @lambda_env)
|
131
126
|
service_key = service_key_checker.read_and_validate_service_key
|
132
|
-
@service_name = service_key.split(':',2).last # instance variable used in testing
|
127
|
+
@service_name = service_key.split(':', 2).last # instance variable used in testing
|
133
128
|
service_key
|
134
129
|
end
|
135
130
|
|
@@ -145,8 +140,8 @@ module SolarWindsAPM
|
|
145
140
|
proxy = ENV['SW_APM_PROXY'] || SolarWindsAPM::Config[:http_proxy] || ''
|
146
141
|
return proxy if proxy == ''
|
147
142
|
|
148
|
-
unless
|
149
|
-
SolarWindsAPM.logger.error {"[#{self.class}/#{__method__}] SW_APM_PROXY/http_proxy doesn't start with 'http://', #{proxy}"}
|
143
|
+
unless %r{http://.*:\d+$}.match?(proxy)
|
144
|
+
SolarWindsAPM.logger.error { "[#{self.class}/#{__method__}] SW_APM_PROXY/http_proxy doesn't start with 'http://', #{proxy}" }
|
150
145
|
return '' # try without proxy, it may work, shouldn't crash but may not report
|
151
146
|
end
|
152
147
|
|
@@ -156,13 +151,15 @@ module SolarWindsAPM
|
|
156
151
|
def read_certificates
|
157
152
|
certificate = ''
|
158
153
|
|
159
|
-
file = appoptics_collector
|
154
|
+
file = appoptics_collector? ? "#{__dir__}/cert/star.appoptics.com.issuer.crt" : ENV.fetch('SW_APM_TRUSTEDPATH', nil)
|
160
155
|
return certificate if file.nil? || file&.empty?
|
161
156
|
|
162
157
|
begin
|
163
|
-
certificate = File.
|
158
|
+
certificate = File.read(file)
|
164
159
|
rescue StandardError => e
|
165
|
-
SolarWindsAPM.logger.error
|
160
|
+
SolarWindsAPM.logger.error do
|
161
|
+
"[#{self.class}/#{__method__}] certificates: #{file} doesn't exist or caused by #{e.message}."
|
162
|
+
end
|
166
163
|
end
|
167
164
|
|
168
165
|
certificate
|
@@ -176,7 +173,7 @@ module SolarWindsAPM
|
|
176
173
|
allowed_uri = ['collector.appoptics.com', 'collector-stg.appoptics.com',
|
177
174
|
'collector.appoptics.com:443', 'collector-stg.appoptics.com:443']
|
178
175
|
|
179
|
-
(allowed_uri.include? ENV
|
176
|
+
(allowed_uri.include? ENV.fetch('SW_APM_COLLECTOR', nil))
|
180
177
|
end
|
181
178
|
|
182
179
|
def sanitize_collector_uri(uri)
|
@@ -186,9 +183,11 @@ module SolarWindsAPM
|
|
186
183
|
sanitized_uri = ::URI.parse("http://#{uri}").host
|
187
184
|
return sanitized_uri unless sanitized_uri.nil?
|
188
185
|
rescue StandardError => e
|
189
|
-
SolarWindsAPM.logger.error
|
186
|
+
SolarWindsAPM.logger.error do
|
187
|
+
"[#{self.class}/#{__method__}] uri for collector #{uri} is malformat. Error: #{e.message}"
|
188
|
+
end
|
190
189
|
end
|
191
|
-
|
190
|
+
''
|
192
191
|
end
|
193
192
|
|
194
193
|
def determine_oboe_log_type
|
@@ -197,5 +196,14 @@ module SolarWindsAPM
|
|
197
196
|
log_type = 4 if @debug_level == -1
|
198
197
|
log_type
|
199
198
|
end
|
199
|
+
|
200
|
+
def determine_lambda
|
201
|
+
if ENV['LAMBDA_TASK_ROOT'].to_s.empty? && ENV['AWS_LAMBDA_FUNCTION_NAME'].to_s.empty?
|
202
|
+
false
|
203
|
+
else
|
204
|
+
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] lambda environment - LAMBDA_TASK_ROOT: #{ENV.fetch('LAMBDA_TASK_ROOT', nil)}; AWS_LAMBDA_FUNCTION_NAME: #{ENV.fetch('AWS_LAMBDA_FUNCTION_NAME', nil)}" }
|
205
|
+
true
|
206
|
+
end
|
207
|
+
end
|
200
208
|
end
|
201
209
|
end
|