lib/instana/instrumentation/instrumented_request.rb in instana-1.193.6 vs lib/instana/instrumentation/instrumented_request.rb in instana-1.195.0
- old
+ new
@@ -7,23 +7,28 @@
require 'cgi'
require 'rack/request'
module Instana
class InstrumentedRequest < Rack::Request
+ W3_TRACE_PARENT_FORMAT = /00-(?<trace>[0-9a-f]+)-(?<parent>[0-9a-f]+)-(?<flags>[0-9a-f]+)/.freeze
+ INSTANA_TRACE_STATE = /in=(?<trace>[0-9a-f]+);(?<span>[0-9a-f]+)/.freeze
+
def skip_trace?
# Honor X-Instana-L
@env.has_key?('HTTP_X_INSTANA_L') && @env['HTTP_X_INSTANA_L'].start_with?('0')
end
def incoming_context
- context = {}
+ context = if @env['HTTP_X_INSTANA_T']
+ context_from_instana_headers
+ elsif @env['HTTP_TRACEPARENT'] && ::Instana.config[:w3_trace_correlation]
+ context_from_trace_parent
+ else
+ {}
+ end
- if @env['HTTP_X_INSTANA_T']
- context[:trace_id] = ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_T'])
- context[:span_id] = ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_S']) if @env['HTTP_X_INSTANA_S']
- context[:level] = @env['HTTP_X_INSTANA_L'][0] if @env['HTTP_X_INSTANA_L']
- end
+ context[:level] = @env['HTTP_X_INSTANA_L'][0] if @env['HTTP_X_INSTANA_L']
context
end
def extra_header_tags
@@ -52,10 +57,57 @@
def correlation_data
@correlation_data ||= parse_correlation_data
end
+ def instana_ancestor
+ @instana_ancestor ||= parse_trace_state
+ end
+
+ def continuing_from_trace_parent?
+ incoming_context.include?(:external_trace_id)
+ end
+
+ def synthetic?
+ @env.has_key?('HTTP_X_INSTANA_SYNTHETIC') && @env['HTTP_X_INSTANA_SYNTHETIC'].eql?('1')
+ end
+
private
+
+ def context_from_instana_headers
+ {
+ trace_id: ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_T']),
+ span_id: ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_S'])
+ }.compact
+ end
+
+ def context_from_trace_parent
+ return {} unless @env.has_key?('HTTP_TRACEPARENT')
+ matches = @env['HTTP_TRACEPARENT'].match(W3_TRACE_PARENT_FORMAT)
+ return {} unless matches
+
+ {
+ external_trace_id: matches['trace'],
+ external_state: @env['HTTP_TRACESTATE'],
+ trace_id: ::Instana::Util.header_to_id(matches['trace'][16..-1]),
+ span_id: ::Instana::Util.header_to_id(matches['parent'])
+ }
+ end
+
+ def parse_trace_state
+ return {} unless @env.has_key?('HTTP_TRACESTATE')
+ token = @env['HTTP_TRACESTATE']
+ .split(/,/)
+ .map { |t| t.match(INSTANA_TRACE_STATE) }
+ .reject { |t| t.nil? }
+ .first
+ return {} unless token
+
+ {
+ t: token['trace'],
+ p: token['span']
+ }
+ end
def parse_correlation_data
return {} unless @env.has_key?('HTTP_X_INSTANA_L')
_level, *tokens = @env['HTTP_X_INSTANA_L'].split(/[,=;]/)
data = tokens