zipkin-tracer 0.32.4 → 0.33.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3d88ef693423edc75cf6fcddfd3197bf653a6629ee36febbeaeda1eafa08ff4
4
- data.tar.gz: c1e83e93144a84a8eaa632dbc50f90e32ee15414614faf3cda15d08f4a06dd18
3
+ metadata.gz: 0da9730b55f7aa56b8b1080b4de79c731e6e09997e1c8ed958f0954d9f9acd70
4
+ data.tar.gz: 5a780069dfa04fe86a86fd805c89f00db11ba5af1f29057625b90d6aa03adf87
5
5
  SHA512:
6
- metadata.gz: 1904ec28b08c0be932e19a6f46275cd48d515bc9002739cfc0d799e89da40eba8f3c0f983f6594ac4c38e2f8a7f19880ae03b2aadd7750cb83545a98c4db78d9
7
- data.tar.gz: fd5c944ce0bfc2024f04562373dbe0185e6da0df9e07392bea5ba9ec197e641126bca4e3e133f9eee1b1abcee4c909ebfc8ea8a7e8eec1c07e2e6a4c68e22e5b
6
+ metadata.gz: 95aab26491cde2e63b9d1e8a304b0edbac6658ee524143b202e53486a5f5552e738749fd16b274b74e7fc894c0d8bc30097e5bca2a5a26441815df662c389b3d
7
+ data.tar.gz: 8826d81412e97b9f0dd1c551bebd959b56782a690a76779d7da81169259c6bcad14cb8a5674c92d7fc6384ef55f5db932aad6d601628339c056439279632f5c7
@@ -28,10 +28,7 @@ module ZipkinTracer
28
28
  def response_call(datum)
29
29
  if span = datum[:span]
30
30
  status = response_status(datum)
31
- if status
32
- record_response_tags(span, status, local_endpoint)
33
- end
34
- span.record(Trace::Annotation::CLIENT_RECV, local_endpoint)
31
+ record_response_tags(span, status) if status
35
32
  Trace.tracer.end_span(span)
36
33
  end
37
34
 
@@ -53,12 +50,8 @@ module ZipkinTracer
53
50
  }
54
51
  end
55
52
 
56
- def local_endpoint
57
- Trace.default_endpoint # The rack middleware set this up for us.
58
- end
59
-
60
53
  def remote_endpoint(url, service_name)
61
- Trace::Endpoint.remote_endpoint(url, service_name, local_endpoint.ip_format) # The endpoint we are calling.
54
+ Trace::Endpoint.remote_endpoint(url, service_name, Trace.default_endpoint.ip_format) # The endpoint we are calling.
62
55
  end
63
56
 
64
57
  def service_name(datum, default)
@@ -69,12 +62,9 @@ module ZipkinTracer
69
62
  datum[:response] && datum[:response][:status] && datum[:response][:status].to_s
70
63
  end
71
64
 
72
- def record_response_tags(span, status, local_endpoint)
73
- span.record_tag(Trace::BinaryAnnotation::STATUS, status, Trace::BinaryAnnotation::Type::STRING, local_endpoint)
74
- if STATUS_ERROR_REGEXP.match(status)
75
- span.record_tag(Trace::BinaryAnnotation::ERROR, status,
76
- Trace::BinaryAnnotation::Type::STRING, local_endpoint)
77
- end
65
+ def record_response_tags(span, status)
66
+ span.record_tag(Trace::Span::Tag::STATUS, status)
67
+ span.record_tag(Trace::Span::Tag::ERROR, status) if STATUS_ERROR_REGEXP.match(status)
78
68
  end
79
69
 
80
70
  def trace!(datum, trace_id)
@@ -85,10 +75,10 @@ module ZipkinTracer
85
75
 
86
76
  span = Trace.tracer.start_span(trace_id, method.downcase)
87
77
  # annotate with method (GET/POST/etc.) and uri path
