zipkin 1.6.0 → 1.6.1

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
- SHA1:
3
- metadata.gz: edcdbbb5c2b3a3c8336007ad27cca00fa18e506c
4
- data.tar.gz: e53e657b504bfed502e210cb4ece872f5d719391
2
+ SHA256:
3
+ metadata.gz: 3b88fff10737cc10e0da917018436f4e0085e2f8bf384605fec56e84450595d3
4
+ data.tar.gz: 51ca7b5a0e4b1fca2a9eeeb02f73c9d139fe8cfaf78165850951cbb4d59bab09
5
5
  SHA512:
6
- metadata.gz: 8815bc72662edeaed1773112b382134fa7b113290d6d8b1eeb62650ce18f54204048a3bfef69ae674fbbd6278af6bbc2f4603505691805eb0a260f45c9147475
7
- data.tar.gz: c28399023b46377b0f3adc267e7b2b242a2e7998302f1ca3739acc8b2411b459af4d6eeef94061640051e4eadd38cb7181e76efe10bf11d2801dab1e93a4d2b7
6
+ metadata.gz: 1c68750c7f6758f4d81d9efd045e040b30afcc36e0679c5f0f12b8623a69f2bdc7fec0ca58ee56bbd1080f710e6449e601b3a5e486e45ea6892aaf1fce942f51
7
+ data.tar.gz: 52a89cb097adfa8ff282ae95d10a22c2c799782ad13fb356769ef2e8f66830390c2e7e18280dc8bb1de969490d090fb98a2542721a11c8d9901f910b8a5e0bae
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thread'
4
+
5
+ require_relative './async_reporter/buffer'
6
+
7
+ module Zipkin
8
+ class AsyncReporter
9
+ def self.create(sender:, flush_interval:)
10
+ reporter = new(sender)
11
+
12
+ # start flush thread
13
+ Thread.new do
14
+ loop do
15
+ reporter.flush
16
+ sleep(flush_interval)
17
+ end
18
+ end
19
+
20
+ reporter
21
+ end
22
+
23
+ def initialize(sender)
24
+ @sender = sender
25
+ @buffer = Buffer.new
26
+ end
27
+
28
+ def flush
29
+ spans = @buffer.retrieve
30
+ @sender.send_spans(spans) if spans.any?
31
+ spans
32
+ end
33
+
34
+ def report(span)
35
+ return unless span.context.sampled?
36
+ @buffer << span
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zipkin
4
+ class AsyncReporter
5
+ class Buffer
6
+ def initialize
7
+ @buffer = []
8
+ @mutex = Mutex.new
9
+ end
10
+
11
+ def <<(element)
12
+ @mutex.synchronize do
13
+ @buffer << element
14
+ true
15
+ end
16
+ end
17
+
18
+ def retrieve
19
+ @mutex.synchronize do
20
+ elements = @buffer.dup
21
+ @buffer.clear
22
+ elements
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'encoders/json_encoder'
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ require_relative 'json_encoder/timestamp'
6
+ require_relative 'json_encoder/log_annotations'
7
+
8
+ module Zipkin
9
+ module Encoders
10
+ class JsonEncoder
11
+ OT_KIND_TO_ZIPKIN_KIND = {
12
+ 'server' => 'SERVER',
13
+ 'client' => 'CLIENT',
14
+ 'producer' => 'PRODUCER',
15
+ 'consumer' => 'CONSUMER'
16
+ }.freeze
17
+
18
+ CONTENT_TYPE = 'application/json'.freeze
19
+
20
+ module Fields
21
+ TRACE_ID = 'traceId'.freeze
22
+ SPAN_ID = 'id'.freeze
23
+ PARENT_ID = 'parentId'.freeze
24
+ OPERATION_NAME = 'name'.freeze
25
+ KIND = 'kind'.freeze
26
+ TIMESTAMP = 'timestamp'.freeze
27
+ DURATION = 'duration'.freeze
28
+ DEBUG = 'debug'.freeze
29
+ SHARED = 'shared'.freeze
30
+ LOCAL_ENDPOINT = 'localEndpoint'.freeze
31
+ REMOTE_ENDPOINT = 'remoteEndpoint'.freeze
32
+ ANNOTATIONS = 'annotations'.freeze
33
+ TAGS = 'tags'.freeze
34
+
35
+ module Endpoint
36
+ SERVICE_NAME = 'serviceName'.freeze
37
+ IPV4 = 'ipv4'.freeze
38
+ IPV6 = 'ipv6'.freeze
39
+ PORT = 'port'.freeze
40
+ end
41
+ end
42
+
43
+ def initialize(local_endpoint)
44
+ @adapter = defined?(Oj) ? OjAdapter : JsonAdapter
45
+ @local_endpoint = serialize_endpoint(local_endpoint)
46
+ end
47
+
48
+ def content_type
49
+ CONTENT_TYPE
50
+ end
51
+
52
+ def encode(spans)
53
+ @adapter.dump(spans.map(&method(:serialize)))
54
+ end
55
+
56
+ private
57
+
58
+ def serialize(span)
59
+ finish_ts = Timestamp.create(span.end_time)
60
+ start_ts = Timestamp.create(span.start_time)
61
+ duration = finish_ts - start_ts
62
+
63
+ {
64
+ Fields::TRACE_ID => span.context.trace_id,
65
+ Fields::SPAN_ID => span.context.span_id,
66
+ Fields::PARENT_ID => span.context.parent_id,
67
+ Fields::OPERATION_NAME => span.operation_name,
68
+ Fields::KIND => OT_KIND_TO_ZIPKIN_KIND[span.tags[:'span.kind'] || 'server'],
69
+ Fields::TIMESTAMP => start_ts,
70
+ Fields::DURATION => duration,
71
+ Fields::DEBUG => false,
72
+ Fields::SHARED => false,
73
+ Fields::LOCAL_ENDPOINT => @local_endpoint,
74
+ Fields::REMOTE_ENDPOINT => serialize_endpoint(Endpoint.remote_endpoint(span)),
75
+ Fields::ANNOTATIONS => LogAnnotations.build(span),
76
+ Fields::TAGS => span.tags
77
+ }
78
+ end
79
+
80
+ def serialize_endpoint(endpoint)
81
+ return nil unless endpoint
82
+
83
+ {
84
+ Fields::Endpoint::SERVICE_NAME => endpoint.service_name,
85
+ Fields::Endpoint::IPV4 => endpoint.ipv4,
86
+ Fields::Endpoint::IPV6 => endpoint.ipv6,
87
+ Fields::Endpoint::PORT => endpoint.port
88
+ }
89
+ end
90
+
91
+ module OjAdapter
92
+ def self.dump(payload)
93
+ Oj.dump(payload, mode: :object)
94
+ end
95
+ end
96
+
97
+ module JsonAdapter
98
+ def self.dump(payload)
99
+ JSON.dump(payload)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zipkin
4
+ module Encoders
5
+ class JsonEncoder
6
+ module LogAnnotations
7
+ module Fields
8
+ TIMESTAMP = 'timestamp'.freeze
9
+ VALUE = 'value'.freeze
10
+ end
11
+
12
+ def self.build(span)
13
+ span.logs.map do |log|
14
+ {
15
+ Fields::TIMESTAMP => Timestamp.create(log.fetch(:timestamp)),
16
+ Fields::VALUE => format_log_value(log)
17
+ }
18
+ end
19
+ end
20
+
21
+ def self.format_log_value(log)
22
+ if log.keys == %i[event timestamp]
23
+ log.fetch(:event)
24
+ else
25
+ log
26
+ .reject { |key, _value| key == :timestamp }
27
+ .map { |key, value| "#{key}=#{value}" }
28
+ .join(' ')
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zipkin
4
+ module Encoders
5
+ class JsonEncoder
6
+ module Timestamp
7
+ def self.create(time)
8
+ (time.to_f * 1_000_000).to_i
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -17,10 +17,10 @@ module Zipkin
17
17
  end
