jaeger-client 0.9.0 → 0.10.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -16
  3. data/crossdock/server +1 -1
  4. data/lib/jaeger/client.rb +25 -15
  5. data/lib/jaeger/client/version.rb +1 -1
  6. data/lib/jaeger/encoders/thrift_encoder.rb +92 -0
  7. data/lib/jaeger/extractors.rb +109 -0
  8. data/lib/jaeger/http_sender.rb +28 -0
  9. data/lib/jaeger/injectors.rb +69 -0
  10. data/lib/jaeger/rate_limiter.rb +61 -0
  11. data/lib/jaeger/{client/reporters.rb → reporters.rb} +0 -0
  12. data/lib/jaeger/reporters/composite_reporter.rb +17 -0
  13. data/lib/jaeger/reporters/in_memory_reporter.rb +30 -0
  14. data/lib/jaeger/reporters/logging_reporter.rb +22 -0
  15. data/lib/jaeger/reporters/null_reporter.rb +11 -0
  16. data/lib/jaeger/reporters/remote_reporter.rb +42 -0
  17. data/lib/jaeger/reporters/remote_reporter/buffer.rb +29 -0
  18. data/lib/jaeger/{client/samplers.rb → samplers.rb} +0 -0
  19. data/lib/jaeger/samplers/const.rb +24 -0
  20. data/lib/jaeger/samplers/guaranteed_throughput_probabilistic.rb +40 -0
  21. data/lib/jaeger/samplers/per_operation.rb +47 -0
  22. data/lib/jaeger/samplers/probabilistic.rb +26 -0
  23. data/lib/jaeger/samplers/rate_limiting.rb +33 -0
  24. data/lib/jaeger/scope.rb +38 -0
  25. data/lib/jaeger/scope_manager.rb +47 -0
  26. data/lib/jaeger/scope_manager/scope_identifier.rb +13 -0
  27. data/lib/jaeger/scope_manager/scope_stack.rb +33 -0
  28. data/lib/jaeger/span.rb +98 -0
  29. data/lib/jaeger/span/thrift_log_builder.rb +18 -0
  30. data/lib/jaeger/span/thrift_tag_builder.rb +43 -0
  31. data/lib/jaeger/span_context.rb +57 -0
  32. data/lib/jaeger/trace_id.rb +39 -0
  33. data/lib/jaeger/tracer.rb +195 -0
  34. data/lib/jaeger/udp_sender.rb +24 -0
  35. data/lib/jaeger/udp_sender/transport.rb +40 -0
  36. metadata +31 -32
  37. data/lib/jaeger/client/carrier.rb +0 -26
  38. data/lib/jaeger/client/encoders/thrift_encoder.rb +0 -94
  39. data/lib/jaeger/client/extractors.rb +0 -111
  40. data/lib/jaeger/client/http_sender.rb +0 -30
  41. data/lib/jaeger/client/injectors.rb +0 -71
  42. data/lib/jaeger/client/rate_limiter.rb +0 -63
  43. data/lib/jaeger/client/reporters/composite_reporter.rb +0 -19
  44. data/lib/jaeger/client/reporters/in_memory_reporter.rb +0 -32
  45. data/lib/jaeger/client/reporters/logging_reporter.rb +0 -24
  46. data/lib/jaeger/client/reporters/null_reporter.rb +0 -13
  47. data/lib/jaeger/client/reporters/remote_reporter.rb +0 -44
  48. data/lib/jaeger/client/reporters/remote_reporter/buffer.rb +0 -31
  49. data/lib/jaeger/client/samplers/const.rb +0 -26
  50. data/lib/jaeger/client/samplers/guaranteed_throughput_probabilistic.rb +0 -42
  51. data/lib/jaeger/client/samplers/per_operation.rb +0 -49
  52. data/lib/jaeger/client/samplers/probabilistic.rb +0 -28
  53. data/lib/jaeger/client/samplers/rate_limiting.rb +0 -35
  54. data/lib/jaeger/client/scope.rb +0 -40
  55. data/lib/jaeger/client/scope_manager.rb +0 -49
  56. data/lib/jaeger/client/scope_manager/scope_identifier.rb +0 -15
  57. data/lib/jaeger/client/scope_manager/scope_stack.rb +0 -35
  58. data/lib/jaeger/client/span.rb +0 -100
  59. data/lib/jaeger/client/span/thrift_log_builder.rb +0 -20
  60. data/lib/jaeger/client/span/thrift_tag_builder.rb +0 -45
  61. data/lib/jaeger/client/span_context.rb +0 -59
  62. data/lib/jaeger/client/trace_id.rb +0 -41
  63. data/lib/jaeger/client/tracer.rb +0 -197
  64. data/lib/jaeger/client/udp_sender.rb +0 -27
  65. data/lib/jaeger/client/udp_sender/transport.rb +0 -42
