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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/.rubocop.yml +3 -0
  4. data/.travis.yml +11 -2
  5. data/Makefile +1 -0
  6. data/README.md +127 -13
  7. data/crossdock/Dockerfile +29 -0
  8. data/crossdock/Gemfile +6 -0
  9. data/crossdock/Gemfile.lock +35 -0
  10. data/crossdock/docker-compose.yml +68 -0
  11. data/crossdock/jaeger-docker-compose.yml +48 -0
  12. data/crossdock/rules.mk +35 -0
  13. data/crossdock/server +173 -0
  14. data/jaeger-client.gemspec +4 -2
  15. data/lib/jaeger/client.rb +42 -18
  16. data/lib/jaeger/client/version.rb +1 -1
  17. data/lib/jaeger/encoders/thrift_encoder.rb +142 -0
  18. data/lib/jaeger/extractors.rb +173 -0
  19. data/lib/jaeger/http_sender.rb +28 -0
  20. data/lib/jaeger/injectors.rb +83 -0
  21. data/lib/jaeger/rate_limiter.rb +61 -0
  22. data/lib/jaeger/recurring_executor.rb +35 -0
  23. data/lib/jaeger/reporters.rb +7 -0
  24. data/lib/jaeger/reporters/composite_reporter.rb +17 -0
  25. data/lib/jaeger/reporters/in_memory_reporter.rb +30 -0
  26. data/lib/jaeger/reporters/logging_reporter.rb +22 -0
  27. data/lib/jaeger/reporters/null_reporter.rb +11 -0
  28. data/lib/jaeger/{client/async_reporter.rb → reporters/remote_reporter.rb} +21 -20
  29. data/lib/jaeger/{client/async_reporter → reporters/remote_reporter}/buffer.rb +2 -2
  30. data/lib/jaeger/samplers.rb +8 -0
  31. data/lib/jaeger/samplers/const.rb +24 -0
  32. data/lib/jaeger/samplers/guaranteed_throughput_probabilistic.rb +47 -0
  33. data/lib/jaeger/samplers/per_operation.rb +79 -0
  34. data/lib/jaeger/samplers/probabilistic.rb +38 -0
  35. data/lib/jaeger/samplers/rate_limiting.rb +51 -0
  36. data/lib/jaeger/samplers/remote_controlled.rb +119 -0
  37. data/lib/jaeger/samplers/remote_controlled/instructions_fetcher.rb +34 -0
  38. data/lib/jaeger/scope.rb +38 -0
  39. data/lib/jaeger/scope_manager.rb +47 -0
  40. data/lib/jaeger/scope_manager/scope_identifier.rb +13 -0
  41. data/lib/jaeger/scope_manager/scope_stack.rb +33 -0
  42. data/lib/jaeger/span.rb +97 -0
  43. data/lib/jaeger/span/thrift_log_builder.rb +18 -0
  44. data/lib/jaeger/span_context.rb +57 -0
  45. data/lib/jaeger/thrift_tag_builder.rb +41 -0
  46. data/lib/jaeger/trace_id.rb +48 -0
  47. data/lib/jaeger/tracer.rb +213 -0
  48. data/lib/jaeger/udp_sender.rb +26 -0
  49. data/lib/jaeger/udp_sender/transport.rb +40 -0
  50. metadata +78 -31
  51. data/lib/jaeger/client/carrier.rb +0 -26
  52. data/lib/jaeger/client/encoders/thrift_encoder.rb +0 -94
  53. data/lib/jaeger/client/extractors.rb +0 -88
  54. data/lib/jaeger/client/http_sender.rb +0 -30
  55. data/lib/jaeger/client/injectors.rb +0 -54
  56. data/lib/jaeger/client/samplers.rb +0 -4
  57. data/lib/jaeger/client/samplers/const.rb +0 -29
  58. data/lib/jaeger/client/samplers/probabilistic.rb +0 -30
  59. data/lib/jaeger/client/scope.rb +0 -40
  60. data/lib/jaeger/client/scope_manager.rb +0 -49
  61. data/lib/jaeger/client/scope_manager/scope_identifier.rb +0 -15
  62. data/lib/jaeger/client/scope_manager/scope_stack.rb +0 -35
  63. data/lib/jaeger/client/span.rb +0 -84
  64. data/lib/jaeger/client/span/thrift_log_builder.rb +0 -20
  65. data/lib/jaeger/client/span/thrift_tag_builder.rb +0 -45
  66. data/lib/jaeger/client/span_context.rb +0 -59
  67. data/lib/jaeger/client/trace_id.rb +0 -41
  68. data/lib/jaeger/client/tracer.rb +0 -189
  69. data/lib/jaeger/client/udp_sender.rb +0 -27
  70. data/lib/jaeger/client/udp_sender/transport.rb +0 -42
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- # SpanContext holds the data for a span that gets inherited to child spans
6
- class SpanContext
7
- module Flags
8
- NONE = 0x00
9
- SAMPLED = 0x01
10
- DEBUG = 0x02
11
- end
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
- def self.create_from_parent_context(span_context)
21
- trace_id = span_context.trace_id
22
- parent_id = span_context.span_id
23
- flags = span_context.flags
24
- span_id = TraceId.generate
25
- new(span_id: span_id, parent_id: parent_id, trace_id: trace_id, flags: flags)
26
- end
27
-
28
- attr_reader :span_id, :parent_id, :trace_id, :baggage, :flags
29
-
30
- def initialize(span_id:, parent_id: 0, trace_id:, flags:, baggage: {})
31
- @span_id = span_id
32
- @parent_id = parent_id
33
- @trace_id = trace_id
34
- @baggage = baggage
35
- @flags = flags
36
- end
37
-
38
- def sampled?
39
- @flags & Flags::SAMPLED == Flags::SAMPLED
40
- end
41
-
42
- def debug?
43
- @flags & Flags::DEBUG == Flags::DEBUG
44
- end
45
-
46
- def to_trace_id
47
- @to_trace_id ||= @trace_id.to_s(16)
48
- end
49
-
50
- def to_parent_id
51
- @to_parent_id ||= @parent_id.zero? ? nil : @parent_id.to_s(16)
52
- end
53
-
54
- def to_span_id
55
- @to_span_id ||= @span_id.to_s(16)
56
- end
57
- end
58
- end
59
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- module TraceId
6
- MAX_64BIT_SIGNED_INT = (1 << 63) - 1
7
- MAX_64BIT_UNSIGNED_INT = (1 << 64) - 1
8
- TRACE_ID_UPPER_BOUND = MAX_64BIT_UNSIGNED_INT + 1
9
-
10
- def self.generate
11
- rand(TRACE_ID_UPPER_BOUND)
12
- end
13
-
14
- def self.base16_hex_id_to_uint64(id)
15
- return nil unless id
16
- value = id.to_i(16)
17
- value > MAX_64BIT_UNSIGNED_INT || value < 0 ? 0 : value
18
- end
19
-
20
- # Thrift defines ID fields as i64, which is signed, therefore we convert
21
- # large IDs (> 2^63) to negative longs
22
- def self.uint64_id_to_int64(id)
23
- id > MAX_64BIT_SIGNED_INT ? id - MAX_64BIT_UNSIGNED_INT - 1 : id
24
- end
25
-
26
- # Convert an integer id into a 0 padded hex string.
27
- # If the string is shorter than 16 characters, it will be padded to 16.
28
- # If it is longer than 16 characters, it is padded to 32.
29
- def self.to_hex(id)
30
- hex_str = id.to_s(16)
31
-
32
- # pad the string with '0's to 16 or 32 characters
33
- if hex_str.length > 16
34
- hex_str.rjust(32, '0')
35
- else
36
- hex_str.rjust(16, '0')
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,189 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- class Tracer
6
- def initialize(reporter:, sampler:, injectors:, extractors:)
7
- @reporter = reporter
8
- @sampler = sampler
9
- @injectors = injectors
10
- @extractors = extractors
11
- @scope_manager = ScopeManager.new
12
- end
13
-
14
- # @return [ScopeManager] the current ScopeManager, which may be a no-op
15
- # but may not be nil.
16
- attr_reader :scope_manager
17
-
18
- # @return [Span, nil] the active span. This is a shorthand for
19
- # `scope_manager.active.span`, and nil will be returned if
20
- # Scope#active is nil.
21
- def active_span
22
- scope = scope_manager.active
23
- scope.span if scope
24
- end
25
-
26
- # Starts a new span.
27
- #
28
- # This is similar to #start_active_span, but the returned Span will not
29
- # be registered via the ScopeManager.
30
- #
31
- # @param operation_name [String] The operation name for the Span
32
- # @param child_of [SpanContext, Span] SpanContext that acts as a parent to
33
- # the newly-started Span. If a Span instance is provided, its
34
- # context is automatically substituted. See [Reference] for more
35
- # information.
36
- #
37
- # If specified, the `references` parameter must be omitted.
38
- # @param references [Array<Reference>] An array of reference
39
- # objects that identify one or more parent SpanContexts.
40
- # @param start_time [Time] When the Span started, if not now
41
- # @param tags [Hash] Tags to assign to the Span at start time
42
- # @param ignore_active_scope [Boolean] whether to create an implicit
43
- # References#CHILD_OF reference to the ScopeManager#active.
44
- #
45
- # @return [Span] The newly-started Span
46
- def start_span(operation_name,
47
- child_of: nil,
48
- references: nil,
49
- start_time: Time.now,
50
- tags: {},
51
- ignore_active_scope: false,
52
- **)
53
- context = prepare_span_context(
54
- child_of: child_of,
55
- references: references,
56
- ignore_active_scope: ignore_active_scope
57
- )
58
- Span.new(
59
- context,
60
- operation_name,
61
- @reporter,
62
- start_time: start_time,
63
- references: references,
64
- tags: tags.merge(
65
- :'sampler.type' => @sampler.type,
66
- :'sampler.param' => @sampler.param
67
- )
68
- )
69
- end
70
-
71
- # Creates a newly started and activated Scope
72
- #
73
- # If the Tracer's ScopeManager#active is not nil, no explicit references
74
- # are provided, and `ignore_active_scope` is false, then an inferred
75
- # References#CHILD_OF reference is created to the ScopeManager#active's
76
- # SpanContext when start_active is invoked.
77
- #
78
- # @param operation_name [String] The operation name for the Span
79
- # @param child_of [SpanContext, Span] SpanContext that acts as a parent to
80
- # the newly-started Span. If a Span instance is provided, its
81
- # context is automatically substituted. See [Reference] for more
82
- # information.
83
- #
84
- # If specified, the `references` parameter must be omitted.
85
- # @param references [Array<Reference>] An array of reference
86
- # objects that identify one or more parent SpanContexts.
87
- # @param start_time [Time] When the Span started, if not now
88
- # @param tags [Hash] Tags to assign to the Span at start time
89
- # @param ignore_active_scope [Boolean] whether to create an implicit
90
- # References#CHILD_OF reference to the ScopeManager#active.
91
- # @param finish_on_close [Boolean] whether span should automatically be
92
- # finished when Scope#close is called
93
- # @yield [Scope] If an optional block is passed to start_active it will
94
- # yield the newly-started Scope. If `finish_on_close` is true then the
95
- # Span will be finished automatically after the block is executed.
96
- # @return [Scope] The newly-started and activated Scope
97
- def start_active_span(operation_name,
98
- child_of: nil,
99
- references: nil,
100
- start_time: Time.now,
101
- tags: {},
102
- ignore_active_scope: false,
103
- finish_on_close: true,
104
- **)
105
- span = start_span(
106
- operation_name,
107
- child_of: child_of,
108
- references: references,
109
- start_time: start_time,
110
- tags: tags,
111
- ignore_active_scope: ignore_active_scope
112
- )
113
- scope = @scope_manager.activate(span, finish_on_close: finish_on_close)
114
-
115
- if block_given?
116
- begin
117
- yield scope
118
- ensure
119
- scope.close
120
- end
121
- end
122
-
123
- scope
124
- end
125
-
126
- # Inject a SpanContext into the given carrier
127
- #
128
- # @param span_context [SpanContext]
129
- # @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY, OpenTracing::FORMAT_RACK]
130
- # @param carrier [Carrier] A carrier object of the type dictated by the specified `format`
131
- def inject(span_context, format, carrier)
132
- @injectors.fetch(format).each do |injector|
133
- injector.inject(span_context, carrier)
134
- end
135
- end
136
-
137
- # Extract a SpanContext in the given format from the given carrier.
138
- #
139
- # @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY, OpenTracing::FORMAT_RACK]
140
- # @param carrier [Carrier] A carrier object of the type dictated by the specified `format`
141
- # @return [SpanContext] the extracted SpanContext or nil if none could be found
142
- def extract(format, carrier)
143
- @extractors
144
- .fetch(format)
145
- .lazy
146
- .map { |extractor| extractor.extract(carrier) }
147
- .reject(&:nil?)
148
- .first
149
- end
150
-
151
- private
152
-
153
- def prepare_span_context(child_of:, references:, ignore_active_scope:)
154
- context =
155
- context_from_child_of(child_of) ||
156
- context_from_references(references) ||
157
- context_from_active_scope(ignore_active_scope)
158
-
159
- if context
160
- SpanContext.create_from_parent_context(context)
161
- else
162
- SpanContext.create_parent_context(@sampler)
163
- end
164
- end
165
-
166
- def context_from_child_of(child_of)
167
- return nil unless child_of
168
- child_of.respond_to?(:context) ? child_of.context : child_of
169
- end
170
-
171
- def context_from_references(references)
172
- return nil if !references || references.none?
173
-
174
- # Prefer CHILD_OF reference if present
175
- ref = references.detect do |reference|
176
- reference.type == OpenTracing::Reference::CHILD_OF
177
- end
178
- (ref || references[0]).context
179
- end
180
-
181
- def context_from_active_scope(ignore_active_scope)
182
- return if ignore_active_scope
183
-
184
- active_scope = @scope_manager.active
185
- active_scope.span.context if active_scope
186
- end
187
- end
188
- end
189
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative './udp_sender/transport'
4
- require 'socket'
5
- require 'thread'
6
-
7
- module Jaeger
8
- module Client
9
- class UdpSender
10
- def initialize(host:, port:, encoder:, logger:)
11
- @encoder = encoder
12
- @logger = logger
13
-
14
- transport = Transport.new(host, port)
15
- protocol = ::Thrift::CompactProtocol.new(transport)
16
- @client = Jaeger::Thrift::Agent::Client.new(protocol)
17
- end
18
-
19
- def send_spans(spans)
20
- batch = @encoder.encode(spans)
21
- @client.emitBatch(batch)
22
- rescue StandardError => error
23
- @logger.error("Failure while sending a batch of spans: #{error}")
24
- end
25
- end
26
- end
27
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jaeger
4
- module Client
5
- class UdpSender
6
- class Transport
7
- FLAGS = 0
8
-
9
- def initialize(host, port)
10
- @socket = UDPSocket.new
11
- @host = host
12
- @port = port
13
- @buffer = ::Thrift::MemoryBufferTransport.new
14
- end
15
-
16
- def write(str)
17
- @buffer.write(str)
18
- end
19
-
20
- def flush
21
- data = @buffer.read(@buffer.available)
22
- send_bytes(data)
23
- end
24
-
25
- def open; end
26
-
27
- def close; end
28
-
29
- private
30
-
31
- def send_bytes(bytes)
32
- @socket.send(bytes, FLAGS, @host, @port)
33
- @socket.flush
34
- rescue Errno::ECONNREFUSED
35
- warn 'Unable to connect to Jaeger Agent'
36
- rescue StandardError => e
37
- warn "Unable to send spans: #{e.message}"
38
- end
39
- end
40
- end
41
- end
42
- end