zipkin-tracer 0.9.1 → 0.10.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/faraday/zipkin-tracer.rb +17 -19
- data/lib/zipkin-tracer/rack/zipkin-tracer.rb +81 -80
- data/lib/zipkin-tracer/trace.rb +7 -0
- data/lib/zipkin-tracer/tracer_factory.rb +40 -0
- data/lib/zipkin-tracer/version.rb +1 -1
- data/lib/zipkin-tracer/zipkin_json_tracer.rb +11 -48
- data/lib/zipkin-tracer/zipkin_kafka_tracer.rb +19 -51
- data/lib/zipkin-tracer/zipkin_tracer_base.rb +71 -0
- metadata +4 -16
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzUzN2QzOWMyMzczNmIxNGRhMzU0YWIzNzU4NWNkZWU3NjY0YTcxOA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDBkMTNiNmU5N2E0NGIwY2ZiZmI1MTYzMTFiYTU5ODkxNmI5NDMxYQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjY1NmFkODBiYzgyZWE4MTA5ZjQwOWU2MDRlZDIyYmZmYmMyZjA0MGNiOWE2
|
10
|
+
ZWQ4MTBiOGU4N2RmNGRhYmE0MjI3MGIyMjg0MjE1OWE4NzM5NWY1MDBlYmQ2
|
11
|
+
NzhlZTc1NGZiNjM3ZGQzYTg2ZDU5NmY1M2Q3YmZkNWNmZjgwODQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NmRjYmYyZWM4OGEzYmMyMTUzYzE5MzNjOGQxZDkyZTRiYTgxYzkyYzg3MTIy
|
14
|
+
YWRiYzkwYmIxYmM3MmIzZmFkZmJlMmZmOTBiM2FjZWFjNjA0ZGMwY2ZhNmI4
|
15
|
+
ZjVmNzU4ZGUwYzczZmNkM2U0M2ZmNjQxZDRkZDI2YTY3MmVlOTU=
|
@@ -16,48 +16,46 @@ module ZipkinTracer
|
|
16
16
|
def initialize(app, service_name = nil)
|
17
17
|
@app = app
|
18
18
|
@service_name = service_name
|
19
|
+
@tracer = Trace.tracer
|
19
20
|
end
|
20
21
|
|
21
22
|
def call(env)
|
22
23
|
# handle either a URI object (passed by Faraday v0.8.x in testing), or something string-izable
|
23
24
|
url = env[:url].respond_to?(:host) ? env[:url] : URI.parse(env[:url].to_s)
|
24
|
-
local_endpoint =
|
25
|
+
local_endpoint = Trace.default_endpoint # The rack middleware set this up for us.
|
25
26
|
remote_endpoint = callee_endpoint(url, local_endpoint.ip_format) # The endpoint we are calling.
|
26
|
-
|
27
27
|
response = nil
|
28
|
-
|
29
|
-
|
30
|
-
::Trace.push(trace_id.next_id)
|
28
|
+
trace_id = Trace.id.next_id
|
29
|
+
with_trace_id(trace_id) do
|
31
30
|
B3_HEADERS.each do |method, header|
|
32
|
-
env[:request_headers][header] =
|
31
|
+
env[:request_headers][header] = trace_id.send(method).to_s
|
33
32
|
end
|
34
33
|
# annotate with method (GET/POST/etc.) and uri path
|
35
|
-
|
36
|
-
record(
|
37
|
-
record(
|
38
|
-
record(
|
34
|
+
@tracer.set_rpc_name(trace_id, env[:method].to_s.downcase)
|
35
|
+
@tracer.record(trace_id, Trace::BinaryAnnotation.new('http.uri', url.path, 'STRING', local_endpoint))
|
36
|
+
@tracer.record(trace_id, Trace::BinaryAnnotation.new('sa', '1', 'BOOL', remote_endpoint))
|
37
|
+
@tracer.record(trace_id, Trace::Annotation.new(Trace::Annotation::CLIENT_SEND, local_endpoint))
|
39
38
|
response = @app.call(env).on_complete do |renv|
|
40
39
|
# record HTTP status code on response
|
41
|
-
record(
|
40
|
+
@tracer.record(trace_id, Trace::BinaryAnnotation.new('http.status', renv[:status].to_s, 'STRING', local_endpoint))
|
42
41
|
end
|
43
|
-
record(
|
44
|
-
ensure
|
45
|
-
::Trace.pop
|
42
|
+
@tracer.record(trace_id, Trace::Annotation.new(Trace::Annotation::CLIENT_RECV, local_endpoint))
|
46
43
|
end
|
47
44
|
response
|
48
45
|
end
|
49
46
|
|
50
47
|
private
|
51
48
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
def with_trace_id(trace_id, &block)
|
50
|
+
Trace.push(trace_id)
|
51
|
+
yield
|
52
|
+
ensure
|
53
|
+
Trace.pop
|
56
54
|
end
|
57
55
|
|
58
56
|
def callee_endpoint(url, ip_format)
|
59
57
|
service_name = @service_name || url.host.split('.').first || 'unknown' # default to url-derived service name
|
60
|
-
|
58
|
+
Trace::Endpoint.make_endpoint(url.host, url.port, service_name, ip_format)
|
61
59
|
end
|
62
60
|
end
|
63
61
|
end
|
@@ -13,11 +13,13 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
require 'finagle-thrift'
|
15
15
|
require 'finagle-thrift/trace'
|
16
|
-
require 'sucker_punch'
|
17
16
|
require 'zipkin-tracer/config'
|
17
|
+
require 'zipkin-tracer/tracer_factory'
|
18
18
|
|
19
19
|
module ZipkinTracer
|
20
20
|
|
21
|
+
# This middleware reads Zipkin headers from the request and sets/creates a Trace.id usable by the rest of the app
|
22
|
+
# It will also send the trace to the Zipkin service using one of the methods configured.
|
21
23
|
class RackHandler
|
22
24
|
B3_REQUIRED_HEADERS = %w[HTTP_X_B3_TRACEID HTTP_X_B3_PARENTSPANID HTTP_X_B3_SPANID HTTP_X_B3_SAMPLED]
|
23
25
|
B3_OPT_HEADERS = %w[HTTP_X_B3_FLAGS]
|
@@ -25,53 +27,33 @@ module ZipkinTracer
|
|
25
27
|
def initialize(app, config = nil)
|
26
28
|
@app = app
|
27
29
|
@lock = Mutex.new
|
30
|
+
@config = Config.new(app, config).freeze
|
31
|
+
@tracer = TracerFactory.new.tracer(@config)
|
32
|
+
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
require 'zipkin-tracer/zipkin_json_tracer'
|
36
|
-
::Trace::ZipkinJsonTracer.new(config.json_api_host, config.traces_buffer)
|
37
|
-
when :scribe
|
38
|
-
require 'zipkin-tracer/careless_scribe'
|
39
|
-
::Trace::ZipkinTracer.new(CarelessScribe.new(config.scribe_server), config.scribe_max_buffer)
|
40
|
-
when :kafka
|
41
|
-
require 'zipkin-tracer/zipkin_kafka_tracer'
|
42
|
-
kafkaTracer = ::Trace::ZipkinKafkaTracer.new
|
43
|
-
kafkaTracer.connect(config.zookeeper)
|
44
|
-
kafkaTracer
|
34
|
+
def call(env)
|
35
|
+
zipkin_env = ZipkinEnv.new(env, @config)
|
36
|
+
trace_id = zipkin_env.trace_id
|
37
|
+
with_trace_id(trace_id) do
|
38
|
+
if !trace_id.sampled? || !routable_request?(env)
|
39
|
+
@app.call(env)
|
45
40
|
else
|
46
|
-
|
41
|
+
trace!(trace_id, zipkin_env) { @app.call(env) }
|
42
|
+
end
|
47
43
|
end
|
48
|
-
|
49
|
-
ip_format = config.adapter == :json ? :string : :i32
|
50
|
-
::Trace.default_endpoint = ::Trace::Endpoint.make_endpoint(
|
51
|
-
nil, # auto detect hostname
|
52
|
-
config.service_port,
|
53
|
-
service_name(config.service_name),
|
54
|
-
ip_format
|
55
|
-
)
|
56
|
-
::Trace.sample_rate = config.sample_rate
|
57
|
-
|
58
|
-
@config = config
|
59
44
|
end
|
60
45
|
|
61
|
-
|
62
|
-
# skip certain requests
|
63
|
-
return @app.call(env) if filtered?(env) || !routable_request?(env)
|
46
|
+
private
|
64
47
|
|
65
|
-
|
66
|
-
|
67
|
-
|
48
|
+
def with_trace_id(trace_id, &block)
|
49
|
+
Trace.push(trace_id)
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
Trace.pop
|
68
53
|
end
|
69
54
|
|
70
|
-
|
71
|
-
|
72
|
-
# Use the Domain environment variable to extract the service name, otherwise use the default config name
|
73
|
-
def service_name(default_name)
|
74
|
-
ENV["DOMAIN"].to_s.empty? ? default_name : ENV["DOMAIN"].split('.').first
|
55
|
+
def record(annotation)
|
56
|
+
@tracer.record(@trace_id, annotation)
|
75
57
|
end
|
76
58
|
|
77
59
|
# If the request is not valid for this service, we do not what to trace it.
|
@@ -83,68 +65,87 @@ module ZipkinTracer
|
|
83
65
|
false
|
84
66
|
end
|
85
67
|
|
86
|
-
def
|
68
|
+
def annotate_plugin(env, status, response_headers, response_body)
|
87
69
|
@config.annotate_plugin.call(env, status, response_headers, response_body) if @config.annotate_plugin
|
88
70
|
end
|
89
71
|
|
90
|
-
def
|
91
|
-
@config.filter_plugin && !@config.filter_plugin.call(env)
|
92
|
-
end
|
93
|
-
|
94
|
-
def force_sample?(env)
|
95
|
-
@config.whitelist_plugin && @config.whitelist_plugin.call(env)
|
96
|
-
end
|
97
|
-
|
98
|
-
def tracing_filter(trace_id, env, whitelisted = false)
|
72
|
+
def trace!(trace_id, zipkin_env, &block)
|
99
73
|
synchronize do
|
100
|
-
::Trace.push(trace_id)
|
101
74
|
#if called by a service, the caller already added the information
|
102
|
-
|
103
|
-
|
104
|
-
|
75
|
+
trace_request_information(trace_id, zipkin_env.env) unless zipkin_env.called_with_zipkin_headers?
|
76
|
+
@tracer.record(trace_id, Trace::Annotation.new(Trace::Annotation::SERVER_RECV, Trace.default_endpoint))
|
77
|
+
@tracer.record(trace_id, Trace::Annotation.new('whitelisted', Trace.default_endpoint)) if zipkin_env.force_sample?
|
105
78
|
end
|
106
|
-
status, headers, body = yield
|
79
|
+
status, headers, body = yield
|
107
80
|
ensure
|
108
81
|
synchronize do
|
109
|
-
|
110
|
-
|
111
|
-
::Trace.pop
|
82
|
+
annotate_plugin(zipkin_env.env, status, headers, body)
|
83
|
+
@tracer.record(trace_id, Trace::Annotation.new(Trace::Annotation::SERVER_SEND, Trace.default_endpoint))
|
112
84
|
end
|
113
|
-
[status, headers, body]
|
114
|
-
end
|
115
|
-
|
116
|
-
def add_request_information(env)
|
117
|
-
::Trace.set_rpc_name(env['REQUEST_METHOD'].to_s.downcase) # get/post and all that jazz
|
118
|
-
::Trace.record(::Trace::BinaryAnnotation.new('http.uri', env['PATH_INFO'], 'STRING', ::Trace.default_endpoint))
|
119
85
|
end
|
120
86
|
|
121
|
-
def
|
122
|
-
|
87
|
+
def trace_request_information(trace_id, env)
|
88
|
+
@tracer.set_rpc_name(trace_id, env['REQUEST_METHOD'].to_s.downcase) # get/post and all that jazz
|
89
|
+
@tracer.record(trace_id, Trace::BinaryAnnotation.new('http.uri', env['PATH_INFO'], 'STRING', Trace.default_endpoint))
|
123
90
|
end
|
124
91
|
|
125
92
|
def synchronize(&block)
|
126
93
|
@lock.synchronize do
|
127
94
|
yield
|
128
95
|
end
|
129
|
-
|
130
|
-
# Usually is better to rescue StandardError but the socket layer can launch Errno kind of exceptions
|
131
|
-
rescue Exception => e
|
96
|
+
rescue => e
|
132
97
|
@config.logger.error("Exception #{e.message} while sending Zipkin traces. #{e.backtrace}")
|
133
98
|
end
|
134
99
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
new_id = Trace.generate_id
|
140
|
-
[new_id, nil, new_id, ('true' if whitelisted || Trace.should_sample?)]
|
141
|
-
end
|
142
|
-
trace_parameters[3] = (trace_parameters[3] == 'true')
|
100
|
+
# Environment with Zipkin information in it
|
101
|
+
class ZipkinEnv
|
102
|
+
attr_reader :env
|
143
103
|
|
144
|
-
|
145
|
-
|
104
|
+
def initialize(env, config)
|
105
|
+
@env = env
|
106
|
+
@config = config
|
107
|
+
end
|
108
|
+
|
109
|
+
def trace_id(default_flags = Trace::Flags::EMPTY)
|
110
|
+
trace_parameters = if called_with_zipkin_headers?
|
111
|
+
@env.values_at(*B3_REQUIRED_HEADERS)
|
112
|
+
else
|
113
|
+
new_id = Trace.generate_id
|
114
|
+
[new_id, nil, new_id]
|
115
|
+
end
|
116
|
+
trace_parameters[3] = should_trace?(trace_parameters[3])
|
117
|
+
trace_parameters += @env.values_at(*B3_OPT_HEADERS) # always check flags
|
118
|
+
trace_parameters[4] = (trace_parameters[4] || default_flags).to_i
|
119
|
+
|
120
|
+
Trace::TraceId.new(*trace_parameters)
|
121
|
+
end
|
122
|
+
|
123
|
+
def called_with_zipkin_headers?
|
124
|
+
@called_with_zipkin_headers ||= B3_REQUIRED_HEADERS.all? { |key| @env.has_key?(key) }
|
125
|
+
end
|
126
|
+
|
127
|
+
def force_sample?
|
128
|
+
@force_sample ||= @config.whitelist_plugin && @config.whitelist_plugin.call(@env)
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
146
132
|
|
147
|
-
|
133
|
+
def current_trace_sampled?
|
134
|
+
rand < @config.sample_rate
|
135
|
+
end
|
136
|
+
|
137
|
+
def should_trace?(parent_trace_sampled)
|
138
|
+
if parent_trace_sampled # A service upstream decided this goes in all the way
|
139
|
+
parent_trace_sampled == 'true'
|
140
|
+
else
|
141
|
+
force_sample? || current_trace_sampled? && !filtered?
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def filtered?
|
146
|
+
@config.filter_plugin && !@config.filter_plugin.call(@env)
|
147
|
+
end
|
148
148
|
end
|
149
|
+
|
149
150
|
end
|
150
151
|
end
|
data/lib/zipkin-tracer/trace.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
require 'finagle-thrift'
|
2
2
|
require 'finagle-thrift/trace'
|
3
|
+
require 'zipkin-tracer/zipkin_tracer_base'
|
3
4
|
|
4
5
|
module Trace
|
6
|
+
|
7
|
+
# We need this to access the tracer from the Faraday middleware.
|
8
|
+
def self.tracer
|
9
|
+
@tracer
|
10
|
+
end
|
11
|
+
|
5
12
|
class Span
|
6
13
|
def to_h
|
7
14
|
{
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
module ZipkinTracer
|
3
|
+
class TracerFactory
|
4
|
+
def tracer(config)
|
5
|
+
adapter = config.adapter
|
6
|
+
|
7
|
+
tracer = case adapter
|
8
|
+
when :json
|
9
|
+
require 'zipkin-tracer/zipkin_json_tracer'
|
10
|
+
options = { json_api_host: config.json_api_host, traces_buffer: config.traces_buffer, logger: config.logger }
|
11
|
+
Trace::ZipkinJsonTracer.new(options)
|
12
|
+
when :scribe
|
13
|
+
require 'zipkin-tracer/careless_scribe'
|
14
|
+
Trace::ZipkinTracer.new(CarelessScribe.new(config.scribe_server), config.scribe_max_buffer)
|
15
|
+
when :kafka
|
16
|
+
require 'zipkin-tracer/zipkin_kafka_tracer'
|
17
|
+
Trace::ZipkinKafkaTracer.new(zookeepers: config.zookeeper)
|
18
|
+
else
|
19
|
+
Trace::NullTracer.new
|
20
|
+
end
|
21
|
+
Trace.tracer = tracer
|
22
|
+
|
23
|
+
# TODO: move this to the TracerBase and kill scribe tracer
|
24
|
+
ip_format = config.adapter == :json ? :string : :i32
|
25
|
+
Trace.default_endpoint = Trace::Endpoint.make_endpoint(
|
26
|
+
nil, # auto detect hostname
|
27
|
+
config.service_port,
|
28
|
+
service_name(config.service_name),
|
29
|
+
ip_format
|
30
|
+
)
|
31
|
+
tracer
|
32
|
+
end
|
33
|
+
|
34
|
+
# Use the Domain environment variable to extract the service name, otherwise use the default config name
|
35
|
+
# TODO: move to the config object
|
36
|
+
def service_name(default_name)
|
37
|
+
ENV["DOMAIN"].to_s.empty? ? default_name : ENV["DOMAIN"].split('.').first
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'json'
|
2
|
-
require 'faraday'
|
3
2
|
require 'sucker_punch'
|
4
|
-
require '
|
3
|
+
require 'zipkin-tracer/zipkin_tracer_base'
|
4
|
+
|
5
5
|
|
6
6
|
class AsyncJsonApiClient
|
7
7
|
include SuckerPunch::Job
|
@@ -19,55 +19,18 @@ class AsyncJsonApiClient
|
|
19
19
|
end
|
20
20
|
|
21
21
|
module Trace
|
22
|
-
class
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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 = {}
|
22
|
+
# This class sends information to the Zipkin API.
|
23
|
+
# The API accepts a JSON representation of a list of spans
|
24
|
+
class ZipkinJsonTracer < ZipkinTracerBase
|
25
|
+
|
26
|
+
def initialize(options)
|
27
|
+
SuckerPunch.logger = options[:logger]
|
28
|
+
@json_api_host = options[:json_api_host]
|
29
|
+
super(options)
|
66
30
|
end
|
67
31
|
|
68
32
|
def flush!
|
69
|
-
AsyncJsonApiClient.new.async.perform(@json_api_host,
|
70
|
-
reset
|
33
|
+
AsyncJsonApiClient.new.async.perform(@json_api_host, spans.values.dup)
|
71
34
|
end
|
72
35
|
end
|
73
36
|
end
|
@@ -2,64 +2,32 @@ require 'finagle-thrift'
|
|
2
2
|
require 'finagle-thrift/tracer'
|
3
3
|
require 'hermann/producer'
|
4
4
|
require 'hermann/discovery/zookeeper'
|
5
|
+
require 'zipkin-tracer/zipkin_tracer_base'
|
5
6
|
|
6
7
|
module Trace
|
7
|
-
class
|
8
|
-
|
8
|
+
# This class sends information to Zipkin through Kafka.
|
9
|
+
# Spans are encoded using Thrift
|
10
|
+
class ZipkinKafkaTracer < ZipkinTracerBase
|
9
11
|
DEFAULT_KAFKA_TOPIC = "zipkin_kafka".freeze
|
10
12
|
|
11
|
-
def initialize(
|
12
|
-
@
|
13
|
-
|
14
|
-
reset
|
15
|
-
end
|
16
|
-
|
17
|
-
# need to connect after initialization
|
18
|
-
def connect(zookeepers)
|
19
|
-
broker_ids = Hermann::Discovery::Zookeeper.new(zookeepers).get_brokers
|
13
|
+
def initialize(options = {})
|
14
|
+
@topic = options[:topic] || DEFAULT_KAFKA_TOPIC
|
15
|
+
broker_ids = Hermann::Discovery::Zookeeper.new(options[:zookeepers]).get_brokers
|
20
16
|
@producer = Hermann::Producer.new(nil, broker_ids)
|
17
|
+
options[:traces_buffer] ||= 1 # Default in Kafka is sending as soon as possible. No buffer.
|
18
|
+
super(options)
|
21
19
|
end
|
22
20
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
when Annotation
|
31
|
-
span.annotations << annotation
|
21
|
+
def flush!
|
22
|
+
messages = spans.values.map do |span|
|
23
|
+
buf = ''
|
24
|
+
trans = Thrift::MemoryBufferTransport.new(buf)
|
25
|
+
oprot = Thrift::BinaryProtocol.new(trans)
|
26
|
+
span.to_thrift.write(oprot)
|
27
|
+
@producer.push(buf, topic: @topic).value!
|
32
28
|
end
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
def set_rpc_name(id, name)
|
38
|
-
return unless id.sampled?
|
39
|
-
span = get_span_for_id(id)
|
40
|
-
span.name = name.to_s
|
29
|
+
rescue Exception
|
30
|
+
# Ignore socket errors, etc
|
41
31
|
end
|
42
|
-
|
43
|
-
private
|
44
|
-
def reset
|
45
|
-
@spans = {}
|
46
|
-
end
|
47
|
-
|
48
|
-
def get_span_for_id(id)
|
49
|
-
key = id.span_id.to_s
|
50
|
-
@spans[key] ||= begin
|
51
|
-
Span.new("", id)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def flush!
|
56
|
-
messages = @spans.values.map do |span|
|
57
|
-
buf = ''
|
58
|
-
trans = Thrift::MemoryBufferTransport.new(buf)
|
59
|
-
oprot = Thrift::BinaryProtocol.new(trans)
|
60
|
-
span.to_thrift.write(oprot)
|
61
|
-
@producer.push(buf, :topic => @topic).value!
|
62
|
-
end
|
63
|
-
end
|
64
32
|
end
|
65
|
-
end
|
33
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'finagle-thrift'
|
3
|
+
require 'finagle-thrift/tracer'
|
4
|
+
|
5
|
+
module Trace
|
6
|
+
# This class is a base for tracers sending information to Zipkin.
|
7
|
+
# It knows about zipkin types of annotations and send traces when the server
|
8
|
+
# is done with its request
|
9
|
+
# Traces dealing with zipkin should inherit from this class and implement the
|
10
|
+
# flush! method which actually sends the information
|
11
|
+
class ZipkinTracerBase < Tracer
|
12
|
+
TRACER_CATEGORY = "zipkin".freeze
|
13
|
+
|
14
|
+
def initialize(options={})
|
15
|
+
@options = options
|
16
|
+
@traces_buffer = options[:traces_buffer] || raise(ArgumentError, 'A proper buffer must be setup for the Zipkin tracer')
|
17
|
+
reset
|
18
|
+
end
|
19
|
+
|
20
|
+
def record(id, annotation)
|
21
|
+
span = get_span_for_id(id)
|
22
|
+
|
23
|
+
case annotation
|
24
|
+
when BinaryAnnotation
|
25
|
+
span.binary_annotations << annotation
|
26
|
+
when Annotation
|
27
|
+
span.annotations << annotation
|
28
|
+
end
|
29
|
+
count = current_count
|
30
|
+
set_current_count(count + 1)
|
31
|
+
|
32
|
+
if current_count >= @traces_buffer || (annotation.is_a?(Annotation) && annotation.value == Annotation::SERVER_SEND)
|
33
|
+
flush!
|
34
|
+
reset
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_rpc_name(id, name)
|
39
|
+
span = get_span_for_id(id)
|
40
|
+
span.name = name.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def flush!
|
44
|
+
raise "not implemented"
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def spans
|
50
|
+
Thread.current[:zipkin_spans] ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def current_count
|
54
|
+
Thread.current[:zipkin_spans_count] ||= 0
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_current_count(count)
|
58
|
+
Thread.current[:zipkin_spans_count] = count
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_span_for_id(id)
|
62
|
+
key = id.span_id.to_s
|
63
|
+
spans[key] ||= Span.new("", id)
|
64
|
+
end
|
65
|
+
|
66
|
+
def reset
|
67
|
+
Thread.current[:zipkin_spans] = {}
|
68
|
+
set_current_count(0)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
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.10.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: 2015-12-
|
16
|
+
date: 2015-12-29 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: finagle-thrift
|
@@ -99,20 +99,6 @@ dependencies:
|
|
99
99
|
- - ~>
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: '10.0'
|
102
|
-
- !ruby/object:Gem::Dependency
|
103
|
-
name: pry
|
104
|
-
requirement: !ruby/object:Gem::Requirement
|
105
|
-
requirements:
|
106
|
-
- - ~>
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: '0.10'
|
109
|
-
type: :development
|
110
|
-
prerelease: false
|
111
|
-
version_requirements: !ruby/object:Gem::Requirement
|
112
|
-
requirements:
|
113
|
-
- - ~>
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
version: '0.10'
|
116
102
|
- !ruby/object:Gem::Dependency
|
117
103
|
name: faraday
|
118
104
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,9 +187,11 @@ files:
|
|
201
187
|
- lib/zipkin-tracer/faraday/zipkin-tracer.rb
|
202
188
|
- lib/zipkin-tracer/rack/zipkin-tracer.rb
|
203
189
|
- lib/zipkin-tracer/trace.rb
|
190
|
+
- lib/zipkin-tracer/tracer_factory.rb
|
204
191
|
- lib/zipkin-tracer/version.rb
|
205
192
|
- lib/zipkin-tracer/zipkin_json_tracer.rb
|
206
193
|
- lib/zipkin-tracer/zipkin_kafka_tracer.rb
|
194
|
+
- lib/zipkin-tracer/zipkin_tracer_base.rb
|
207
195
|
homepage: https://github.com/openzipkin/zipkin-tracer
|
208
196
|
licenses: []
|
209
197
|
metadata: {}
|