jaeger-client 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9af8a3a945af29ffe9f0045a2eff121fa519c689d04a680a41c7346a198cbf6
4
- data.tar.gz: aad37d03df89f03707f91d3fd2f58b0af5b84122736b24f35edff791bb5f0b7a
3
+ metadata.gz: 7de16fd42664a20ad343e3fdc701f057b93df9e9c8ac6e76d4ea6b36895a7733
4
+ data.tar.gz: 32421b715a39b2710cae5bf9f7c6ca075872717ac53964de98429f063ebc93ba
5
5
  SHA512:
6
- metadata.gz: 975e4605ee85e4e1b34b763233c16fe6ec3ec0ad88a01f8d1239b523e97bc8fde5844a2ca0d152c71a3b7f601be6237fd70303f31229cb995d896958180aaef7
7
- data.tar.gz: 490214bc62f0a922e869b24ccbf5510538fa84365d50aafa1e892fe498aaa79e7bcb7d47da97445db8e07c4ebfb2481ecc6cb6aaeac7f81224e5a1ec90eb4616
6
+ metadata.gz: dacf1771b57e8f12074a0426b75b09b6a19610c13d4cb86b687e9930fc24a7e4a20f5c5e2819760e02a88baf01a8438f2175688be57dff2dffd80e5d45303522
7
+ data.tar.gz: b8bdaa192c6c2109b7711431ec9eebe3e4352e5e71426c65355abd5aad358cf0f4ceaaecb25dec2cf3a622d0982294ea578858234c71682a841f7bb3bb4090c0
data/README.md CHANGED
@@ -43,11 +43,11 @@ To use `HttpSender`:
43
43
  ```ruby
44
44
  OpenTracing.global_tracer = Jaeger::Client.build(
45
45
  service_name: 'service_name',
46
- reporter: Jaeger::Client::Reporter::RemoteReporter.new(
47
- sender: Jaeger::Client::HttpSender.new(
46
+ reporter: Jaeger::Reporters::RemoteReporter.new(
47
+ sender: Jaeger::HttpSender.new(
48
48
  url: 'http://localhost:14268/api/traces',
49
49
  headers: { 'key' => 'value' }, # headers key is optional
50
- encoder: Jaeger::Client::Encoders::ThriftEncoder.new(service_name: 'service_name')
50
+ encoder: Jaeger::Encoders::ThriftEncoder.new(service_name: 'service_name')
51
51
  ),
52
52
  flush_interval: 10
53
53
  )
@@ -61,7 +61,7 @@ NullReporter ignores all spans.
61
61
  ```ruby
62
62
  OpenTracing.global_tracer = Jaeger::Client.build(
63
63
  service_name: 'service_name',
64
- reporter: Jaeger::Client::Reporter::NullReporter.new
64
+ reporter: Jaeger::Reporters::NullReporter.new
65
65
  )
66
66
  ```
67
67
 
@@ -72,43 +72,41 @@ LoggingReporter prints some details about the span using `logger`. This is meant
72
72
  ```ruby
73
73
  OpenTracing.global_tracer = Jaeger::Client.build(
74
74
  service_name: 'service_name',
75
- reporter: Jaeger::Client::Reporter::LoggingReporter.new
75
+ reporter: Jaeger::Reporters::LoggingReporter.new
76
76
  )
