Class: OpenTelemetry::Sampler::XRay::SamplingRuleApplier

Inherits:
Object
  • Object
show all
Defined in:
lib/opentelemetry/sampler/xray/sampling_rule_applier.rb

Overview

SamplingRuleApplier is responsible for applying Reservoir Sampling and Probability Sampling from the Sampling Rule when determining the sampling decision for spans that matched the rule

Constant Summary collapse

MAX_DATE_TIME_SECONDS =
Time.at(8_640_000_000_000)
SEMCONV =
OpenTelemetry::SemanticConventions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sampling_rule, statistics = OpenTelemetry::Sampler::XRay::Statistics.new, target = nil) ⇒ SamplingRuleApplier

Returns a new instance of SamplingRuleApplier.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/opentelemetry/sampler/xray/sampling_rule_applier.rb', line 26

def initialize(sampling_rule, statistics = OpenTelemetry::Sampler::XRay::Statistics.new, target = nil)
  @sampling_rule = sampling_rule
  @fixed_rate_sampler = OpenTelemetry::SDK::Trace::Samplers::TraceIdRatioBased.new(@sampling_rule.fixed_rate)

  @reservoir_sampler = if @sampling_rule.reservoir_size.positive?
                         OpenTelemetry::Sampler::XRay::RateLimitingSampler.new(1)
                       else
                         OpenTelemetry::Sampler::XRay::RateLimitingSampler.new(0)
                       end

  @reservoir_expiry_time = MAX_DATE_TIME_SECONDS
  @statistics = statistics
  @statistics_lock = Mutex.new

  @statistics.reset_statistics
  @borrowing_enabled = true

  apply_target(target) if target
end

Instance Attribute Details

#sampling_ruleObject (readonly)

Returns the value of attribute sampling_rule.



21
22
23
# File 'lib/opentelemetry/sampler/xray/sampling_rule_applier.rb', line 21

def sampling_rule
  @sampling_rule
end

Instance Method Details

#matches?(attributes, resource) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/opentelemetry/sampler/xray/sampling_rule_applier.rb', line 50

def matches?(attributes, resource)
  http_target = nil
  http_url = nil
  http_method = nil
  http_host = nil

  unless attributes.nil?
    http_target = attributes[SEMCONV::Trace::HTTP_TARGET]
    http_url = attributes[SEMCONV::Trace::HTTP_URL]
    http_method = attributes[SEMCONV::Trace::HTTP_METHOD]
    http_host = attributes[SEMCONV::Trace::HTTP_HOST]
  end

  service_type = nil
  resource_arn = nil

  resource_hash = resource.attribute_enumerator.to_h

  if resource
    service_name = resource_hash[SEMCONV::Resource::SERVICE_NAME] || ''
    cloud_platform = resource_hash[SEMCONV::Resource::CLOUD_PLATFORM]
    service_type = OpenTelemetry::Sampler::XRay::Utils::CLOUD_PLATFORM_MAPPING[cloud_platform] if cloud_platform.is_a?(String)
    resource_arn = get_arn(resource, attributes)
  end

  if http_target.nil? && http_url.is_a?(String)
    begin
      uri = URI(http_url)
      http_target = uri.path.empty? ? '/' : uri.path
    rescue URI::InvalidURIError
      http_target = '/'
    end
  elsif http_target.nil? && http_url.nil?
    http_target = '/'
  end

  OpenTelemetry::Sampler::XRay::Utils.attribute_match?(attributes, @sampling_rule.attributes) &&
    OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.host, http_host) &&
    OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.http_method, http_method) &&
    OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.service_name, service_name) &&
    OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.url_path, http_target) &&
    OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.service_type, service_type) &&
    OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.resource_arn, resource_arn)
end

#should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/opentelemetry/sampler/xray/sampling_rule_applier.rb', line 95

def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
  has_borrowed = false
  result = OpenTelemetry::SDK::Trace::Samplers::Result.new(
    decision: OpenTelemetry::SDK::Trace::Samplers::Decision::DROP,
    tracestate: OpenTelemetry::Trace::Tracestate::DEFAULT
  )

  now = Time.now
  reservoir_expired = now >= @reservoir_expiry_time

  unless reservoir_expired
    result = @reservoir_sampler.should_sample?(
      trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes
    )
    has_borrowed = @borrowing_enabled && result.instance_variable_get(:@decision) != OpenTelemetry::SDK::Trace::Samplers::Decision::DROP
  end

  if result.instance_variable_get(:@decision) == OpenTelemetry::SDK::Trace::Samplers::Decision::DROP
    result = @fixed_rate_sampler.should_sample?(
      trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes
    )
  end

  @statistics_lock.synchronize do
    @statistics.sample_count += result.instance_variable_get(:@decision) == OpenTelemetry::SDK::Trace::Samplers::Decision::DROP ? 0 : 1
    @statistics.borrow_count += has_borrowed ? 1 : 0
    @statistics.request_count += 1
  end

  result
end

#snapshot_statisticsObject



127
128
129
130
131
132
133
# File 'lib/opentelemetry/sampler/xray/sampling_rule_applier.rb', line 127

def snapshot_statistics
  @statistics_lock.synchronize do
    statistics_copy = @statistics.dup
    @statistics.reset_statistics
    return statistics_copy
  end
end

#with_target(target) ⇒ Object



46
47
48
# File 'lib/opentelemetry/sampler/xray/sampling_rule_applier.rb', line 46

def with_target(target)
  self.class.new(@sampling_rule, @statistics, target)
end