zipkin 0.2.0 → 0.3.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
  SHA1:
3
- metadata.gz: 504536eebfe1f9f6ce03dd1c9bb1ef0d2c0d870f
4
- data.tar.gz: 9e7638f5c9b6cfc0a1061955f3475ad1c5f352d8
3
+ metadata.gz: 6f92fdc7348802e3c0b140837bdb2f5d48cfe442
4
+ data.tar.gz: '0881fd1f33ab80865a57b2e53b2be6d059a2ff9f'
5
5
  SHA512:
6
- metadata.gz: 0fff4fc9878ad37a878968c8805a755f110ac98418dcd88f4229fca5ceb41642c3f66df02a2aad9a0d1903e9dfbd824a359dff77d870a33b5de936b53fe04bfe
7
- data.tar.gz: 31b4d916668c882181a08aeb1026557e42051a5ea6b7c91074085ff83ade66153ea3df616ca001ef67a48e804f114cedc45faacffa02441621c58fe477b36135
6
+ metadata.gz: 20dec927215cc426b259b496a679c974ea2cdcac3e22ce21c0469af8aa2bf26ffebaaf88283877d00f6b55dc20cb06dd69d25660a86057aed8755479c15c5d9d
7
+ data.tar.gz: a116973247a56ad090eb6f3c0820073bba313f1790e1013c217ebc02a4fb2b78f9f5c933b97723e79d6413548b0586c2a180a01a54b81ccc74d5681baa640be5
@@ -0,0 +1,73 @@
1
+ require 'thread'
2
+
3
+ module Zipkin
4
+ class Collector
5
+ def initialize(local_endpoint)
6
+ @buffer = Buffer.new
7
+ @local_endpoint = local_endpoint
8
+ end
9
+
10
+ def retrieve
11
+ @buffer.retrieve
12
+ end
13
+
14
+ def send_span(span, end_time)
15
+ finish_ts = (end_time.to_f * 1_000_000).to_i
16
+ start_ts = (span.start_time.to_f * 1_000_000).to_i
17
+ duration = finish_ts - start_ts
18
+ is_server = ['server', 'consumer'].include?(span.tags['span.kind'] || 'server')
19
+
20
+ @buffer << {
21
+ traceId: span.context.trace_id,
22
+ id: span.context.span_id,
23
+ parentId: span.context.parent_id,
24
+ name: span.operation_name,
25
+ timestamp: start_ts,
26
+ duration: duration,
27
+ annotations: [
28
+ {
29
+ timestamp: start_ts,
30
+ value: is_server ? 'sr' : 'cs',
31
+ endpoint: @local_endpoint
32
+ },
33
+ {
34
+ timestamp: finish_ts,
35
+ value: is_server ? 'ss': 'cr',
36
+ endpoint: @local_endpoint
37
+ }
38
+ ],
39
+ binaryAnnotations: build_binary_annotations(span)
40
+ }
41
+ end
42
+
43
+ private
44
+
45
+ def build_binary_annotations(span)
46
+ span.tags.map do |name, value|
47
+ {key: name, value: value.to_s}
48
+ end
49
+ end
50
+
51
+ class Buffer
52
+ def initialize
53
+ @buffer = []
54
+ @mutex = Mutex.new
55
+ end
56
+
57
+ def <<(element)
58
+ @mutex.synchronize do
59
+ @buffer << element
60
+ true
61
+ end
62
+ end
63
+
64
+ def retrieve
65
+ @mutex.synchronize do
66
+ elements = @buffer.dup
67
+ @buffer.clear
68
+ elements
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,5 @@
1
+ require 'socket'
2
+
1
3
  module Zipkin
2
4
  class Endpoint
3
5
  LOCAL_IP = Socket.ip_address_list.detect(&:ipv4_private?).ip_address
@@ -1,33 +1,43 @@
1
- require 'faraday'
2
- require 'faraday_middleware'
3
- require 'sucker_punch'
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
4
 
5
5
  module Zipkin
6
6
  class JsonClient
