Skip to content

Commit

Permalink
Merge pull request #67 from solarwindscloud/NH-44743
Browse files Browse the repository at this point in the history
NH-44743: use txn_manager to store root span
  • Loading branch information
xuan-cao-swi authored Aug 31, 2023
2 parents 3fc1502 + 245a3cf commit 745264d
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 35 deletions.
24 changes: 11 additions & 13 deletions lib/solarwinds_apm/api/transaction_name.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,20 @@ def set_transaction_name(custom_name=nil)
status = false
elsif SolarWindsAPM::Context.toString == '99-00000000000000000000000000000000-0000000000000000-00' # noop
status = true
elsif SolarWindsAPM::OTelConfig.class_variable_get(:@@config)[:span_processor].nil?
SolarWindsAPM.logger.warn {"[#{name}/#{__method__}] Solarwinds processor is missing. Set transaction name failed."}
status = false
else
solarwinds_processor = SolarWindsAPM::OTelConfig.class_variable_get(:@@config)[:span_processor]
if solarwinds_processor.nil?
SolarWindsAPM.logger.warn {"[#{name}/#{__method__}] Solarwinds processor is missing. Set transaction name failed."}
status = false
else
entry_trace_id = ::OpenTelemetry::Baggage.value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_TRACE_ID)
entry_span_id = ::OpenTelemetry::Baggage.value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_SPAN_ID)
trace_flags = ::OpenTelemetry::Baggage.value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_TRACE_FLAG)
solarwinds_processor = SolarWindsAPM::OTelConfig.class_variable_get(:@@config)[:span_processor]
current_span = ::OpenTelemetry::Trace.current_span
entry_trace_id = current_span.context.hex_trace_id
entry_span_id, trace_flags = solarwinds_processor.txn_manager.get_root_context_h(entry_trace_id)&.split('-')

status = false if entry_trace_id.nil? || entry_span_id.nil? || trace_flags.nil?
status = false if entry_trace_id == '0'*32 || entry_span_id == '0'*16 || trace_flags == '00' # not sampled
status = false if entry_trace_id.nil? || entry_span_id.nil? || trace_flags.nil?
status = false if entry_trace_id == '0'*32 || entry_span_id == '0'*16 || trace_flags == '00' # not sampled

solarwinds_processor.txn_manager.set("#{entry_trace_id}-#{entry_span_id}",custom_name)
SolarWindsAPM.logger.debug {"[#{name}/#{__method__}] Cached custom transaction name for #{entry_trace_id}-#{entry_span_id} as #{custom_name}"}
end
solarwinds_processor.txn_manager.set("#{entry_trace_id}-#{entry_span_id}",custom_name)
SolarWindsAPM.logger.debug {"[#{name}/#{__method__}] Cached custom transaction name for #{entry_trace_id}-#{entry_span_id} as #{custom_name}"}
end
status
end
Expand Down
4 changes: 0 additions & 4 deletions lib/solarwinds_apm/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ module Constants
INTL_SWO_PROPAGATOR = "solarwinds_propagator".freeze
INTL_SWO_DEFAULT_PROPAGATORS = [INTL_SWO_TRACECONTEXT_PROPAGATOR, "baggage",INTL_SWO_PROPAGATOR].freeze
INTL_SWO_SUPPORT_EMAIL = "[email protected]".freeze
INTL_SWO_CURRENT_SPAN_ID = "sw-current-entry-span-id".freeze
INTL_SWO_CURRENT_TRACE_ID = "sw-current-trace-id".freeze
INTL_SWO_CURRENT_TRACE_FLAG = "sw-current-trace-flag".freeze

INTL_SWO_OTEL_SCOPE_NAME = "otel.scope.name".freeze
INTL_SWO_OTEL_SCOPE_VERSION = "otel.scope.version".freeze

Expand Down
8 changes: 3 additions & 5 deletions lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ def on_start(span, parent_context)
return if parent_span && parent_span.context != ::OpenTelemetry::Trace::SpanContext::INVALID && parent_span.context.remote? == false

trace_flags = span.context.trace_flags.sampled? ? '01' : '00'
::OpenTelemetry::Context.attach(::OpenTelemetry::Baggage.set_value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_TRACE_ID, span.context.hex_trace_id))
::OpenTelemetry::Context.attach(::OpenTelemetry::Baggage.set_value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_SPAN_ID, span.context.hex_span_id))
::OpenTelemetry::Context.attach(::OpenTelemetry::Baggage.set_value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_TRACE_FLAG, trace_flags))

@txn_manager.set_root_context_h(span.context.hex_trace_id,"#{span.context.hex_span_id}-#{trace_flags}")

SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] current baggage values: #{::OpenTelemetry::Baggage.values}"}
end

Expand Down Expand Up @@ -92,7 +90,7 @@ def on_finish(span)

SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] liboboe_txn_name: #{liboboe_txn_name}"}
@txn_manager["#{span.context.hex_trace_id}-#{span.context.hex_span_id}"] = liboboe_txn_name if span.context.trace_flags.sampled?

@txn_manager.delete_root_context_h(span.context.hex_trace_id)
@exporter&.export([span.to_span_data]) if span.context.trace_flags.sampled?
end