18
18
 
19
19
  module PeerInfo
20
- SERVICE = :'peer.service'
21
- IPV4 = :'peer.ipv4'
22
- IPV6 = :'peer.ipv6'
23
- PORT = :'peer.port'
20
+ SERVICE = 'peer.service'.freeze
21
+ IPV4 = 'peer.ipv4'.freeze
22
+ IPV6 = 'peer.ipv6'.freeze
23
+ PORT = 'peer.port'.freeze
24
24
 
25
25
  def self.keys
26
26
  [SERVICE, IPV4, IPV6, PORT]
@@ -28,34 +28,38 @@ module Zipkin
28
28
  end
29
29
 
30
30
  def self.local_endpoint(service_name)
31
- {
32
- serviceName: service_name,
33
- ipv4: LOCAL_IP
34
- }
31
+ new(service_name: service_name, ipv4: LOCAL_IP)
35
32
  end
36
33
 
37
34
  def self.remote_endpoint(span)
38
35
  tags = span.tags
39
- kind = tags[:'span.kind'] || SpanKind::SERVER
36
+ kind = tags['span.kind'] || SpanKind::SERVER
40
37
 
41
38
  case kind
42
39
  when SpanKind::SERVER, SpanKind::CLIENT
43
40
  return nil if (tags.keys & PeerInfo.keys).empty?
