zipkin-tracer 0.8.0 → 0.9.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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZmU3ZjM4OTBmOGM0NWRmMjkwNjkzZWY1MmE1ZWM5MWY4OTQ5OGQ3Yw==
4
+ NGI0MTlmZDJhZWVmMzRjYzA5NjRiZTJiMDljODdiNjg0MjNiZTI4Mg==
5
5
  data.tar.gz: !binary |-
6
- MzI1NmFiNTEzOGYwYTVlMzk4MDljZDIxYzE5ZGQxY2RmZTc3ZjdiMA==
6
+ Mjk4ZTcyZWYzNmRhMTE3MTc2OTk4YTYxMDExNTc5M2ZlMWJlNjZjZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YjNlYTFjZDcyY2IwZDMxMjUwMjNhNzZhZGJmNjk4ODA0ZGIwNWQ2N2NlZDZm
10
- ODViMmM1MmM5OWNhNmFlZjIwNzgxOTY4MDhiNjFkMTkxMGVjN2Q0OTQ1MjAx
11
- YWM1YzY4Zjg0YjRhODI0NTUxZTdhZDdiMDY3YmRlZmE2MmU0MjU=
9
+ YzkzZWUwZjY1N2QwM2E3MGNhMjI5MTE2MTRjYzA5ZGI5MWFmOWQzMzliNjRj
10
+ MmRhMDlhOWFiNTU4ZTVkODI5NmI1ZTU0ZWE4MThmNTA3M2NmNDdjZjgyYTg0
11
+ MTczMWE4N2E1YzYyOTM5ODY0YjQ3NGRhNmQxYjg2NjZiNDVjOGQ=
12
12
  data.tar.gz: !binary |-
13
- NDEzMGRmNTBhZWRmYTc0YTc3NDllODkxMDExMWYzODQzMTgwZjg2MTAyNWQz
14
- ZjFjYjVjMDAyNGI5NDM3NmNmZTQ4YWUyYmZkYTllYWMwZGNjZjBjZjdhYjgw
15
- Nzc1MjM4MjkyY2RmNGFjOGE0OGRhMmFlODhjZmQ4ZGYwNzczYTg=
13
+ NWVjNjJhMzljZDRkODVkNjc5NjU2MDU0ODRhZmQ0Yjg0OTZiZTIzMTFiNGUz
14
+ MTYwNTkwMzhkNzU3N2MwZGExZGI4YzNjYzdiNTdkYzI0NzBlNTUwYzAzY2Nj
15
+ OGFhNzliMGExYWQyZWJhYTFjMzgxODMzMDA3MTNlYWMwMTVhZDk=
data/lib/zipkin-tracer.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require 'base64' #Bug in finagle. They should be requiring this: finagle-thrift-1.4.1/lib/finagle-thrift/tracer.rb:115
2
+ require 'zipkin-tracer/trace'
2
3
  require 'zipkin-tracer/rack/zipkin-tracer'
3
4
 
4
5
  begin
5
6
  require 'faraday'
6
7
  require 'zipkin-tracer/faraday/zipkin-tracer'
7
8
  rescue LoadError #Faraday is not available, we do not load our code.
8
- end
9
+ end
@@ -16,7 +16,7 @@ require 'sucker_punch'
16
16
 
17
17
 
18
18
  module ScribeThrift
19
- # This is here just for the monkey partching
19
+ # This is here just for the monkey patching
20
20
  class Client
21
21
  # This method in the original class was both sending and receiving logs.
22
22
  # The original class: https://github.com/twitter/scribe/blob/master/vendor/gen-rb/scribe.rb
@@ -46,12 +46,10 @@ class AsyncScribe
46
46
  rescue ThriftClient::NoServersAvailable, Thrift::Exception
47
47
  # I couldn't care less
48
48
  end
49
-
50
49
  end
51
50
 
52
51
  # Scribe which rescue thrift errors to avoid them to raise to the client
53
52
  class CarelessScribe
54
-
55
53
  def initialize(scribe_server_address)
56
54
  @server_address = scribe_server_address
57
55
  end
@@ -66,5 +64,4 @@ class CarelessScribe
66
64
  rescue ThriftClient::NoServersAvailable, Thrift::Exception
