jaeger-client 0.10.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,10 +6,12 @@ module Jaeger
6
6
  def self.parse(trace)
7
7
  return nil if !trace || trace == ''
8
8
 
9
- trace_arguments = trace.split(':').map(&TraceId.method(:base16_hex_id_to_uint64))
9
+ trace_arguments = trace.split(':')
10
10
  return nil if trace_arguments.size != 4
11
11
 
12
- trace_id, span_id, parent_id, flags = trace_arguments
12
+ trace_id = TraceId.base16_hex_id_to_uint128(trace_arguments[0])
13
+ span_id, parent_id, flags = trace_arguments[1..3].map(&TraceId.method(:base16_hex_id_to_uint64))
14
+
13
15
  return nil if trace_id.zero? || span_id.zero?
14
16
 
15
17
  SpanContext.new(
@@ -63,13 +65,47 @@ module Jaeger
63
65
  end
64
66
 
65
67
  class B3RackCodec
68
+ class Keys
69
+ TRACE_ID = 'HTTP_X_B3_TRACEID'
70
+ SPAN_ID = 'HTTP_X_B3_SPANID'
71
+ PARENT_SPAN_ID = 'HTTP_X_B3_PARENTSPANID'
72
+ FLAGS = 'HTTP_X_B3_FLAGS'
73
+ SAMPLED = 'HTTP_X_B3_SAMPLED'
74
+ end.freeze
75
+
76
+ def self.extract(carrier)
77
+ B3CodecCommon.extract(carrier, Keys)
78
+ end
79
+ end
80
+
81
+ class B3TextMapCodec
82
+ class Keys
83
+ TRACE_ID = 'x-b3-traceid'
84
+ SPAN_ID = 'x-b3-spanid'
85
+ PARENT_SPAN_ID = 'x-b3-parentspanid'
86
+ FLAGS = 'x-b3-flags'
87
+ SAMPLED = 'x-b3-sampled'
88
+ end.freeze
89
+
66
90
  def self.extract(carrier)
67
- trace_id = TraceId.base16_hex_id_to_uint64(carrier['HTTP_X_B3_TRACEID'])
68
- span_id = TraceId.base16_hex_id_to_uint64(carrier['HTTP_X_B3_SPANID'])
69
- parent_id = TraceId.base16_hex_id_to_uint64(carrier['HTTP_X_B3_PARENTSPANID'])
70
- flags = parse_flags(carrier['HTTP_X_B3_FLAGS'], carrier['HTTP_X_B3_SAMPLED'])
91
+ B3CodecCommon.extract(carrier, Keys)
92
+ end
93
+ end
94
+
95
+ class B3CodecCommon
96
+ def self.extract(carrier, keys)
97
+ return nil if carrier[keys::TRACE_ID].nil? || carrier[keys::SPAN_ID].nil?
98
+
99
+ trace_id = if carrier[keys::TRACE_ID].length <= 16
100
+ TraceId.base16_hex_id_to_uint64(carrier[keys::TRACE_ID])
101
+ else
102
+ TraceId.base16_hex_id_to_uint128(carrier[keys::TRACE_ID])
103
+ end
104
+
105
+ span_id = TraceId.base16_hex_id_to_uint64(carrier[keys::SPAN_ID])
106
+ parent_id = TraceId.base16_hex_id_to_uint64(carrier[keys::PARENT_SPAN_ID])
107
+ flags = parse_flags(carrier[keys::FLAGS], carrier[keys::SAMPLED])
71
108
 
72
- return nil if span_id.nil? || trace_id.nil?
73
109
  return nil if span_id.zero? || trace_id.zero?
74
110
 
75
111
  SpanContext.new(
@@ -91,6 +127,34 @@ module Jaeger
91
127
  private_class_method :parse_flags
92
128
  end
93
129
 
130
+ class TraceContextRackCodec
131
+ # Internal regex used to identify the TraceContext version
132
+ VERSION_PATTERN = /^([0-9a-fA-F]{2})-(.+)$/.freeze
133
+
134
+ # Internal regex used to parse fields in version 0
135
+ HEADER_V0_PATTERN = /^([0-9a-fA-F]{32})-([0-9a-fA-F]{16})(-([0-9a-fA-F]{2}))?$/.freeze
136
+
137
+ def self.extract(carrier)
138
+ header_value = carrier['HTTP_TRACEPARENT']
139
+
140
+ version_match = VERSION_PATTERN.match(header_value)
141
+ return nil unless version_match
142
+
143
+ # We currently only support version 0
144
+ return nil if version_match[1].to_i(16) != 0
145
+
146
+ match = HEADER_V0_PATTERN.match(version_match[2])
147
+ return nil unless match
148
+
149
+ trace_id = TraceId.base16_hex_id_to_uint128(match[1])
150
+ span_id = TraceId.base16_hex_id_to_uint64(match[2])
151
+ flags = TraceId.base16_hex_id_to_uint64(match[4])
152
+ return nil if trace_id.zero? || span_id.zero?
153
+
154
+ SpanContext.new(trace_id: trace_id, span_id: span_id, flags: flags)
155
+ end
156
+ end
157
+
94
158
  DEFAULT_EXTRACTORS = {
95
159
  OpenTracing::FORMAT_TEXT_MAP => JaegerTextMapCodec,
96
160
  OpenTracing::FORMAT_BINARY => JaegerBinaryCodec,
@@ -4,7 +4,7 @@ require 'logger'
4
4
 
5
5
  module Jaeger
6
6
  class HttpSender
7
- def initialize(url:, headers: {}, encoder:, logger: Logger.new(STDOUT))
7
+ def initialize(url:, encoder:, headers: {}, logger: Logger.new($stdout))
8
8
  @encoder = encoder
9
9
  @logger = logger
10
10
 
@@ -21,8 +21,8 @@ module Jaeger
21
21
  batch = @encoder.encode(spans)
22
22
  @transport.write(@serializer.serialize(batch))
23
23
  @transport.flush
24
- rescue StandardError => error
25
- @logger.error("Failure while sending a batch of spans: #{error}")
24
+ rescue StandardError => e
25
+ @logger.error("Failure while sending a batch of spans: #{e}")
26
26
  end
27
27
  end
28
28
  end
@@ -51,18 +51,32 @@ module Jaeger
51
51
  end
52
52
  end
53
53
 
54
+ class TraceContextRackCodec
55
+ def self.inject(span_context, carrier)
56
+ flags = span_context.sampled? || span_context.debug? ? 1 : 0
57
+
58
+ carrier['traceparent'] = format(
59
+ '%<version>s-%<trace_id>s-%<span_id>s-%<flags>s',
60
+ version: '00',
61
+ trace_id: span_context.trace_id.to_s(16).rjust(32, '0'),
62
+ span_id: span_context.span_id.to_s(16).rjust(16, '0'),
63
+ flags: flags.to_s(16).rjust(2, '0')
64
+ )
65
+ end
66
+ end
67
+
54
68
  DEFAULT_INJECTORS = {
55
69
  OpenTracing::FORMAT_TEXT_MAP => JaegerTextMapCodec,
56
70
  OpenTracing::FORMAT_BINARY => JaegerBinaryCodec,
57
71
  OpenTracing::FORMAT_RACK => JaegerRackCodec
58
72
  }.freeze
59
73
 
60
- def self.prepare(extractors)
61
- DEFAULT_INJECTORS.reduce(extractors) do |acc, (format, default)|
62
- provided_extractors = Array(extractors[format])
63
- provided_extractors += [default] if provided_extractors.empty?
74
+ def self.prepare(injectors)
75
+ DEFAULT_INJECTORS.reduce(injectors) do |acc, (format, default)|
76
+ provided_injectors = Array(injectors[format])
77
+ provided_injectors += [default] if provided_injectors.empty?
64
78
 
65
- acc.merge(format => provided_extractors)
79
+ acc.merge(format => provided_injectors)
66
80
  end
67
81
  end
68
82
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ # Executes a given block periodically. The block will be executed only once
5
+ # when interval is set to 0.
6
+ class RecurringExecutor
7
+ def initialize(interval:)
8
+ @interval = interval
9
+ end
10
+
11
+ def start(&block)
12
+ raise 'Already running' if @thread
13
+
14
+ @thread = Thread.new do
15
+ if @interval <= 0
16
+ yield
17
+ else
18
+ loop do
19
+ yield
20
+ sleep @interval
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def running?
27
+ @thread&.alive?
28
+ end
29
+
30
+ def stop
31
+ @thread.kill
32
+ @thread = nil
33
+ end
34
+ end
35
+ end
@@ -16,7 +16,7 @@ module Jaeger
16
16
  }
17
17
  end
18
18
 
19
- def sample?(*)
19
+ def sample(*)
20
20
  [@decision, @tags]
21
21
  end
22
22
  end
@@ -12,27 +12,34 @@ module Jaeger
12
12
  # emitted, ie. if is_sampled() for both samplers return true, the tags
13
13
  # for Probabilistic sampler will be used.
14
14
  class GuaranteedThroughputProbabilistic
15
- attr_reader :tags
15
+ attr_reader :tags, :probabilistic_sampler, :lower_bound_sampler
16
16
 
17
17
  def initialize(lower_bound:, rate:, lower_bound_sampler: nil)
18
18
  @probabilistic_sampler = Probabilistic.new(rate: rate)
19
19
  @lower_bound_sampler = lower_bound_sampler || RateLimiting.new(max_traces_per_second: lower_bound)
20
20
  @lower_bound_tags = {
21
21
  'sampler.type' => 'lowerbound',
22
- 'sampler.param' => lower_bound
22
+ 'sampler.param' => rate
23
23
  }
24
24
  end
25
25
 
26
- def sample?(*args)
27
- is_sampled, probabilistic_tags = @probabilistic_sampler.sample?(*args)
26
+ def update(lower_bound:, rate:)
27
+ is_updated = @probabilistic_sampler.update(rate: rate)
28
+ is_updated = @lower_bound_sampler.update(max_traces_per_second: lower_bound) || is_updated
29
+ @lower_bound_tags['sampler.param'] = rate
30
+ is_updated
31
+ end
32
+
33
+ def sample(...)
34
+ is_sampled, probabilistic_tags = @probabilistic_sampler.sample(...)
28
35
  if is_sampled
29
36
  # We still call lower_bound_sampler to update the rate limiter budget
30
- @lower_bound_sampler.sample?(*args)
37
+ @lower_bound_sampler.sample(...)
31
38
 
32
39
  return [is_sampled, probabilistic_tags]
33
40
  end
34
41
 
35
- is_sampled, _tags = @lower_bound_sampler.sample?(*args)
42
+ is_sampled, _tags = @lower_bound_sampler.sample(...)
36
43
  [is_sampled, @lower_bound_tags]
37
44
  end
38
45
  end
@@ -10,37 +10,67 @@ module Jaeger
10
10
  DEFAULT_SAMPLING_PROBABILITY = 0.001
11
11
  DEFAULT_LOWER_BOUND = 1.0 / (10.0 * 60.0) # sample once every 10 minutes'
12
12
 
13
+ attr_reader :default_sampling_probability, :lower_bound, :samplers
14
+
13
15
  def initialize(strategies:, max_operations:)
14
16
  @max_operations = max_operations
17
+ @samplers = {}
18
+ update(strategies: strategies)
19
+ end
20
+
21
+ def update(strategies:)
22
+ is_updated = false
23
+
15
24
  @default_sampling_probability =
16
25
  strategies[:default_sampling_probability] || DEFAULT_SAMPLING_PROBABILITY
17
- @lower_bound = strategies[:default_lower_bound_traces_per_second] || DEFAULT_LOWER_BOUND
26
+ @lower_bound =
27
+ strategies[:default_lower_bound_traces_per_second] || DEFAULT_LOWER_BOUND
18
28
 
19
- @default_sampler = Probabilistic.new(rate: @default_sampling_probability)
20
- @samplers = (strategies[:per_operation_strategies] || []).reduce({}) do |acc, strategy|
21
- operation = strategy.fetch(:operation)
22
- rate = strategy.fetch(:probabilistic_sampling)
23
- sampler = GuaranteedThroughputProbabilistic.new(
24
- lower_bound: @lower_bound,
25
- rate: rate
26
- )
27
- acc.merge(operation => sampler)
29
+ if @default_sampler
30
+ is_updated = @default_sampler.update(rate: @default_sampling_probability)
31
+ else
32
+ @default_sampler = Probabilistic.new(rate: @default_sampling_probability)
28
33
  end
34
+
35
+ update_operation_strategies(strategies) || is_updated
29
36
  end
30
37
 
31
- def sample?(opts)
38
+ def sample(opts)
32
39
  operation_name = opts.fetch(:operation_name)
33
40
  sampler = @samplers[operation_name]
34
- return sampler.sample?(opts) if sampler
41
+ return sampler.sample(opts) if sampler
35
42
 
36
- return @default_sampler.sample?(opts) if @samplers.length >= @max_operations
43
+ return @default_sampler.sample(opts) if @samplers.length >= @max_operations
37
44
 
38
45
  sampler = GuaranteedThroughputProbabilistic.new(
39
46
  lower_bound: @lower_bound,
40
47
  rate: @default_sampling_probability
41
48
  )
42
49
  @samplers[operation_name] = sampler
43
- sampler.sample?(opts)
50
+ sampler.sample(opts)
51
+ end
52
+
53
+ private
54
+
55
+ def update_operation_strategies(strategies)
56
+ is_updated = false
57
+
58
+ (strategies[:per_operation_strategies] || []).each do |strategy|
59
+ operation = strategy.fetch(:operation)
60
+ rate = strategy.fetch(:probabilistic_sampling).fetch(:sampling_rate)
61
+
62
+ if (sampler = @samplers[operation])
63
+ is_updated = sampler.update(lower_bound: @lower_bound, rate: rate) || is_updated
64
+ else
65
+ @samplers[operation] = GuaranteedThroughputProbabilistic.new(
66
+ lower_bound: @lower_bound,
67
+ rate: rate
68
+ )
69
+ is_updated = true
70
+ end
71
+ end
72
+
73
+ is_updated
44
74
  end
45
75
  end
46
76
  end
@@ -6,19 +6,33 @@ module Jaeger
6
6
  #
7
7
  # Sample a portion of traces using trace_id as the random decision
8
8
  class Probabilistic
9
+ attr_reader :rate
10
+
9
11
  def initialize(rate: 0.001)
12
+ update(rate: rate)
13
+ end
14
+
15
+ def update(rate:)
10
16
  if rate < 0.0 || rate > 1.0
11
17
  raise "Sampling rate must be between 0.0 and 1.0, got #{rate.inspect}"
12
18
  end
13
19
 
20
+ new_boundary = TraceId::TRACE_ID_UPPER_BOUND * rate
21
+ return false if @boundary == new_boundary
22
+
23
+ @rate = rate
14
24
  @boundary = TraceId::TRACE_ID_UPPER_BOUND * rate
15
25
  @tags = {
16
26
  'sampler.type' => 'probabilistic',
17
27
  'sampler.param' => rate
18
28
  }
29
+
30
+ true
19
31
  end
20
32
 
21
- def sample?(trace_id:, **)
33
+ def sample(opts)
34
+ trace_id = opts.fetch(:trace_id)
35
+
22
36
  [@boundary >= trace_id, @tags]
23
37
  end
24
38
  end
@@ -8,24 +8,42 @@ module Jaeger
8
8
  # well, but if requests are bursty, especially sub-second, then a number
9
9
  # of sequential requests can be sampled each second.
10
10
  class RateLimiting
11
- attr_reader :tags
11
+ attr_reader :tags, :max_traces_per_second
12
12
 
13
13
  def initialize(max_traces_per_second: 10)
14
+ update(max_traces_per_second: max_traces_per_second)
15
+ end
16
+
17
+ def update(max_traces_per_second:)
14
18
  if max_traces_per_second < 0.0
15
19
  raise "max_traces_per_second must not be negative, got #{max_traces_per_second}"
16
20
  end
17
21
 
18
- @rate_limiter = RateLimiter.new(
19
- credits_per_second: max_traces_per_second,
20
- max_balance: [max_traces_per_second, 1.0].max
21
- )
22
+ return false if max_traces_per_second == @max_traces_per_second
23
+
22
24
  @tags = {
23
25
  'sampler.type' => 'ratelimiting',
24
26
  'sampler.param' => max_traces_per_second
25
27
  }
28
+ @max_traces_per_second = max_traces_per_second
29
+ max_balance = [max_traces_per_second, 1.0].max
30
+
31
+ if @rate_limiter
32
+ @rate_limiter.update(
33
+ credits_per_second: max_traces_per_second,
34
+ max_balance: max_balance
35
+ )
36
+ else
37
+ @rate_limiter = RateLimiter.new(
38
+ credits_per_second: max_traces_per_second,
39
+ max_balance: [max_traces_per_second, 1.0].max
40
+ )
41
+ end
42
+
43
+ true
26
44
  end
27
45
 
28
- def sample?(*)
46
+ def sample(*)
29
47
  [@rate_limiter.check_credit(1.0), @tags]
30
48
  end
31
49
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Samplers
5
+ class RemoteControlled
6
+ class InstructionsFetcher
7
+ FetchFailed = Class.new(StandardError)
8
+
9
+ def initialize(host:, port:, service_name:)
10
+ @host = host
11
+ @port = port
12
+ @service_name = service_name
13
+ end
14
+
15
+ def fetch
16
+ http = Net::HTTP.new(@host, @port)
17
+ path = "/sampling?service=#{CGI.escape(@service_name)}"
18
+ response =
19
+ begin
20
+ http.request(Net::HTTP::Get.new(path))
21
+ rescue StandardError => e
22
+ raise FetchFailed, e.inspect
23
+ end
24
+
25
+ unless response.is_a?(Net::HTTPSuccess)
26
+ raise FetchFailed, "Unsuccessful response (code=#{response.code})"
27
+ end
28
+
29
+ JSON.parse(response.body)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'remote_controlled/instructions_fetcher'
4
+
5
+ module Jaeger
6
+ module Samplers
7
+ class RemoteControlled
8
+ DEFAULT_REFRESH_INTERVAL = 60
9
+ DEFAULT_SAMPLING_HOST = 'localhost'
10
+ DEFAULT_SAMPLING_PORT = 5778
11
+
12
+ attr_reader :sampler
13
+
14
+ def initialize(opts = {})
15
+ @sampler = opts.fetch(:sampler, Probabilistic.new)
16
+ @logger = opts.fetch(:logger, Logger.new($stdout))
17
+
18
+ @poll_executor = opts[:poll_executor] || begin
19
+ refresh_interval = opts.fetch(:refresh_interval, DEFAULT_REFRESH_INTERVAL)
20
+ RecurringExecutor.new(interval: refresh_interval)
21
+ end
22
+
23
+ @instructions_fetcher = opts[:instructions_fetcher] || begin
24
+ service_name = opts.fetch(:service_name)
25
+ host = opts.fetch(:host, DEFAULT_SAMPLING_HOST)
26
+ port = opts.fetch(:port, DEFAULT_SAMPLING_PORT)
27
+ InstructionsFetcher.new(host: host, port: port, service_name: service_name)
28
+ end
29
+ end
30
+
31
+ def sample(*args)
32
+ @poll_executor.start(&method(:poll)) unless @poll_executor.running?
33
+
34
+ @sampler.sample(*args)
35
+ end
36
+
37
+ def poll
38
+ @logger.debug 'Fetching sampling strategy'
39
+
40
+ instructions = @instructions_fetcher.fetch
41
+ handle_instructions(instructions)
42
+ rescue InstructionsFetcher::FetchFailed => e
43
+ @logger.warn "Fetching sampling strategy failed: #{e.message}"
44
+ end
45
+
46
+ private
47
+
48
+ def handle_instructions(instructions)
49
+ if instructions['operationSampling']
50
+ update_per_operation_sampler(instructions['operationSampling'])
51
+ else
52
+ update_rate_limiting_or_probabilistic_sampler(instructions['strategyType'], instructions)
53
+ end
54
+ end
55
+
56
+ def update_per_operation_sampler(instructions)
57
+ strategies = normalize(instructions)
58
+
59
+ if @sampler.is_a?(PerOperation)
60
+ @sampler.update(strategies: strategies)
61
+ else
62
+ @sampler = PerOperation.new(strategies: strategies, max_operations: 2000)
63
+ end
64
+ end
65
+
66
+ def normalize(instructions)
67
+ {
68
+ default_sampling_probability: instructions['defaultSamplingProbability'],
69
+ default_lower_bound_traces_per_second: instructions['defaultLowerBoundTracesPerSecond'],
70
+ per_operation_strategies: instructions['perOperationStrategies'].map do |strategy|
71
+ {
72
+ operation: strategy['operation'],
73
+ probabilistic_sampling: {
74
+ sampling_rate: strategy['probabilisticSampling']['samplingRate']
75
+ }
76
+ }
77
+ end
78
+ }
79
+ end
80
+
81
+ def update_rate_limiting_or_probabilistic_sampler(strategy, instructions)
82
+ case strategy
83
+ when 'PROBABILISTIC'
84
+ update_probabilistic_strategy(instructions['probabilisticSampling'])
85
+ when 'RATE_LIMITING'
86
+ update_rate_limiting_strategy(instructions['rateLimitingSampling'])
87
+ else
88
+ @logger.warn "Unknown sampling strategy #{strategy}"
89
+ end
90
+ end
91
+
92
+ def update_probabilistic_strategy(instructions)
93
+ rate = instructions['samplingRate']
94
+ return unless rate
95
+
96
+ if @sampler.is_a?(Probabilistic)
97
+ @sampler.update(rate: rate)
98
+ @logger.info "Updated Probabilistic sampler (rate=#{rate})"
99
+ else
100
+ @sampler = Probabilistic.new(rate: rate)
101
+ @logger.info "Updated sampler to Probabilistic (rate=#{rate})"
102
+ end
103
+ end
104
+
105
+ def update_rate_limiting_strategy(instructions)
106
+ max_traces_per_second = instructions['maxTracesPerSecond']
107
+ return unless max_traces_per_second
108
+
109
+ if @sampler.is_a?(RateLimiting)
110
+ @sampler.update(max_traces_per_second: max_traces_per_second)
111
+ @logger.info "Updated Ratelimiting sampler (max_traces_per_second=#{max_traces_per_second})"
112
+ else
113
+ @sampler = RateLimiting.new(max_traces_per_second: max_traces_per_second)
114
+ @logger.info "Updated sampler to Ratelimiting (max_traces_per_second=#{max_traces_per_second})"
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -5,3 +5,4 @@ require_relative 'samplers/guaranteed_throughput_probabilistic'
5
5
  require_relative 'samplers/per_operation'
6
6
  require_relative 'samplers/probabilistic'
7
7
  require_relative 'samplers/rate_limiting'
8
+ require_relative 'samplers/remote_controlled'
data/lib/jaeger/scope.rb CHANGED
@@ -23,6 +23,7 @@ module Jaeger
23
23
  # updating the ScopeManager#active in the process.
24
24
  def close
25
25
  raise "Tried to close already closed span: #{inspect}" if @closed
26
+
26
27
  @closed = true
27
28
 
28
29
  @span.finish if @finish_on_close
@@ -30,8 +31,8 @@ module Jaeger
30
31
 
31
32
  if removed_scope != self # rubocop:disable Style/GuardClause
32
33
  raise 'Removed non-active scope, ' \
33
- "removed: #{removed_scope.inspect}, "\
34
- "expected: #{inspect}"
34
+ "removed: #{removed_scope.inspect}, "\
35
+ "expected: #{inspect}"
35
36
  end
36
37
  end
37
38
  end
@@ -27,6 +27,7 @@ module Jaeger
27
27
  # returned instance.
28
28
  def activate(span, finish_on_close: true)
29
29
  return active if active && active.span == span
30
+
30
31
  scope = Scope.new(span, @scope_stack, finish_on_close: finish_on_close)
31
32
  @scope_stack.push(scope)
32
33
  scope
data/lib/jaeger/span.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'span/thrift_tag_builder'
4
3
  require_relative 'span/thrift_log_builder'
5
4
 
6
5
  module Jaeger
@@ -35,7 +34,7 @@ module Jaeger
35
34
  # a String, Numeric, or Boolean it will be encoded with to_s
36
35
  def set_tag(key, value)
37
36
  if key == 'sampling.priority'
38
- if value.to_i > 0
37
+ if value.to_i.positive?
39
38
  return self if @context.debug?
40
39
 
41
40
  @context.flags = @context.flags | SpanContext::Flags::SAMPLED | SpanContext::Flags::DEBUG
@@ -72,9 +71,9 @@ module Jaeger
72
71
  # Add a log entry to this span
73
72
  #
74
73
  # @deprecated Use {#log_kv} instead.
75
- def log(*args)
74
+ def log(...)
76
75
  warn 'Span#log is deprecated. Please use Span#log_kv instead.'
77
- log_kv(*args)
76
+ log_kv(...)
78
77
  end
79
78
 
80
79
  # Add a log entry to this span
@@ -19,10 +19,10 @@ module Jaeger
19
19
  )
20
20
  end
21
21
 
22
- attr_reader :span_id, :parent_id, :trace_id, :baggage, :flags
23
- attr_writer :flags
22
+ attr_accessor :flags
23
+ attr_reader :span_id, :parent_id, :trace_id, :baggage
24
24
 
25
- def initialize(span_id:, parent_id: 0, trace_id:, flags:, baggage: {})
25
+ def initialize(span_id:, trace_id:, flags:, parent_id: 0, baggage: {})
26
26
  @span_id = span_id
27
27
  @parent_id = parent_id
28
28
  @trace_id = trace_id