88
- span.record_tag(Trace::BinaryAnnotation::METHOD, method.upcase, Trace::BinaryAnnotation::Type::STRING, local_endpoint)
89
- span.record_tag(Trace::BinaryAnnotation::PATH, url.path, Trace::BinaryAnnotation::Type::STRING, local_endpoint)
90
- span.record_tag(Trace::BinaryAnnotation::SERVER_ADDRESS, SERVER_ADDRESS_SPECIAL_VALUE, Trace::BinaryAnnotation::Type::BOOL, remote_endpoint(url, service_name))
91
- span.record(Trace::Annotation::CLIENT_SEND, local_endpoint)
78
+ span.kind = Trace::Span::Kind::CLIENT
79
+ span.remote_endpoint = remote_endpoint(url, service_name)
80
+ span.record_tag(Trace::Span::Tag::METHOD, method.upcase)
81
+ span.record_tag(Trace::Span::Tag::PATH, url.path)
92
82
 
93
83
  # store the span in the datum hash so it can be used in the response_call
94
84
  datum[:span] = span
@@ -44,42 +44,37 @@ module ZipkinTracer
44
44
  # handle either a URI object (passed by Faraday v0.8.x in testing), or something string-izable
45
45
  method = env[:method].to_s
46
46
  url = env[:url].respond_to?(:host) ? env[:url] : URI.parse(env[:url].to_s)
47
- local_endpoint = Trace.default_endpoint # The rack middleware set this up for us.
48
- remote_endpoint = Trace::Endpoint.remote_endpoint(url, @service_name, local_endpoint.ip_format) # The endpoint we are calling.
47
+ remote_endpoint = Trace::Endpoint.remote_endpoint(url, @service_name, Trace.default_endpoint.ip_format) # The endpoint we are calling.
49
48
  Trace.tracer.with_new_span(trace_id, method.downcase) do |span|
50
49
  @span = span # So we can record on exceptions
51
50
  # annotate with method (GET/POST/etc.) and uri path
52
- span.record_tag(Trace::BinaryAnnotation::METHOD, method.upcase, Trace::BinaryAnnotation::Type::STRING, local_endpoint)
53
- span.record_tag(Trace::BinaryAnnotation::PATH, url.path, Trace::BinaryAnnotation::Type::STRING, local_endpoint)
54
- span.record_tag(Trace::BinaryAnnotation::SERVER_ADDRESS, SERVER_ADDRESS_SPECIAL_VALUE, Trace::BinaryAnnotation::Type::BOOL, remote_endpoint)
55
- span.record(Trace::Annotation::CLIENT_SEND, local_endpoint)
51
+ span.kind = Trace::Span::Kind::CLIENT
52
+ span.remote_endpoint = remote_endpoint
53
+ span.record_tag(Trace::Span::Tag::METHOD, method.upcase)
54
+ span.record_tag(Trace::Span::Tag::PATH, url.path)
56
55
  response = @app.call(env).on_complete do |renv|
57
- record_response_tags(span, renv[:status].to_s, local_endpoint)
56
+ record_response_tags(span, renv[:status].to_s)
58
57
  end
59
- span.record(Trace::Annotation::CLIENT_RECV, local_endpoint)
60
58
  end
61
59
  response
62
60
  rescue Net::ReadTimeout
63
- record_error(@span, 'Request timed out.', local_endpoint)
61
+ record_error(@span, 'Request timed out.')
64
62
  raise
65
63
  rescue Faraday::ConnectionFailed
66
- record_error(@span, 'Request connection failed.', local_endpoint)
64
+ record_error(@span, 'Request connection failed.')
67
65
  raise
68
66
  rescue Faraday::ClientError
69
- record_error(@span, 'Generic Faraday client error.', local_endpoint)
67
+ record_error(@span, 'Generic Faraday client error.')
70
68
  raise
71
69
  end
72
70
 
