class SplunkTracing::Tracer
Constants
- CARRIER_BAGGAGE_PREFIX
- CARRIER_SAMPLED
- CARRIER_SPAN_ID
- CARRIER_TRACER_STATE_PREFIX
- CARRIER_TRACE_ID
- DEFAULT_MAX_LOG_RECORDS
- DEFAULT_MAX_SPAN_RECORDS
- MIN_MAX_LOG_RECORDS
- MIN_MAX_SPAN_RECORDS
Attributes
Public Class Methods
Initialize a new tracer. Either an access_token
or a transport must be provided. A component_name is always required. @param component_name [String] Component name to use for the tracer @param access_token
[String] The project access token when pushing to SplunkTracing
@param transport [SplunkTracing::Transport] How the data should be transported @param tags [Hash] Tracer-level tags @return SplunkTracing::Tracer
@raise SplunkTracing::ConfigurationError if the group name or access token is not a valid string.
# File lib/splunktracing/tracer.rb, line 27 def initialize(component_name:, access_token: nil, transport: nil, tags: {}) configure(component_name: component_name, access_token: access_token, transport: transport, tags: tags) end
Public Instance Methods
Returns the span from the active scope, if any.
@return [Span, nil] the active span. This is a shorthand for
`scope_manager.active.span`, and nil will be returned if Scope#active is nil.
# File lib/splunktracing/tracer.rb, line 123 def active_span scope = scope_manager.active scope.span if scope end
Disables the tracer @param discard [Boolean] whether to discard queued data
# File lib/splunktracing/tracer.rb, line 208 def disable(discard: true) @enabled = false @reporter.clear if discard @reporter.flush end
Enables the tracer
# File lib/splunktracing/tracer.rb, line 202 def enable @enabled = true end
@return true if the tracer is enabled
# File lib/splunktracing/tracer.rb, line 196 def enabled? return @enabled if defined?(@enabled) @enabled = true end
Extract a SpanContext
from a carrier @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY, OpenTracing::FORMAT_RACK] @param carrier [Carrier] A carrier object of the type dictated by the specified `format` @return [SpanContext] the extracted SpanContext
or nil if none could be found
# File lib/splunktracing/tracer.rb, line 180 def extract(format, carrier) case format when OpenTracing::FORMAT_TEXT_MAP extract_from_text_map(carrier) when OpenTracing::FORMAT_BINARY warn 'Binary join format not yet implemented' nil when OpenTracing::FORMAT_RACK extract_from_rack(carrier) else warn 'Unknown join format' nil end end
Internal use only. @private
# File lib/splunktracing/tracer.rb, line 222 def finish_span(span) return unless enabled? @reporter.add_span(span) end
Flush to the Transport
# File lib/splunktracing/tracer.rb, line 215 def flush return unless enabled? @reporter.flush end
Inject a SpanContext
into the given carrier
@param spancontext [SpanContext] @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY] @param carrier [Carrier] A carrier object of the type dictated by the specified `format`
# File lib/splunktracing/tracer.rb, line 163 def inject(span_context, format, carrier) case format when OpenTracing::FORMAT_TEXT_MAP inject_to_text_map(span_context, carrier) when OpenTracing::FORMAT_BINARY warn 'Binary inject format not yet implemented' when OpenTracing::FORMAT_RACK inject_to_rack(span_context, carrier) else warn 'Unknown inject format' end end
# File lib/splunktracing/tracer.rb, line 31 def max_log_records @max_log_records ||= DEFAULT_MAX_LOG_RECORDS end
# File lib/splunktracing/tracer.rb, line 35 def max_log_records=(max) @max_log_records = [MIN_MAX_LOG_RECORDS, max].max end
# File lib/splunktracing/tracer.rb, line 39 def max_span_records @max_span_records ||= DEFAULT_MAX_SPAN_RECORDS end
# File lib/splunktracing/tracer.rb, line 43 def max_span_records=(max) @max_span_records = [MIN_MAX_SPAN_RECORDS, max].max @reporter.max_span_records = @max_span_records end
Set the report flushing period. If set to 0, no flushing will be done, you must manually call flush.
# File lib/splunktracing/tracer.rb, line 50 def report_period_seconds=(seconds) @reporter.period = seconds end
Creates a scope manager or returns the already-created one.
@return [ScopeManager] the current ScopeManager
, which may be a no-op but
may not be nil.
# File lib/splunktracing/tracer.rb, line 60 def scope_manager @scope_manager ||= SplunkTracing::ScopeManager.new end
Returns a newly started and activated Scope
.
If ScopeManager#active
is not nil, no explicit references are provided, and `ignore_active_scope` is false, then an inferred References#CHILD_OF reference is created to the ScopeManager#active
's SpanContext
when start_active_span
is invoked.
@param operation_name [String] The operation name for the Span
@param child_of [SpanContext, Span] SpanContext
that acts as a parent to
the newly-started Span. If a Span instance is provided, its context is automatically substituted. See [Reference] for more information. If specified, the `references` parameter must be omitted.
@param references [Array<Reference>] An array of reference
objects that identify one or more parent SpanContexts.
@param start_time [Time] When the Span
started, if not now @param tags [Hash] Tags to assign to the Span
at start time @param ignore_active_scope [Boolean] whether to create an implicit
References#CHILD_OF reference to the ScopeManager#active.
@param finish_on_close [Boolean] whether span should automatically be
finished when Scope#close is called
@yield [Scope] If an optional block is passed to start_active it will
yield the newly-started Scope. If `finish_on_close` is true then the Span will be finished automatically after the block is executed.
@return [Scope] The newly-started and activated Scope
# File lib/splunktracing/tracer.rb, line 90 def start_active_span(operation_name, child_of: nil, references: nil, start_time: Time.now, tags: nil, ignore_active_scope: false, finish_on_close: true) if child_of.nil? && references.nil? && !ignore_active_scope child_of = active_span end span = start_span( operation_name, child_of: child_of, references: references, start_time: start_time, tags: tags, ignore_active_scope: ignore_active_scope ) scope_manager.activate(span: span, finish_on_close: finish_on_close).tap do |scope| if block_given? yield scope scope.close end end end
Starts a new span.
@param operation_name [String] The operation name for the Span
@param child_of [SpanContext] SpanContext
that acts as a parent to
the newly-started Span. If a Span instance is provided, its .span_context is automatically substituted.
@param references [Array<SpanContext>] An array of SpanContexts that
identify any parent SpanContexts of newly-started Span. If Spans are provided, their .span_context is automatically substituted.
@param start_time [Time] When the Span
started, if not now @param tags [Hash] Tags to assign to the Span
at start time @param ignore_active_scope [Boolean] whether to create an implicit
References#CHILD_OF reference to the ScopeManager#active.
@return [Span]
# File lib/splunktracing/tracer.rb, line 142 def start_span(operation_name, child_of: nil, references: nil, start_time: nil, tags: nil, ignore_active_scope: false) if child_of.nil? && references.nil? && !ignore_active_scope child_of = active_span end Span.new( tracer: self, operation_name: operation_name, child_of: child_of, references: references, start_micros: start_time.nil? ? SplunkTracing.micros(Time.now) : SplunkTracing.micros(start_time), tags: tags, max_log_records: max_log_records, ) end
Protected Instance Methods
# File lib/splunktracing/tracer.rb, line 229 def configure(component_name:, access_token: nil, transport: nil, tags: {}) raise ConfigurationError, "component_name must be a string" unless component_name.is_a?(String) raise ConfigurationError, "component_name cannot be blank" if component_name.empty? if transport.nil? and !access_token.nil? transport = Transport::HTTPJSON.new(access_token: access_token) end raise ConfigurationError, "you must provide an access token or a transport" if transport.nil? raise ConfigurationError, "#{transport} is not a SplunkTracing transport class" if !(SplunkTracing::Transport::Base === transport) @guid = SplunkTracing.guid @reporter = SplunkTracing::Reporter.new( max_span_records: max_span_records, transport: transport, guid: guid, component_name: component_name, tags: tags ) end
Private Instance Methods
# File lib/splunktracing/tracer.rb, line 311 def extract_from_rack(env) extract_from_text_map(env.reduce({}){|memo, tuple| raw_header, value = tuple header = raw_header.to_s.gsub(/^HTTP_/, '').tr('_', '-').downcase memo[header] = value if header.start_with?(CARRIER_TRACER_STATE_PREFIX, CARRIER_BAGGAGE_PREFIX) memo }) end
# File lib/splunktracing/tracer.rb, line 275 def extract_from_text_map(carrier) # If the carrier does not have both the span_id and trace_id key # skip the processing and just return a normal span if !carrier.has_key?(CARRIER_SPAN_ID) || !carrier.has_key?(CARRIER_TRACE_ID) return nil end baggage = carrier.reduce({}) do |baggage, tuple| key, value = tuple if key.start_with?(CARRIER_BAGGAGE_PREFIX) plain_key = key.to_s[CARRIER_BAGGAGE_PREFIX.length..key.to_s.length] baggage[plain_key] = value end baggage end SpanContext.new( id: carrier[CARRIER_SPAN_ID], trace_id: carrier[CARRIER_TRACE_ID], baggage: baggage, ) end
# File lib/splunktracing/tracer.rb, line 297 def inject_to_rack(span_context, carrier) carrier[CARRIER_SPAN_ID] = span_context.id carrier[CARRIER_TRACE_ID] = span_context.trace_id unless span_context.trace_id.nil? carrier[CARRIER_SAMPLED] = 'true' span_context.baggage.each do |key, value| if key =~ /[^A-Za-z0-9\-_]/ # TODO: log the error internally next end carrier[CARRIER_BAGGAGE_PREFIX + key] = value end end
# File lib/splunktracing/tracer.rb, line 265 def inject_to_text_map(span_context, carrier) carrier[CARRIER_SPAN_ID] = span_context.id carrier[CARRIER_TRACE_ID] = span_context.trace_id unless span_context.trace_id.nil? carrier[CARRIER_SAMPLED] = 'true' span_context.baggage.each do |key, value| carrier[CARRIER_BAGGAGE_PREFIX + key] = value end end