zipkin-tracer 0.44.0 → 0.47.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46e54f012c081598681f2f5da8a961f29cb8656b8a21fa1877358724c2fa20b8
4
- data.tar.gz: c22b07513bdca3173bdedbf1948d00f09907f669142f4d186c5f66808bb4d959
3
+ metadata.gz: 7f1cd6e0b5790c467741c87272cab1fe3b1462eca4fe8a86ecdaac2589c42e01
4
+ data.tar.gz: cc1a4565e51850f3da085782a949b672fe6ef98c3d908ecc3f0682996b695a16
5
5
  SHA512:
6
- metadata.gz: f5b58005b5f1fe570f50cb36b66b7f72d6e27a620fee2453b3bc7b74e46202ddebb16b5b6d1e71d3a698f236ffebe7cd1ad60de128103f7a40929f12180eca82
7
- data.tar.gz: dc910caca3ce2234aa5e12bc2c8363a98a711f717e84e05943a6246f0c462fd614486617cf9a9211721da92abb3d01bee18e1e6a0c66e7220c340395f56f79fd
6
+ metadata.gz: 276fb50c73250e91458e7a2ad92f013f56f8ededd1861bac85b5dbb72a6f75b5e7a03c522bdc2097d9fe162890889288c02df1500593733244d960ad69c23298
7
+ data.tar.gz: d0cc046aaa2267a2f6ad987dba4567c35e672688528532a29d7101749978522a7a14d1c79004eb8e50b1663493f2aa9bfc7768356edbe79e22d2eae81b8a32a0
@@ -25,7 +25,7 @@ deploy:
25
25
  on:
26
26
  tags: true
27
27
  repo: openzipkin/zipkin-ruby
28
- condition: "$TRAVIS_RUBY_VERSION == 2.7"
28
+ condition: $TRAVIS_RUBY_VERSION == 2.7 && $BUNDLE_GEMFILE == $TRAVIS_BUILD_DIR/gemfiles/faraday_1.x.gemfile
29
29
 
30
30
  notifications:
31
31
  webhooks:
@@ -1,3 +1,18 @@
1
+ # 0.47.2
2
+ * Fix to not flush local component span when a server span or a consumer span is in the stack.
3
+
4
+ # 0.47.1
5
+ * Fix to set `SERVER` span kind at the beginning to avoid being flushed before closing.
6
+
7
+ # 0.47.0
8
+ * Add a `check_routes` option to make the routable request check optional.
9
+
10
+ # 0.46.0
11
+ * Add Amazon SQS tracer.
12
+
13
+ # 0.45.0
14
+ * Add a `trace_context` option to the TraceWrapper utility class to retrieve trace data.
15
+
1
16
  # 0.44.0
2
17
  * Allow Faraday 1.x.
3
18
 
data/README.md CHANGED
@@ -21,6 +21,7 @@ use ZipkinTracer::RackHandler, config
21
21
  * `:service_name` **REQUIRED** - the name of the service being traced. There are two ways to configure this value. Either write the service name in the config file or set the "DOMAIN" environment variable (e.g. 'test-service.example.com' or 'test-service'). The environment variable takes precedence over the config file value.
22
22
  * `:sample_rate` (default: 0.1) - the ratio of requests to sample, from 0 to 1
23
23
  * `:sampled_as_boolean` - When set to true (default but deprecrated), it uses true/false for the `X-B3-Sampled` header. When set to false uses 1/0 which is preferred.
24
+ * `:check_routes` - When set to `true`, only routable requests are sampled. Defaults to `false`.
24
25
  * `:trace_id_128bit` - When set to true, high 8-bytes will be prepended to trace_id. The upper 4-bytes are epoch seconds and the lower 4-bytes are random. This makes it convertible to Amazon X-Ray trace ID format v1. (See http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-request-tracing.html)
25
26
  * `:async` - By default senders will flush traces asynchronously. Set to `false` to make that process synchronous. Only supported by the HTTP, RabbitMQ, and SQS senders.
26
27
  * `:logger` - The default logger for Rails apps is `Rails.logger`, else it is `STDOUT`. Use this option to pass a custom logger.
