jaeger-client 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46d05119eb9543907c6e1182a80346da57b634623425a4eeb74e06d637b73799
4
- data.tar.gz: 171cdd21fd1872db8d1adef226e901dffd595ed7eab76f8c99f902363b638f9d
3
+ metadata.gz: c9af8a3a945af29ffe9f0045a2eff121fa519c689d04a680a41c7346a198cbf6
4
+ data.tar.gz: aad37d03df89f03707f91d3fd2f58b0af5b84122736b24f35edff791bb5f0b7a
5
5
  SHA512:
6
- metadata.gz: 756a18ecf9e931670df3a9058613a5af99a2391eceabfc7c7fdeea5a1371c12757f818fd71e8616d96aa3a544dc0a0cb7728d22b9f4ae7dfb62863f7f37f1c4e
7
- data.tar.gz: e89a5e9ff633cca38e030b31cd7a9df68bfa7bcbebfbd5f68ad61a663d04ade3c517465e2b8fcc707afe80696d2aad330ac51caf14a32551788b08322cd4ee4b
6
+ metadata.gz: 975e4605ee85e4e1b34b763233c16fe6ec3ec0ad88a01f8d1239b523e97bc8fde5844a2ca0d152c71a3b7f601be6237fd70303f31229cb995d896958180aaef7
7
+ data.tar.gz: 490214bc62f0a922e869b24ccbf5510538fa84365d50aafa1e892fe498aaa79e7bcb7d47da97445db8e07c4ebfb2481ecc6cb6aaeac7f81224e5a1ec90eb4616
data/README.md CHANGED
@@ -28,18 +28,56 @@ OpenTracing.start_active_span('span name') do
28
28
  end
29
29
  ```
30
30
 
31
- The tracer can also take an externally configured sender. For example, the `HttpSender` can be configured with a different endpoint and headers for authentication.
31
+ See [opentracing-ruby](https://github.com/opentracing/opentracing-ruby) for more examples.
32
+
33
+ ### Reporters
34
+
35
+ #### RemoteReporter (default)
36
+
37
+ RemoteReporter buffers spans in memory and sends them out of process using Sender.
38
+
39
+ There are two senders: `UdpSender` (default) and `HttpSender`.
40
+
41
+ To use `HttpSender`:
42
+
32
43
  ```ruby