77
77
  ```
78
78
 
79
79
  LoggingReporter can also use a custom logger. For this provide logger using `logger` keyword argument.
80
80
 
81
- See [opentracing-ruby](https://github.com/opentracing/opentracing-ruby) for more examples.
82
-
83
81
  ### Samplers
84
82
 
85
83
  #### Const sampler
86
84
 
87
- `Const` sampler always makes the same decision for new traces depending on the initialization value. Set `sampler` to: `Jaeger::Client::Samplers::Const.new(true)` to mark all new traces as sampled.
85
+ `Const` sampler always makes the same decision for new traces depending on the initialization value. Set `sampler` to: `Jaeger::Samplers::Const.new(true)` to mark all new traces as sampled.
88
86
 
89
87
  #### Probabilistic sampler
90
88
 
91
- `Probabilistic` sampler samples traces with probability equal to `rate` (must be between 0.0 and 1.0). This can be enabled by setting `Jaeger::Client::Samplers::Probabilistic.new(rate: 0.1)`
89
+ `Probabilistic` sampler samples traces with probability equal to `rate` (must be between 0.0 and 1.0). This can be enabled by setting `Jaeger::Samplers::Probabilistic.new(rate: 0.1)`
92
90
 
93
91
  #### RateLimiting sampler
94
92
 
95
93
  `RateLimiting` sampler samples at most `max_traces_per_second`. The distribution of sampled traces follows burstiness of the service, i.e. a service with uniformly distributed requests will have those requests sampled uniformly as well, but if requests are bursty, especially sub-second, then a number of sequential requests can be sampled each second.
96
94
 
97
- Set `sampler` to `Jaeger::Client::Samplers::RateLimiting.new(max_traces_per_second: 100)`
95
+ Set `sampler` to `Jaeger::Samplers::RateLimiting.new(max_traces_per_second: 100)`
98
96
 
99
97
  #### GuaranteedThroughputProbabilistic sampler
100
98
 
101
99
  `GuaranteedThroughputProbabilistic` is a sampler that guarantees a throughput by using a Probabilistic sampler and RateLimiting sampler The RateLimiting sampler is used to establish a lower_bound so that every operation is sampled at least once in the time interval defined by the lower_bound.
102
100
 
103
- Set `sampler` to `Jaeger::Client::Samplers::GuaranteedThroughputProbabilistic.new(lower_bound: 10, rate: 0.001)`
101
+ Set `sampler` to `Jaeger::Samplers::GuaranteedThroughputProbabilistic.new(lower_bound: 10, rate: 0.001)`
104
102
 
105
103
  #### PerOperation sampler
106
104
 
107
105
  `PerOperation` sampler leverages both Probabilistic sampler and RateLimiting sampler via the GuaranteedThroughputProbabilistic sampler. This sampler keeps track of all operations and delegates calls the the respective GuaranteedThroughputProbabilistic sampler.
108
106
 
109
107
  Set `sampler` to
110
- ```
111
- Jaeger::Client::Samplers::PerOperation.new(
108
+ ```ruby
109
+ Jaeger::Samplers::PerOperation.new(
112
110
  strategies: {
113
111
  per_operation_strategies: [
114
112
  { operation: 'GET /articles', probabilistic_sampling: 0.5 },
@@ -127,14 +125,14 @@ Jaeger Tracer supports Zipkin B3 Propagation HTTP headers, which are used by a l
127
125
 
128
126
  To set it up you need to change FORMAT_RACK injector and extractor.
129
127
 
130
- ```
128
+ ```ruby
131
129
  OpenTracing.global_tracer = Jaeger::Client.build(
132
130
  service_name: 'service_name',
133
131
  injectors: {
134
- OpenTracing::FORMAT_RACK => [Jaeger::Client::Injectors::B3RackCodec]
132
+ OpenTracing::FORMAT_RACK => [Jaeger::Injectors::B3RackCodec]
135
133
  },
136
134
  extractors: {
137
- OpenTracing::FORMAT_RACK => [Jaeger::Client::Extractors::B3RackCodec]
135
+ OpenTracing::FORMAT_RACK => [Jaeger::Extractors::B3RackCodec]
138
136
  }
139
137
  )
140
138
  ```
@@ -103,7 +103,7 @@ class HttpServer < Sinatra::Application
103
103
  host: 'jaeger-agent',
104
104
  port: 6831,
105
105
  flush_interval: 1,
106
- sampler: Jaeger::Client::Samplers::Const.new(true)
106
+ sampler: Jaeger::Samplers::Const.new(true)
107
107
  )
108
108
  end
109
109
 
@@ -6,25 +6,35 @@ require 'opentracing'
6
6
  require 'jaeger/thrift/agent'
7
7
  require 'logger'
8
8
 
9
- require_relative 'client/tracer'
10
- require_relative 'client/span'
11
- require_relative 'client/span_context'
12
- require_relative 'client/scope'
13
- require_relative 'client/scope_manager'
14
- require_relative 'client/carrier'
15
- require_relative 'client/trace_id'
16
- require_relative 'client/udp_sender'
17
- require_relative 'client/http_sender'
18
- require_relative 'client/reporters'
9
+ require_relative 'tracer'
10
+ require_relative 'span'
11
+ require_relative 'span_context'
12
+ require_relative 'scope'
13
+ require_relative 'scope_manager'
14
+ require_relative 'trace_id'
15
+ require_relative 'udp_sender'
16
+ require_relative 'http_sender'
17
+ require_relative 'reporters'
19
18
  require_relative 'client/version'