7
- def initialize(url)
8
- @faraday = Faraday.new(url: url) do |faraday|
9
- faraday.request :json
10
- faraday.request :retry, max: 3, interval: 10, backoff_factor: 2
11
- faraday.adapter Faraday.default_adapter
7
+ def initialize(url:, collector:, flush_interval:)
8
+ @collector = collector
9
+ @flush_interval = flush_interval
10
+ @spans_uri = URI.parse("#{url}/api/v1/spans")
11
+ end
12
+
13
+ def start
14
+ @thread = Thread.new do
15
+ loop do
16
+ emit_batch(@collector.retrieve)
17
+ sleep @flush_interval
18
+ end
12
19
  end
13
20
  end
14
21
 
15
- def send_span(payload)
16
- SpanSender.perform_async(payload: payload, faraday: @faraday)
22
+ def stop
23
+ @thread.terminate if @thread
24
+ emit_batch(@collector.retrieve)
17
25
  end
18
26
 
19
- class SpanSender
20
- include SuckerPunch::Job
21
- workers 4
27
+ private
22
28
 
23
- def perform(payload:, faraday:)
24
- response = faraday.post '/api/v1/spans' do |req|
25
- req.body = [payload]
26
- end
29
+ def emit_batch(spans)
30
+ return if spans.empty?
27
31
 
28
- if response.status != 202
29
- STDERR.puts(response.body)
30
- end
32
+ http = Net::HTTP.new(@spans_uri.host, @spans_uri.port)
33
+ request = Net::HTTP::Post.new(@spans_uri.request_uri, {
34
+ 'Content-Type' => 'application/json'
35
+ })
36
+ request.body = JSON.dump(spans)
37
+ response = http.request(request)
38
+
39
+ if response.code != 202
40
+ STDERR.puts(response.body)
31
41
  end
32
42
  end
33
43
  end
data/lib/zipkin/span.rb CHANGED
@@ -2,22 +2,21 @@ module Zipkin
2
2
  class Span
3
3
  attr_accessor :operation_name
4
4
 
5
- attr_reader :context
5
+ attr_reader :context, :start_time, :tags
6
6
 
7
7
  # Creates a new {Span}
8
8
  #
9
9
  # @param context [SpanContext] the context of the span
10
- # @param context [String] the operation name
11
- # @param client [Faraday] faraday instace for making http requests
10
+ # @param operation_name [String] the operation name
11
+ # @param collector [Collector] the span collector
12
12
  #
13
13
  # @return [Span] a new Span
14
- def initialize(context, operation_name, client, start_time: Time.now, tags: {}, local_endpoint:)
14
+ def initialize(context, operation_name, collector, start_time: Time.now, tags: {})
15
15
  @context = context
16
16
  @operation_name = operation_name
17
- @client = client
17
+ @collector = collector
18
18
  @start_time = start_time
19
19
  @tags = tags
20
- @local_endpoint = local_endpoint
21
20
  end
22
21
 
23
22
  # Set a tag value on this span
@@ -59,40 +58,7 @@ module Zipkin
59
58
  #
60
59
  # @param end_time [Time] custom end time, if not now
61
60
  def finish(end_time: Time.now)
62
- finish_ts = (end_time.to_f * 1_000_000).to_i
63
- start_ts = (@start_time.to_f * 1_000_000).to_i
64
- duration = finish_ts - start_ts
65
- is_server = ['server', 'consumer'].include?(@tags['span.kind'] || 'server')
66
-
67
- @client.send_span(
68
- traceId: @context.trace_id,
69
- id: @context.span_id,
70
- parentId: @context.parent_id,
71
- name: @operation_name,
72
- timestamp: start_ts,
73
- duration: duration,
74
- annotations: [
75
- {
76
- timestamp: start_ts,
77
- value: is_server ? 'sr' : 'cs',
78
- endpoint: @local_endpoint
79
- },
80
- {
81
- timestamp: finish_ts,
82
- value: is_server ? 'ss': 'cr',
83
- endpoint: @local_endpoint
84
- }
85
- ],
86
- binaryAnnotations: build_binary_annotations
87
- )
88
- end
89
-
90
- private
91
-
92
- def build_binary_annotations
93
- @tags.map do |name, value|
94
- {key: name, value: value.to_s}
95
- end
61
+ @collector.send_span(self, end_time)
96
62
  end
