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.
- checksums.yaml +4 -4
- data/README.md +14 -16
- data/crossdock/server +1 -1
- data/lib/jaeger/client.rb +25 -15
- data/lib/jaeger/client/version.rb +1 -1
- data/lib/jaeger/encoders/thrift_encoder.rb +92 -0
- data/lib/jaeger/extractors.rb +109 -0
- data/lib/jaeger/http_sender.rb +28 -0
- data/lib/jaeger/injectors.rb +69 -0
- data/lib/jaeger/rate_limiter.rb +61 -0
- data/lib/jaeger/{client/reporters.rb → reporters.rb} +0 -0
- data/lib/jaeger/reporters/composite_reporter.rb +17 -0
- data/lib/jaeger/reporters/in_memory_reporter.rb +30 -0
- data/lib/jaeger/reporters/logging_reporter.rb +22 -0
- data/lib/jaeger/reporters/null_reporter.rb +11 -0
- data/lib/jaeger/reporters/remote_reporter.rb +42 -0
- data/lib/jaeger/reporters/remote_reporter/buffer.rb +29 -0
- data/lib/jaeger/{client/samplers.rb → samplers.rb} +0 -0
- data/lib/jaeger/samplers/const.rb +24 -0
- data/lib/jaeger/samplers/guaranteed_throughput_probabilistic.rb +40 -0
- data/lib/jaeger/samplers/per_operation.rb +47 -0
- data/lib/jaeger/samplers/probabilistic.rb +26 -0
- data/lib/jaeger/samplers/rate_limiting.rb +33 -0
- data/lib/jaeger/scope.rb +38 -0
- data/lib/jaeger/scope_manager.rb +47 -0
- data/lib/jaeger/scope_manager/scope_identifier.rb +13 -0
- data/lib/jaeger/scope_manager/scope_stack.rb +33 -0
- data/lib/jaeger/span.rb +98 -0
- data/lib/jaeger/span/thrift_log_builder.rb +18 -0
- data/lib/jaeger/span/thrift_tag_builder.rb +43 -0
- data/lib/jaeger/span_context.rb +57 -0
- data/lib/jaeger/trace_id.rb +39 -0
- data/lib/jaeger/tracer.rb +195 -0
- data/lib/jaeger/udp_sender.rb +24 -0
- data/lib/jaeger/udp_sender/transport.rb +40 -0
- metadata +31 -32
- data/lib/jaeger/client/carrier.rb +0 -26
- data/lib/jaeger/client/encoders/thrift_encoder.rb +0 -94
- data/lib/jaeger/client/extractors.rb +0 -111
- data/lib/jaeger/client/http_sender.rb +0 -30
- data/lib/jaeger/client/injectors.rb +0 -71
- data/lib/jaeger/client/rate_limiter.rb +0 -63
- data/lib/jaeger/client/reporters/composite_reporter.rb +0 -19
- data/lib/jaeger/client/reporters/in_memory_reporter.rb +0 -32
- data/lib/jaeger/client/reporters/logging_reporter.rb +0 -24
- data/lib/jaeger/client/reporters/null_reporter.rb +0 -13
- data/lib/jaeger/client/reporters/remote_reporter.rb +0 -44
- data/lib/jaeger/client/reporters/remote_reporter/buffer.rb +0 -31
- data/lib/jaeger/client/samplers/const.rb +0 -26
- data/lib/jaeger/client/samplers/guaranteed_throughput_probabilistic.rb +0 -42
- data/lib/jaeger/client/samplers/per_operation.rb +0 -49
- data/lib/jaeger/client/samplers/probabilistic.rb +0 -28
- data/lib/jaeger/client/samplers/rate_limiting.rb +0 -35
- data/lib/jaeger/client/scope.rb +0 -40
- data/lib/jaeger/client/scope_manager.rb +0 -49
- data/lib/jaeger/client/scope_manager/scope_identifier.rb +0 -15
- data/lib/jaeger/client/scope_manager/scope_stack.rb +0 -35
- data/lib/jaeger/client/span.rb +0 -100
- data/lib/jaeger/client/span/thrift_log_builder.rb +0 -20
- data/lib/jaeger/client/span/thrift_tag_builder.rb +0 -45
- data/lib/jaeger/client/span_context.rb +0 -59
- data/lib/jaeger/client/trace_id.rb +0 -41
- data/lib/jaeger/client/tracer.rb +0 -197
- data/lib/jaeger/client/udp_sender.rb +0 -27
- 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,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
|
data/lib/jaeger/client/scope.rb
DELETED
@@ -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
|