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 +8 -8
- data/lib/zipkin-tracer/application.rb +30 -0
- data/lib/zipkin-tracer/config.rb +5 -18
- data/lib/zipkin-tracer/faraday/zipkin-tracer.rb +8 -13
- data/lib/zipkin-tracer/rack/zipkin-tracer.rb +3 -12
- data/lib/zipkin-tracer/trace.rb +31 -11
- data/lib/zipkin-tracer/trace_client.rb +34 -0
- data/lib/zipkin-tracer/tracer_factory.rb +1 -2
- data/lib/zipkin-tracer/version.rb +1 -1
- data/lib/zipkin-tracer/zipkin_tracer_base.rb +8 -1
- data/lib/zipkin-tracer.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MDU1NDhkYTRmYTdjMGI5ZDg0M2ZhZDRmZTY3ZWI3MjQ0ZjAyMGQwMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTcwOTZmNWYyYmIxNGIxMzY5NWVlYjM4ODVlMzQ2MGE0MTk1NjJiNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZTE4ZThiOTZjN2Y2MWUxNDBhMDRlMGZjYjI1NGUwZGIyNWQ0YThhNmFiN2I0
|
10
|
+
NzJjNzJiYmE0ZWJkNmFhZTI1YzYxNGFiYjk1NjM4NGZjNTZhMjQzZjMxODgx
|
11
|
+
ZTM3NmM1M2Y4OGFkNDc4ZTBkNDM3MTc4MjMyMWM5MWIyMjU0OTc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
data/lib/zipkin-tracer/config.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'logger'
|
2
|
-
|
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 ||
|
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] ||
|
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 =
|
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
|
data/lib/zipkin-tracer/trace.rb
CHANGED
@@ -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
|
-
|
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.
|
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
|
@@ -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
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.
|
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-
|
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
|