44
41
 
45
- {
46
- serviceName: tags[PeerInfo::SERVICE],
42
+ new(
43
+ service_name: tags[PeerInfo::SERVICE],
47
44
  ipv4: tags[PeerInfo::IPV4],
48
45
  ipv6: tags[PeerInfo::IPV6],
49
46
  port: tags[PeerInfo::PORT]
50
- }
47
+ )
51
48
  when SpanKind::PRODUCER, SpanKind::CONSUMER
52
- {
53
- serviceName: 'broker'
54
- }
49
+ new(service_name: 'broker')
55
50
  else
56
51
  warn "Unkown span kind: #{kind}"
57
52
  nil
58
53
  end
59
54
  end
55
+
56
+ def initialize(service_name: nil, ipv4: nil, ipv6: nil, port: nil)
57
+ @service_name = service_name
58
+ @ipv4 = ipv4
59
+ @ipv6 = ipv6
60
+ @port = port
61
+ end
62
+
63
+ attr_reader :service_name, :ipv4, :ipv6, :port
60
64
  end
61
65
  end
@@ -2,43 +2,23 @@
2
2
 
3
3
  require 'net/http'
4
4
  require 'uri'
5
- require 'json'
6
5
 
7
6
  module Zipkin
8
- class JsonClient
9
- def initialize(url:, collector:, flush_interval:, logger: Logger.new(STDOUT))
10
- @collector = collector
11
- @flush_interval = flush_interval
7
+ class HTTPClient
8
+ def initialize(url:, encoder:, logger:)
9
+ @encoder = encoder
12
10
  @spans_uri = URI.parse("#{url}/api/v2/spans")
13
11
  @logger = logger
14
12
  end
15
13
 
16
- def start
17
- @thread = Thread.new do
18
- loop do
19
- emit_batch(@collector.retrieve)
20
- sleep @flush_interval
21
- end
22
- end
23
- end
24
-
25
- def stop
26
- @thread.terminate if @thread
27
- emit_batch(@collector.retrieve)
28
- end
29
-
30
- private
31
-
32
- def emit_batch(spans)
33
- return if spans.empty?
34
-
14
+ def send_spans(spans)
35
15
  http = Net::HTTP.new(@spans_uri.host, @spans_uri.port)
36
16
  http.use_ssl = @spans_uri.scheme == 'https'
37
17
  request = Net::HTTP::Post.new(
38
18
  @spans_uri.request_uri,
39
- 'Content-Type' => 'application/json'
19
+ 'Content-Type' => @encoder.content_type
40
20
  )
