zipkin-tracer 0.11.0 → 0.12.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
- MmU0MDJhYzQxZGM5ODVkZmI0NzliYzI3MGQ0MmRhYjUyNmRhNjE2MQ==
4
+ MDU1NDhkYTRmYTdjMGI5ZDg0M2ZhZDRmZTY3ZWI3MjQ0ZjAyMGQwMQ==
5
5
  data.tar.gz: !binary |-
6
- YWQ3ZDNhMmY4YjhkMmUxZDgwOTY5NzIyZGU0NzJkYjNmNGFkZGM0Zg==
6
+ OTcwOTZmNWYyYmIxNGIxMzY5NWVlYjM4ODVlMzQ2MGE0MTk1NjJiNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NmRlMTEzYmEzYzM5YmQ4MzllNTViZDdjOWY0ZmU1YzMzYjYxZjZlZWM5MGFl
10
- NWU3OGVmMDA1MGJiZTA0Y2I5M2M4ZTRiOGZkMTJiYWI2ZmU1NTY5NTM4MWU2
11
- NWY3MWFjZDEzNzY0N2UwMmJkZDBiNWM4NTcxNjU5YzhiYzA0YmY=
9
+ ZTE4ZThiOTZjN2Y2MWUxNDBhMDRlMGZjYjI1NGUwZGIyNWQ0YThhNmFiN2I0
10
+ NzJjNzJiYmE0ZWJkNmFhZTI1YzYxNGFiYjk1NjM4NGZjNTZhMjQzZjMxODgx
11
+ ZTM3NmM1M2Y4OGFkNDc4ZTBkNDM3MTc4MjMyMWM5MWIyMjU0OTc=
12
12
  data.tar.gz: !binary |-
13
- NmNjMzA2OWQzYmE5ZGVkNDNjOWM5ODkyZjYxZjZiN2FmMWM5MjljMTdjODdh
14
- ZGQ4YjVlOWFmOWMzODgyMWEyNWZlNzdjODk4YjA5ODk0YTU0ZjM1NjBjNTRh
15
- MzVjZmFmZmY2YmIzMDRhYjU1MWIxOGRlMTRhY2M1NzBjMTBlMzI=
13
+ YTU1YjJkZDU5NTU3MzY3OWFmNzE4Yjk4OTM0MGM5YTE3NjUyMzY1MzJmOGE0
14
+ MDNhYWNmNGI3NjEyMGQ3OGE4NDEyODRjZWQzNjUwYmEyMGIwMWFhNzU4ZDBi
15
+ MGRhMjM0YTRlNjE0ZTdhNjA0NTMzOTA4ZjYyYTNhNjg2Y2MxMWM=
@@ -0,0 +1,30 @@
1
+ module ZipkinTracer
2
+
3
+ # Useful methods on the Application we are instrumenting
4
+ class Application
5
+ # If the request is not valid for this service, we do not what to trace it.
6
+ def self.routable_request?(path_info)
7
+ return true unless defined?(Rails) # If not running on a Rails app, we can't verify if it is invalid
8
+ Rails.application.routes.recognize_path(path_info)
9
+ true
10
+ rescue ActionController::RoutingError
11
+ false
12
+ end
13
+
14
+ def self.logger
15
+ if defined?(Rails) # If we happen to be inside a Rails app, use its logger
16
+ Rails.logger
17
+ else
18
+ Logger.new(STDOUT)
19
+ end
20
+ end
21
+
22
+ def self.config(app)
23
+ if app.respond_to?(:config) && app.config.respond_to?(:zipkin_tracer)
24
+ app.config.zipkin_tracer
25
+ else
26
+ {}
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,13 +1,15 @@
1
1
  require 'logger'
2
- module ZipkinTracer
2
+ require 'zipkin-tracer/application'
3
3
 
4
+ module ZipkinTracer
5
+ # Configuration of this gem. It reads the configuration and provides default values
4
6
  class Config
5
7
  attr_reader :service_name, :service_port, :json_api_host, :traces_buffer,
6
8
  :scribe_server, :zookeeper, :sample_rate, :scribe_max_buffer, :annotate_plugin,
7
9
  :filter_plugin, :whitelist_plugin, :logger
8
10
 
9
11
  def initialize(app, config_hash)
10
- config = config_hash || app_config(app)
12
+ config = config_hash || Application.config(app)
11
13
  @service_name = config[:service_name]
12
14
  @service_port = config[:service_port] || DEFAULTS[:service_port]
13
15
  @json_api_host = config[:json_api_host]
@@ -19,7 +21,7 @@ module ZipkinTracer
19
21
  @annotate_plugin = config[:annotate_plugin] # call for trace annotation
