zipkin-tracer 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|