zipkin 0.1.0 → 0.2.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 +4 -4
- data/README.md +9 -13
- data/lib/zipkin/endpoint.rb +12 -0
- data/lib/zipkin/json_client.rb +34 -0
- data/lib/zipkin/span.rb +43 -5
- data/lib/zipkin/span_context.rb +5 -5
- data/lib/zipkin/trace_id.rb +1 -1
- data/lib/zipkin/tracer.rb +59 -34
- data/lib/zipkin.rb +0 -4
- data/script/create_trace +40 -0
- data/zipkin.gemspec +4 -1
- metadata +47 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 504536eebfe1f9f6ce03dd1c9bb1ef0d2c0d870f
|
4
|
+
data.tar.gz: 9e7638f5c9b6cfc0a1061955f3475ad1c5f352d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fff4fc9878ad37a878968c8805a755f110ac98418dcd88f4229fca5ceb41642c3f66df02a2aad9a0d1903e9dfbd824a359dff77d870a33b5de936b53fe04bfe
|
7
|
+
data.tar.gz: 31b4d916668c882181a08aeb1026557e42051a5ea6b7c91074085ff83ade66153ea3df616ca001ef67a48e804f114cedc45faacffa02441621c58fe477b36135
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Zipkin
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
OpenTracing Tracer implementation for Zipkin in Ruby
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -12,17 +10,15 @@ Add this line to your application's Gemfile:
|
|
12
10
|
gem 'zipkin'
|
13
11
|
```
|
14
12
|
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install zipkin
|
22
|
-
|
23
13
|
## Usage
|
24
14
|
|
25
|
-
|
15
|
+
```ruby
|
16
|
+
require 'zipkin/tracer'
|
17
|
+
OpenTracing.global_tracer = Zipkin::Tracer.build(url: 'http://localhost:9411', service_name: 'echo')
|
18
|
+
|
19
|
+
span = OpenTracing.start_span('span name')
|
20
|
+
span.finish
|
21
|
+
```
|
26
22
|
|
27
23
|
## Development
|
28
24
|
|
@@ -32,7 +28,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
28
|
|
33
29
|
## Contributing
|
34
30
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
31
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/salemove/zipkin-ruby-opentracing
|
36
32
|
|
37
33
|
|
38
34
|
## License
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'sucker_punch'
|
4
|
+
|
5
|
+
module Zipkin
|
6
|
+
class JsonClient
|
7
|
+
def initialize(url)
|
8
|
+
@faraday = Faraday.new(url: url) do |faraday|
|
9
|
+
faraday.request :json
|
10
|
+
faraday.request :retry, max: 3, interval: 10, backoff_factor: 2
|
11
|
+
faraday.adapter Faraday.default_adapter
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def send_span(payload)
|
16
|
+
SpanSender.perform_async(payload: payload, faraday: @faraday)
|
17
|
+
end
|
18
|
+
|
19
|
+
class SpanSender
|
20
|
+
include SuckerPunch::Job
|
21
|
+
workers 4
|
22
|
+
|
23
|
+
def perform(payload:, faraday:)
|
24
|
+
response = faraday.post '/api/v1/spans' do |req|
|
25
|
+
req.body = [payload]
|
26
|
+
end
|
27
|
+
|
28
|
+
if response.status != 202
|
29
|
+
STDERR.puts(response.body)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/zipkin/span.rb
CHANGED
@@ -6,13 +6,18 @@ module Zipkin
|
|
6
6
|
|
7
7
|
# Creates a new {Span}
|
8
8
|
#
|
9
|
-
# @param tracer [Tracer] the tracer that created this span
|
10
9
|
# @param context [SpanContext] the context of the span
|
10
|
+
# @param context [String] the operation name
|
11
|
+
# @param client [Faraday] faraday instace for making http requests
|
11
12
|
#
|
12
13
|
# @return [Span] a new Span
|
13
|
-
def initialize(
|
14
|
-
@tracer = tracer
|
14
|
+
def initialize(context, operation_name, client, start_time: Time.now, tags: {}, local_endpoint:)
|
15
15
|
@context = context
|
16
|
+
@operation_name = operation_name
|
17
|
+
@client = client
|
18
|
+
@start_time = start_time
|
19
|
+
@tags = tags
|
20
|
+
@local_endpoint = local_endpoint
|
16
21
|
end
|
17
22
|
|
18
23
|
# Set a tag value on this span
|
@@ -21,7 +26,7 @@ module Zipkin
|
|
21
26
|
# @param value [String, Numeric, Boolean] the value of the tag. If it's not
|
22
27
|
# a String, Numeric, or Boolean it will be encoded with to_s
|
23
28
|
def set_tag(key, value)
|
24
|
-
|
29
|
+
@tags = @tags.merge(key => value)
|
25
30
|
end
|
26
31
|
|
27
32
|
# Set a baggage item on the span
|
@@ -54,7 +59,40 @@ module Zipkin
|
|
54
59
|
#
|
55
60
|
# @param end_time [Time] custom end time, if not now
|
56
61
|
def finish(end_time: Time.now)
|
57
|
-
|
62
|
+
finish_ts = (end_time.to_f * 1_000_000).to_i
|
63
|
+
start_ts = (@start_time.to_f * 1_000_000).to_i
|
64
|
+
duration = finish_ts - start_ts
|
65
|
+
is_server = ['server', 'consumer'].include?(@tags['span.kind'] || 'server')
|
66
|
+
|
67
|
+
@client.send_span(
|
68
|
+
traceId: @context.trace_id,
|
69
|
+
id: @context.span_id,
|
70
|
+
parentId: @context.parent_id,
|
71
|
+
name: @operation_name,
|
72
|
+
timestamp: start_ts,
|
73
|
+
duration: duration,
|
74
|
+
annotations: [
|
75
|
+
{
|
76
|
+
timestamp: start_ts,
|
77
|
+
value: is_server ? 'sr' : 'cs',
|
78
|
+
endpoint: @local_endpoint
|
79
|
+
},
|
80
|
+
{
|
81
|
+
timestamp: finish_ts,
|
82
|
+
value: is_server ? 'ss': 'cr',
|
83
|
+
endpoint: @local_endpoint
|
84
|
+
}
|
85
|
+
],
|
86
|
+
binaryAnnotations: build_binary_annotations
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def build_binary_annotations
|
93
|
+
@tags.map do |name, value|
|
94
|
+
{key: name, value: value.to_s}
|
95
|
+
end
|
58
96
|
end
|
59
97
|
end
|
60
98
|
end
|
data/lib/zipkin/span_context.rb
CHANGED
@@ -2,14 +2,14 @@ module Zipkin
|
|
2
2
|
# SpanContext holds the data for a span that gets inherited to child spans
|
3
3
|
class SpanContext
|
4
4
|
def self.create_parent_context
|
5
|
+
trace_id = TraceId.generate
|
5
6
|
span_id = TraceId.generate
|
6
|
-
trace_id
|
7
|
-
new(span_id: span_id, trace_id: trace_id)
|
7
|
+
new(trace_id: trace_id, span_id: span_id)
|
8
8
|
end
|
9
9
|
|
10
|
-
def self.
|
11
|
-
trace_id =
|
12
|
-
parent_id =
|
10
|
+
def self.create_from_parent_context(span_context)
|
11
|
+
trace_id = span_context.trace_id
|
12
|
+
parent_id = span_context.span_id
|
13
13
|
span_id = TraceId.generate
|
14
14
|
new(span_id: span_id, parent_id: parent_id, trace_id: trace_id)
|
15
15
|
end
|
data/lib/zipkin/trace_id.rb
CHANGED
data/lib/zipkin/tracer.rb
CHANGED
@@ -1,71 +1,96 @@
|
|
1
|
+
require 'opentracing'
|
2
|
+
|
3
|
+
require_relative 'span'
|
4
|
+
require_relative 'span_context'
|
5
|
+
require_relative 'carrier'
|
6
|
+
require_relative 'trace_id'
|
7
|
+
require_relative 'json_client'
|
8
|
+
require_relative 'endpoint'
|
9
|
+
|
1
10
|
module Zipkin
|
2
11
|
class Tracer
|
3
|
-
def self.build(
|
12
|
+
def self.build(url:, service_name:)
|
13
|
+
client = JsonClient.new(url)
|
14
|
+
new(client, service_name)
|
4
15
|
end
|
5
16
|
|
6
|
-
def initialize(client)
|
17
|
+
def initialize(client, service_name)
|
7
18
|
@client = client
|
19
|
+
@local_endpoint = Endpoint.local_endpoint(service_name)
|
8
20
|
end
|
9
21
|
|
10
|
-
#
|
22
|
+
# Starts a new span.
|
11
23
|
#
|
12
|
-
# @param operation_name [String]
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# @param
|
18
|
-
# The time when the Span started, if not now
|
19
|
-
# @param tags [Hash]
|
20
|
-
# Tags to assign to the Span at start time
|
24
|
+
# @param operation_name [String] The operation name for the Span
|
25
|
+
# @param child_of [SpanContext, Span] SpanContext that acts as a parent to
|
26
|
+
# the newly-started Span. If a Span instance is provided, its
|
27
|
+
# context is automatically substituted.
|
28
|
+
# @param start_time [Time] When the Span started, if not now
|
29
|
+
# @param tags [Hash] Tags to assign to the Span at start time
|
21
30
|
#
|
22
|
-
# @return [Span]
|
23
|
-
|
24
|
-
def start_span(operation_name, child_of: nil, start_time: Time.now, tags: nil)
|
31
|
+
# @return [Span] The newly-started Span
|
32
|
+
def start_span(operation_name, child_of: nil, start_time: Time.now, tags: {}, **)
|
25
33
|
context =
|
26
34
|
if child_of
|
27
|
-
|
35
|
+
parent_context = child_of.respond_to?(:context) ? child_of.context : child_of
|
36
|
+
SpanContext.create_from_parent_context(parent_context)
|
28
37
|
else
|
29
38
|
SpanContext.create_parent_context
|
30
39
|
end
|
31
|
-
|
32
|
-
span.operation_name = operation_name
|
33
|
-
span
|
40
|
+
Span.new(context, operation_name, @client, start_time: start_time, tags: tags, local_endpoint: @local_endpoint)
|
34
41
|
end
|
35
42
|
|
36
43
|
# Inject a SpanContext into the given carrier
|
37
44
|
#
|
38
45
|
# @param span_context [SpanContext]
|
39
46
|
# @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY, OpenTracing::FORMAT_RACK]
|
40
|
-
#
|
41
|
-
# @param carrier [Carrier]
|
42
|
-
# A carrier object of the type dictated by the specified `format`
|
47
|
+
# @param carrier [Carrier] A carrier object of the type dictated by the specified `format`
|
43
48
|
def inject(span_context, format, carrier)
|
44
49
|
case format
|
45
|
-
when OpenTracing::FORMAT_TEXT_MAP
|
46
|
-
|
50
|
+
when OpenTracing::FORMAT_TEXT_MAP
|
51
|
+
carrier['trace-id'] = span_context.trace_id
|
52
|
+
carrier['parent-id'] = span_context.parent_id
|
53
|
+
carrier['span-id'] = span_context.span_id
|
54
|
+
when OpenTracing::FORMAT_RACK
|
55
|
+
carrier['X-Trace-Id'] = span_context.trace_id
|
56
|
+
carrier['X-Trace-Parent-Id'] = span_context.parent_id
|
57
|
+
carrier['X-Trace-Span-Id'] = span_context.span_id
|
47
58
|
else
|
48
|
-
|
59
|
+
STDERR.puts "Logasm::Tracer with format #{format} is not supported yet"
|
49
60
|
end
|
50
61
|
end
|
51
62
|
|
52
63
|
# Extract a SpanContext in the given format from the given carrier.
|
53
64
|
#
|
54
65
|
# @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY, OpenTracing::FORMAT_RACK]
|
55
|
-
# @param carrier [Carrier]
|
56
|
-
#
|
57
|
-
#
|
58
|
-
# @return [SpanContext]
|
59
|
-
# the extracted SpanContext or nil if none could be found
|
66
|
+
# @param carrier [Carrier] A carrier object of the type dictated by the specified `format`
|
67
|
+
# @return [SpanContext] the extracted SpanContext or nil if none could be found
|
60
68
|
def extract(format, carrier)
|
61
69
|
case format
|
62
|
-
when OpenTracing::FORMAT_TEXT_MAP
|
63
|
-
|
70
|
+
when OpenTracing::FORMAT_TEXT_MAP
|
71
|
+
trace_id = carrier['trace-id']
|
72
|
+
parent_id = carrier['parent-id']
|
73
|
+
span_id = carrier['span-id']
|
74
|
+
|
75
|
+
if trace_id && span_id
|
76
|
+
SpanContext.new(trace_id: trace_id, parent_id: parent_id, span_id: span_id)
|
77
|
+
else
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
when OpenTracing::FORMAT_RACK
|
81
|
+
trace_id = carrier['HTTP_X_TRACE_ID']
|
82
|
+
parent_id = carrier['HTTP_X_TRACE_PARENT_ID']
|
83
|
+
span_id = carrier['HTTP_X_TRACE_SPAN_ID']
|
84
|
+
|
85
|
+
if trace_id && span_id
|
86
|
+
SpanContext.new(trace_id: trace_id, parent_id: parent_id, span_id: span_id)
|
87
|
+
else
|
88
|
+
nil
|
89
|
+
end
|
64
90
|
else
|
65
|
-
|
91
|
+
STDERR.puts "Logasm::Tracer with format #{format} is not supported yet"
|
66
92
|
nil
|
67
93
|
end
|
68
94
|
end
|
69
|
-
|
70
95
|
end
|
71
96
|
end
|
data/lib/zipkin.rb
CHANGED
data/script/create_trace
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup
|
5
|
+
|
6
|
+
require 'zipkin/tracer'
|
7
|
+
|
8
|
+
url = ENV['ZIPKIN_URL'] || 'http://localhost:9411'
|
9
|
+
|
10
|
+
tracer1 = Zipkin::Tracer.build(url: url, service_name: 'test-service')
|
11
|
+
tracer2 = Zipkin::Tracer.build(url: url, service_name: 'downstream-service')
|
12
|
+
|
13
|
+
outer_span = tracer1.start_span('receive request', tags: {
|
14
|
+
'span.kind' => 'server'
|
15
|
+
})
|
16
|
+
sleep 1
|
17
|
+
|
18
|
+
inner_span = tracer1.start_span('fetch info from downstream', child_of: outer_span, tags: {
|
19
|
+
'span.kind' => 'client',
|
20
|
+
'peer.service' => 'downstream-service',
|
21
|
+
'peer.ipv4' => '6.6.6.6',
|
22
|
+
'peer.port' => 443
|
23
|
+
})
|
24
|
+
sleep 0.3 # emulate network delay
|
25
|
+
|
26
|
+
downstream_span = tracer2.start_span('downstream operation', child_of: inner_span, tags: {
|
27
|
+
'span.kind' => 'server'
|
28
|
+
})
|
29
|
+
sleep 0.5
|
30
|
+
downstream_span.finish
|
31
|
+
|
32
|
+
sleep 0.2 # emulate network delay
|
33
|
+
|
34
|
+
inner_span.finish
|
35
|
+
|
36
|
+
sleep 0.1 # doing something with fetched info
|
37
|
+
outer_span.finish
|
38
|
+
|
39
|
+
puts "Finishing..."
|
40
|
+
sleep 3
|
data/zipkin.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'zipkin'
|
7
|
-
spec.version = '0.
|
7
|
+
spec.version = '0.2.0'
|
8
8
|
spec.authors = ['SaleMove TechMovers']
|
9
9
|
spec.email = ['techmovers@salemove.com']
|
10
10
|
|
@@ -24,4 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
25
25
|
|
26
26
|
spec.add_dependency 'opentracing', '~> 0.3'
|
27
|
+
spec.add_dependency 'faraday'
|
28
|
+
spec.add_dependency 'faraday_middleware'
|
29
|
+
spec.add_dependency 'sucker_punch', '~> 2.0'
|
27
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zipkin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SaleMove TechMovers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,48 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: faraday_middleware
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sucker_punch
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.0'
|
69
111
|
description: ''
|
70
112
|
email:
|
71
113
|
- techmovers@salemove.com
|
@@ -84,10 +126,13 @@ files:
|
|
84
126
|
- bin/setup
|
85
127
|
- lib/zipkin.rb
|
86
128
|
- lib/zipkin/carrier.rb
|
129
|
+
- lib/zipkin/endpoint.rb
|
130
|
+
- lib/zipkin/json_client.rb
|
87
131
|
- lib/zipkin/span.rb
|
88
132
|
- lib/zipkin/span_context.rb
|
89
133
|
- lib/zipkin/trace_id.rb
|
90
134
|
- lib/zipkin/tracer.rb
|
135
|
+
- script/create_trace
|
91
136
|
- zipkin.gemspec
|
92
137
|
homepage: ''
|
93
138
|
licenses:
|