41
- request.body = JSON.dump(spans)
21
+ request.body = @encoder.encode(spans)
42
22
  response = http.request(request)
43
23
 
44
24
  if response.code != '202'
@@ -4,26 +4,26 @@ module Zipkin
4
4
  class Span
5
5
  attr_accessor :operation_name
6
6
 
7
- attr_reader :context, :start_time, :tags, :logs, :references
7
+ attr_reader :context, :start_time, :end_time, :tags, :logs, :references
8
8
 
9
9
  # Creates a new {Span}
10
10
  #
11
11
  # @param context [SpanContext] the context of the span
12
12
  # @param operation_name [String] the operation name
13
- # @param collector [Collector] the span collector
13
+ # @param reporter [#report] the span reporter
14
14
  #
15
15
  # @return [Span] a new Span
16
16
  def initialize(
17
17
  context,
18
18
  operation_name,
19
- collector,
19
+ reporter,
20
20
  start_time: Time.now,
21
21
  tags: {},
22
22
  references: nil
23
23
  )
24
24
  @context = context
25
25
  @operation_name = operation_name
26
- @collector = collector
26
+ @reporter = reporter
27
27
  @start_time = start_time
28
28
  @tags = {}
29
29
  @logs = []
@@ -39,7 +39,7 @@ module Zipkin
39
39
  # a String, Numeric, or Boolean it will be encoded with to_s
40
40
  def set_tag(key, value)
41
41
  sanitized_value = valid_tag_value?(value) ? value : value.to_s
42
- @tags = @tags.merge(key.to_sym => sanitized_value)
42
+ @tags = @tags.merge(key.to_s => sanitized_value)
43
43
  end
44
44
 
45
45
  # Set a baggage item on the span
@@ -80,7 +80,8 @@ module Zipkin
80
80
  #
81
81
  # @param end_time [Time] custom end time, if not now
82
82
  def finish(end_time: Time.now)
83
- @collector.send_span(self, end_time)
83
+ @end_time = end_time
84
+ @reporter.report(self)
84
85
  end
85
86
 
86
87
  private
@@ -7,12 +7,13 @@ require_relative 'span'
7
7
  require_relative 'span_context'
8
8
  require_relative 'carrier'
9
9
  require_relative 'trace_id'
10
- require_relative 'json_client'
10
+ require_relative 'http_client'
11
11
  require_relative 'endpoint'
12
- require_relative 'collector'
12
+ require_relative 'async_reporter'
13
13
  require_relative 'scope_manager'
14
14
  require_relative 'scope'
15
15
  require_relative 'samplers'
16
+ require_relative 'encoders'
16
17
 
17
18
  module Zipkin
18
19
  class Tracer
@@ -22,30 +23,22 @@ module Zipkin
22
23
  service_name:,
23
24
  flush_interval: DEFAULT_FLUSH_INTERVAL,
24
25
  logger: Logger.new(STDOUT),
25
- sampler: Samplers::Const.new(true))
26
- collector = Collector.new(Endpoint.local_endpoint(service_name))
27
- sender = JsonClient.new(
28
- url: url,
29
- collector: collector,
30
- flush_interval: flush_interval,
31
- logger: logger
32
- )
33
- sender.start
34
- new(collector, sender, logger: logger, sampler: sampler)
26
+ sampler: Samplers::Const.new(true),
27
+ encoder: Encoders::JsonEncoder)
28
+ encoder = encoder.new(Endpoint.local_endpoint(service_name))
29
+ sender = HTTPClient.new(url: url, encoder: encoder, logger: logger)
30
+ reporter = AsyncReporter.create(sender: sender, flush_interval: flush_interval)
31
+ new(reporter, sender, logger: logger, sampler: sampler)
35
32
  end
36
33
 
37
- def initialize(collector, sender, logger: Logger.new(STDOUT), sampler:)
38
- @collector = collector
34
+ def initialize(reporter, sender, logger: Logger.new(STDOUT), sampler:)
35
+ @reporter = reporter
39
36
  @sender = sender