20
- require_relative 'client/samplers'
21
- require_relative 'client/encoders/thrift_encoder'
22
- require_relative 'client/injectors'
23
- require_relative 'client/extractors'
24
- require_relative 'client/rate_limiter'
19
+ require_relative 'samplers'
20
+ require_relative 'encoders/thrift_encoder'
21
+ require_relative 'injectors'
22
+ require_relative 'extractors'
23
+ require_relative 'rate_limiter'
25
24
 
26
25
  module Jaeger
27
26
  module Client
27
+ # We initially had everything under Jaeger::Client namespace. This however
28
+ # was not very useful and was removed. These assignments are here for
29
+ # backwards compatibility. Fine to remove in the next major version.
30
+ UdpSender = Jaeger::UdpSender
31
+ HttpSender = Jaeger::HttpSender
32
+ Encoders = Jaeger::Encoders
33
+ Samplers = Jaeger::Samplers
34
+ Reporters = Jaeger::Reporters
35
+ Injectors = Jaeger::Injectors
36
+ Extractors = Jaeger::Extractors
37
+
28
38
  DEFAULT_FLUSH_INTERVAL = 10
29
39
 
30
40
  def self.build(host: '127.0.0.1',
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jaeger
4
4
  module Client
5
- VERSION = '0.9.0'.freeze
5
+ VERSION = '0.10.0'.freeze
6
6
  end
7
7
  end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Encoders
5
+ class ThriftEncoder
6
+ def initialize(service_name:)
7
+ @service_name = service_name
8
+ @tags = [
9
+ Jaeger::Thrift::Tag.new(
10
+ 'key' => 'jaeger.version',
11
+ 'vType' => Jaeger::Thrift::TagType::STRING,
12
+ 'vStr' => 'Ruby-' + Jaeger::Client::VERSION
13
+ ),
14
+ Jaeger::Thrift::Tag.new(
15
+ 'key' => 'hostname',
16
+ 'vType' => Jaeger::Thrift::TagType::STRING,
17
+ 'vStr' => Socket.gethostname
18
+ )
19
+ ]
20
+ ipv4 = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }
21
+ unless ipv4.nil? # rubocop:disable Style/GuardClause
22
+ @tags << Jaeger::Thrift::Tag.new(
23
+ 'key' => 'ip',
24
+ 'vType' => Jaeger::Thrift::TagType::STRING,
25
+ 'vStr' => ipv4.ip_address
26
+ )
27
+ end
28
+ end
29
+
30
+ def encode(spans)
31
+ Jaeger::Thrift::Batch.new(
32
+ 'process' => Jaeger::Thrift::Process.new(
33
+ 'serviceName' => @service_name,
34
+ 'tags' => @tags
35
+ ),
36
+ 'spans' => spans.map(&method(:encode_span))
37
+ )
38
+ end
39
+
40
+ private
41
+
42
+ def encode_span(span)
43
+ context = span.context
44
+ start_ts, duration = build_timestamps(span)
45
+
46
+ Jaeger::Thrift::Span.new(
47
+ 'traceIdLow' => TraceId.uint64_id_to_int64(context.trace_id),
48
+ 'traceIdHigh' => 0,
49
+ 'spanId' => TraceId.uint64_id_to_int64(context.span_id),
50
+ 'parentSpanId' => TraceId.uint64_id_to_int64(context.parent_id),
51
+ 'operationName' => span.operation_name,
52
+ 'references' => build_references(span.references || []),
53
+ 'flags' => context.flags,
54
+ 'startTime' => start_ts,
55
+ 'duration' => duration,
56
+ 'tags' => span.tags,
57
+ 'logs' => span.logs
58
+ )
59
+ end
60
+
61
+ def build_references(references)
62
+ references.map do |ref|
63
+ Jaeger::Thrift::SpanRef.new(
64
+ 'refType' => span_ref_type(ref.type),
65
+ 'traceIdLow' => TraceId.uint64_id_to_int64(ref.context.trace_id),
66
+ 'traceIdHigh' => 0,
67
+ 'spanId' => TraceId.uint64_id_to_int64(ref.context.span_id)
68
+ )
69
+ end
70
+ end
71
+
72
+ def build_timestamps(span)
73
+ start_ts = (span.start_time.to_f * 1_000_000).to_i
74
+ end_ts = (span.end_time.to_f * 1_000_000).to_i
75
+ duration = end_ts - start_ts
76
+ [start_ts, duration]
77
+ end
78
+
79
+ def span_ref_type(type)
80
+ case type
81
+ when OpenTracing::Reference::CHILD_OF
82
+ Jaeger::Thrift::SpanRefType::CHILD_OF
83
+ when OpenTracing::Reference::FOLLOWS_FROM
84
+ Jaeger::Thrift::SpanRefType::FOLLOWS_FROM
85
+ else
86
+ warn "Jaeger::Client with format #{type} is not supported yet"
87
+ nil
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Extractors
5
+ class SerializedJaegerTrace
6
+ def self.parse(trace)
7
+ return nil if !trace || trace == ''
8
+
9
+ trace_arguments = trace.split(':').map(&TraceId.method(:base16_hex_id_to_uint64))
10
+ return nil if trace_arguments.size != 4
11
+
12
+ trace_id, span_id, parent_id, flags = trace_arguments
13
+ return nil if trace_id.zero? || span_id.zero?
14
+
15
+ SpanContext.new(
16
+ trace_id: trace_id,
17
+ parent_id: parent_id,
18
+ span_id: span_id,
19
+ flags: flags
20
+ )
21
+ end
22
+ end
23
+
24
+ class JaegerTextMapCodec
25
+ def self.extract(carrier)
26
+ context = SerializedJaegerTrace.parse(carrier['uber-trace-id'])
27
+ return nil unless context
28
+
29
+ carrier.each do |key, value|
30
+ baggage_match = key.match(/\Auberctx-([\w-]+)\Z/)
31
+ if baggage_match
32
+ context.set_baggage_item(baggage_match[1], value)
33
+ end
34
+ end
35
+
36
+ context
37
+ end
38
+ end
39
+
40
+ class JaegerRackCodec
41
+ def self.extract(carrier)
42
+ serialized_trace = carrier['HTTP_UBER_TRACE_ID']
43
+ serialized_trace = CGI.unescape(serialized_trace) if serialized_trace
44
+ context = SerializedJaegerTrace.parse(serialized_trace)
45
+ return nil unless context
46
+
47
+ carrier.each do |key, value|
48
+ baggage_match = key.match(/\AHTTP_UBERCTX_(\w+)\Z/)
49
+ if baggage_match
50
+ key = baggage_match[1].downcase.tr('_', '-')
51
+ context.set_baggage_item(key, CGI.unescape(value))
52
+ end
53
+ end
54
+
55
+ context
56
+ end
57
+ end
58
+
59
+ class JaegerBinaryCodec
60
+ def self.extract(_carrier)
61
+ warn 'Jaeger::Client with binary format is not supported yet'
62
+ end
63
+ end
64
+
65
+ class B3RackCodec
66
+ def self.extract(carrier)
67
+ trace_id = TraceId.base16_hex_id_to_uint64(carrier['HTTP_X_B3_TRACEID'])
68
+ span_id = TraceId.base16_hex_id_to_uint64(carrier['HTTP_X_B3_SPANID'])
69
+ parent_id = TraceId.base16_hex_id_to_uint64(carrier['HTTP_X_B3_PARENTSPANID'])
70
+ flags = parse_flags(carrier['HTTP_X_B3_FLAGS'], carrier['HTTP_X_B3_SAMPLED'])
71
+
72
+ return nil if span_id.nil? || trace_id.nil?
73
+ return nil if span_id.zero? || trace_id.zero?
74
+
75
+ SpanContext.new(
76
+ trace_id: trace_id,
77
+ parent_id: parent_id,
78
+ span_id: span_id,
79
+ flags: flags
80
+ )
81
+ end
82
+
83
+ # if the flags header is '1' then the sampled header should not be present
84
+ def self.parse_flags(flags_header, sampled_header)
85
+ if flags_header == '1'
86
+ Jaeger::SpanContext::Flags::DEBUG
87
+ else
88
+ TraceId.base16_hex_id_to_uint64(sampled_header)
89
+ end
90
+ end
91
+ private_class_method :parse_flags
92
+ end
93
+
94
+ DEFAULT_EXTRACTORS = {
95
+ OpenTracing::FORMAT_TEXT_MAP => JaegerTextMapCodec,
96
+ OpenTracing::FORMAT_BINARY => JaegerBinaryCodec,
97
+ OpenTracing::FORMAT_RACK => JaegerRackCodec
98
+ }.freeze
99
+
100
+ def self.prepare(extractors)
101
+ DEFAULT_EXTRACTORS.reduce(extractors) do |acc, (format, default)|
102
+ provided_extractors = Array(extractors[format])
103
+ provided_extractors += [default] if provided_extractors.empty?
104
+
105
+ acc.merge(format => provided_extractors)
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Jaeger
6
+ class HttpSender
7
+ def initialize(url:, headers: {}, encoder:, logger: Logger.new(STDOUT))
8
+ @encoder = encoder
9
+ @logger = logger
10
+
11
+ @uri = URI(url)
12
+ @uri.query = 'format=jaeger.thrift'
13
+
14
+ @transport = ::Thrift::HTTPClientTransport.new(@uri.to_s)
15
+ @transport.add_headers(headers)
16
+
17
+ @serializer = ::Thrift::Serializer.new
18
+ end
19
+
20
+ def send_spans(spans)
21
+ batch = @encoder.encode(spans)
22
+ @transport.write(@serializer.serialize(batch))
23
+ @transport.flush
24
+ rescue StandardError => error
25
+ @logger.error("Failure while sending a batch of spans: #{error}")
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jaeger
4
+ module Injectors
5
+ def self.context_as_jaeger_string(span_context)
6
+ [
7
+ span_context.trace_id.to_s(16),
8
+ span_context.span_id.to_s(16),
9
+ span_context.parent_id.to_s(16),
10
+ span_context.flags.to_s(16)
11
+ ].join(':')
12
+ end
13
+
14
+ class JaegerTextMapCodec
15
+ def self.inject(span_context, carrier)
16
+ carrier['uber-trace-id'] = Injectors.context_as_jaeger_string(span_context)
17
+ span_context.baggage.each do |key, value|
18
+ carrier["uberctx-#{key}"] = value
19
+ end
20
+ end
21
+ end
22
+
23
+ class JaegerRackCodec
24
+ def self.inject(span_context, carrier)
25
+ carrier['uber-trace-id'] =
26
+ CGI.escape(Injectors.context_as_jaeger_string(span_context))
27
+ span_context.baggage.each do |key, value|
28
+ carrier["uberctx-#{key}"] = CGI.escape(value)
29
+ end
30
+ end
31
+ end
32
+
33
+ class JaegerBinaryCodec
34
+ def self.inject(_span_context, _carrier)
35
+ warn 'Jaeger::Client with binary format is not supported yet'
36
+ end
37
+ end
38
+
39
+ class B3RackCodec
40
+ def self.inject(span_context, carrier)
41
+ carrier['x-b3-traceid'] = TraceId.to_hex(span_context.trace_id)
42
+ carrier['x-b3-spanid'] = TraceId.to_hex(span_context.span_id)
43
+ carrier['x-b3-parentspanid'] = TraceId.to_hex(span_context.parent_id)
44
+
45
+ # flags (for debug) and sampled headers are mutually exclusive
46
+ if span_context.flags == Jaeger::SpanContext::Flags::DEBUG
47
+ carrier['x-b3-flags'] = '1'
48
+ else
49
+ carrier['x-b3-sampled'] = span_context.flags.to_s(16)
50
+ end
51
+ end
52
+ end
53
+
54
+ DEFAULT_INJECTORS = {
55
+ OpenTracing::FORMAT_TEXT_MAP => JaegerTextMapCodec,
56
+ OpenTracing::FORMAT_BINARY => JaegerBinaryCodec,
57
+ OpenTracing::FORMAT_RACK => JaegerRackCodec
58
+ }.freeze
59
+
60
+ def self.prepare(extractors)
61
+ DEFAULT_INJECTORS.reduce(extractors) do |acc, (format, default)|
62
+ provided_extractors = Array(extractors[format])
63
+ provided_extractors += [default] if provided_extractors.empty?
64
+
65
+ acc.merge(format => provided_extractors)
66
+ end
67
+ end
68
+ end
69
+ end