73
- def record_error(span, msg, local_endpoint)
74
- span.record_tag(Trace::BinaryAnnotation::ERROR, msg, Trace::BinaryAnnotation::Type::STRING, local_endpoint)
71
+ def record_error(span, msg)
72
+ span.record_tag(Trace::Span::Tag::ERROR, msg)
75
73
  end
76
74
 
77
- def record_response_tags(span, status, local_endpoint)
78
- span.record_tag(Trace::BinaryAnnotation::STATUS, status, Trace::BinaryAnnotation::Type::STRING, local_endpoint)
79
- if STATUS_ERROR_REGEXP.match(status)
80
- span.record_tag(Trace::BinaryAnnotation::ERROR, status,
81
- Trace::BinaryAnnotation::Type::STRING, local_endpoint)
82
- end
75
+ def record_response_tags(span, status)
76
+ span.record_tag(Trace::Span::Tag::STATUS, status)
77
+ span.record_tag(Trace::Span::Tag::ERROR, status) if STATUS_ERROR_REGEXP.match(status)
83
78
  end
84
79
 
85
80
  end
@@ -1,17 +1,17 @@
1
1
  require 'resolv'
2
2
 
3
3
  module ZipkinTracer
4
- # Resolves hostnames in the endpoints of the annotations.
4
+ # Resolves hostnames in the endpoints of the spans.
5
5
  # Resolving hostnames is a very expensive operation. We want to store them raw in the main thread
6
6
  # and resolve them in a different thread where we do not affect execution times.
7
7
  class HostnameResolver
8
8
  def spans_with_ips(spans)
9
9
  host_to_ip = hosts_to_ipv4(spans)
10
10
 
11
- each_annotation(spans) do |annotation|
12
- hostname = annotation.host.ipv4
11
+ each_endpoint(spans) do |endpoint|
12
+ hostname = endpoint.ipv4
13
13
  unless resolved_ip_address?(hostname.to_s)
14
- annotation.host.ipv4 = host_to_ip[hostname]
14
+ endpoint.ipv4 = host_to_ip[hostname]
15
15
  end
16
16
  end
17
17
  end
@@ -28,24 +28,19 @@ module ZipkinTracer
28
28
  ip_string.to_i.to_s == ip_string
29
29
  end
30
30
 
31
- def each_annotation(spans, &block)
31
+ def each_endpoint(spans, &block)
32
32
  spans.each do |span|
33
- span.annotations.each do |annotation|
34
- yield annotation
35
- end
36
- span.binary_annotations.each do |annotation|
37
- yield annotation
33
+ [span.local_endpoint, span.remote_endpoint].each do |endpoint|
34
+ yield endpoint if endpoint
38
35
  end
39
36
  end
40
37
  end
41
38
 
42
- # Annotations come in pairs like CS/CR, SS/SR.
43
- # Each annnotation has a hostname so we, for sure, will have the same host multiple times.
44
39
  # Using this to resolve only once per host
45
40
  def hosts_to_ipv4(spans)
46
41
  hosts = []
47
- each_annotation(spans) do |annotation|
48
- hosts.push(annotation.host)
42
+ each_endpoint(spans) do |endpoint|
43
+ hosts.push(endpoint)
49
44
  end
50
45
  hosts.uniq!
51
46
  resolve(hosts)
@@ -61,7 +56,7 @@ module ZipkinTracer
61
56
  end
62
57
 
63
58
  def host_to_ip(hostname, ip_format)
64
- ipv4 = begin
59
+ begin
65
60
  ip_format == :string ? Socket.getaddrinfo(hostname, nil, :INET).first[IP_FIELD] : Trace::Endpoint.host_to_i32(hostname)
66
61
  rescue
67
62
  ip_format == :string ? LOCALHOST : LOCALHOST_I32
@@ -12,7 +12,7 @@ module ZipkinTracer
12
12
  REQUEST_METHOD = Rack::REQUEST_METHOD rescue 'REQUEST_METHOD'.freeze
13
13
 