33
- require 'jaeger/client'
34
- require 'jaeger/client/http_sender'
44
+ OpenTracing.global_tracer = Jaeger::Client.build(
45
+ service_name: 'service_name',
46
+ reporter: Jaeger::Client::Reporter::RemoteReporter.new(
47
+ sender: Jaeger::Client::HttpSender.new(
48
+ url: 'http://localhost:14268/api/traces',
49
+ headers: { 'key' => 'value' }, # headers key is optional
50
+ encoder: Jaeger::Client::Encoders::ThriftEncoder.new(service_name: 'service_name')
51
+ ),
52
+ flush_interval: 10
53
+ )
54
+ )
55
+ ```
56
+
57
+ #### NullReporter
35
58
 
36
- headers = { "auth_token" => token }
37
- encoder = Jaeger::Client::Encoders::ThriftEncoder.new(service_name: "service_name")
38
- sender = Jaeger::Client::HttpSender.new(url: "http://localhost:14268/api/traces", headers: headers, encoder: encoder)
59
+ NullReporter ignores all spans.
39
60
 
40
- OpenTracing.global_tracer = Jaeger::Client.build(service_name: "service_name", sender: sender)
61
+ ```ruby
62
+ OpenTracing.global_tracer = Jaeger::Client.build(
63
+ service_name: 'service_name',
64
+ reporter: Jaeger::Client::Reporter::NullReporter.new
65
+ )
41
66
  ```
42
67
 
68
+ #### LoggingReporter
69
+
70
+ LoggingReporter prints some details about the span using `logger`. This is meant only for debugging. Do not parse and use this information for anything critical. The implemenation can change at any time.
71
+
72
+ ```ruby
73
+ OpenTracing.global_tracer = Jaeger::Client.build(
74
+ service_name: 'service_name',
75
+ reporter: Jaeger::Client::Reporter::LoggingReporter.new
76
+ )
77
+ ```
78
+
79
+ LoggingReporter can also use a custom logger. For this provide logger using `logger` keyword argument.
80
+
43
81
  See [opentracing-ruby](https://github.com/opentracing/opentracing-ruby) for more examples.
44
82
 
45
83
  ### Samplers
@@ -52,6 +90,37 @@ See [opentracing-ruby](https://github.com/opentracing/opentracing-ruby) for more
52
90
 
53
91
  `Probabilistic` sampler samples traces with probability equal to `rate` (must be between 0.0 and 1.0). This can be enabled by setting `Jaeger::Client::Samplers::Probabilistic.new(rate: 0.1)`
54
92
 
93
+ #### RateLimiting sampler
94
+
95
+ `RateLimiting` sampler samples at most `max_traces_per_second`. The distribution of sampled traces follows burstiness of the service, i.e. a service with uniformly distributed requests will have those requests sampled uniformly as well, but if requests are bursty, especially sub-second, then a number of sequential requests can be sampled each second.
96
+
97
+ Set `sampler` to `Jaeger::Client::Samplers::RateLimiting.new(max_traces_per_second: 100)`
98
+
99
+ #### GuaranteedThroughputProbabilistic sampler
100
+
101
+ `GuaranteedThroughputProbabilistic` is a sampler that guarantees a throughput by using a Probabilistic sampler and RateLimiting sampler The RateLimiting sampler is used to establish a lower_bound so that every operation is sampled at least once in the time interval defined by the lower_bound.
102
+
103
+ Set `sampler` to `Jaeger::Client::Samplers::GuaranteedThroughputProbabilistic.new(lower_bound: 10, rate: 0.001)`
104
+
105
+ #### PerOperation sampler
106
+
107
+ `PerOperation` sampler leverages both Probabilistic sampler and RateLimiting sampler via the GuaranteedThroughputProbabilistic sampler. This sampler keeps track of all operations and delegates calls the the respective GuaranteedThroughputProbabilistic sampler.
108
+
109
+ Set `sampler` to
110
+ ```
111
+ Jaeger::Client::Samplers::PerOperation.new(
112
+ strategies: {
113
+ per_operation_strategies: [
114
+ { operation: 'GET /articles', probabilistic_sampling: 0.5 },
115
+ { operation: 'POST /articles', probabilistic_sampling: 1.0 }
116
+ ],
117
+ default_sampling_probability: 0.001,
118
+ default_lower_bound_traces_per_second: 1.0 / (10.0 * 60.0)
119
+ },
120
+ max_operations: 1000
121
+ )
122
+ ```
123
+
55
124
  ### Zipkin HTTP B3 compatible header propagation
56
125
 
57
126
  Jaeger Tracer supports Zipkin B3 Propagation HTTP headers, which are used by a lot of Zipkin tracers. This means that you can use Jaeger in conjunction with OpenZipkin tracers.
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = 'OpenTracing Tracer implementation for Jaeger in Ruby'
13
13
  spec.description = ''
14
- spec.homepage = ''
14
+ spec.homepage = 'https://github.com/salemove/jaeger-client-ruby'
15
15
  spec.license = 'MIT'
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency 'rspec', '~> 3.0'
26
26
  spec.add_development_dependency 'rubocop', '~> 0.54.0'
27
27
  spec.add_development_dependency 'rubocop-rspec', '~> 1.24.0'
28
+ spec.add_development_dependency 'timecop', '~> 0.9'
28
29
 
29
30
  spec.add_dependency 'opentracing', '~> 0.3'
30
31
  spec.add_dependency 'thrift'
@@ -14,12 +14,14 @@ require_relative 'client/scope_manager'
14
14
  require_relative 'client/carrier'
15
15
  require_relative 'client/trace_id'
16
16
  require_relative 'client/udp_sender'
17
- require_relative 'client/async_reporter'
17
+ require_relative 'client/http_sender'
18
+ require_relative 'client/reporters'
18
19
  require_relative 'client/version'
19
20
  require_relative 'client/samplers'
20
21
  require_relative 'client/encoders/thrift_encoder'
21
22
  require_relative 'client/injectors'
22
23
  require_relative 'client/extractors'
24
+ require_relative 'client/rate_limiter'
23
25
 
24
26
  module Jaeger
25
27
  module Client
@@ -32,15 +34,20 @@ module Jaeger
32
34
  sampler: Samplers::Const.new(true),
33
35
  logger: Logger.new(STDOUT),
34
36
  sender: nil,
37
+ reporter: nil,
35
38
  injectors: {},
36
39
  extractors: {})
37
40
  encoder = Encoders::ThriftEncoder.new(service_name: service_name)
38
41
 
39
- if sender.nil?
40
- sender = UdpSender.new(host: host, port: port, encoder: encoder, logger: logger)
42
+ if sender
43
+ warn '[DEPRECATION] Passing `sender` directly to Jaeger::Client.build is deprecated.' \
44
+ 'Please use `reporter` instead.'
41
45
  end
42
46
 
43
- reporter = AsyncReporter.create(sender: sender, flush_interval: flush_interval)
47
+ reporter ||= Reporters::RemoteReporter.new(
48
+ sender: sender || UdpSender.new(host: host, port: port, encoder: encoder, logger: logger),
49
+ flush_interval: flush_interval
50
+ )
44
51
 
45
52
  Tracer.new(
46
53
  reporter: reporter,
@@ -49,7 +49,7 @@ module Jaeger
49
49
  baggage_match = key.match(/\AHTTP_UBERCTX_(\w+)\Z/)
50
50
  if baggage_match
51
51
  key = baggage_match[1].downcase.tr('_', '-')
52
- context.set_baggage_item(key, value)
52
+ context.set_baggage_item(key, CGI.unescape(value))
53
53
  end
54
54
  end
55
55
 
@@ -26,7 +26,7 @@ module Jaeger
26
26
  carrier['uber-trace-id'] =
27
27
  CGI.escape(Injectors.context_as_jaeger_string(span_context))
28
28
  span_context.baggage.each do |key, value|
29
- carrier["uberctx-#{key}"] = value
29
+ carrier["uberctx-#{key}"] = CGI.escape(value)
30
30
  end
31
31
  end
32
32
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ # RateLimiter is based on leaky bucket algorithm, formulated in terms of a
6
+ # credits balance that is replenished every time check_credit() method is
7
+ # called (tick) by the amount proportional to the time elapsed since the
8
+ # last tick, up to the max_balance. A call to check_credit() takes a cost
9
+ # of an item we want to pay with the balance. If the balance exceeds the
10
+ # cost of the item, the item is "purchased" and the balance reduced,
11
+ # indicated by returned value of true. Otherwise the balance is unchanged
12
+ # and return false.
13
+ #
14
+ # This can be used to limit a rate of messages emitted by a service by
15
+ # instantiating the Rate Limiter with the max number of messages a service
16
+ # is allowed to emit per second, and calling check_credit(1.0) for each
17
+ # message to determine if the message is within the rate limit.
18
+ #
19
+ # It can also be used to limit the rate of traffic in bytes, by setting
20
+ # credits_per_second to desired throughput as bytes/second, and calling
21
+ # check_credit() with the actual message size.
22
+ class RateLimiter
23
+ def initialize(credits_per_second:, max_balance:)
24
+ @credits_per_second = credits_per_second
25
+ @max_balance = max_balance
26
+ @balance = max_balance
27
+ @last_tick = Time.now
28
+ end
29
+
30
+ def check_credit(item_cost)
31
+ update_balance
32
+
33
+ return false if @balance < item_cost
34
+
35
+ @balance -= item_cost
36
+ true
37
+ end
38
+
39
+ def update(credits_per_second:, max_balance:)
40
+ update_balance
41
+
42
+ @credits_per_second = credits_per_second
43
+
44
+ # The new balance should be proportional to the old balance
45
+ @balance = max_balance * @balance / @max_balance
46
+ @max_balance = max_balance
47
+ end
48
+
49
+ private
50
+
51
+ def update_balance
52
+ current_time = Time.now
53
+ elapsed_time = current_time - @last_tick
54
+ @last_tick = current_time
55
+
56
+ @balance += elapsed_time * @credits_per_second
57
+ return if @balance <= @max_balance
58
+
59
+ @balance = @max_balance
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'reporters/composite_reporter'
4
+ require_relative 'reporters/in_memory_reporter'
5
+ require_relative 'reporters/logging_reporter'
6
+ require_relative 'reporters/null_reporter'
7
+ require_relative 'reporters/remote_reporter'
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ module Reporters
6
+ class CompositeReporter
7
+ def initialize(reporters:)
8
+ @reporters = reporters
9
+ end
10
+
11
+ def report(span)
12
+ @reporters.each do |reporter|
13
+ reporter.report(span)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,25 +2,28 @@
2
2
 
3
3
  module Jaeger
4
4
  module Client
5
- class AsyncReporter
6
- class Buffer
5
+ module Reporters
6
+ class InMemoryReporter
7
7
  def initialize
8
- @buffer = []
8
+ @spans = []
9
9
  @mutex = Mutex.new
10
10
  end
11
11
 
12
- def <<(element)
12
+ def report(span)
13
13
  @mutex.synchronize do
14
- @buffer << element
15
- true
14
+ @spans << span
16
15
  end
17
16
  end
18
17
 
19
- def retrieve
18
+ def spans
20
19
  @mutex.synchronize do
21
- elements = @buffer.dup
22
- @buffer.clear
23
- elements
20
+ @spans
21
+ end
22
+ end
23
+
24
+ def clear
25
+ @mutex.synchronize do
26
+ @spans.clear
24
27
  end
25
28
  end
26
29
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ module Reporters
6
+ class LoggingReporter
7
+ def initialize(logger: Logger.new($stdout))
8
+ @logger = logger
9
+ end
10
+
11
+ def report(span)
12
+ span_info = {
13
+ operation_name: span.operation_name,
14
+ start_time: span.start_time.iso8601,
15
+ end_time: span.end_time.iso8601,
16
+ trace_id: span.context.to_trace_id,
17
+ span_id: span.context.to_span_id
18
+ }
19
+ @logger.info "Span reported: #{span_info}"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ module Reporters
6
+ class NullReporter
7
+ def report(_span)
8
+ # no-op
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './remote_reporter/buffer'
4
+
5
+ module Jaeger
6
+ module Client
7
+ module Reporters
8
+ class RemoteReporter
9
+ def initialize(sender:, flush_interval:)
10
+ @sender = sender
11
+ @flush_interval = flush_interval
12
+ @buffer = Buffer.new
13
+ end
14
+
15
+ def flush
16
+ spans = @buffer.retrieve
17
+ @sender.send_spans(spans) if spans.any?
18
+ spans
19
+ end
20
+
21
+ def report(span)
22
+ return if !span.context.sampled? && !span.context.debug?
23
+
24
+ init_reporter_thread
25
+ @buffer << span
26
+ end
27
+
28
+ private
29
+
30
+ def init_reporter_thread
31
+ return if @initializer_pid == Process.pid
32
+
33
+ @initializer_pid = Process.pid
34
+ Thread.new do
35
+ loop do
36
+ flush
37
+ sleep(@flush_interval)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ module Reporters
6
+ class RemoteReporter
7
+ class Buffer
8
+ def initialize
9
+ @buffer = []
10
+ @mutex = Mutex.new
11
+ end
12
+
13
+ def <<(element)
14
+ @mutex.synchronize do
15
+ @buffer << element
16
+ true
17
+ end
18
+ end
19
+
20
+ def retrieve
21
+ @mutex.synchronize do
22
+ elements = @buffer.dup
23
+ @buffer.clear
24
+ elements
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,4 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'samplers/const'
4
+ require_relative 'samplers/guaranteed_throughput_probabilistic'
5
+ require_relative 'samplers/per_operation'
4
6
  require_relative 'samplers/probabilistic'
7
+ require_relative 'samplers/rate_limiting'
@@ -11,18 +11,15 @@ module Jaeger
11
11
  class Const
12
12
  def initialize(decision)
13
13
  @decision = decision
14
- @param = decision ? '1' : '0'
14
+ @tags = {
15
+ 'sampler.type' => 'const',
16
+ 'sampler.param' => @decision ? 1 : 0
17
+ }
15
18
  end
16
19
 
17
20
  def sample?(*)
18
- @decision
21
+ [@decision, @tags]
19
22
  end
20
-
21
- def type
22
- 'const'
23
- end
24
-
25
- attr_reader :param
26
23
  end
27
24
  end
28
25
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ module Samplers
6
+ # A sampler that leverages both Probabilistic sampler and RateLimiting
7
+ # sampler. The RateLimiting is used as a guaranteed lower bound sampler
8
+ # such that every operation is sampled at least once in a time interval
9
+ # defined by the lower_bound. ie a lower_bound of 1.0 / (60 * 10) will
10
+ # sample an operation at least once every 10 minutes.
11
+ #
12
+ # The Probabilistic sampler is given higher priority when tags are
13
+ # emitted, ie. if is_sampled() for both samplers return true, the tags
14
+ # for Probabilistic sampler will be used.
15
+ class GuaranteedThroughputProbabilistic
16
+ attr_reader :tags
17
+
18
+ def initialize(lower_bound:, rate:, lower_bound_sampler: nil)
19
+ @probabilistic_sampler = Probabilistic.new(rate: rate)
20
+ @lower_bound_sampler = lower_bound_sampler || RateLimiting.new(max_traces_per_second: lower_bound)
21
+ @lower_bound_tags = {
22
+ 'sampler.type' => 'lowerbound',
23
+ 'sampler.param' => lower_bound
24
+ }
25
+ end
26
+
27
+ def sample?(*args)
28
+ is_sampled, probabilistic_tags = @probabilistic_sampler.sample?(*args)
29
+ if is_sampled
30
+ # We still call lower_bound_sampler to update the rate limiter budget
31
+ @lower_bound_sampler.sample?(*args)
32
+
33
+ return [is_sampled, probabilistic_tags]
34
+ end
35
+
36
+ is_sampled, _tags = @lower_bound_sampler.sample?(*args)
37
+ [is_sampled, @lower_bound_tags]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ module Samplers
6
+ # A sampler that leverages both Probabilistic sampler and RateLimiting
7
+ # sampler via the GuaranteedThroughputProbabilistic sampler. This sampler
8
+ # keeps track of all operations and delegates calls the the respective
9
+ # GuaranteedThroughputProbabilistic sampler.
10
+ class PerOperation
11
+ DEFAULT_SAMPLING_PROBABILITY = 0.001
12
+ DEFAULT_LOWER_BOUND = 1.0 / (10.0 * 60.0) # sample once every 10 minutes'
13
+
14
+ def initialize(strategies:, max_operations:)
15
+ @max_operations = max_operations
16
+ @default_sampling_probability =
17
+ strategies[:default_sampling_probability] || DEFAULT_SAMPLING_PROBABILITY
18
+ @lower_bound = strategies[:default_lower_bound_traces_per_second] || DEFAULT_LOWER_BOUND
19
+
20
+ @default_sampler = Probabilistic.new(rate: @default_sampling_probability)
21
+ @samplers = (strategies[:per_operation_strategies] || []).reduce({}) do |acc, strategy|
22
+ operation = strategy.fetch(:operation)
23
+ rate = strategy.fetch(:probabilistic_sampling)
24
+ sampler = GuaranteedThroughputProbabilistic.new(
25
+ lower_bound: @lower_bound,
26
+ rate: rate
27
+ )
28
+ acc.merge(operation => sampler)
29
+ end
30
+ end
31
+
32
+ def sample?(opts)
33
+ operation_name = opts.fetch(:operation_name)
34
+ sampler = @samplers[operation_name]
35
+ return sampler.sample?(opts) if sampler
36
+
37
+ return @default_sampler.sample?(opts) if @samplers.length >= @max_operations
38
+
39
+ sampler = GuaranteedThroughputProbabilistic.new(
40
+ lower_bound: @lower_bound,
41
+ rate: @default_sampling_probability
42
+ )
43
+ @samplers[operation_name] = sampler
44
+ sampler.sample?(opts)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -8,22 +8,20 @@ module Jaeger
8
8
  # Sample a portion of traces using trace_id as the random decision
9
9
  class Probabilistic
10
10
  def initialize(rate: 0.001)
11
- @param = rate.to_s
12
11
  if rate < 0.0 || rate > 1.0
13
12
  raise "Sampling rate must be between 0.0 and 1.0, got #{rate.inspect}"
14
13
  end
15
- @boundary = TraceId::TRACE_ID_UPPER_BOUND * rate
16
- end
17
14
 
18
- def sample?(trace_id)
19
- @boundary >= trace_id
15
+ @boundary = TraceId::TRACE_ID_UPPER_BOUND * rate
16
+ @tags = {
17
+ 'sampler.type' => 'probabilistic',
18
+ 'sampler.param' => rate
19
+ }
20
20
  end
21
21
 
22
- def type
23
- 'probabilistic'
22
+ def sample?(trace_id:, **)
23
+ [@boundary >= trace_id, @tags]
24
24
  end
25
-
26
- attr_reader :param
27
25
  end
28
26
  end
29
27
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Client
5
+ module Samplers
6
+ # Samples at most max_traces_per_second. The distribution of sampled
7
+ # traces follows burstiness of the service, i.e. a service with uniformly
8
+ # distributed requests will have those requests sampled uniformly as
9
+ # well, but if requests are bursty, especially sub-second, then a number
10
+ # of sequential requests can be sampled each second.
11
+ class RateLimiting
12
+ attr_reader :tags
13
+
14
+ def initialize(max_traces_per_second: 10)
15
+ if max_traces_per_second < 0.0
16
+ raise "max_traces_per_second must not be negative, got #{max_traces_per_second}"
17
+ end
18
+
19
+ @rate_limiter = RateLimiter.new(
20
+ credits_per_second: max_traces_per_second,
21
+ max_balance: [max_traces_per_second, 1.0].max
22
+ )
23
+ @tags = {
24
+ 'sampler.type' => 'ratelimiting',
25
+ 'sampler.param' => max_traces_per_second
26
+ }
27
+ end
28
+
29
+ def sample?(*)
30
+ [@rate_limiter.check_credit(1.0), @tags]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -10,13 +10,6 @@ module Jaeger
10
10
  DEBUG = 0x02
11
11
  end
12
12
 
13
- def self.create_parent_context(sampler = Samplers::Const.new(true))
14
- trace_id = TraceId.generate
15
- span_id = TraceId.generate
16
- flags = sampler.sample?(trace_id) ? Flags::SAMPLED : Flags::NONE
17
- new(trace_id: trace_id, span_id: span_id, flags: flags)
18
- end
19
-
20
13
  def self.create_from_parent_context(span_context)
21
14
  new(
22
15
  trace_id: span_context.trace_id,
@@ -50,7 +50,8 @@ module Jaeger
50
50
  tags: {},
51
51
  ignore_active_scope: false,
52
52
  **)
53
- context = prepare_span_context(
53
+ context, sampler_tags = prepare_span_context(
54
+ operation_name: operation_name,
54
55
  child_of: child_of,
55
56
  references: references,
56
57
  ignore_active_scope: ignore_active_scope
@@ -61,10 +62,7 @@ module Jaeger
61
62
  @reporter,
62
63
  start_time: start_time,
63
64
  references: references,
64
- tags: tags.merge(
65
- :'sampler.type' => @sampler.type,
66
- :'sampler.param' => @sampler.param
67
- )
65
+ tags: tags.merge(sampler_tags)
68
66
  )
69
67
  end
70
68
 
@@ -150,16 +148,26 @@ module Jaeger
150
148
 
151
149
  private
152
150
 
153
- def prepare_span_context(child_of:, references:, ignore_active_scope:)
151
+ def prepare_span_context(operation_name:, child_of:, references:, ignore_active_scope:)
154
152
  context =
155
153
  context_from_child_of(child_of) ||
156
154
  context_from_references(references) ||
157
155
  context_from_active_scope(ignore_active_scope)
158
156
 
159
157
  if context
160
- SpanContext.create_from_parent_context(context)
158
+ [SpanContext.create_from_parent_context(context), {}]
161
159
  else
162
- SpanContext.create_parent_context(@sampler)
160
+ trace_id = TraceId.generate
161
+ is_sampled, tags = @sampler.sample?(
162
+ trace_id: trace_id,
163
+ operation_name: operation_name
164
+ )
165
+ span_context = SpanContext.new(
166
+ trace_id: trace_id,
167
+ span_id: trace_id,
168
+ flags: is_sampled ? SpanContext::Flags::SAMPLED : SpanContext::Flags::NONE
169
+ )
170
+ [span_context, tags]
163
171
  end
164
172
  end
165
173
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jaeger
4
4
  module Client
5
- VERSION = '0.8.0'.freeze
5
+ VERSION = '0.9.0'.freeze
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jaeger-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SaleMove TechMovers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-21 00:00:00.000000000 Z
11
+ date: 2018-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.24.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: timecop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.9'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.9'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: opentracing
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -136,16 +150,25 @@ files:
136
150
  - crossdock/server
137
151
  - jaeger-client.gemspec
138
152
  - lib/jaeger/client.rb
139
- - lib/jaeger/client/async_reporter.rb
140
- - lib/jaeger/client/async_reporter/buffer.rb
141
153
  - lib/jaeger/client/carrier.rb
142
154
  - lib/jaeger/client/encoders/thrift_encoder.rb
143
155
  - lib/jaeger/client/extractors.rb
144
156
  - lib/jaeger/client/http_sender.rb
145
157
  - lib/jaeger/client/injectors.rb
158
+ - lib/jaeger/client/rate_limiter.rb
159
+ - lib/jaeger/client/reporters.rb
160
+ - lib/jaeger/client/reporters/composite_reporter.rb
161
+ - lib/jaeger/client/reporters/in_memory_reporter.rb
162
+ - lib/jaeger/client/reporters/logging_reporter.rb
163
+ - lib/jaeger/client/reporters/null_reporter.rb
164
+ - lib/jaeger/client/reporters/remote_reporter.rb
165
+ - lib/jaeger/client/reporters/remote_reporter/buffer.rb
146
166
  - lib/jaeger/client/samplers.rb
147
167
  - lib/jaeger/client/samplers/const.rb
168
+ - lib/jaeger/client/samplers/guaranteed_throughput_probabilistic.rb
169
+ - lib/jaeger/client/samplers/per_operation.rb
148
170
  - lib/jaeger/client/samplers/probabilistic.rb
171
+ - lib/jaeger/client/samplers/rate_limiting.rb
149
172
  - lib/jaeger/client/scope.rb
150
173
  - lib/jaeger/client/scope_manager.rb
151
174
  - lib/jaeger/client/scope_manager/scope_identifier.rb
@@ -176,7 +199,7 @@ files:
176
199
  - thrift/gen-rb/jaeger/thrift/zipkin/zipkincore_types.rb
177
200
  - thrift/jaeger.thrift
178
201
  - thrift/zipkincore.thrift
179
- homepage: ''
202
+ homepage: https://github.com/salemove/jaeger-client-ruby
180
203
  licenses:
181
204
  - MIT
182
205
  metadata: {}
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'thread'
4
-
5
- require_relative './async_reporter/buffer'
6
-
7
- module Jaeger
8
- module Client
9
- class AsyncReporter
10
- def self.create(sender:, flush_interval:)
11
- new(sender, flush_interval)
12
- end
13
-
14
- def initialize(sender, flush_interval)
15
- @sender = sender
16
- @flush_interval = flush_interval
17
- @buffer = Buffer.new
18
- end
19
-
20
- def flush
21
- spans = @buffer.retrieve
22
- @sender.send_spans(spans) if spans.any?
23
- spans
24
- end
25
-
26
- def report(span)
27
- return if !span.context.sampled? && !span.context.debug?
28
-
29
- init_reporter_thread
30
- @buffer << span
31
- end
32
-
33
- private
34
-
35
- def init_reporter_thread
36
- return if @initializer_pid == Process.pid
37
-
38
- @initializer_pid = Process.pid
39
- Thread.new do
40
- loop do
41
- flush
42
- sleep(@flush_interval)
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end