67
65
  # I couldn't care less
68
66
  end
69
-
70
67
  end
@@ -2,13 +2,16 @@ require 'logger'
2
2
  module ZipkinTracer
3
3
 
4
4
  class Config
5
- attr_reader :service_name, :service_port, :scribe_server, :zookeeper, :sample_rate,
6
- :scribe_max_buffer, :annotate_plugin, :filter_plugin, :whitelist_plugin, :logger
5
+ attr_reader :service_name, :service_port, :json_api_host, :traces_buffer,
6
+ :scribe_server, :zookeeper, :sample_rate, :scribe_max_buffer, :annotate_plugin,
7
+ :filter_plugin, :whitelist_plugin, :logger
7
8
 
8
9
  def initialize(app, config_hash)
9
10
  config = config_hash || app_config(app)
10
11
  @service_name = config[:service_name]
11
12
  @service_port = config[:service_port] || DEFAULTS[:service_port]
13
+ @json_api_host = config[:json_api_host]
14
+ @traces_buffer = config[:traces_buffer] || DEFAULTS[:traces_buffer]
12
15
  @scribe_server = config[:scribe_server]
13
16
  @zookeeper = config[:zookeeper]
14
17
  @sample_rate = config[:sample_rate] || DEFAULTS[:sample_rate]
@@ -19,12 +22,16 @@ module ZipkinTracer
19
22
  @logger = config[:logger] || fallback_logger
20
23
  end
21
24
 
22
- def using_scribe?
23
- !!(@scribe_server && defined?(::Scribe))
24
- end
25
-
26
- def using_kafka?
27
- !!(@zookeeper && RUBY_PLATFORM == 'java' && defined?(::Hermann))
25
+ def adapter
26
+ if !!@json_api_host
27
+ :json
28
+ elsif !!(@scribe_server && defined?(::Scribe))
29
+ :scribe
30
+ elsif !!(@zookeeper && RUBY_PLATFORM == 'java' && defined?(::Hermann))
31
+ :kafka
32
+ else
33
+ nil
34
+ end
28
35
  end
29
36
 
30
37
  private
@@ -38,6 +45,7 @@ module ZipkinTracer
38
45
  end
39
46
 