14
14
  DEFAULT_SERVER_RECV_TAGS = {
15
- Trace::BinaryAnnotation::PATH => PATH_INFO
15
+ Trace::Span::Tag::PATH => PATH_INFO
16
16
  }.freeze
17
17
 
18
18
  def initialize(app, config = nil)
@@ -55,12 +55,11 @@ module ZipkinTracer
55
55
 
56
56
  def trace!(span, zipkin_env, &block)
57
57
  trace_request_information(span, zipkin_env)
58
- span.record(Trace::Annotation::SERVER_RECV)
58
+ span.kind = Trace::Span::Kind::SERVER
59
59
  span.record('whitelisted') if zipkin_env.force_sample?
60
60
  status, headers, body = yield
61
61
  ensure
62
62
  annotate_plugin(span, zipkin_env.env, status, headers, body)
63
- span.record(Trace::Annotation::SERVER_SEND)
64
63
  end
65
64
 
66
65
  def trace_request_information(span, zipkin_env)
@@ -10,10 +10,10 @@ module ZipkinTracer
10
10
  end
11
11
 
12
12
  def trace_id(default_flags = Trace::Flags::EMPTY)
13
- trace_id, span_id, parent_span_id = retrieve_or_generate_ids
13
+ trace_id, span_id, parent_span_id, shared = retrieve_or_generate_ids
14
14
  sampled = sampled_header_value(@env['HTTP_X_B3_SAMPLED'])
15
15
  flags = (@env['HTTP_X_B3_FLAGS'] || default_flags).to_i
16
- Trace::TraceId.new(trace_id, parent_span_id, span_id, sampled, flags)
16
+ Trace::TraceId.new(trace_id, parent_span_id, span_id, sampled, flags, shared)
17
17
  end
18
18
 
19
19
  def called_with_zipkin_headers?
@@ -33,12 +33,14 @@ module ZipkinTracer
33
33
  if called_with_zipkin_headers?
34
34
  trace_id, span_id = @env.values_at(*B3_REQUIRED_HEADERS)
35
35
  parent_span_id = @env['HTTP_X_B3_PARENTSPANID']
36
+ shared = true
36
37
  else
37
38
  span_id = TraceGenerator.new.generate_id
38
39
  trace_id = TraceGenerator.new.generate_id_from_span_id(span_id)
39
40
  parent_span_id = nil
41
+ shared = false
40
42
  end
41
- [trace_id, span_id, parent_span_id]
43
+ [trace_id, span_id, parent_span_id, shared]
42
44
  end
43
45
 
44
46
  def new_sampled_header_value(sampled)
@@ -48,54 +48,17 @@ module Trace
48
48
  # Moved here as a first step, eventually move them out of the Trace module
49
49
 
50
50
  class Annotation
51
- CLIENT_SEND = "cs"
52
- CLIENT_RECV = "cr"
53
- SERVER_SEND = "ss"
54
- SERVER_RECV = "sr"
51
+ attr_reader :value, :timestamp
55
52
 
56
- attr_reader :value, :host, :timestamp
57
- def initialize(value, host)
53
+ def initialize(value)
58
54
  @timestamp = (Time.now.to_f * 1000 * 1000).to_i # micros
59
55
  @value = value
60
- @host = host
61
- end
62
-
63
- def to_h
64
- {
65
- value: @value,
66
- timestamp: @timestamp,
67
- endpoint: host.to_h
68
- }
69
- end
70
- end
71
-
72
- class BinaryAnnotation
73
- SERVER_ADDRESS = 'sa'.freeze
74
- URI = 'http.url'.freeze
75
- METHOD = 'http.method'.freeze
76
- PATH = 'http.path'.freeze
77
- STATUS = 'http.status'.freeze
78
- LOCAL_COMPONENT = 'lc'.freeze
79
- ERROR = 'error'.freeze
80
-
81
- module Type
82
- BOOL = "BOOL"
83
- STRING = "STRING"
84
- end
85
- attr_reader :key, :value, :host
86
-
87
- def initialize(key, value, annotation_type, host)
88
- @key = key
89
- @value = value
90
- @annotation_type = annotation_type
91
- @host = host
92
56
  end