Expand Down
18 changes: 18 additions & 0 deletions lib/solarwinds_apm/support/txn_name_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ module OpenTelemetry
class TxnNameManager
def initialize
@cache = {}
@root_context_h = {}
@mutex = Mutex.new
end

def get(key)
Expand All @@ -20,6 +22,22 @@ def set(key, value)
end

alias []= set

def set_root_context_h(key, value)
@mutex.synchronize do
@root_context_h[key] = value
end
end

def get_root_context_h(key)
@root_context_h[key]
end

def delete_root_context_h(key)
@mutex.synchronize do
@root_context_h.delete(key)
end
end
end
end
end
20 changes: 14 additions & 6 deletions test/api/set_transaction_name_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
describe 'SolarWinds Set Transaction Name Test' do
before do
@span = create_span
@dummy_span = create_span
@dummy_span.context.instance_variable_set(:@span_id, 'fake_span_id') # with fake span_id, should still find the right root span
SolarWindsAPM::OTelConfig.initialize
@processors = ::OpenTelemetry.tracer_provider.instance_variable_get(:@span_processors)
@solarwinds_processor = @processors.last
Expand All @@ -23,23 +25,29 @@

it 'calculate_transaction_names_with_unsampled_span' do
@solarwinds_processor.on_start(@span, ::OpenTelemetry::Context.current)
result = SolarWindsAPM::API.set_transaction_name('abcdf')
_(result).must_equal false
OpenTelemetry::Trace.stub(:current_span, @dummy_span) do
result = SolarWindsAPM::API.set_transaction_name('abcdf')
_(result).must_equal false
end
_(@solarwinds_processor.txn_manager.get("77cb6ccc522d3106114dd6ecbb70036a-31e175128efc4018")).must_equal "abcdf"
end

it 'calculate_transaction_names_with_empty_transaction_name' do
@solarwinds_processor.on_start(@span, ::OpenTelemetry::Context.current)
result = SolarWindsAPM::API.set_transaction_name('')
_(result).must_equal false
OpenTelemetry::Trace.stub(:current_span, @dummy_span) do
result = SolarWindsAPM::API.set_transaction_name('')
_(result).must_equal false
end
assert_nil(@solarwinds_processor.txn_manager.get("77cb6ccc522d3106114dd6ecbb70036a-31e175128efc4018"))
end

it 'calculate_transaction_names_with_sampled_span' do
@span.context.trace_flags.instance_variable_set(:@flags, 1)
@solarwinds_processor.on_start(@span, ::OpenTelemetry::Context.current)
result = SolarWindsAPM::API.set_transaction_name('abcdf')
_(result).must_equal true
OpenTelemetry::Trace.stub(:current_span, @dummy_span) do
result = SolarWindsAPM::API.set_transaction_name('abcdf')
_(result).must_equal true
end
_(@solarwinds_processor.txn_manager.get("77cb6ccc522d3106114dd6ecbb70036a-31e175128efc4018")).must_equal "abcdf"
end
end
1 change: 0 additions & 1 deletion test/minitest_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ def $stdout.write(string)
# Bundler.require(:default, :test) # this load the solarwinds_apm library
SolarWindsAPM.logger.level = 1


# Dummy Propagator for testing
module Dummy
class TextMapPropagator
Expand Down
3 changes: 1 addition & 2 deletions test/opentelemetry/solarwinds_processor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
span = create_span
processor = SolarWindsAPM::OpenTelemetry::SolarWindsProcessor.new(@exporter, @txn_name_manager)
processor.on_start(span, ::OpenTelemetry::Context.current)
_(::OpenTelemetry::Baggage.value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_TRACE_ID)).must_equal '77cb6ccc522d3106114dd6ecbb70036a'
_(::OpenTelemetry::Baggage.value(::SolarWindsAPM::Constants::INTL_SWO_CURRENT_SPAN_ID)).must_equal '31e175128efc4018'
_(processor.txn_manager.get_root_context_h('77cb6ccc522d3106114dd6ecbb70036a')).must_equal "31e175128efc4018-00"
end
end
12 changes: 8 additions & 4 deletions test/support/txn_name_manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,27 @@
@txn_manager.set("c","d")
end

it 'test set' do
it 'test_set' do
@txn_manager.set("a","b")
_(@txn_manager.get("a")).must_equal "b"
end

it 'test []' do
it 'test_[]' do
@txn_manager["e"] = "f"
_(@txn_manager.get("e")).must_equal "f"
end

it 'test del' do
it 'test_del' do
@txn_manager.del("c")
_(@txn_manager.get("c")).must_equal nil
end

it 'test get' do
it 'test_get' do
@txn_manager.get("c").must_equal "d"
end

it 'test_set_get_root_context' do
@txn_manager.set_root_context_h('key1', 'abcd')
_(@txn_manager.get_root_context_h('key1')).must_equal 'abcd'
end
end
2 changes: 2 additions & 0 deletions test/test_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ if [ -n "$RUN_TESTS" ]; then {
export SW_APM_REPORTER=file
mkdir -p log
test/run_tests.sh
status=$?
echo "Finished Unit Test"
exit $status
}
fi

0 comments on commit 745264d

Please sign in to comment.