solarwinds_apm 6.1.2 → 7.0.0.prev2
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/README.md +5 -3
- data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +1 -30
- data/lib/solarwinds_apm/api/current_trace_info.rb +10 -6
- data/lib/solarwinds_apm/api/custom_metrics.rb +8 -25
- data/lib/solarwinds_apm/api/tracing.rb +12 -27
- data/lib/solarwinds_apm/api/transaction_name.rb +6 -10
- data/lib/solarwinds_apm/config.rb +7 -1
- data/lib/solarwinds_apm/constants.rb +1 -0
- data/lib/solarwinds_apm/noop/api.rb +5 -2
- data/lib/solarwinds_apm/noop.rb +0 -24
- data/lib/solarwinds_apm/opentelemetry/otlp_processor.rb +116 -66
- data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +0 -2
- data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +5 -4
- data/lib/solarwinds_apm/opentelemetry.rb +5 -7
- data/lib/solarwinds_apm/otel_native_config.rb +180 -0
- data/lib/solarwinds_apm/patch/README.md +15 -0
- data/lib/solarwinds_apm/{noop/metadata.rb → sampling/dice.rb} +19 -17
- data/lib/solarwinds_apm/sampling/http_sampler.rb +87 -0
- data/lib/solarwinds_apm/sampling/json_sampler.rb +52 -0
- data/lib/solarwinds_apm/sampling/metrics.rb +38 -0
- data/lib/solarwinds_apm/sampling/oboe_sampler.rb +348 -0
- data/lib/solarwinds_apm/sampling/sampler.rb +197 -0
- data/lib/solarwinds_apm/sampling/sampling_constants.rb +127 -0
- data/lib/solarwinds_apm/sampling/sampling_patch.rb +49 -0
- data/lib/solarwinds_apm/sampling/setting_example.txt +1 -0
- data/lib/solarwinds_apm/{noop/context.rb → sampling/settings.rb} +14 -25
- data/lib/solarwinds_apm/sampling/token_bucket.rb +126 -0
- data/lib/solarwinds_apm/sampling/trace_options.rb +100 -0
- data/lib/solarwinds_apm/{patch.rb → sampling.rb} +20 -4
- data/lib/solarwinds_apm/support/logger_formatter.rb +1 -1
- data/lib/solarwinds_apm/support/logging_log_event.rb +1 -1
- data/lib/solarwinds_apm/support/lumberjack_formatter.rb +1 -1
- data/lib/solarwinds_apm/support/otlp_endpoint.rb +99 -0
- data/lib/solarwinds_apm/support/resource_detector.rb +192 -0
- data/lib/solarwinds_apm/support/service_key_checker.rb +12 -6
- data/lib/solarwinds_apm/support/transaction_settings.rb +6 -0
- data/lib/solarwinds_apm/support/txn_name_manager.rb +54 -9
- data/lib/solarwinds_apm/support/utils.rb +9 -0
- data/lib/solarwinds_apm/support.rb +2 -4
- data/lib/solarwinds_apm/version.rb +4 -4
- data/lib/solarwinds_apm.rb +27 -73
- metadata +107 -40
- data/ext/oboe_metal/extconf.rb +0 -168
- data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +0 -1
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +0 -1
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +0 -1
- data/ext/oboe_metal/lib/liboboe-1.0-lambda-aarch64.so.sha256 +0 -1
- data/ext/oboe_metal/lib/liboboe-1.0-lambda-x86_64.so.sha256 +0 -1
- data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +0 -1
- data/ext/oboe_metal/src/VERSION +0 -1
- data/ext/oboe_metal/src/bson/bson.h +0 -220
- data/ext/oboe_metal/src/bson/platform_hacks.h +0 -91
- data/ext/oboe_metal/src/init_solarwinds_apm.cc +0 -18
- data/ext/oboe_metal/src/oboe.h +0 -930
- data/ext/oboe_metal/src/oboe_api.cpp +0 -793
- data/ext/oboe_metal/src/oboe_api.h +0 -621
- data/ext/oboe_metal/src/oboe_debug.h +0 -17
- data/ext/oboe_metal/src/oboe_swig_wrap.cc +0 -11045
- data/lib/oboe_metal.rb +0 -187
- data/lib/solarwinds_apm/cert/star.appoptics.com.issuer.crt +0 -24
- data/lib/solarwinds_apm/noop/span.rb +0 -25
- data/lib/solarwinds_apm/oboe_init_options.rb +0 -222
- data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +0 -239
- data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +0 -174
- data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +0 -333
- data/lib/solarwinds_apm/otel_config.rb +0 -174
- data/lib/solarwinds_apm/otel_lambda_config.rb +0 -56
- data/lib/solarwinds_apm/patch/dummy_patch.rb +0 -12
- data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +0 -33
- data/lib/solarwinds_apm/support/support_report.rb +0 -99
- data/lib/solarwinds_apm/support/transaction_cache.rb +0 -57
- data/lib/solarwinds_apm/support/x_trace_options.rb +0 -138
@@ -1,239 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
4
|
-
#
|
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
|
6
|
-
#
|
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.
|
8
|
-
|
9
|
-
module SolarWindsAPM
|
10
|
-
module OpenTelemetry
|
11
|
-
# SolarWindsExporter
|
12
|
-
class SolarWindsExporter
|
13
|
-
SUCCESS = ::OpenTelemetry::SDK::Trace::Export::SUCCESS # ::OpenTelemetry #=> the OpenTelemetry at top level (to ignore SolarWindsAPM)
|
14
|
-
FAILURE = ::OpenTelemetry::SDK::Trace::Export::FAILURE
|
15
|
-
|
16
|
-
private_constant(:SUCCESS, :FAILURE)
|
17
|
-
|
18
|
-
def initialize(txn_manager: nil)
|
19
|
-
@shutdown = false
|
20
|
-
@txn_manager = txn_manager
|
21
|
-
@reporter = SolarWindsAPM::Reporter
|
22
|
-
@context = SolarWindsAPM::Context
|
23
|
-
@metadata = SolarWindsAPM::Metadata
|
24
|
-
@version_cache = {}
|
25
|
-
end
|
26
|
-
|
27
|
-
def export(span_data, timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
|
28
|
-
return FAILURE if @shutdown
|
29
|
-
|
30
|
-
status = SUCCESS
|
31
|
-
span_data.each do |data|
|
32
|
-
status = log_span_data(data)
|
33
|
-
end
|
34
|
-
|
35
|
-
status
|
36
|
-
end
|
37
|
-
|
38
|
-
def force_flush(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
|
39
|
-
SUCCESS
|
40
|
-
end
|
41
|
-
|
42
|
-
def shutdown(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
|
43
|
-
@shutdown = true
|
44
|
-
SUCCESS
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def log_span_data(span_data)
|
50
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] span_data: #{span_data.inspect}\n" }
|
51
|
-
|
52
|
-
md = build_meta_data(span_data)
|
53
|
-
event = nil
|
54
|
-
if span_data.parent_span_id == ::OpenTelemetry::Trace::INVALID_SPAN_ID
|
55
|
-
event = @context.createEntry(md, (span_data.start_timestamp.to_i / 1000).to_i)
|
56
|
-
add_info_transaction_name(span_data, event)
|
57
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] Start a new trace." }
|
58
|
-
else
|
59
|
-
parent_md = build_meta_data(span_data, parent: true)
|
60
|
-
event = @context.createEntry(md, (span_data.start_timestamp.to_i / 1000).to_i, parent_md)
|
61
|
-
SolarWindsAPM.logger.debug do
|
62
|
-
"[#{self.class}/#{__method__}] Continue trace from parent metadata: #{parent_md.toString}."
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
layer_name = "#{span_data.kind}:#{span_data.name}"
|
67
|
-
event.addInfo('Layer', layer_name)
|
68
|
-
event.addInfo('sw.span_kind', span_data.kind.to_s)
|
69
|
-
event.addInfo('Language', 'Ruby')
|
70
|
-
|
71
|
-
add_instrumentation_scope(event, span_data)
|
72
|
-
add_instrumented_framework(event, span_data)
|
73
|
-
add_span_data_attributes(event, span_data.attributes) if span_data.attributes
|
74
|
-
|
75
|
-
event.addInfo(SolarWindsAPM::Constants::INTL_SWO_OTEL_STATUS, span_data.status.ok? ? 'OK' : 'ERROR')
|
76
|
-
unless span_data.status.description.empty?
|
77
|
-
event.addInfo(SolarWindsAPM::Constants::INTL_SWO_OTEL_STATUS_DESCRIPTION,
|
78
|
-
span_data.status.description)
|
79
|
-
end
|
80
|
-
|
81
|
-
@reporter.send_report(event, with_system_timestamp: false)
|
82
|
-
|
83
|
-
# info / exception event
|
84
|
-
span_data.events&.each do |span_data_event|
|
85
|
-
span_data_event.name == 'exception' ? report_exception_event(span_data_event) : report_info_event(span_data_event)
|
86
|
-
end
|
87
|
-
|
88
|
-
event = @context.createExit((span_data.end_timestamp.to_i / 1000).to_i)
|
89
|
-
event.addInfo('Layer', layer_name)
|
90
|
-
@reporter.send_report(event, with_system_timestamp: false)
|
91
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] Exit a trace: #{event.metadataString}" }
|
92
|
-
SUCCESS
|
93
|
-
rescue StandardError => e
|
94
|
-
SolarWindsAPM.logger.info { "[#{self.class}/#{__method__}] exporter error: \n #{e.message} #{e.backtrace}\n" }
|
95
|
-
FAILURE
|
96
|
-
end
|
97
|
-
|
98
|
-
##
|
99
|
-
# extract the span_data.attributes (OpenTelemetry::SDK::Trace::SpanData.attributes)
|
100
|
-
def add_span_data_attributes(event, span_attributes)
|
101
|
-
target = 'http.target'
|
102
|
-
attributes = span_attributes.dup
|
103
|
-
attributes[target] = attributes[target].split('?').first if attributes[target] && SolarWindsAPM::Config[:log_args] == false
|
104
|
-
attributes.each { |k, v| event.addInfo(k, v) }
|
105
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] span_data attributes added: #{attributes.inspect}" }
|
106
|
-
end
|
107
|
-
|
108
|
-
##
|
109
|
-
# get instrumentation scope data: scope name and version.
|
110
|
-
# the version if the opentelemetry-instrumentation-* gem version
|
111
|
-
def add_instrumentation_scope(event, span_data)
|
112
|
-
scope_name = ''
|
113
|
-
scope_version = ''
|
114
|
-
if span_data.instrumentation_scope
|
115
|
-
scope_name = span_data.instrumentation_scope.name if span_data.instrumentation_scope.name
|
116
|
-
scope_version = span_data.instrumentation_scope.version if span_data.instrumentation_scope.version
|
117
|
-
end
|
118
|
-
event.addInfo(SolarWindsAPM::Constants::INTL_SWO_OTEL_SCOPE_NAME, scope_name)
|
119
|
-
event.addInfo(SolarWindsAPM::Constants::INTL_SWO_OTEL_SCOPE_VERSION, scope_version)
|
120
|
-
end
|
121
|
-
|
122
|
-
##
|
123
|
-
# add the gem library version to event
|
124
|
-
# p.s. gem library version is not same as the opentelemetry-instrumentation-* gem version
|
125
|
-
def add_instrumented_framework(event, span_data)
|
126
|
-
scope_name = span_data.instrumentation_scope.name
|
127
|
-
scope_name = scope_name.downcase if scope_name
|
128
|
-
return unless scope_name&.include? 'opentelemetry::instrumentation'
|
129
|
-
|
130
|
-
framework = scope_name.split('::')[2..]&.join('::')
|
131
|
-
return if framework.nil? || framework.empty?
|
132
|
-
|
133
|
-
framework = normalize_framework_name(framework)
|
134
|
-
framework_version = check_framework_version(framework)
|
135
|
-
SolarWindsAPM.logger.debug do
|
136
|
-
"[#{self.class}/#{__method__}] #{span_data.instrumentation_scope.name} with #{framework} and version #{framework_version}"
|
137
|
-
end
|
138
|
-
event.addInfo("Ruby.#{framework}.Version", framework_version) unless framework_version.nil?
|
139
|
-
end
|
140
|
-
|
141
|
-
##
|
142
|
-
# helper function that extract gem library version for func add_instrumented_framework
|
143
|
-
def check_framework_version(framework)
|
144
|
-
framework_version = nil
|
145
|
-
if @version_cache.key?(framework)
|
146
|
-
|
147
|
-
framework_version = @version_cache[framework]
|
148
|
-
else
|
149
|
-
|
150
|
-
begin
|
151
|
-
require framework
|
152
|
-
framework_version = Gem.loaded_specs[version_framework_name(framework)].version.to_s
|
153
|
-
rescue LoadError => e
|
154
|
-
SolarWindsAPM.logger.debug do
|
155
|
-
"[#{self.class}/#{__method__}] couldn't load #{framework} with error #{e.message}; skip"
|
156
|
-
end
|
157
|
-
rescue StandardError => e
|
158
|
-
SolarWindsAPM.logger.debug do
|
159
|
-
"[#{self.class}/#{__method__}] couldn't find #{framework} with error #{e.message}; skip"
|
160
|
-
end
|
161
|
-
ensure
|
162
|
-
@version_cache[framework] = framework_version
|
163
|
-
end
|
164
|
-
end
|
165
|
-
SolarWindsAPM.logger.debug do
|
166
|
-
"[#{self.class}/#{__method__}] current framework version cached: #{@version_cache.inspect}"
|
167
|
-
end
|
168
|
-
framework_version
|
169
|
-
end
|
170
|
-
|
171
|
-
##
|
172
|
-
# helper function that convert opentelemetry instrumentation name to gem library understandable
|
173
|
-
def normalize_framework_name(framework)
|
174
|
-
case framework
|
175
|
-
when 'net::http'
|
176
|
-
'net/http'
|
177
|
-
else
|
178
|
-
framework
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
##
|
183
|
-
# helper function that convert opentelemetry instrumentation name to gem library understandable
|
184
|
-
def version_framework_name(framework)
|
185
|
-
case framework
|
186
|
-
when 'net/http'
|
187
|
-
'net-http'
|
188
|
-
else
|
189
|
-
framework
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
##
|
194
|
-
# Add transaction name from cache to root span then removes from cache
|
195
|
-
def add_info_transaction_name(span_data, event)
|
196
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] transaction manager: #{@txn_manager.inspect}." }
|
197
|
-
trace_span_id = "#{span_data.hex_trace_id}-#{span_data.hex_span_id}"
|
198
|
-
txname = @txn_manager.get(trace_span_id) || ''
|
199
|
-
event.addInfo('TransactionName', txname)
|
200
|
-
@txn_manager.del(trace_span_id)
|
201
|
-
end
|
202
|
-
|
203
|
-
##
|
204
|
-
# report exception event
|
205
|
-
def report_exception_event(span_event)
|
206
|
-
event = @context.createEvent((span_event.timestamp.to_i / 1000).to_i)
|
207
|
-
event.addInfo('Label', 'error')
|
208
|
-
event.addInfo('Spec', 'error')
|
209
|
-
|
210
|
-
unless span_event.attributes.nil?
|
211
|
-
attributes = span_event.attributes.dup
|
212
|
-
attributes.delete('exception.type') if event.addInfo('ErrorClass', attributes['exception.type'])
|
213
|
-
attributes.delete('exception.message') if event.addInfo('ErrorMsg', attributes['exception.message'])
|
214
|
-
attributes.delete('exception.stacktrace') if event.addInfo('Backtrace', attributes['exception.stacktrace'])
|
215
|
-
attributes.each { |key, value| event.addInfo(key, value) }
|
216
|
-
end
|
217
|
-
|
218
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] exception event #{event.metadataString}" }
|
219
|
-
@reporter.send_report(event, with_system_timestamp: false)
|
220
|
-
end
|
221
|
-
|
222
|
-
##
|
223
|
-
# report non-exception/info event
|
224
|
-
def report_info_event(span_event)
|
225
|
-
event = @context.createEvent((span_event.timestamp.to_i / 1000).to_i)
|
226
|
-
event.addInfo('Label', 'info')
|
227
|
-
span_event.attributes&.each { |key, value| event.addInfo(key, value) }
|
228
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] info event #{event.metadataString}" }
|
229
|
-
@reporter.send_report(event, with_system_timestamp: false)
|
230
|
-
end
|
231
|
-
|
232
|
-
def build_meta_data(span_data, parent: false)
|
233
|
-
flag = span_data.trace_flags.sampled? ? 1 : 0
|
234
|
-
xtr = parent == false ? "00-#{span_data.hex_trace_id}-#{span_data.hex_span_id}-0#{flag}" : "00-#{span_data.hex_trace_id}-#{span_data.hex_parent_span_id}-0#{flag}"
|
235
|
-
@metadata.fromString(xtr)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
@@ -1,174 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# © 2023 SolarWinds Worldwide, LLC. All rights reserved.
|
4
|
-
#
|
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
|
6
|
-
#
|
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.
|
8
|
-
|
9
|
-
module SolarWindsAPM
|
10
|
-
module OpenTelemetry
|
11
|
-
# reference: OpenTelemetry::SDK::Trace::SpanProcessor
|
12
|
-
class SolarWindsProcessor
|
13
|
-
HTTP_METHOD = 'http.method'
|
14
|
-
HTTP_ROUTE = 'http.route'
|
15
|
-
HTTP_STATUS_CODE = 'http.status_code'
|
16
|
-
HTTP_URL = 'http.url'
|
17
|
-
LIBOBOE_HTTP_SPAN_STATUS_UNAVAILABLE = 0
|
18
|
-
|
19
|
-
attr_reader :txn_manager
|
20
|
-
|
21
|
-
def initialize(txn_manager)
|
22
|
-
@txn_manager = txn_manager
|
23
|
-
end
|
24
|
-
|
25
|
-
# Called when a {Span} is started, if the {Span#recording?}
|
26
|
-
# returns true.
|
27
|
-
#
|
28
|
-
# @param [Span] span the {Span} that just started.
|
29
|
-
# @param [Context] parent_context the parent {Context} of the newly
|
30
|
-
# started span.
|
31
|
-
def on_start(span, parent_context)
|
32
|
-
SolarWindsAPM.logger.debug do
|
33
|
-
"[#{self.class}/#{__method__}] processor on_start span: #{span.to_span_data.inspect}, parent_context: #{parent_context.inspect}"
|
34
|
-
end
|
35
|
-
|
36
|
-
return if non_entry_span(parent_context: parent_context)
|
37
|
-
|
38
|
-
trace_flags = span.context.trace_flags.sampled? ? '01' : '00'
|
39
|
-
@txn_manager.set_root_context_h(span.context.hex_trace_id, "#{span.context.hex_span_id}-#{trace_flags}")
|
40
|
-
span.add_attributes({ 'sw.is_entry_span' => true })
|
41
|
-
rescue StandardError => e
|
42
|
-
SolarWindsAPM.logger.info { "[#{self.class}/#{__method__}] processor on_start error: #{e.message}" }
|
43
|
-
end
|
44
|
-
|
45
|
-
# Called when a {Span} is ended, if the {Span#recording?}
|
46
|
-
# returns true.
|
47
|
-
#
|
48
|
-
# @param [Span] span the {Span} that just ended.
|
49
|
-
def on_finish(span)
|
50
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] processor on_finish span: #{span.to_span_data.inspect}" }
|
51
|
-
|
52
|
-
return if non_entry_span(span: span)
|
53
|
-
|
54
|
-
span_time = calculate_span_time(start_time: span.start_timestamp, end_time: span.end_timestamp)
|
55
|
-
domain = nil
|
56
|
-
has_error = error?(span)
|
57
|
-
trans_name = calculate_transaction_names(span)
|
58
|
-
if span_http?(span)
|
59
|
-
status_code = get_http_status_code(span)
|
60
|
-
request_method = span.attributes[HTTP_METHOD]
|
61
|
-
url_tran = span.attributes[HTTP_URL]
|
62
|
-
|
63
|
-
SolarWindsAPM.logger.debug do
|
64
|
-
"[#{self.class}/#{__method__}] createHttpSpan with\n
|
65
|
-
trans_name: #{trans_name}\n
|
66
|
-
url_tran: #{url_tran}\n
|
67
|
-
domain: #{domain}\n
|
68
|
-
span_time: #{span_time}\n
|
69
|
-
status_code: #{status_code}\n
|
70
|
-
request_method: #{request_method}\n
|
71
|
-
has_error: #{has_error}"
|
72
|
-
end
|
73
|
-
|
74
|
-
liboboe_txn_name = SolarWindsAPM::Span.createHttpSpan(trans_name, url_tran, domain, span_time, status_code,
|
75
|
-
request_method, has_error)
|
76
|
-
|
77
|
-
else
|
78
|
-
|
79
|
-
SolarWindsAPM.logger.debug do
|
80
|
-
"[#{self.class}/#{__method__}] createSpan with \n
|
81
|
-
trans_name: #{trans_name}\n
|
82
|
-
domain: #{domain}\n
|
83
|
-
span_time: #{span_time}\n
|
84
|
-
has_error: #{has_error}"
|
85
|
-
end
|
86
|
-
|
87
|
-
liboboe_txn_name = SolarWindsAPM::Span.createSpan(trans_name, domain, span_time, has_error)
|
88
|
-
end
|
89
|
-
|
90
|
-
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] liboboe_txn_name: #{liboboe_txn_name}" }
|
91
|
-
if span.context.trace_flags.sampled?
|
92
|
-
@txn_manager["#{span.context.hex_trace_id}-#{span.context.hex_span_id}"] =
|
93
|
-
liboboe_txn_name
|
94
|
-
end
|
95
|
-
@txn_manager.delete_root_context_h(span.context.hex_trace_id)
|
96
|
-
rescue StandardError => e
|
97
|
-
SolarWindsAPM.logger.info do
|
98
|
-
"[#{self.class}/#{__method__}] solarwinds_processor on_finish error: #{e.message}"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# @param [optional Numeric] timeout An optional timeout in seconds.
|
103
|
-
# @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
|
104
|
-
# a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
|
105
|
-
def force_flush(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
|
106
|
-
::OpenTelemetry::SDK::Trace::Export::SUCCESS
|
107
|
-
end
|
108
|
-
|
109
|
-
# @param [optional Numeric] timeout An optional timeout in seconds.
|
110
|
-
# @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
|
111
|
-
# a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
|
112
|
-
def shutdown(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
|
113
|
-
::OpenTelemetry::SDK::Trace::Export::SUCCESS
|
114
|
-
end
|
115
|
-
|
116
|
-
private
|
117
|
-
|
118
|
-
# This span from inbound HTTP request if from a SERVER by some http.method
|
119
|
-
def span_http?(span)
|
120
|
-
span.kind == ::OpenTelemetry::Trace::SpanKind::SERVER && !span.attributes[HTTP_METHOD].nil?
|
121
|
-
end
|
122
|
-
|
123
|
-
# Calculate if this span instance has_error
|
124
|
-
# return [Integer]
|
125
|
-
def error?(span)
|
126
|
-
span.status.code == ::OpenTelemetry::Trace::Status::ERROR ? 1 : 0
|
127
|
-
end
|
128
|
-
|
129
|
-
# Calculate HTTP status_code from span or default to UNAVAILABLE
|
130
|
-
# Something went wrong in OTel or instrumented service crashed early
|
131
|
-
# if no status_code in attributes of HTTP span
|
132
|
-
def get_http_status_code(span)
|
133
|
-
span.attributes[HTTP_STATUS_CODE] || LIBOBOE_HTTP_SPAN_STATUS_UNAVAILABLE
|
134
|
-
end
|
135
|
-
|
136
|
-
# check if it's entry span based on no parent or parent is remote
|
137
|
-
def non_entry_span(span: nil, parent_context: nil)
|
138
|
-
if parent_context
|
139
|
-
parent_span = ::OpenTelemetry::Trace.current_span(parent_context)
|
140
|
-
parent_span && parent_span.context != ::OpenTelemetry::Trace::SpanContext::INVALID && parent_span.context.remote? == false
|
141
|
-
elsif span
|
142
|
-
span.attributes['sw.is_entry_span'] != true
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# Get trans_name and url_tran of this span instance.
|
147
|
-
# Predecessor order: custom SDK > env var SW_APM_TRANSACTION_NAME > automatic naming
|
148
|
-
def calculate_transaction_names(span)
|
149
|
-
trace_span_id = "#{span.context.hex_trace_id}-#{span.context.hex_span_id}"
|
150
|
-
trans_name = @txn_manager.get(trace_span_id)
|
151
|
-
if trans_name
|
152
|
-
SolarWindsAPM.logger.debug do
|
153
|
-
"[#{self.class}/#{__method__}] found trans name from txn_manager: #{trans_name} by #{trace_span_id}"
|
154
|
-
end
|
155
|
-
@txn_manager.del(trace_span_id)
|
156
|
-
elsif ENV.key?('SW_APM_TRANSACTION_NAME') && ENV['SW_APM_TRANSACTION_NAME'] != ''
|
157
|
-
trans_name = ENV.fetch('SW_APM_TRANSACTION_NAME', nil)
|
158
|
-
else
|
159
|
-
trans_name = span.attributes[HTTP_ROUTE] || nil
|
160
|
-
trans_name = span.name if span.name && (trans_name.nil? || trans_name.empty?)
|
161
|
-
end
|
162
|
-
trans_name
|
163
|
-
end
|
164
|
-
|
165
|
-
# Calculate span time in microseconds (us) using start and end time
|
166
|
-
# in nanoseconds (ns). OTel span start/end_time are optional.
|
167
|
-
def calculate_span_time(start_time: nil, end_time: nil)
|
168
|
-
return 0 if start_time.nil? || end_time.nil?
|
169
|
-
|
170
|
-
((end_time.to_i - start_time.to_i) / 1e3).round
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|