93
57
 
94
58
  def to_h
95
59
  {
96
- key: @key,
97
60
  value: @value,
98
- endpoint: host.to_h
61
+ timestamp: @timestamp
99
62
  }
100
63
  end
101
64
  end
@@ -138,14 +101,15 @@ module Trace
138
101
 
139
102
  # A TraceId contains all the information of a given trace id
140
103
  class TraceId
141
- attr_reader :trace_id, :parent_id, :span_id, :sampled, :flags
104
+ attr_reader :trace_id, :parent_id, :span_id, :sampled, :flags, :shared
142
105
 
143
- def initialize(trace_id, parent_id, span_id, sampled, flags)
106
+ def initialize(trace_id, parent_id, span_id, sampled, flags, shared = false)
144
107
  @trace_id = Trace.trace_id_128bit ? TraceId128Bit.from_value(trace_id) : SpanId.from_value(trace_id)
145
108
  @parent_id = parent_id.nil? ? nil : SpanId.from_value(parent_id)
146
109
  @span_id = SpanId.from_value(span_id)
147
110
  @sampled = sampled
148
111
  @flags = flags
112
+ @shared = shared
149
113
  end
150
114
 
151
115
  def next_id
@@ -162,7 +126,8 @@ module Trace
162
126
  end
163
127
 
164
128
  def to_s
165
- "TraceId(trace_id = #{@trace_id.to_s}, parent_id = #{@parent_id.to_s}, span_id = #{@span_id.to_s}, sampled = #{@sampled.to_s}, flags = #{@flags.to_s})"
129
+ "TraceId(trace_id = #{@trace_id.to_s}, parent_id = #{@parent_id.to_s}, span_id = #{@span_id.to_s}," \
130
+ " sampled = #{@sampled.to_s}, flags = #{@flags.to_s}, shared = #{@shared.to_s})"
166
131
  end
167
132
  end
168
133
 
@@ -199,12 +164,29 @@ module Trace
199
164
 
200
165
  # A span may contain many annotations
201
166
  class Span
202
- attr_accessor :name, :annotations, :binary_annotations, :debug
167
+ module Tag
168
+ METHOD = "http.method".freeze
169
+ PATH = "http.path".freeze
170
+ STATUS = "http.status_code".freeze
171
+ LOCAL_COMPONENT = "lc".freeze # TODO: Remove LOCAL_COMPONENT and related methods when no longer needed
172
+ ERROR = "error".freeze
173
+ end
174
+
175
+ module Kind
176
+ CLIENT = "CLIENT".freeze
177
+ SERVER = "SERVER".freeze
178
+ end
179
+
180
+ attr_accessor :name, :kind, :local_endpoint, :remote_endpoint, :annotations, :tags, :debug
181
+
203
182
  def initialize(name, span_id)
204
183
  @name = name
205
184
  @span_id = span_id
185
+ @kind = nil
186
+ @local_endpoint = nil
187
+ @remote_endpoint = nil
206
188
  @annotations = []
207
- @binary_annotations = []
189
+ @tags = {}
208
190
  @debug = span_id.debug?
209
191
  @timestamp = to_microseconds(Time.now)
210
192
  @duration = UNKNOWN_DURATION
@@ -219,28 +201,31 @@ module Trace
219
201
  name: @name,
220
202
  traceId: @span_id.trace_id.to_s,
221
203
  id: @span_id.span_id.to_s,
222
- annotations: @annotations.map(&:to_h),
223
- binaryAnnotations: @binary_annotations.map(&:to_h),
204
+ localEndpoint: @local_endpoint.to_h,
224
205
  timestamp: @timestamp,
225
206
  duration: @duration,
226
207
  debug: @debug
227
208
  }
228
209
  h[:parentId] = @span_id.parent_id.to_s unless @span_id.parent_id.nil?