97
63
  end
98
64
  end
@@ -3,24 +3,30 @@ module Zipkin
3
3
  class SpanContext
4
4
  def self.create_parent_context
5
5
  trace_id = TraceId.generate
6
- span_id = TraceId.generate
7
- new(trace_id: trace_id, span_id: span_id)
6
+ new(trace_id: trace_id, span_id: trace_id, sampled: true)
8
7
  end
9
8
 
10
9
  def self.create_from_parent_context(span_context)
11
- trace_id = span_context.trace_id
12
- parent_id = span_context.span_id
13
- span_id = TraceId.generate
14
- new(span_id: span_id, parent_id: parent_id, trace_id: trace_id)
10
+ new(
11
+ span_id: TraceId.generate,
12
+ parent_id: span_context.span_id,
13
+ trace_id: span_context.trace_id,
14
+ sampled: span_context.sampled?
15
+ )
15
16
  end
16
17
 
17
18
  attr_reader :span_id, :parent_id, :trace_id, :baggage
18
19
 
19
- def initialize(span_id:, parent_id: nil, trace_id:, baggage: {})
20
+ def initialize(span_id:, parent_id: nil, trace_id:, sampled:, baggage: {})
20
21
  @span_id = span_id
21
22
  @parent_id = parent_id
22
23
  @trace_id = trace_id
24
+ @sampled = sampled
23
25
  @baggage = baggage
24
26
  end
27
+
28
+ def sampled?
29
+ @sampled
30
+ end
25
31
  end
26
32
  end
data/lib/zipkin/tracer.rb CHANGED
@@ -6,17 +6,30 @@ require_relative 'carrier'
6
6
  require_relative 'trace_id'
7
7
  require_relative 'json_client'
8
8
  require_relative 'endpoint'
9
+ require_relative 'collector'
9
10
 
10
11
  module Zipkin
11
12
  class Tracer
12
- def self.build(url:, service_name:)
13
- client = JsonClient.new(url)
14
- new(client, service_name)
13
+ DEFAULT_FLUSH_INTERVAL = 10
14
+
15
+ def self.build(url:, service_name:, flush_interval: DEFAULT_FLUSH_INTERVAL)
16
+ collector = Collector.new(Endpoint.local_endpoint(service_name))
17
+ sender = JsonClient.new(
18
+ url: url,
19
+ collector: collector,
20
+ flush_interval: flush_interval
21
+ )
22
+ sender.start
23
+ new(collector, sender)
24
+ end
25
+
26
+ def initialize(collector, sender)
27
+ @collector = collector
28
+ @sender = sender
15
29
  end
16
30
 
17
- def initialize(client, service_name)
18
- @client = client
19
- @local_endpoint = Endpoint.local_endpoint(service_name)
31
+ def stop
32
+ @sender.stop
20
33
  end
21
34
 
22
35
  # Starts a new span.
@@ -37,7 +50,10 @@ module Zipkin
37
50
  else
38
51
  SpanContext.create_parent_context
39
52
  end
40
- Span.new(context, operation_name, @client, start_time: start_time, tags: tags, local_endpoint: @local_endpoint)
53
+ Span.new(context, operation_name, @collector, {
54
+ start_time: start_time,
55
+ tags: tags
56
+ })
41
57
  end
42
58
 
43
59
  # Inject a SpanContext into the given carrier
@@ -47,14 +63,11 @@ module Zipkin
47
63
  # @param carrier [Carrier] A carrier object of the type dictated by the specified `format`
48
64
  def inject(span_context, format, carrier)
49
65
  case format
50
- when OpenTracing::FORMAT_TEXT_MAP
51
- carrier['trace-id'] = span_context.trace_id
52
- carrier['parent-id'] = span_context.parent_id
53
- carrier['span-id'] = span_context.span_id
54
66
  when OpenTracing::FORMAT_RACK