20
22
  @filter_plugin = config[:filter_plugin] # skip tracing if returns false
21
23
  @whitelist_plugin = config[:whitelist_plugin] # force sampling if returns true
22
- @logger = config[:logger] || fallback_logger
24
+ @logger = config[:logger] || Application.logger
23
25
  end
24
26
 
25
27
  def adapter
@@ -36,14 +38,6 @@ module ZipkinTracer
36
38
 
37
39
  private
38
40
 
39
- def fallback_logger
40
- if defined?(Rails) # If we happen to be inside a Rails app, use its logger
41
- Rails.logger
42
- else
43
- Logger.new(STDOUT)
44
- end
45
- end
46
-
47
41
  DEFAULTS = {
48
42
  traces_buffer: 100,
49
43
  scribe_max_buffer: 10,
@@ -51,12 +45,5 @@ module ZipkinTracer
51
45
  service_port: 80
52
46
  }
53
47
 
54
- def app_config(app)
55
- if app.respond_to?(:config) && app.config.respond_to?(:zipkin_tracer)
56
- app.config.zipkin_tracer
57
- else
58
- {}
59
- end
60
- end
61
48
  end
62
49
  end
@@ -4,6 +4,7 @@ require 'finagle-thrift/tracer'
4
4
  require 'uri'
5
5
 
6
6
  module ZipkinTracer
7
+ # Faraday middleware. It will add CR/CS annotations to outgoing connections done by Faraday
7
8
  class FaradayHandler < ::Faraday::Middleware
8
9
  B3_HEADERS = {
9
10
  trace_id: 'X-B3-TraceId',
@@ -34,21 +35,19 @@ module ZipkinTracer
34
35
  end
35
36
 
36
37
  private
37
- SERVER_ADDRESS = 'sa'
38
- SERVER_ADDRESS_SPECIAL_VALUE = '1'
39
- STRING_TYPE = 'STRING'
40
- BOOLEAN_TYPE = 'BOOL'
41
- URI_KEY = 'http.uri'
42
- STATUS_KEY = 'http.status'
43
- UNKNOWN_URL = 'unknown'
44
-
38
+ SERVER_ADDRESS = 'sa'.freeze
39
+ SERVER_ADDRESS_SPECIAL_VALUE = '1'.freeze
40
+ STRING_TYPE = 'STRING'.freeze
41
+ BOOLEAN_TYPE = 'BOOL'.freeze
42
+ URI_KEY = 'http.uri'.freeze
43
+ STATUS_KEY = 'http.status'.freeze
45
44
 
46
45
  def trace!(env, trace_id)
47
46
  response = nil
48
47
  # handle either a URI object (passed by Faraday v0.8.x in testing), or something string-izable
49
48
  url = env[:url].respond_to?(:host) ? env[:url] : URI.parse(env[:url].to_s)
50
49
  local_endpoint = Trace.default_endpoint # The rack middleware set this up for us.
51
- remote_endpoint = callee_endpoint(url, local_endpoint.ip_format) # The endpoint we are calling.
50
+ remote_endpoint = Trace::Endpoint.remote_endpoint(url, @service_name, local_endpoint.ip_format) # The endpoint we are calling.
52
51
  @tracer.with_new_span(trace_id, env[:method].to_s.downcase) do |span|
53
52
  # annotate with method (GET/POST/etc.) and uri path
54
53
  span.record(Trace::BinaryAnnotation.new(URI_KEY, url.path, STRING_TYPE, local_endpoint))
@@ -70,9 +69,5 @@ module ZipkinTracer
70
69
  Trace.pop
71
70
  end
72
71
 
73
- def callee_endpoint(url, ip_format)
74
- service_name = @service_name || url.host.split('.').first || UNKNOWN_URL # default to url-derived service name
75
- Trace::Endpoint.make_endpoint(url.host, url.port, service_name, ip_format)
76
- end
77
72
  end
78
73
  end
@@ -21,8 +21,8 @@ module ZipkinTracer
21
21
  # This middleware reads Zipkin headers from the request and sets/creates a Trace.id usable by the rest of the app
22
22
  # It will also send the trace to the Zipkin service using one of the methods configured.
23
23
  class RackHandler
24
- B3_REQUIRED_HEADERS = %w[HTTP_X_B3_TRACEID HTTP_X_B3_PARENTSPANID HTTP_X_B3_SPANID HTTP_X_B3_SAMPLED]
25
- B3_OPT_HEADERS = %w[HTTP_X_B3_FLAGS]
24
+ B3_REQUIRED_HEADERS = %w[HTTP_X_B3_TRACEID HTTP_X_B3_PARENTSPANID HTTP_X_B3_SPANID HTTP_X_B3_SAMPLED].freeze
25
+ B3_OPT_HEADERS = %w[HTTP_X_B3_FLAGS].freeze
26
26
 
27
27
  def initialize(app, config = nil)
28
28
  @app = app
@@ -35,7 +35,7 @@ module ZipkinTracer
35
35
  zipkin_env = ZipkinEnv.new(env, @config)
36
36
  trace_id = zipkin_env.trace_id
37
37
  with_trace_id(trace_id) do
38
- if !trace_id.sampled? || !routable_request?(env)
38
+ if !trace_id.sampled? || !Application.routable_request?(env['PATH_INFO'])
39
39
  @app.call(env)
40
40
  else
41
41
  @tracer.with_new_span(trace_id, zipkin_env.env['REQUEST_METHOD'].to_s.downcase) do |span|
@@ -54,15 +54,6 @@ module ZipkinTracer
54
54
  Trace.pop
55
55
  end
56
56
 
57
- # If the request is not valid for this service, we do not what to trace it.
58
- def routable_request?(env)
59
- return true unless defined?(Rails) # If not running on a Rails app, we can't verify if it is invalid
60
- Rails.application.routes.recognize_path(env['PATH_INFO'])
61
- true
62
- rescue ActionController::RoutingError
63
- false
64
- end
65
-
66
57
  def annotate_plugin(env, status, response_headers, response_body)
67
58
  @config.annotate_plugin.call(env, status, response_headers, response_body) if @config.annotate_plugin
68
59
  end
@@ -8,8 +8,11 @@ module Trace
8
8
  @tracer
9
9
  end
10
10
 
11
+ # A span may contain many annotations
12
+ # This class is defined in finagle-thrift. We are adding extra methods here
11
13
  class Span
12
14
  attr_reader :size
15
+ attr_accessor :timestamp, :duration
13
16
 
14
17
  # We record information into spans, then we send these spans to zipkin
15
18
  def record(annotation)
@@ -31,11 +34,14 @@ module Trace
31
34
  parentId: @span_id.parent_id.nil? ? nil : @span_id.parent_id.to_s,
32
35
  annotations: @annotations.map!(&:to_h),
33
36
  binaryAnnotations: @binary_annotations.map!(&:to_h),
37
+ timestamp: timestamp,
38
+ duration: duration,
34
39
  debug: @debug
35
40
  }
