jaeger-client 0.7.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|