55
- carrier['X-Trace-Id'] = span_context.trace_id
56
- carrier['X-Trace-Parent-Id'] = span_context.parent_id
57
- carrier['X-Trace-Span-Id'] = span_context.span_id
67
+ carrier['X-B3-TraceId'] = span_context.trace_id
68
+ carrier['X-B3-ParentSpanId'] = span_context.parent_id
69
+ carrier['X-B3-SpanId'] = span_context.span_id
70
+ carrier['X-B3-Sampled'] = span_context.sampled? ? '1' : '0'
58
71
  else
59
72
  STDERR.puts "Logasm::Tracer with format #{format} is not supported yet"
60
73
  end
@@ -67,23 +80,19 @@ module Zipkin
67
80
  # @return [SpanContext] the extracted SpanContext or nil if none could be found
68
81
  def extract(format, carrier)
69
82
  case format
70
- when OpenTracing::FORMAT_TEXT_MAP
71
- trace_id = carrier['trace-id']
72
- parent_id = carrier['parent-id']
73
- span_id = carrier['span-id']
74
-
75
- if trace_id && span_id
76
- SpanContext.new(trace_id: trace_id, parent_id: parent_id, span_id: span_id)
77
- else
78
- nil
79
- end
80
83
  when OpenTracing::FORMAT_RACK
81
- trace_id = carrier['HTTP_X_TRACE_ID']
82
- parent_id = carrier['HTTP_X_TRACE_PARENT_ID']
83
- span_id = carrier['HTTP_X_TRACE_SPAN_ID']
84
+ trace_id = carrier['HTTP_X_B3_TRACEID']
85
+ parent_id = carrier['HTTP_X_B3_PARENTSPANID']
86
+ span_id = carrier['HTTP_X_B3_SPANID']
87
+ sampled = carrier['HTTP_X_B3_SAMPLED'] == '1'
84
88
 
85
89
  if trace_id && span_id
86
- SpanContext.new(trace_id: trace_id, parent_id: parent_id, span_id: span_id)
90
+ SpanContext.new(
91
+ trace_id: trace_id,
92
+ parent_id: parent_id,
93
+ span_id: span_id,
94
+ sampled: sampled
95
+ )
87
96
  else
88
97
  nil
89
98
  end
data/script/create_trace CHANGED
@@ -38,3 +38,8 @@ outer_span.finish
38
38
 
39
39
  puts "Finishing..."
40
40
  sleep 3
41
+
42
+ tracer1.stop
43
+ tracer2.stop
44
+
45
+ puts "Finished"
data/zipkin.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'zipkin'
7
- spec.version = '0.2.0'
7
+ spec.version = '0.3.0'
8
8
  spec.authors = ['SaleMove TechMovers']
9
9
  spec.email = ['techmovers@salemove.com']
10
10
 
@@ -24,7 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'rspec', '~> 3.0'
25
25
 
26
26
  spec.add_dependency 'opentracing', '~> 0.3'
27
- spec.add_dependency 'faraday'
28
- spec.add_dependency 'faraday_middleware'
29
- spec.add_dependency 'sucker_punch', '~> 2.0'
27
+ spec.add_dependency 'json'
30
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zipkin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SaleMove TechMovers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-20 00:00:00.000000000 Z
11
+ date: 2017-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.3'
69
69
  - !ruby/object:Gem::Dependency
70
- name: faraday
70
+ name: json
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -80,34 +80,6 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: faraday_middleware
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: sucker_punch
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '2.0'
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '2.0'
111
83
  description: ''
112
84
  email:
113
85
  - techmovers@salemove.com
@@ -126,6 +98,7 @@ files:
126
98
  - bin/setup
127
99
  - lib/zipkin.rb
128
100
  - lib/zipkin/carrier.rb
101
+ - lib/zipkin/collector.rb
129
102
  - lib/zipkin/endpoint.rb
130
103
  - lib/zipkin/json_client.rb
131
104
  - lib/zipkin/span.rb
@@ -154,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
127
  version: '0'
155
128
  requirements: []
156
129
  rubyforge_project:
157
- rubygems_version: 2.6.8
130
+ rubygems_version: 2.6.11
158
131
  signing_key:
159
132
  specification_version: 4
160
133
  summary: OpenTracing Tracer implementation for Zipkin in Ruby