36
41
  end
37
42
  end
38
43
 
44
+ # This class is defined in finagle-thrift. We are adding extra methods here
39
45
  class Annotation
40
46
  def to_h
41
47
  {
@@ -46,6 +52,7 @@ module Trace
46
52
  end
47
53
  end
48
54
 
55
+ # This class is defined in finagle-thrift. We are adding extra methods here
49
56
  class BinaryAnnotation
50
57
  def to_h
51
58
  {
@@ -56,16 +63,36 @@ module Trace
56
63
  end
57
64
  end
58
65
 
66
+ # This class is defined in finagle-thrift. We are adding extra methods here
59
67
  class Endpoint
60
- LOCALHOST = '127.0.0.1'
61
- LOCALHOST_I32 = 0x7f000001
68
+ LOCALHOST = '127.0.0.1'.freeze
69
+ LOCALHOST_I32 = 0x7f000001.freeze
70
+ UNKNOWN_URL = 'unknown'.freeze
62
71
 
72
+ # we cannot override the initializer to add an extra parameter so use a factory
63
73
  attr_accessor :ip_format
64
74
 
65
- # we cannot override the initializer to add an extra parameter so use a factory
75
+ def self.local_endpoint(service_port, service_name, ip_format)
76
+ hostname = Socket.gethostname
77
+ Endpoint.make_endpoint(hostname, service_port, service_name, ip_format)
78
+ end
79
+
80
+ def self.remote_endpoint(url, remote_service_name, ip_format)
81
+ service_name = remote_service_name || url.host.split('.').first || UNKNOWN_URL # default to url-derived service name
82
+ Endpoint.make_endpoint(url.host, url.port, service_name, ip_format)
83
+ end
84
+
85
+ def to_h
86
+ {
87
+ ipv4: ipv4,
88
+ port: port,
89
+ serviceName: service_name
90
+ }
91
+ end
92
+
93
+ private
66
94
  def self.make_endpoint(hostname, service_port, service_name, ip_format)
67
95
  ipv4 = begin
68
- hostname ||= Socket.gethostname
69
96
  ip_format == :string ? Socket.getaddrinfo(hostname, nil, :INET)[0][3] : host_to_i32(hostname)
70
97
  rescue
71
98
  ip_format == :string ? LOCALHOST : LOCALHOST_I32
@@ -76,12 +103,5 @@ module Trace
76
103
  ep
77
104
  end
78
105
 
79
- def to_h
80
- {
81
- ipv4: ipv4,
82
- port: port,
83
- serviceName: service_name
84
- }
85
- end
86
106
  end
87
107
  end
@@ -0,0 +1,34 @@
1
+ module ZipkinTracer
2
+ class TraceClient
3
+ LOCAL_COMPONENT = 'lc'.freeze
4
+ STRING_TYPE = 'STRING'.freeze
5
+
6
+ def self.local_component_span(local_component_value, &block)
7
+ if block_given?
8
+ client = self.new(LOCAL_COMPONENT, &block)
9
+ client.record_local_component local_component_value
10
+ end
11
+ end
12
+
13
+ def initialize(name, &block)
14
+ @trace_id = Trace.id.next_id
15
+ Trace.tracer.with_new_span(@trace_id, name) do |span|
16
+ @span = span
17
+ block.call(self)
18
+ end
19
+ end
20
+
21
+ def record(key)
22
+ @span.record(Trace::Annotation.new(key, Trace.default_endpoint)) if @trace_id.sampled?
23
+ end
24
+
25
+ def record_tag(key, value)
26
+ @span.record(Trace::BinaryAnnotation.new(key, value, STRING_TYPE, Trace.default_endpoint)) if @trace_id.sampled?
27
+ end
28
+
29
+ def record_local_component(value)
30
+ record_tag(LOCAL_COMPONENT, value)
31
+ end
32
+
33
+ end
34
+ end
@@ -22,8 +22,7 @@ module ZipkinTracer
22
22
 
23
23
  # TODO: move this to the TracerBase and kill scribe tracer
24
24
  ip_format = config.adapter == :json ? :string : :i32
25
- Trace.default_endpoint = Trace::Endpoint.make_endpoint(
26
- nil, # auto detect hostname
25
+ Trace.default_endpoint = Trace::Endpoint.local_endpoint(
27
26
  config.service_port,
28
27
  service_name(config.service_name),
29
28
  ip_format
@@ -12,5 +12,5 @@
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.11.0"
15
+ VERSION = "0.12.0"
16
16
  end
@@ -17,14 +17,17 @@ module Trace
17
17
 
18
18
  def with_new_span(trace_id, name)
19
19
  span = start_span(trace_id, name)
20
+ start_time = Time.now
21
+ span.timestamp = to_microseconds(start_time)
20
22
  result = yield span
23
+ span.duration = to_microseconds(Time.now - start_time)
21
24
  may_flush(span)
22
25
  result
23
26
  end
24
27
 
25
28
  def may_flush(span)
26
29
  size = spans.values.map(&:size).inject(:+) || 0
27
- if size >= @traces_buffer || span.annotations.any?{ |ann| ann == Annotation::SERVER_SEND }
30
+ if size >= @traces_buffer || span.annotations.any?{ |ann| ann.value == Annotation::SERVER_SEND }
28
31
  flush!
29
32
  reset
30
33
  end
@@ -54,5 +57,9 @@ module Trace
54
57
  def reset
55
58
  Thread.current[:zipkin_spans] = {}
56
59
  end
60
+
61
+ def to_microseconds(time)
62
+ (time.to_f * 1_000_000).to_i
63
+ end
57
64
  end
58
65
  end
data/lib/zipkin-tracer.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'base64' #Bug in finagle. They should be requiring this: finagle-thrift-1.4.1/lib/finagle-thrift/tracer.rb:115
2
2
  require 'zipkin-tracer/trace'
3
3
  require 'zipkin-tracer/rack/zipkin-tracer'
4
+ require 'zipkin-tracer/trace_client'
4
5
 
5
6
  begin
6
7
  require 'faraday'
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.11.0
4
+ version: 0.12.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: 2016-01-28 00:00:00.000000000 Z
16
+ date: 2016-02-02 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: faraday
@@ -182,11 +182,13 @@ extensions: []
182
182
  extra_rdoc_files: []
183
183
  files:
184
184
  - lib/zipkin-tracer.rb
185
+ - lib/zipkin-tracer/application.rb
185
186
  - lib/zipkin-tracer/careless_scribe.rb
186
187
  - lib/zipkin-tracer/config.rb
187
188
  - lib/zipkin-tracer/faraday/zipkin-tracer.rb
188
189
  - lib/zipkin-tracer/rack/zipkin-tracer.rb
189
190
  - lib/zipkin-tracer/trace.rb
191
+ - lib/zipkin-tracer/trace_client.rb
190
192
  - lib/zipkin-tracer/tracer_factory.rb
191
193
  - lib/zipkin-tracer/version.rb
192
194
  - lib/zipkin-tracer/zipkin_json_tracer.rb