210
+ h[:kind] = @kind unless @kind.nil?
211
+ h[:remoteEndpoint] = @remote_endpoint.to_h unless @remote_endpoint.nil?
212
+ h[:annotations] = @annotations.map(&:to_h) unless @annotations.empty?
213
+ h[:tags] = @tags unless @tags.empty?
214
+ h[:shared] = true if @span_id.shared
229
215
  h
230
216
  end
231
217
 
232
218
  # We record information into spans, then we send these spans to zipkin
233
- def record(value, endpoint = Trace.default_endpoint)
234
- annotations << Trace::Annotation.new(value.to_s, endpoint)
219
+ def record(value)
220
+ annotations << Trace::Annotation.new(value.to_s)
235
221
  end
236
222
 
237
- def record_tag(key, value, type = Trace::BinaryAnnotation::Type::STRING, endpoint = Trace.default_endpoint)
238
- value = value.to_s if type == Trace::BinaryAnnotation::Type::STRING
239
- binary_annotations << Trace::BinaryAnnotation.new(key, value, type, endpoint)
223
+ def record_tag(key, value)
224
+ @tags[key] = value
240
225
  end
241
226
 
242
227
  def record_local_component(value)
243
- record_tag(BinaryAnnotation::LOCAL_COMPONENT, value)
228
+ record_tag(Tag::LOCAL_COMPONENT, value)
244
229
  end
245
230
 
246
231
  def has_parent_span?
@@ -293,6 +278,5 @@ module Trace
293
278
  hsh[:port] = port if port
294
279
  hsh
295
280
  end
296
-
297
281
  end
298
282
  end
@@ -1,3 +1,3 @@
1
1
  module ZipkinTracer
2
- VERSION = '0.32.4'.freeze
2
+ VERSION = '0.33.0'.freeze
3
3
  end
@@ -5,7 +5,7 @@ require 'zipkin-tracer/hostname_resolver'
5
5
 
6
6
  class AsyncJsonApiClient
7
7
  include SuckerPunch::Job
8
- SPANS_PATH = '/api/v1/spans'
8
+ SPANS_PATH = '/api/v2/spans'
9
9
 
10
10
  def perform(json_api_host, spans)
11
11
  spans_with_ips = ::ZipkinTracer::HostnameResolver.new.spans_with_ips(spans).map(&:to_h)
@@ -22,12 +22,10 @@ module Trace
22
22
 
23
23
  def end_span(span)
24
24
  span.close
25
- # If in a thread not handling incoming http requests, it will not have Annotation::SERVER_SEND, so the span
25
+ # If in a thread not handling incoming http requests, it will not have Kind::SERVER, so the span
26
26
  # will never be flushed and will cause memory leak.
27
- # It will have CLIENT_SEND and CLIENT_RECV if the thread sends out http requests, so use CLIENT_RECV as the sign
28
- # to flush the span.
29
27
  # If no parent span, then current span needs to flush when it ends.
30
- if !span.has_parent_span? || span.annotations.any? { |ann| ann.value == Annotation::SERVER_SEND }
28
+ if !span.has_parent_span? || span.kind == Trace::Span::Kind::SERVER
31
29
  flush!
32
30
  reset
33
31
  end
@@ -35,6 +33,7 @@ module Trace
35
33
 
36
34
  def start_span(trace_id, name)
37
35
  span = Span.new(name, trace_id)
36
+ span.local_endpoint = Trace.default_endpoint
38
37
  store_span(trace_id, span)
39
38
  span
40
39
  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.32.4
4
+ version: 0.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franklin Hu
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2019-03-01 00:00:00.000000000 Z
16
+ date: 2019-03-08 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: faraday
@@ -206,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
206
  - !ruby/object:Gem::Version
207
207
  version: 1.3.5
208
208
  requirements: []
209
- rubygems_version: 3.0.2
209
+ rubygems_version: 3.0.3
210
210
  signing_key:
211
211
  specification_version: 4
212
212
  summary: Ruby tracing via Zipkin