@@ -1,63 +0,0 @@
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
@@ -1,19 +0,0 @@
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
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- module Reporters
6
- class InMemoryReporter
7
- def initialize
8
- @spans = []
9
- @mutex = Mutex.new
10
- end
11
-
12
- def report(span)
13
- @mutex.synchronize do
14
- @spans << span
15
- end
16
- end
17
-
18
- def spans
19
- @mutex.synchronize do
20
- @spans
21
- end
22
- end
23
-
24
- def clear
25
- @mutex.synchronize do
26
- @spans.clear
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,24 +0,0 @@
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
@@ -1,13 +0,0 @@
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
@@ -1,44 +0,0 @@
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
@@ -1,31 +0,0 @@
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,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- module Samplers
6
- # Const sampler
7
- #
8
- # A sampler that always makes the same decision for new traces depending
9
- # on the initialization value. Use `Jaeger::Client::Samplers::Const.new(true)`
10
- # to mark all new traces as sampled.
11
- class Const
12
- def initialize(decision)
13
- @decision = decision
14
- @tags = {
15
- 'sampler.type' => 'const',
16
- 'sampler.param' => @decision ? 1 : 0
17
- }
18
- end
19
-
20
- def sample?(*)
21
- [@decision, @tags]
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,42 +0,0 @@
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
@@ -1,49 +0,0 @@
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
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- module Samplers
6
- # Probabilistic sampler
7
- #
8
- # Sample a portion of traces using trace_id as the random decision
9
- class Probabilistic
10
- def initialize(rate: 0.001)
11
- if rate < 0.0 || rate > 1.0
12
- raise "Sampling rate must be between 0.0 and 1.0, got #{rate.inspect}"
13
- end
14
-
15
- @boundary = TraceId::TRACE_ID_UPPER_BOUND * rate
16
- @tags = {
17
- 'sampler.type' => 'probabilistic',
18
- 'sampler.param' => rate
19
- }
20
- end
21
-
22
- def sample?(trace_id:, **)
23
- [@boundary >= trace_id, @tags]
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,35 +0,0 @@
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
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- # Scope represents an OpenTracing Scope
6
- #
7
- # See http://www.opentracing.io for more information.
8
- class Scope
9
- def initialize(span, scope_stack, finish_on_close:)
10
- @span = span
11
- @scope_stack = scope_stack
12
- @finish_on_close = finish_on_close
13
- @closed = false
14
- end
15
-
16
- # Return the Span scoped by this Scope
17
- #
18
- # @return [Span]
19
- attr_reader :span
20
-
21
- # Close scope
22
- #
23
- # Mark the end of the active period for the current thread and Scope,
24
- # updating the ScopeManager#active in the process.
25
- def close
26
- raise "Tried to close already closed span: #{inspect}" if @closed
27
- @closed = true
28
-
29
- @span.finish if @finish_on_close
30
- removed_scope = @scope_stack.pop
31
-
32
- if removed_scope != self # rubocop:disable Style/GuardClause
33
- raise 'Removed non-active scope, ' \
34
- "removed: #{removed_scope.inspect}, "\
35
- "expected: #{inspect}"
36
- end
37
- end
38
- end
39
- end
40
- end