zipkin 0.2.0 → 0.3.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
  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