jaeger-client 0.7.1 → 1.1.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/.gitmodules +3 -0
- data/.rubocop.yml +3 -0
- data/.travis.yml +11 -2
- data/Makefile +1 -0
- data/README.md +127 -13
- data/crossdock/Dockerfile +29 -0
- data/crossdock/Gemfile +6 -0
- data/crossdock/Gemfile.lock +35 -0
- data/crossdock/docker-compose.yml +68 -0
- data/crossdock/jaeger-docker-compose.yml +48 -0
- data/crossdock/rules.mk +35 -0
- data/crossdock/server +173 -0
- data/jaeger-client.gemspec +4 -2
- data/lib/jaeger/client.rb +42 -18
- data/lib/jaeger/client/version.rb +1 -1
- data/lib/jaeger/encoders/thrift_encoder.rb +142 -0
- data/lib/jaeger/extractors.rb +173 -0
- data/lib/jaeger/http_sender.rb +28 -0
- data/lib/jaeger/injectors.rb +83 -0
- data/lib/jaeger/rate_limiter.rb +61 -0
- data/lib/jaeger/recurring_executor.rb +35 -0
- data/lib/jaeger/reporters.rb +7 -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/{client/async_reporter.rb → reporters/remote_reporter.rb} +21 -20
- data/lib/jaeger/{client/async_reporter → reporters/remote_reporter}/buffer.rb +2 -2
- data/lib/jaeger/samplers.rb +8 -0
- data/lib/jaeger/samplers/const.rb +24 -0
- data/lib/jaeger/samplers/guaranteed_throughput_probabilistic.rb +47 -0
- data/lib/jaeger/samplers/per_operation.rb +79 -0
- data/lib/jaeger/samplers/probabilistic.rb +38 -0
- data/lib/jaeger/samplers/rate_limiting.rb +51 -0
- data/lib/jaeger/samplers/remote_controlled.rb +119 -0
- data/lib/jaeger/samplers/remote_controlled/instructions_fetcher.rb +34 -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 +97 -0
- data/lib/jaeger/span/thrift_log_builder.rb +18 -0
- data/lib/jaeger/span_context.rb +57 -0
- data/lib/jaeger/thrift_tag_builder.rb +41 -0
- data/lib/jaeger/trace_id.rb +48 -0
- data/lib/jaeger/tracer.rb +213 -0
- data/lib/jaeger/udp_sender.rb +26 -0
- data/lib/jaeger/udp_sender/transport.rb +40 -0
- metadata +78 -31
- 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 -88
- data/lib/jaeger/client/http_sender.rb +0 -30
- data/lib/jaeger/client/injectors.rb +0 -54
- data/lib/jaeger/client/samplers.rb +0 -4
- data/lib/jaeger/client/samplers/const.rb +0 -29
- data/lib/jaeger/client/samplers/probabilistic.rb +0 -30
- 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 -84
- 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 -189
- data/lib/jaeger/client/udp_sender.rb +0 -27
- data/lib/jaeger/client/udp_sender/transport.rb +0 -42
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
module Jaeger
|
6
|
-
module Client
|
7
|
-
class HttpSender
|
8
|
-
def initialize(url:, headers: {}, encoder:, logger: Logger.new(STDOUT))
|
9
|
-
@encoder = encoder
|
10
|
-
@logger = logger
|
11
|
-
|
12
|
-
@uri = URI(url)
|
13
|
-
@uri.query = 'format=jaeger.thrift'
|
14
|
-
|
15
|
-
@transport = ::Thrift::HTTPClientTransport.new(@uri.to_s)
|
16
|
-
@transport.add_headers(headers)
|
17
|
-
|
18
|
-
@serializer = ::Thrift::Serializer.new
|
19
|
-
end
|
20
|
-
|
21
|
-
def send_spans(spans)
|
22
|
-
batch = @encoder.encode(spans)
|
23
|
-
@transport.write(@serializer.serialize(batch))
|
24
|
-
@transport.flush
|
25
|
-
rescue StandardError => error
|
26
|
-
@logger.error("Failure while sending a batch of spans: #{error}")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jaeger
|
4
|
-
module Client
|
5
|
-
module Injectors
|
6
|
-
class JaegerTextMapCodec
|
7
|
-
def self.inject(span_context, carrier)
|
8
|
-
carrier['uber-trace-id'] = [
|
9
|
-
span_context.trace_id.to_s(16),
|
10
|
-
span_context.span_id.to_s(16),
|
11
|
-
span_context.parent_id.to_s(16),
|
12
|
-
span_context.flags.to_s(16)
|
13
|
-
].join(':')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class JaegerBinaryCodec
|
18
|
-
def self.inject(_span_context, _carrier)
|
19
|
-
warn 'Jaeger::Client with binary format is not supported yet'
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class B3RackCodec
|
24
|
-
def self.inject(span_context, carrier)
|
25
|
-
carrier['x-b3-traceid'] = TraceId.to_hex(span_context.trace_id)
|
26
|
-
carrier['x-b3-spanid'] = TraceId.to_hex(span_context.span_id)
|
27
|
-
carrier['x-b3-parentspanid'] = TraceId.to_hex(span_context.parent_id)
|
28
|
-
|
29
|
-
# flags (for debug) and sampled headers are mutually exclusive
|
30
|
-
if span_context.flags == Jaeger::Client::SpanContext::Flags::DEBUG
|
31
|
-
carrier['x-b3-flags'] = '1'
|
32
|
-
else
|
33
|
-
carrier['x-b3-sampled'] = span_context.flags.to_s(16)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
DEFAULT_INJECTORS = {
|
39
|
-
OpenTracing::FORMAT_TEXT_MAP => JaegerTextMapCodec,
|
40
|
-
OpenTracing::FORMAT_BINARY => JaegerBinaryCodec,
|
41
|
-
OpenTracing::FORMAT_RACK => JaegerTextMapCodec
|
42
|
-
}.freeze
|
43
|
-
|
44
|
-
def self.prepare(extractors)
|
45
|
-
DEFAULT_INJECTORS.reduce(extractors) do |acc, (format, default)|
|
46
|
-
provided_extractors = Array(extractors[format])
|
47
|
-
provided_extractors += [default] if provided_extractors.empty?
|
48
|
-
|
49
|
-
acc.merge(format => provided_extractors)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,29 +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
|
-
@param = decision ? '1' : '0'
|
15
|
-
end
|
16
|
-
|
17
|
-
def sample?(*)
|
18
|
-
@decision
|
19
|
-
end
|
20
|
-
|
21
|
-
def type
|
22
|
-
'const'
|
23
|
-
end
|
24
|
-
|
25
|
-
attr_reader :param
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,30 +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
|
-
@param = rate.to_s
|
12
|
-
if rate < 0.0 || rate > 1.0
|
13
|
-
raise "Sampling rate must be between 0.0 and 1.0, got #{rate.inspect}"
|
14
|
-
end
|
15
|
-
@boundary = TraceId::TRACE_ID_UPPER_BOUND * rate
|
16
|
-
end
|
17
|
-
|
18
|
-
def sample?(trace_id)
|
19
|
-
@boundary >= trace_id
|
20
|
-
end
|
21
|
-
|
22
|
-
def type
|
23
|
-
'probabilistic'
|
24
|
-
end
|
25
|
-
|
26
|
-
attr_reader :param
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
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
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'scope_manager/scope_stack'
|
4
|
-
require_relative 'scope_manager/scope_identifier'
|
5
|
-
|
6
|
-
module Jaeger
|
7
|
-
module Client
|
8
|
-
# ScopeManager represents an OpenTracing ScopeManager
|
9
|
-
#
|
10
|
-
# See http://www.opentracing.io for more information.
|
11
|
-
#
|
12
|
-
# The ScopeManager interface abstracts both the activation of Span instances
|
13
|
-
# via ScopeManager#activate and access to an active Span/Scope via
|
14
|
-
# ScopeManager#active
|
15
|
-
#
|
16
|
-
class ScopeManager
|
17
|
-
def initialize
|
18
|
-
@scope_stack = ScopeStack.new
|
19
|
-
end
|
20
|
-
|
21
|
-
# Make a span instance active
|
22
|
-
#
|
23
|
-
# @param span [Span] the Span that should become active
|
24
|
-
# @param finish_on_close [Boolean] whether the Span should automatically be
|
25
|
-
# finished when Scope#close is called
|
26
|
-
# @return [Scope] instance to control the end of the active period for the
|
27
|
-
# Span. It is a programming error to neglect to call Scope#close on the
|
28
|
-
# returned instance.
|
29
|
-
def activate(span, finish_on_close: true)
|
30
|
-
return active if active && active.span == span
|
31
|
-
scope = Scope.new(span, @scope_stack, finish_on_close: finish_on_close)
|
32
|
-
@scope_stack.push(scope)
|
33
|
-
scope
|
34
|
-
end
|
35
|
-
|
36
|
-
# Return active scope
|
37
|
-
#
|
38
|
-
# If there is a non-null Scope, its wrapped Span becomes an implicit parent
|
39
|
-
# (as Reference#CHILD_OF) of any newly-created Span at
|
40
|
-
# Tracer#start_active_span or Tracer#start_span time.
|
41
|
-
#
|
42
|
-
# @return [Scope] the currently active Scope which can be used to access the
|
43
|
-
# currently active Span.
|
44
|
-
def active
|
45
|
-
@scope_stack.peek
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jaeger
|
4
|
-
module Client
|
5
|
-
class ScopeManager
|
6
|
-
# @api private
|
7
|
-
class ScopeIdentifier
|
8
|
-
def self.generate
|
9
|
-
# 65..90.chr are characters between A and Z
|
10
|
-
"opentracing_#{(0...8).map { rand(65..90).chr }.join}".to_sym
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jaeger
|
4
|
-
module Client
|
5
|
-
class ScopeManager
|
6
|
-
# @api private
|
7
|
-
class ScopeStack
|
8
|
-
def initialize
|
9
|
-
# Generate a random identifier to use as the Thread.current key. This is
|
10
|
-
# needed so that it would be possible to create multiple tracers in one
|
11
|
-
# thread (mostly useful for testing purposes)
|
12
|
-
@scope_identifier = ScopeIdentifier.generate
|
13
|
-
end
|
14
|
-
|
15
|
-
def push(scope)
|
16
|
-
store << scope
|
17
|
-
end
|
18
|
-
|
19
|
-
def pop
|
20
|
-
store.pop
|
21
|
-
end
|
22
|
-
|
23
|
-
def peek
|
24
|
-
store.last
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def store
|
30
|
-
Thread.current[@scope_identifier] ||= []
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/jaeger/client/span.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'span/thrift_tag_builder'
|
4
|
-
require_relative 'span/thrift_log_builder'
|
5
|
-
|
6
|
-
module Jaeger
|
7
|
-
module Client
|
8
|
-
class Span
|
9
|
-
attr_accessor :operation_name
|
10
|
-
|
11
|
-
attr_reader :context, :start_time, :end_time, :references, :tags, :logs
|
12
|
-
|
13
|
-
# Creates a new {Span}
|
14
|
-
#
|
15
|
-
# @param context [SpanContext] the context of the span
|
16
|
-
# @param operation_name [String] the operation name
|
17
|
-
# @param reporter [#report] span reporter
|
18
|
-
#
|
19
|
-
# @return [Span] a new Span
|
20
|
-
def initialize(context, operation_name, reporter, start_time: Time.now, references: [], tags: {})
|
21
|
-
@context = context
|
22
|
-
@operation_name = operation_name
|
23
|
-
@reporter = reporter
|
24
|
-
@start_time = start_time
|
25
|
-
@references = references
|
26
|
-
@tags = tags.map { |key, value| ThriftTagBuilder.build(key, value) }
|
27
|
-
@logs = []
|
28
|
-
end
|
29
|
-
|
30
|
-
# Set a tag value on this span
|
31
|
-
#
|
32
|
-
# @param key [String] the key of the tag
|
33
|
-
# @param value [String, Numeric, Boolean] the value of the tag. If it's not
|
34
|
-
# a String, Numeric, or Boolean it will be encoded with to_s
|
35
|
-
def set_tag(key, value)
|
36
|
-
# Using Thrift::Tag to avoid unnecessary memory allocations
|
37
|
-
@tags << ThriftTagBuilder.build(key, value)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Set a baggage item on the span
|
41
|
-
#
|
42
|
-
# @param key [String] the key of the baggage item
|
43
|
-
# @param value [String] the value of the baggage item
|
44
|
-
def set_baggage_item(key, value)
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
|
-
# Get a baggage item
|
49
|
-
#
|
50
|
-
# @param key [String] the key of the baggage item
|
51
|
-
#
|
52
|
-
# @return Value of the baggage item
|
53
|
-
def get_baggage_item(key)
|
54
|
-
nil
|
55
|
-
end
|
56
|
-
|
57
|
-
# Add a log entry to this span
|
58
|
-
#
|
59
|
-
# @deprecated Use {#log_kv} instead.
|
60
|
-
def log(*args)
|
61
|
-
warn 'Span#log is deprecated. Please use Span#log_kv instead.'
|
62
|
-
log_kv(*args)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Add a log entry to this span
|
66
|
-
#
|
67
|
-
# @param timestamp [Time] time of the log
|
68
|
-
# @param fields [Hash] Additional information to log
|
69
|
-
def log_kv(timestamp: Time.now, **fields)
|
70
|
-
# Using Thrift::Log to avoid unnecessary memory allocations
|
71
|
-
@logs << ThriftLogBuilder.build(timestamp, fields)
|
72
|
-
nil
|
73
|
-
end
|
74
|
-
|
75
|
-
# Finish the {Span}
|
76
|
-
#
|
77
|
-
# @param end_time [Time] custom end time, if not now
|
78
|
-
def finish(end_time: Time.now)
|
79
|
-
@end_time = end_time
|
80
|
-
@reporter.report(self)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jaeger
|
4
|
-
module Client
|
5
|
-
class Span
|
6
|
-
class ThriftLogBuilder
|
7
|
-
FIELDS = Jaeger::Thrift::Log::FIELDS
|
8
|
-
TIMESTAMP = FIELDS[Jaeger::Thrift::Log::TIMESTAMP].fetch(:name)
|
9
|
-
LOG_FIELDS = FIELDS[Jaeger::Thrift::Log::LOG_FIELDS].fetch(:name)
|
10
|
-
|
11
|
-
def self.build(timestamp, fields)
|
12
|
-
Jaeger::Thrift::Log.new(
|
13
|
-
TIMESTAMP => (timestamp.to_f * 1_000_000).to_i,
|
14
|
-
LOG_FIELDS => fields.map { |key, value| ThriftTagBuilder.build(key, value) }
|
15
|
-
)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jaeger
|
4
|
-
module Client
|
5
|
-
class Span
|
6
|
-
class ThriftTagBuilder
|
7
|
-
FIELDS = Jaeger::Thrift::Tag::FIELDS
|
8
|
-
KEY = FIELDS[Jaeger::Thrift::Tag::KEY].fetch(:name)
|
9
|
-
VTYPE = FIELDS[Jaeger::Thrift::Tag::VTYPE].fetch(:name)
|
10
|
-
VLONG = FIELDS[Jaeger::Thrift::Tag::VLONG].fetch(:name)
|
11
|
-
VDOUBLE = FIELDS[Jaeger::Thrift::Tag::VDOUBLE].fetch(:name)
|
12
|
-
VBOOL = FIELDS[Jaeger::Thrift::Tag::VBOOL].fetch(:name)
|
13
|
-
VSTR = FIELDS[Jaeger::Thrift::Tag::VSTR].fetch(:name)
|
14
|
-
|
15
|
-
def self.build(key, value)
|
16
|
-
if value.is_a?(Integer)
|
17
|
-
Jaeger::Thrift::Tag.new(
|
18
|
-
KEY => key.to_s,
|
19
|
-
VTYPE => Jaeger::Thrift::TagType::LONG,
|
20
|
-
VLONG => value
|
21
|
-
)
|
22
|
-
elsif value.is_a?(Float)
|
23
|
-
Jaeger::Thrift::Tag.new(
|
24
|
-
KEY => key.to_s,
|
25
|
-
VTYPE => Jaeger::Thrift::TagType::DOUBLE,
|
26
|
-
VDOUBLE => value
|
27
|
-
)
|
28
|
-
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
29
|
-
Jaeger::Thrift::Tag.new(
|
30
|
-
KEY => key.to_s,
|
31
|
-
VTYPE => Jaeger::Thrift::TagType::BOOL,
|
32
|
-
VBOOL => value
|
33
|
-
)
|
34
|
-
else
|
35
|
-
Jaeger::Thrift::Tag.new(
|
36
|
-
KEY => key.to_s,
|
37
|
-
VTYPE => Jaeger::Thrift::TagType::STRING,
|
38
|
-
VSTR => value.to_s
|
39
|
-
)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|