40
37
  @logger = logger
41
38
  @scope_manager = ScopeManager.new
42
39
  @sampler = sampler
43
40
  end
44
41
 
45
- def stop
46
- @sender.stop
47
- end
48
-
49
42
  # @return [ScopeManager] the current ScopeManager, which may be a no-op but
50
43
  # may not be nil.
51
44
  attr_reader :scope_manager
@@ -93,7 +86,7 @@ module Zipkin
93
86
  Span.new(
94
87
  context,
95
88
  operation_name,
96
- @collector,
89
+ @reporter,
97
90
  start_time: start_time,
98
91
  references: references,
99
92
  tags: tags || {}
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler'
4
5
  Bundler.setup
@@ -7,8 +8,8 @@ require 'zipkin/tracer'
7
8
 
8
9
  url = ENV['ZIPKIN_URL'] || 'http://localhost:9411'
9
10
 
10
- tracer1 = Zipkin::Tracer.build(url: url, service_name: 'test-service')
11
- tracer2 = Zipkin::Tracer.build(url: url, service_name: 'downstream-service')
11
+ tracer1 = Zipkin::Tracer.build(url: url, service_name: 'test-service', flush_interval: 1)
12
+ tracer2 = Zipkin::Tracer.build(url: url, service_name: 'downstream-service', flush_interval: 1)
12
13
 
13
14
  rpc_span = tracer1.start_span(
14
15
  'receive request',
@@ -45,7 +46,4 @@ async_span = tracer2.start_span(
45
46
  sleep 0.3 # emulate network delay
46
47
  async_span.finish
47
48
 
48
- tracer1.stop
49
- tracer2.stop
50
-
51
49
  puts 'Finished'
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler'
5
+ Bundler.setup
6
+
7
+ require 'zipkin/tracer'
8
+
9
+ url = ENV['ZIPKIN_URL'] || 'http://localhost:9411'
10
+
11
+ tracer1 = Zipkin::Tracer.build(url: url, service_name: 'user-service', flush_interval: 1)
12
+ tracer2 = Zipkin::Tracer.build(url: url, service_name: 'name-service', flush_interval: 1)
13
+
14
+ root_span = tracer1.start_span(
15
+ 'GET /users/:id',
16
+ tags: {
17
+ 'span.kind' => 'server',
18
+ 'http.method' => 'get',
19
+ 'http.url' => 'http://example.com/users/5'
20
+ }
21
+ )
22
+ sleep 1
23
+
24
+ fetch_name_span = tracer1.start_span(
25
+ 'get',
26
+ child_of: root_span,
27
+ tags: {
28
+ 'span.kind' => 'client',
29
+ 'http.method' => 'get',
30
+ 'http.url' => 'GET /users/5/name'
31
+ }
32
+ )
33
+ sleep 0.3 # emulate network delay
34
+
35
+ name_service_span = tracer2.start_span(
36
+ 'GET /users/:id/name',
37
+ child_of: fetch_name_span,
38
+ tags: {
39
+ 'span.kind' => 'server',
40
+ 'http.method' => 'get',
41
+ 'http.url' => 'http://example.com/users/5/name'
42
+ }
43
+ )
44
+ sleep 0.5
45
+ name_service_span.finish
46
+
47
+ sleep 0.2 # emulate network delay
48
+ fetch_name_span.finish
49
+
50
+ sleep 0.1 # doing something with fetched info
51
+ root_span.finish
52
+
53
+ puts 'Finishing...'
54
+ sleep 3
55
+
56
+ puts 'Finished'
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler'
4
5
  Bundler.setup
@@ -7,10 +8,10 @@ require 'zipkin/tracer'
7
8
 
8
9
  url = ENV['ZIPKIN_URL'] || 'http://localhost:9411'
9
10
 
10
- tracer1 = Zipkin::Tracer.build(url: url, service_name: 'test-service')
11
- tracer2 = Zipkin::Tracer.build(url: url, service_name: 'downstream-service')
11
+ tracer1 = Zipkin::Tracer.build(url: url, service_name: 'test-service', flush_interval: 1)
12
+ tracer2 = Zipkin::Tracer.build(url: url, service_name: 'downstream-service-1', flush_interval: 1)
12
13
 
13
- outer_span = tracer1.start_span(
14
+ root_span = tracer1.start_span(
14
15
  'receive request',
15
16
  tags: {
16
17
  'span.kind' => 'server'
@@ -18,39 +19,52 @@ outer_span = tracer1.start_span(
18
19
  )
19
20
  sleep 1
20
21
 
21
- inner_span = tracer1.start_span(
22
- 'fetch info from downstream',
23
- child_of: outer_span,
22
+ fetch_info_from_service1_span = tracer1.start_span(
23
+ 'fetch info from service 1',
24
+ child_of: root_span,
24
25
  tags: {
25
26
  'span.kind' => 'client',
26
- 'peer.service' => 'downstream-service',
27
- 'peer.ipv4' => '6.6.6.6',
27
+ 'peer.ipv4' => '2.2.2.2',
28
28
  'peer.port' => 443
29
29
  }
30
30
  )
31
31
  sleep 0.3 # emulate network delay
32
32
 
33
- downstream_span = tracer2.start_span(
34
- 'downstream operation',
35
- child_of: inner_span,
36
- tags: { 'span.kind' => 'server' }
33
+ service1_span = tracer2.start_span(
34
+ 'service 1 operation',
35
+ child_of: fetch_info_from_service1_span,
36
+ tags: {
37
+ 'span.kind' => 'server',
38
+ 'peer.ipv4' => '1.1.1.1',
39
+ 'peer.port' => 443
40
+ }
37
41
  )
38
- downstream_span.log_kv(event: 'custom-event')
39
- downstream_span.log_kv(foo: 'bar', baz: 'buz')
42
+ service1_span.log_kv(event: 'custom-event')
43
+ service1_span.log_kv(foo: 'bar', baz: 'buz')
40
44
  sleep 0.5
41
- downstream_span.finish
45
+ service1_span.finish
42
46
 
43
47
  sleep 0.2 # emulate network delay
44
48
 
45
- inner_span.finish
49
+ fetch_info_from_service1_span.finish
50
+
51
+ fetch_info_from_service2_span = tracer1.start_span(
52
+ 'fetch info from service 2 which does not have tracing',
53
+ child_of: root_span,
54
+ tags: {
55
+ 'span.kind' => 'client',
56
+ 'peer.service' => 'downstream-service-2',
57
+ 'peer.ipv4' => '3.3.3.3',
58
+ 'peer.port' => 443
59
+ }
60
+ )
61
+ sleep 0.3 # emulate network delay
62
+ fetch_info_from_service2_span.finish
46
63
 
47
64
  sleep 0.1 # doing something with fetched info
48
- outer_span.finish
65
+ root_span.finish
49
66
 
50
67
  puts 'Finishing...'
51
68
  sleep 3
52
69
 
53
- tracer1.stop
54
- tracer2.stop
55
-
56
70
  puts 'Finished'
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'zipkin'
6
- spec.version = '1.6.0'
6
+ spec.version = '1.6.1'
7
7
  spec.authors = ['SaleMove TechMovers']
8
8
  spec.email = ['techmovers@salemove.com']
9
9
 
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: 1.6.0
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - SaleMove TechMovers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-10 00:00:00.000000000 Z
11
+ date: 2018-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -126,12 +126,15 @@ files:
126
126
  - bin/console
127
127
  - bin/setup
128
128
  - lib/zipkin.rb
129
+ - lib/zipkin/async_reporter.rb
130
+ - lib/zipkin/async_reporter/buffer.rb
129
131
  - lib/zipkin/carrier.rb
130
- - lib/zipkin/collector.rb
131
- - lib/zipkin/collector/log_annotations.rb
132
- - lib/zipkin/collector/timestamp.rb
132
+ - lib/zipkin/encoders.rb
133
+ - lib/zipkin/encoders/json_encoder.rb
134
+ - lib/zipkin/encoders/json_encoder/log_annotations.rb
135
+ - lib/zipkin/encoders/json_encoder/timestamp.rb
133
136
  - lib/zipkin/endpoint.rb
134
- - lib/zipkin/json_client.rb
137
+ - lib/zipkin/http_client.rb
135
138
  - lib/zipkin/samplers.rb
136
139
  - lib/zipkin/samplers/const.rb
137
140
  - lib/zipkin/samplers/probabilistic.rb
@@ -144,6 +147,7 @@ files:
144
147
  - lib/zipkin/trace_id.rb
145
148
  - lib/zipkin/tracer.rb
146
149
  - script/create_follows_from_trace
150
+ - script/create_http_trace
147
151
  - script/create_trace
148
152
  - zipkin.gemspec
149
153
  homepage: ''
@@ -166,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
170
  version: '0'
167
171
  requirements: []
168
172
  rubyforge_project:
169
- rubygems_version: 2.6.11
173
+ rubygems_version: 2.7.6
170
174
  signing_key:
171
175
  specification_version: 4
172
176
  summary: OpenTracing Tracer implementation for Zipkin in Ruby
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'thread'
4
-
5
- require_relative './collector/timestamp'
6
- require_relative './collector/log_annotations'
7
-
8
- module Zipkin
9
- class Collector
10
- OT_KIND_TO_ZIPKIN_KIND = {
11
- 'server' => 'SERVER',
12
- 'client' => 'CLIENT',
13
- 'producer' => 'PRODUCER',
14
- 'consumer' => 'CONSUMER'
15
- }.freeze
16
-
17
- def initialize(local_endpoint)
18
- @buffer = Buffer.new
19
- @local_endpoint = local_endpoint
20
- end
21
-
22
- def retrieve
23
- @buffer.retrieve
24
- end
25
-
26
- def send_span(span, end_time)
27
- finish_ts = Timestamp.create(end_time)
28
- start_ts = Timestamp.create(span.start_time)
29
- duration = finish_ts - start_ts
30
- return unless span.context.sampled?
31
-
32
- @buffer << {
33
- traceId: span.context.trace_id,
34
- id: span.context.span_id,
35
- parentId: span.context.parent_id,
36
- name: span.operation_name,
37
- kind: OT_KIND_TO_ZIPKIN_KIND[span.tags[:'span.kind'] || 'server'],
38
- timestamp: start_ts,
39
- duration: duration,
40
- debug: false,
41
- shared: false,
42
- localEndpoint: @local_endpoint,
43
- remoteEndpoint: Endpoint.remote_endpoint(span),
44
- annotations: LogAnnotations.build(span),
45
- tags: span.tags
46
- }
47
- end
48
-
49
- class Buffer
50
- def initialize
51
- @buffer = []
52
- @mutex = Mutex.new
53
- end
54
-
55
- def <<(element)
56
- @mutex.synchronize do
57
- @buffer << element
58
- true
59
- end
60
- end
61
-
62
- def retrieve
63
- @mutex.synchronize do
64
- elements = @buffer.dup
65
- @buffer.clear
66
- elements
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Zipkin
4
- class Collector
5
- module LogAnnotations
6
- def self.build(span)
7
- span.logs.map do |log|
8
- {
9
- timestamp: Timestamp.create(log.fetch(:timestamp)),
10
- value: format_log_value(log)
11
- }
12
- end
13
- end
14
-
15
- def self.format_log_value(log)
16
- if log.keys == %i[event timestamp]
17
- log.fetch(:event)
18
- else
19
- log
20
- .reject { |key, _value| key == :timestamp }
21
- .map { |key, value| "#{key}=#{value}" }
22
- .join(' ')
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Zipkin
4
- class Collector
5
- module Timestamp
6
- def self.create(time)
7
- (time.to_f * 1_000_000).to_i
8
- end
9
- end
10
- end
11
- end