zipkin-tracer 0.32.4 → 0.33.0

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: 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