@@ -81,6 +82,38 @@ end
81
82
 
82
83
  By default workers aren't traced. You can specify the workers that you want to trace with traceable_workers config option. If you want all your workers to be traced pass [:all] to traceable_workers option (traceable_workers: [:all]).
83
84
 
85
+ ### Tracing Amazon SQS messages
86
+
87
+ Amazon SQS tracing can be turned on by requiring [zipkin-tracer/sqs/adapter](lib/zipkin-tracer/sqs/adapter.rb):
88
+ ```ruby
89
+ require 'zipkin-tracer/sqs/adapter'
90
+ ```
91
+
92
+ This SQS adapter overrides the `send_message` and `send_message_batch` methods to add trace data as message attributes and to generate a producer span when the methods are called. Since all SQS messages are affected, it is not recommended to use this feature with the [SQS sender](lib/zipkin-tracer/zipkin_sqs_sender.rb).
93
+
94
+ When receiving messages, you need to pass the `message_attribute_names: ['All']` option to retrive message attributes:
95
+ ```ruby
96
+ resp = sqs.receive_message(
97
+ queue_url: queue_url,
98
+ message_attribute_names: ['All']
99
+ )
100
+ ```
101
+
102
+ Then you can utilize the [TraceWrapper](#tracewrapper) class to generate a consumer span:
103
+ ```ruby
104
+ msg = resp.messages.first
105
+ trace_context = msg.message_attributes.each_with_object({}) { |(key, value), hsh| hsh[key.to_sym] = value.string_value }
106
+
107
+ TraceWrapper.wrap_in_custom_span(config, 'receive_message',
108
+ span_kind: Trace::Span::Kind::CONSUMER,
109
+ trace_context: trace_context
110
+ ) do |span|
111
+ span.remote_endpoint = Trace::Endpoint.remote_endpoint(nil, 'amazon-sqs')
112
+ span.record_tag('queue.url', queue_url)
113
+ :
114
+ end
115
+ ```
116
+
84
117
  ### Local tracing
85
118
 
86
119
  `ZipkinTracer::TraceClient` provides an API to record local traces in your application.
@@ -242,6 +275,18 @@ TraceWrapper.wrap_in_custom_span(config, "custom span") do |span|
242
275
  end
243
276
  ```
244
277
 
278
+ The `trace_context:` keyword argument can be used to retrieve trace data:
279
+ ```ruby
280
+ trace_context = {
281
+ trace_id: '234555b04cf7e099',
282
+ span_id: '234555b04cf7e099',
283
+ sampled: 'true'
284
+ }
285
+
286
+ TraceWrapper.wrap_in_custom_span(config, "custom span", trace_context: trace_context) do |span|
287
+ :
288
+ end
289
+ ```
245
290
 
246
291
  ## Development
247
292
 
@@ -5,7 +5,7 @@ require 'zipkin-tracer/rack/zipkin-tracer'
5
5
  module ZipkinTracer
6
6
  # Configuration of this gem. It reads the configuration and provides default values
7
7
  class Config
8
- attr_reader :service_name, :sample_rate, :sampled_as_boolean, :trace_id_128bit, :async, :logger,
8
+ attr_reader :service_name, :sample_rate, :sampled_as_boolean, :check_routes, :trace_id_128bit, :async, :logger,
9
9
  :json_api_host, :zookeeper, :kafka_producer, :kafka_topic, :sqs_queue_name, :sqs_region, :log_tracing,
10
10
  :annotate_plugin, :filter_plugin, :whitelist_plugin, :rabbit_mq_connection, :rabbit_mq_exchange,
11
11
  :rabbit_mq_routing_key, :write_b3_single_format
@@ -47,6 +47,8 @@ module ZipkinTracer
47
47
  if @sampled_as_boolean
48
48
  @logger && @logger.warn("Using a boolean in the Sampled header is deprecated. Consider setting sampled_as_boolean to false")
49
49
  end
50
+ # When set to true, only routable requests are sampled
51
+ @check_routes = config[:check_routes].nil? ? DEFAULTS[:check_routes] : config[:check_routes]
50
52
 
51
53
  # When set to true, high 8-bytes will be prepended to trace_id.
52
54
  # The upper 4-bytes are epoch seconds and the lower 4-bytes are random.
@@ -95,6 +97,7 @@ module ZipkinTracer
95
97
  DEFAULTS = {
96
98
  sample_rate: 0.1,
97
99
  sampled_as_boolean: true,
100
+ check_routes: false,
98
101
  trace_id_128bit: false,
99
102
  write_b3_single_format: false
100
103
  }
@@ -11,15 +11,17 @@ module ZipkinTracer
11
11
 
12
12
  each_endpoint(spans) do |endpoint|
13
13
  hostname = endpoint.ipv4
14
- unless resolved_ip_address?(hostname.to_s)
15
- endpoint.ipv4 = resolved_hosts[hostname]
16
- end
14
+ next unless hostname
15
+ next if resolved_ip_address?(hostname.to_s)
16
+
17
+ endpoint.ipv4 = resolved_hosts[hostname]
17
18
  end
18
19
  end
19
20
 
20
21
  private
22
+
21
23
  LOCALHOST = '127.0.0.1'.freeze
22
- LOCALHOST_I32 = 0x7f000001.freeze
24
+ LOCALHOST_I32 = 0x7f000001
23
25
  MAX_I32 = ((2 ** 31) - 1)
24
26
  MASK = (2 ** 32) - 1
25
27
  IP_FIELD = 3
@@ -49,10 +51,9 @@ module ZipkinTracer
49
51
  end
50
52
 
51
53
  def resolve(hosts, ip_format)
52
- hosts.inject({}) do |host_map, host|
54
+ hosts.each_with_object({}) do |host, host_map|
53
55
  hostname = host.ipv4 # This field has been temporarly used to store the hostname.
54
- host_map[hostname] = host_to_format(hostname, ip_format)
55
- host_map
56
+ host_map[hostname] = host_to_format(hostname, ip_format) if hostname
56
57
  end
57
58
  end
58
59
 
@@ -25,6 +25,7 @@ module ZipkinTracer
25
25
  @app.call(env)
26
26
  else
27
27
  @tracer.with_new_span(trace_id, span_name(env)) do |span|
28
+ span.kind = Trace::Span::Kind::SERVER
28
29
  trace!(span, zipkin_env) { @app.call(env) }
29
30
  end
30
31
  end
@@ -55,7 +56,6 @@ module ZipkinTracer
55
56
  end
56
57
 
57
58
  def trace_server_information(span, zipkin_env, status)
58
- span.kind = Trace::Span::Kind::SERVER
59
59
  span.record_status(status)
60
60
  SERVER_RECV_TAGS.each { |annotation_key, env_key| span.record_tag(annotation_key, zipkin_env.env[env_key]) }
61
61
  end
@@ -71,7 +71,7 @@ module ZipkinTracer
71
71
  if parent_trace_sampled # A service upstream decided this goes in all the way
72
72
  parent_trace_sampled
73
73
  else
74
- new_sampled_header_value(force_sample? || current_trace_sampled? && !filtered? && routable_request?)
74
+ new_sampled_header_value(force_sample? || current_trace_sampled? && !filtered? && traceable_request?)
75
75
  end
76
76
  end
77
77
 
@@ -83,9 +83,10 @@ module ZipkinTracer
83
83
  @config.filter_plugin && !@config.filter_plugin.call(@env)
84
84
  end
85
85
 
86
- def routable_request?
86
+ def traceable_request?
87
+ return true unless @config.check_routes
88
+
87
89
  Application.routable_request?(@env)
88
90
  end
89
-
90
91
  end
91
92
  end
@@ -0,0 +1,4 @@
1
+ require 'aws-sdk-sqs'
2
+ require 'zipkin-tracer/sqs/zipkin-tracer'
3
+
4
+ Aws::SQS::Client.prepend(ZipkinTracer::SqsHandler)
@@ -0,0 +1,57 @@
1
+ module ZipkinTracer
2
+ # This module is designed to prepend to the SQS client to add trace data as message attributes.
3
+ # https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-sqs/lib/aws-sdk-sqs/client.rb
4
+ module SqsHandler
5
+ def send_message(params = {}, options = {})
6
+ zipkin_sqs_trace_wrapper(params, __method__) { |params_with_trace| super(params_with_trace, options) }
7
+ end
8
+
9
+ def send_message_batch(params = {}, options = {})
10
+ zipkin_sqs_trace_wrapper(params, __method__) { |params_with_trace| super(params_with_trace, options) }
11
+ end
12
+
13
+ private
14
+
15
+ ZIPKIN_KEYS = %i[trace_id parent_id span_id sampled].freeze
16
+ ZIPKIN_REMOTE_ENDPOINT_SQS = Trace::Endpoint.remote_endpoint(nil, 'amazon-sqs')
17
+
18
+ def zipkin_sqs_trace_wrapper(params, method_name)
19
+ trace_id = TraceGenerator.new.next_trace_id
20
+ zipkin_set_message_attributes(params, method_name, trace_id)
21
+
22
+ TraceContainer.with_trace_id(trace_id) do
23
+ if Trace.tracer && trace_id.sampled?
24
+ Trace.tracer.with_new_span(trace_id, method_name) do |span|
25
+ span.kind = Trace::Span::Kind::PRODUCER
26
+ span.remote_endpoint = ZIPKIN_REMOTE_ENDPOINT_SQS
27
+ span.record_tag('queue.url', params[:queue_url])
28
+ yield(params)
29
+ end
30
+ else
31
+ yield(params)
32
+ end
33
+ end
34
+ end
35
+
36
+ def zipkin_set_message_attributes(params, method_name, trace_id)
37
+ attributes = zipkin_message_attributes(trace_id)
38
+ case method_name
39
+ when :send_message
40
+ params[:message_attributes] = attributes.merge(params[:message_attributes] || {})
41
+ when :send_message_batch
42
+ params[:entries].each do |entry|
43
+ entry[:message_attributes] = attributes.merge(entry[:message_attributes] || {})
44
+ end
45
+ end
46
+ end
47
+
48
+ def zipkin_message_attributes(trace_id)
49
+ ZIPKIN_KEYS.each_with_object({}) do |zipkin_key, message_attributes|
50
+ zipkin_value = trace_id.send(zipkin_key)
51
+ next unless zipkin_value
52
+
53
+ message_attributes[zipkin_key] = { string_value: zipkin_value.to_s, data_type: 'String' }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -115,21 +115,21 @@ module Trace
115
115
  end
116
116
 
117
117
  def next_id
118
- TraceId.new(@trace_id, @span_id, ZipkinTracer::TraceGenerator.new.generate_id, @sampled, @flags)
118
+ TraceId.new(trace_id, span_id, ZipkinTracer::TraceGenerator.new.generate_id, sampled, flags)
119
119
  end
120
120
 
121
121
  # the debug flag is used to ensure the trace passes ALL samplers
122
122
  def debug?
123
- @flags & Flags::DEBUG == Flags::DEBUG
123
+ flags & Flags::DEBUG == Flags::DEBUG
124
124
  end
125
125
 
126
126
  def sampled?
127
- debug? || ['1', 'true'].include?(@sampled)
127
+ debug? || %w[1 true].include?(sampled)
128
128
  end
129
129
 
130
130
  def to_s
131
- "TraceId(trace_id = #{@trace_id.to_s}, parent_id = #{@parent_id.to_s}, span_id = #{@span_id.to_s}," \
132
- " sampled = #{@sampled.to_s}, flags = #{@flags.to_s}, shared = #{@shared.to_s})"
131
+ "TraceId(trace_id = #{trace_id}, parent_id = #{parent_id}, span_id = #{span_id}," \
132
+ " sampled = #{sampled}, flags = #{flags}, shared = #{shared})"
133
133
  end
134
134
  end
135
135
 
@@ -277,8 +277,8 @@ module Trace
277
277
  end
278
278
 
279
279
  def self.remote_endpoint(url, remote_service_name)
280
- service_name = remote_service_name || url.host.split('.').first || UNKNOWN_URL # default to url-derived service name
281
- Endpoint.new(url.host, url.port, service_name)
280
+ service_name = remote_service_name || url&.host&.split('.')&.first || UNKNOWN_URL # default to url-derived service name
281
+ Endpoint.new(url&.host, url&.port, service_name)
282
282
  end
283
283
 
284
284
  def to_h
@@ -1,10 +1,13 @@
1
1
  module ZipkinTracer
2
2
  class TraceWrapper
3
- def self.wrap_in_custom_span(config, span_name, span_kind: Trace::Span::Kind::SERVER, app: nil)
3
+ REQUIRED_KEYS = %i[trace_id span_id].freeze
4
+ KEYS = %i[trace_id parent_id span_id sampled].freeze
5
+
6
+ def self.wrap_in_custom_span(config, span_name, span_kind: Trace::Span::Kind::SERVER, app: nil, trace_context: nil)
4
7
  raise ArgumentError, "you must provide a block" unless block_given?
5
8
 
6
9
  initialize_tracer(app, config)
7
- trace_id = ZipkinTracer::TraceGenerator.new.next_trace_id
10
+ trace_id = next_trace_id(trace_context)
8
11
 
9
12
  ZipkinTracer::TraceContainer.with_trace_id(trace_id) do
10
13
  if trace_id.sampled?
@@ -24,5 +27,13 @@ module ZipkinTracer
24
27
  zipkin_config = ZipkinTracer::Config.new(app, config).freeze
25
28
  ZipkinTracer::TracerFactory.new.tracer(zipkin_config)
26
29
  end
30
+
31
+ def self.next_trace_id(trace_context)
32
+ if trace_context.is_a?(Hash) && REQUIRED_KEYS.all? { |key| trace_context.key?(key) }
33
+ Trace::TraceId.new(*trace_context.values_at(*KEYS), Trace::Flags::EMPTY).next_id
34
+ else
35
+ ZipkinTracer::TraceGenerator.new.next_trace_id
36
+ end
37
+ end
27
38
  end
28
39
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ZipkinTracer
4
- VERSION = '0.44.0'
4
+ VERSION = '0.47.2'
5
5
  end
@@ -7,8 +7,7 @@ module Trace
7
7
  # Senders dealing with zipkin should inherit from this class and implement the
8
8
  # flush! method which actually sends the information
9
9
  class ZipkinSenderBase
10
-
11
- def initialize(options={})
10
+ def initialize(options = {})
12
11
  @options = options
13
12
  reset
14
13
  end
@@ -39,8 +38,9 @@ module Trace
39
38
  end
40
39
 
41
40
  def skip_flush?(span)
42
- return true if span.kind == Trace::Span::Kind::CLIENT && span.has_parent_span?
43
- return true if span.kind == Trace::Span::Kind::PRODUCER && spans.any? { |s| s.kind == Trace::Span::Kind::SERVER }
41
+ return false if span.kind == Trace::Span::Kind::SERVER || span.kind == Trace::Span::Kind::CONSUMER
42
+
43
+ spans.any? { |s| s.kind == Trace::Span::Kind::SERVER || s.kind == Trace::Span::Kind::CONSUMER }
44
44
  end
45
45
 
46
46
  def flush!
@@ -62,6 +62,5 @@ module Trace
62
62
  def reset
63
63
  Thread.current[THREAD_KEY] = []
64
64
  end
65
-
66
65
  end
67
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zipkin-tracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.44.0
4
+ version: 0.47.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franklin Hu
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2020-04-16 00:00:00.000000000 Z
17
+ date: 2020-10-12 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: faraday
@@ -241,6 +241,8 @@ files:
241
241
  - lib/zipkin-tracer/rack/zipkin-tracer.rb
242
242
  - lib/zipkin-tracer/rack/zipkin_env.rb
243
243
  - lib/zipkin-tracer/sidekiq/middleware.rb
244
+ - lib/zipkin-tracer/sqs/adapter.rb
245
+ - lib/zipkin-tracer/sqs/zipkin-tracer.rb
244
246
  - lib/zipkin-tracer/trace.rb
245
247
  - lib/zipkin-tracer/trace_client.rb
246
248
  - lib/zipkin-tracer/trace_container.rb