40
47
  DEFAULTS = {
48
+ traces_buffer: 100,
41
49
  scribe_max_buffer: 10,
42
50
  sample_rate: 0.1,
43
51
  service_port: 80
@@ -6,14 +6,14 @@ require 'uri'
6
6
  module ZipkinTracer
7
7
  class FaradayHandler < ::Faraday::Middleware
8
8
  B3_HEADERS = {
9
- :trace_id => "X-B3-TraceId",
10
- :parent_id => "X-B3-ParentSpanId",
11
- :span_id => "X-B3-SpanId",
12
- :sampled => "X-B3-Sampled",
13
- :flags => "X-B3-Flags"
9
+ trace_id: 'X-B3-TraceId',
10
+ parent_id: 'X-B3-ParentSpanId',
11
+ span_id: 'X-B3-SpanId',
12
+ sampled: 'X-B3-Sampled',
13
+ flags: 'X-B3-Flags'
14
14
  }.freeze
15
15
 
16
- def initialize(app, service_name=nil)
16
+ def initialize(app, service_name = nil)
17
17
  @app = app
18
18
  @service_name = service_name
19
19
  end
@@ -22,7 +22,7 @@ module ZipkinTracer
22
22
  # handle either a URI object (passed by Faraday v0.8.x in testing), or something string-izable
23
23
  url = env[:url].respond_to?(:host) ? env[:url] : URI.parse(env[:url].to_s)
24
24
  local_endpoint = ::Trace.default_endpoint # The rack middleware set this up for us.
25
- remote_endpoint = callee_endpoint(url) # The endpoint we are calling.
25
+ remote_endpoint = callee_endpoint(url, local_endpoint.ip_format) # The endpoint we are calling.
26
26
 
27
27
  response = nil
28
28
  begin
@@ -33,12 +33,12 @@ module ZipkinTracer
33
33
  end
34
34
  # annotate with method (GET/POST/etc.) and uri path
35
35
  ::Trace.set_rpc_name(env[:method].to_s.downcase)
36
- record(::Trace::BinaryAnnotation.new("http.uri", url.path, "STRING", local_endpoint))
37
- record(::Trace::BinaryAnnotation.new("sa", "1", "BOOL", remote_endpoint))
36
+ record(::Trace::BinaryAnnotation.new('http.uri', url.path, 'STRING', local_endpoint))
37
+ record(::Trace::BinaryAnnotation.new('sa', '1', 'BOOL', remote_endpoint))
38
38
  record(::Trace::Annotation.new(::Trace::Annotation::CLIENT_SEND, local_endpoint))
39
39
  response = @app.call(env).on_complete do |renv|
40
40
  # record HTTP status code on response
41
- record(::Trace::BinaryAnnotation.new("http.status", renv[:status].to_s, "STRING", local_endpoint))
41
+ record(::Trace::BinaryAnnotation.new('http.status', renv[:status].to_s, 'STRING', local_endpoint))
42
42
  end
43
43
  record(::Trace::Annotation.new(::Trace::Annotation::CLIENT_RECV, local_endpoint))
44
44
  ensure
@@ -55,18 +55,9 @@ module ZipkinTracer
55
55
  #TODO: if this class some day accepts a config hash, add a logger
56
56
  end
57
57
 
58
- def callee_endpoint(url)
58
+ def callee_endpoint(url, ip_format)
59
59
  service_name = @service_name || url.host.split('.').first || 'unknown' # default to url-derived service name
60
- ::Trace::Endpoint.new(host_ip_for(url.host), url.port, service_name)
60
+ ::Trace::Endpoint.make_endpoint(url.host, url.port, service_name, ip_format)
61
61
  end
62
-
63
- # get host IP for specified hostname, catching exceptions
64
- def host_ip_for(hostname)
65
- ::Trace::Endpoint.host_to_i32(hostname)
66
- rescue
67
- # default to 0.0.0.0 if lookup fails
68
- 0x00000000
69
- end
70
-
71
62
  end
72
63
  end
@@ -17,35 +17,49 @@ require 'scribe'
17
17
 
18
18
  require 'zipkin-tracer/config'
19
19
  require 'zipkin-tracer/careless_scribe'
20
+ require 'zipkin-tracer/zipkin_json_tracer'
20
21
 
21
22
  if RUBY_PLATFORM == 'java'
22
23
  require 'hermann/producer'
23
24
  require 'zipkin-tracer/zipkin_kafka_tracer'
24
25
  end
25
26
 
27
+
26
28
  module ZipkinTracer extend self
27
29
 
28
30
  class RackHandler
29
31
  B3_REQUIRED_HEADERS = %w[HTTP_X_B3_TRACEID HTTP_X_B3_PARENTSPANID HTTP_X_B3_SPANID HTTP_X_B3_SAMPLED]
30
32
  B3_OPT_HEADERS = %w[HTTP_X_B3_FLAGS]
31
33
 
32
- def initialize(app, config=nil)
34
+ def initialize(app, config = nil)
33
35
  @app = app
34
36
  @lock = Mutex.new
35
37
 
36
38
  config = Config.new(app, config)
37
-
38
- ::Trace.tracer = if config.using_scribe?
39
- ::Trace::ZipkinTracer.new(CarelessScribe.new(config.scribe_server), config.scribe_max_buffer)
40
- elsif config.using_kafka?
41
- kafkaTracer = ::Trace::ZipkinKafkaTracer.new
42
- kafkaTracer.connect(config.zookeeper)
43
- kafkaTracer
44
- else
45
- ::Trace::NullTracer.new
39
+ SuckerPunch.logger = config.logger
40
+ adapter = config.adapter
41
+
42
+ ::Trace.tracer = case adapter
43
+ when :json
44
+ ::Trace::ZipkinJsonTracer.new(config.json_api_host, config.traces_buffer)
45
+ when :scribe
46
+ ::Trace::ZipkinTracer.new(CarelessScribe.new(config.scribe_server), config.scribe_max_buffer)
47
+ when :kafka
48
+ kafkaTracer = ::Trace::ZipkinKafkaTracer.new
49
+ kafkaTracer.connect(config.zookeeper)
50
+ kafkaTracer
51
+ else
52
+ ::Trace::NullTracer.new
46
53
  end
47
- ::Trace.default_endpoint = ::Trace::Endpoint.new( local_ip, config.service_port , config.service_name)
48
- ::Trace.sample_rate=(config.sample_rate)
54
+
55
+ ip_format = config.adapter == :json ? :string : :i32
56
+ ::Trace.default_endpoint = ::Trace::Endpoint.make_endpoint(
57
+ nil, # auto detect hostname
58
+ config.service_port,
59
+ service_name(config.service_name),
60
+ ip_format
61
+ )
62
+ ::Trace.sample_rate = config.sample_rate
49
63
 
50
64
  @config = config
51
65
  end
@@ -53,6 +67,7 @@ module ZipkinTracer extend self
53
67
  def call(env)
54
68
  # skip certain requests
55
69
  return @app.call(env) if filtered?(env) || !routable_request?(env)
70
+
56
71
  whitelisted = force_sample?(env)
57
72
  id = get_or_create_trace_id(env, whitelisted) # note that this depends on the sample rate being set
58
73
  tracing_filter(id, env, whitelisted) { @app.call(env) }
@@ -60,10 +75,15 @@ module ZipkinTracer extend self
60
75
 
61
76
  private
62
77
 
78
+ # Use the Domain environment variable to extract the service name, otherwise use the default config name
79
+ def service_name(default_name)
80
+ ENV["DOMAIN"].to_s.empty? ? default_name : ENV["DOMAIN"].split('.').first
81
+ end
82
+
63
83
  # If the request is not valid for this service, we do not what to trace it.
64
84
  def routable_request?(env)
65
- return true unless defined?(Rails) #If not running on a Rails app, we can't verify if it is invalid
66
- Rails.application.routes.recognize_path(env["PATH_INFO"])
85
+ return true unless defined?(Rails) # If not running on a Rails app, we can't verify if it is invalid
86
+ Rails.application.routes.recognize_path(env['PATH_INFO'])
67
87
  true
68
88
  rescue ActionController::RoutingError
69
89
  false
@@ -81,7 +101,7 @@ module ZipkinTracer extend self
81
101
  @config.whitelist_plugin && @config.whitelist_plugin.call(env)
82
102
  end
83
103
 
84
- def tracing_filter(trace_id, env, whitelisted=false)
104
+ def tracing_filter(trace_id, env, whitelisted = false)
85
105
  synchronize do
86
106
  ::Trace.push(trace_id)
87
107
  #if called by a service, the caller already added the information
@@ -99,11 +119,9 @@ module ZipkinTracer extend self
99
119
  [status, headers, body]
100
120
  end
101
121
 
102
- private
103
-
104
122
  def add_request_information(env)
105
- ::Trace.set_rpc_name(env["REQUEST_METHOD"].to_s.downcase) # get/post and all that jazz
106
- ::Trace.record(::Trace::BinaryAnnotation.new("http.uri", env["PATH_INFO"], "STRING", ::Trace.default_endpoint))
123
+ ::Trace.set_rpc_name(env['REQUEST_METHOD'].to_s.downcase) # get/post and all that jazz
124
+ ::Trace.record(::Trace::BinaryAnnotation.new('http.uri', env['PATH_INFO'], 'STRING', ::Trace.default_endpoint))
107
125
  end
108
126
 
109
127
  def called_with_zipkin_headers?(env)
@@ -114,8 +132,8 @@ module ZipkinTracer extend self
114
132
  @lock.synchronize do
115
133
  yield
116
134
  end
117
- # Nothing wonky that the tracer does should stop us from using the app!!!
118
- # Usually is better to rescue StandardError but the socket layer can launch Errno kind of exceptions
135
+ # Nothing wonky that the tracer does should stop us from using the app!!!
136
+ # Usually is better to rescue StandardError but the socket layer can launch Errno kind of exceptions
119
137
  rescue Exception => e
120
138
  @config.logger.error("Exception #{e.message} while sending Zipkin traces. #{e.backtrace}")
121
139
  end
@@ -125,23 +143,14 @@ module ZipkinTracer extend self
125
143
  env.values_at(*B3_REQUIRED_HEADERS)
126
144
  else
127
145
  new_id = Trace.generate_id
128
- [new_id, nil, new_id, ("true" if whitelisted || Trace.should_sample?)]
146
+ [new_id, nil, new_id, ('true' if whitelisted || Trace.should_sample?)]
129
147
  end
130
- trace_parameters[3] = (trace_parameters[3] == "true")
148
+ trace_parameters[3] = (trace_parameters[3] == 'true')
131
149
 
132
150
  trace_parameters += env.values_at(*B3_OPT_HEADERS) # always check flags
133
151
  trace_parameters[4] = (trace_parameters[4] || default_flags).to_i
134
152
 
135
153
  Trace::TraceId.new(*trace_parameters)
136
154
  end
137
-
138
- def local_ip
139
- ::Trace::Endpoint.host_to_i32(Socket.gethostname)
140
- rescue
141
- # Default to local if lockup fails
142
- ::Trace::Endpoint.host_to_i32('127.0.0.1')
143
- end
144
-
145
155
  end
146
-
147
156
  end
@@ -0,0 +1,67 @@
1
+ require 'finagle-thrift'
2
+ require 'finagle-thrift/trace'
3
+
4
+ module Trace
5
+ class Span
6
+ def to_h
7
+ {
8
+ name: @name,
9
+ traceId: @span_id.trace_id.to_s,
10
+ id: @span_id.span_id.to_s,
11
+ parentId: @span_id.parent_id.nil? ? nil : @span_id.parent_id.to_s,
12
+ annotations: @annotations.map!(&:to_h),
13
+ binaryAnnotations: @binary_annotations.map!(&:to_h),
14
+ debug: @debug
15
+ }
16
+ end
17
+ end
18
+
19
+ class Annotation
20
+ def to_h
21
+ {
22
+ value: @value,
23
+ timestamp: @timestamp,
24
+ endpoint: host.to_h
25
+ }
26
+ end
27
+ end
28
+
29
+ class BinaryAnnotation
30
+ def to_h
31
+ {
32
+ key: @key,
33
+ value: @value,
34
+ endpoint: host.to_h
35
+ }
36
+ end
37
+ end
38
+
39
+ class Endpoint
40
+ LOCALHOST = '127.0.0.1'
41
+ LOCALHOST_I32 = 0x7f000001
42
+
43
+ attr_accessor :ip_format
44
+
45
+ # we cannot override the initializer to add an extra parameter so use a factory
46
+ def self.make_endpoint(hostname, service_port, service_name, ip_format)
47
+ ipv4 = begin
48
+ hostname ||= Socket.gethostname
49
+ ip_format == :string ? Socket.getaddrinfo(hostname, nil, :INET)[0][3] : host_to_i32(hostname)
50
+ rescue
51
+ ip_format == :string ? LOCALHOST : LOCALHOST_I32
52
+ end
53
+
54
+ ep = Endpoint.new(ipv4, service_port, service_name)
55
+ ep.ip_format = ip_format
56
+ ep
57
+ end
58
+
59
+ def to_h
60
+ {
61
+ ipv4: ipv4,
62
+ port: port,
63
+ serviceName: service_name
64
+ }
65
+ end
66
+ end
67
+ end
@@ -12,6 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  module ZipkinTracer
15
- VERSION = "0.8.0"
15
+ VERSION = "0.9.0"
16
16
  end
17
17
 
@@ -0,0 +1,73 @@
1
+ require 'json'
2
+ require 'faraday'
3
+ require 'finagle-thrift'
4
+ require 'finagle-thrift/tracer'
5
+
6
+ class AsyncJsonApiClient
7
+ include SuckerPunch::Job
8
+ SPANS_PATH = '/api/v1/spans'
9
+
10
+ def perform(json_api_host, spans)
11
+ resp = Faraday.new(json_api_host).post do |req|
12
+ req.url SPANS_PATH
13
+ req.headers['Content-Type'] = 'application/json'
14
+ req.body = JSON.generate(spans.map!(&:to_h))
15
+ end
16
+ rescue => e
17
+ SuckerPunch.logger.error(e)
18
+ end
19
+ end
20
+
21
+ module Trace
22
+ class ZipkinJsonTracer < Tracer
23
+ TRACER_CATEGORY = "zipkin".freeze
24
+
25
+ def initialize(json_api_host, traces_buffer)
26
+ @json_api_host = json_api_host
27
+ @traces_buffer = traces_buffer
28
+ reset
29
+ end
30
+
31
+ def record(id, annotation)
32
+ return unless id.sampled?
33
+ span = get_span_for_id(id)
34
+
35
+ case annotation
36
+ when BinaryAnnotation
37
+ span.binary_annotations << annotation
38
+ when Annotation
39
+ span.annotations << annotation
40
+ end
41
+
42
+ @count += 1
43
+ if @count >= @traces_buffer || (annotation.is_a?(Annotation) && annotation.value == Annotation::SERVER_SEND)
44
+ flush!
45
+ end
46
+ end
47
+
48
+ def set_rpc_name(id, name)
49
+ return unless id.sampled?
50
+ span = get_span_for_id(id)
51
+ span.name = name.to_s
52
+ end
53
+
54
+ private
55
+
56
+ def get_span_for_id(id)
57
+ key = id.span_id.to_s
58
+ @spans[key] ||= begin
59
+ Span.new("", id)
60
+ end
61
+ end
62
+
63
+ def reset
64
+ @count = 0
65
+ @spans = {}
66
+ end
67
+
68
+ def flush!
69
+ AsyncJsonApiClient.new.async.perform(@json_api_host, @spans.values.dup)
70
+ reset
71
+ end
72
+ end
73
+ end
metadata CHANGED
@@ -1,16 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zipkin-tracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franklin Hu
8
8
  - R Tyler Croy
9
9
  - James Way
10
+ - Jordi Polo
11
+ - Julien Feltesse
12
+ - Scott Steeg
10
13
  autorequire:
11
14
  bindir: bin
12
15
  cert_chain: []
13
- date: 2015-11-22 00:00:00.000000000 Z
16
+ date: 2015-12-14 00:00:00.000000000 Z
14
17
  dependencies:
15
18
  - !ruby/object:Gem::Dependency
16
19
  name: finagle-thrift
@@ -124,6 +127,34 @@ dependencies:
124
127
  - - ~>
125
128
  - !ruby/object:Gem::Version
126
129
  version: '0.8'
130
+ - !ruby/object:Gem::Dependency
131
+ name: timecop
132
+ requirement: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ~>
135
+ - !ruby/object:Gem::Version
136
+ version: '0.8'
137
+ type: :development
138
+ prerelease: false
139
+ version_requirements: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ~>
142
+ - !ruby/object:Gem::Version
143
+ version: '0.8'
144
+ - !ruby/object:Gem::Dependency
145
+ name: webmock
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ~>
149
+ - !ruby/object:Gem::Version
150
+ version: '1.22'
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '1.22'
127
158
  - !ruby/object:Gem::Dependency
128
159
  name: hermann
129
160
  requirement: !ruby/object:Gem::Requirement
@@ -157,6 +188,9 @@ email:
157
188
  - franklin@twitter.com
158
189
  - tyler@monkeypox.org
159
190
  - jamescway@gmail.com
191
+ - jcarres@mdsol.com
192
+ - jfeltesse@mdsol.com
193
+ - ssteeg@mdsol.com
160
194
  executables: []
161
195
  extensions: []
162
196
  extra_rdoc_files: []
@@ -166,7 +200,9 @@ files:
166
200
  - lib/zipkin-tracer/config.rb
167
201
  - lib/zipkin-tracer/faraday/zipkin-tracer.rb
168
202
  - lib/zipkin-tracer/rack/zipkin-tracer.rb
203
+ - lib/zipkin-tracer/trace.rb
169
204
  - lib/zipkin-tracer/version.rb
205
+ - lib/zipkin-tracer/zipkin_json_tracer.rb
170
206
  - lib/zipkin-tracer/zipkin_kafka_tracer.rb
171
207
  homepage: https://github.com/openzipkin/zipkin-tracer
172
208
  licenses: []