zipkin 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -0
- data/README.md +9 -2
- data/lib/zipkin.rb +2 -0
- data/lib/zipkin/carrier.rb +2 -0
- data/lib/zipkin/collector.rb +12 -8
- data/lib/zipkin/collector/log_annotations.rb +2 -0
- data/lib/zipkin/collector/timestamp.rb +2 -0
- data/lib/zipkin/endpoint.rb +7 -5
- data/lib/zipkin/json_client.rb +2 -0
- data/lib/zipkin/scope.rb +38 -0
- data/lib/zipkin/scope_manager.rb +47 -0
- data/lib/zipkin/scope_manager/scope_identifier.rb +13 -0
- data/lib/zipkin/scope_manager/scope_stack.rb +33 -0
- data/lib/zipkin/span.rb +13 -1
- data/lib/zipkin/span_context.rb +2 -0
- data/lib/zipkin/trace_id.rb +2 -0
- data/lib/zipkin/tracer.rb +106 -11
- data/zipkin.gemspec +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57c74dfca283ccf9531225d1765bd897a53dd527
|
4
|
+
data.tar.gz: e3ac03480369442405e7ffdbb7988e9fa7e32f16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 981f0408f902b0a88f856eeefea27bee2032ab4712a63e499c2ebc001e286b351dd3d4209e2eb6ad176eeb880f4dac4d0e48010fbe135425a59bbc9e53d59644
|
7
|
+
data.tar.gz: 69e2ec0aa4e2c385c9e8944c8154714b2aa1f6744fef02a2b36ca5a391a8f55508a310680bad702c73bb86ed7633e192b877c9cd4ba84b68055917e248a9cb68
|
data/.rubocop.yml
CHANGED
@@ -24,8 +24,20 @@ Metrics/MethodLength:
|
|
24
24
|
Metrics/AbcSize:
|
25
25
|
Enabled: no
|
26
26
|
|
27
|
+
Metrics/ClassLength:
|
28
|
+
Enabled: no
|
29
|
+
|
30
|
+
Metrics/ParameterLists:
|
31
|
+
Enabled: no
|
32
|
+
|
27
33
|
Lint/UnusedMethodArgument:
|
28
34
|
Enabled: no
|
29
35
|
|
36
|
+
Style/FrozenStringLiteralComment:
|
37
|
+
Enabled: yes
|
38
|
+
EnforcedStyle: always
|
39
|
+
Include:
|
40
|
+
- 'lib/**/*'
|
41
|
+
|
30
42
|
Metrics/LineLength:
|
31
43
|
Max: 120
|
data/README.md
CHANGED
@@ -20,10 +20,17 @@ gem 'zipkin'
|
|
20
20
|
require 'zipkin/tracer'
|
21
21
|
OpenTracing.global_tracer = Zipkin::Tracer.build(url: 'http://localhost:9411', service_name: 'echo')
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
OpenTracing.start_active_span('span name') do
|
24
|
+
# do something
|
25
|
+
|
26
|
+
OpenTracing.start_active_span('inner span name') do
|
27
|
+
# do something else
|
28
|
+
end
|
29
|
+
end
|
25
30
|
```
|
26
31
|
|
32
|
+
See [opentracing-ruby](https://github.com/opentracing/opentracing-ruby) for more examples.
|
33
|
+
|
27
34
|
## Development
|
28
35
|
|
29
36
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/zipkin.rb
CHANGED
data/lib/zipkin/carrier.rb
CHANGED
data/lib/zipkin/collector.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thread'
|
2
4
|
|
3
5
|
require_relative './collector/timestamp'
|
@@ -5,6 +7,13 @@ require_relative './collector/log_annotations'
|
|
5
7
|
|
6
8
|
module Zipkin
|
7
9
|
class Collector
|
10
|
+
OT_KIND_TO_ZIPKIN_KIND = {
|
11
|
+
'server' => 'SERVER',
|
12
|
+
'client' => 'CLIENT',
|
13
|
+
'producer' => 'PRODUCER',
|
14
|
+
'consumer' => 'CONSUMER'
|
15
|
+
}.freeze
|
16
|
+
|
8
17
|
def initialize(local_endpoint)
|
9
18
|
@buffer = Buffer.new
|
10
19
|
@local_endpoint = local_endpoint
|
@@ -18,13 +27,14 @@ module Zipkin
|
|
18
27
|
finish_ts = Timestamp.create(end_time)
|
19
28
|
start_ts = Timestamp.create(span.start_time)
|
20
29
|
duration = finish_ts - start_ts
|
30
|
+
return unless span.context.sampled?
|
21
31
|
|
22
32
|
@buffer << {
|
23
33
|
traceId: span.context.trace_id,
|
24
34
|
id: span.context.span_id,
|
25
35
|
parentId: span.context.parent_id,
|
26
36
|
name: span.operation_name,
|
27
|
-
kind:
|
37
|
+
kind: OT_KIND_TO_ZIPKIN_KIND[span.tags[:'span.kind'] || 'server'],
|
28
38
|
timestamp: start_ts,
|
29
39
|
duration: duration,
|
30
40
|
debug: false,
|
@@ -32,16 +42,10 @@ module Zipkin
|
|
32
42
|
localEndpoint: @local_endpoint,
|
33
43
|
remoteEndpoint: Endpoint.remote_endpoint(span),
|
34
44
|
annotations: LogAnnotations.build(span),
|
35
|
-
tags:
|
45
|
+
tags: span.tags
|
36
46
|
}
|
37
47
|
end
|
38
48
|
|
39
|
-
private
|
40
|
-
|
41
|
-
def build_tags(span)
|
42
|
-
span.tags.map { |key, value| [key.to_s, value.to_s] }.to_h
|
43
|
-
end
|
44
|
-
|
45
49
|
class Buffer
|
46
50
|
def initialize
|
47
51
|
@buffer = []
|
data/lib/zipkin/endpoint.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'socket'
|
2
4
|
|
3
5
|
module Zipkin
|
@@ -15,10 +17,10 @@ module Zipkin
|
|
15
17
|
end
|
16
18
|
|
17
19
|
module PeerInfo
|
18
|
-
SERVICE = 'peer.service'
|
19
|
-
IPV4 = 'peer.ipv4'
|
20
|
-
IPV6 = 'peer.ipv6'
|
21
|
-
PORT = 'peer.port'
|
20
|
+
SERVICE = :'peer.service'
|
21
|
+
IPV4 = :'peer.ipv4'
|
22
|
+
IPV6 = :'peer.ipv6'
|
23
|
+
PORT = :'peer.port'
|
22
24
|
|
23
25
|
def self.keys
|
24
26
|
[SERVICE, IPV4, IPV6, PORT]
|
@@ -34,7 +36,7 @@ module Zipkin
|
|
34
36
|
|
35
37
|
def self.remote_endpoint(span)
|
36
38
|
tags = span.tags
|
37
|
-
kind = tags['span.kind'] || SpanKind::SERVER
|
39
|
+
kind = tags[:'span.kind'] || SpanKind::SERVER
|
38
40
|
|
39
41
|
case kind
|
40
42
|
when SpanKind::SERVER, SpanKind::CLIENT
|
data/lib/zipkin/json_client.rb
CHANGED
data/lib/zipkin/scope.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zipkin
|
4
|
+
# Scope represents an OpenTracing Scope
|
5
|
+
#
|
6
|
+
# See http://www.opentracing.io for more information.
|
7
|
+
class Scope
|
8
|
+
def initialize(span, scope_stack, finish_on_close:)
|
9
|
+
@span = span
|
10
|
+
@scope_stack = scope_stack
|
11
|
+
@finish_on_close = finish_on_close
|
12
|
+
@closed = false
|
13
|
+
end
|
14
|
+
|
15
|
+
# Return the Span scoped by this Scope
|
16
|
+
#
|
17
|
+
# @return [Span]
|
18
|
+
attr_reader :span
|
19
|
+
|
20
|
+
# Close scope
|
21
|
+
#
|
22
|
+
# Mark the end of the active period for the current thread and Scope,
|
23
|
+
# updating the ScopeManager#active in the process.
|
24
|
+
def close
|
25
|
+
raise "Tried to close already closed span: #{inspect}" if @closed
|
26
|
+
@closed = true
|
27
|
+
|
28
|
+
@span.finish if @finish_on_close
|
29
|
+
removed_scope = @scope_stack.pop
|
30
|
+
|
31
|
+
if removed_scope != self # rubocop:disable Style/GuardClause
|
32
|
+
raise 'Removed non-active scope, ' \
|
33
|
+
"removed: #{removed_scope.inspect}, "\
|
34
|
+
"expected: #{inspect}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'scope_manager/scope_stack'
|
4
|
+
require_relative 'scope_manager/scope_identifier'
|
5
|
+
|
6
|
+
module Zipkin
|
7
|
+
# ScopeManager represents an OpenTracing ScopeManager
|
8
|
+
#
|
9
|
+
# See http://www.opentracing.io for more information.
|
10
|
+
#
|
11
|
+
# The ScopeManager interface abstracts both the activation of Span instances
|
12
|
+
# via ScopeManager#activate and access to an active Span/Scope via
|
13
|
+
# ScopeManager#active
|
14
|
+
#
|
15
|
+
class ScopeManager
|
16
|
+
def initialize
|
17
|
+
@scope_stack = ScopeStack.new
|
18
|
+
end
|
19
|
+
|
20
|
+
# Make a span instance active
|
21
|
+
#
|
22
|
+
# @param span [Span] the Span that should become active
|
23
|
+
# @param finish_on_close [Boolean] whether the Span should automatically be
|
24
|
+
# finished when Scope#close is called
|
25
|
+
# @return [Scope] instance to control the end of the active period for the
|
26
|
+
# Span. It is a programming error to neglect to call Scope#close on the
|
27
|
+
# returned instance.
|
28
|
+
def activate(span, finish_on_close: true)
|
29
|
+
return active if active && active.span == span
|
30
|
+
scope = Scope.new(span, @scope_stack, finish_on_close: finish_on_close)
|
31
|
+
@scope_stack.push(scope)
|
32
|
+
scope
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return active scope
|
36
|
+
#
|
37
|
+
# If there is a non-null Scope, its wrapped Span becomes an implicit parent
|
38
|
+
# (as Reference#CHILD_OF) of any newly-created Span at
|
39
|
+
# Tracer#start_active_span or Tracer#start_span time.
|
40
|
+
#
|
41
|
+
# @return [Scope] the currently active Scope which can be used to access the
|
42
|
+
# currently active Span.
|
43
|
+
def active
|
44
|
+
@scope_stack.peek
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zipkin
|
4
|
+
class ScopeManager
|
5
|
+
# @api private
|
6
|
+
class ScopeIdentifier
|
7
|
+
def self.generate
|
8
|
+
# 65..90.chr are characters between A and Z
|
9
|
+
"opentracing_#{(0...8).map { rand(65..90).chr }.join}".to_sym
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zipkin
|
4
|
+
class ScopeManager
|
5
|
+
# @api private
|
6
|
+
class ScopeStack
|
7
|
+
def initialize
|
8
|
+
# Generate a random identifier to use as the Thread.current key. This is
|
9
|
+
# needed so that it would be possible to create multiple tracers in one
|
10
|
+
# thread (mostly useful for testing purposes)
|
11
|
+
@scope_identifier = ScopeIdentifier.generate
|
12
|
+
end
|
13
|
+
|
14
|
+
def push(scope)
|
15
|
+
store << scope
|
16
|
+
end
|
17
|
+
|
18
|
+
def pop
|
19
|
+
store.pop
|
20
|
+
end
|
21
|
+
|
22
|
+
def peek
|
23
|
+
store.last
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def store
|
29
|
+
Thread.current[@scope_identifier] ||= []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/zipkin/span.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zipkin
|
2
4
|
class Span
|
3
5
|
attr_accessor :operation_name
|
@@ -26,7 +28,8 @@ module Zipkin
|
|
26
28
|
# @param value [String, Numeric, Boolean] the value of the tag. If it's not
|
27
29
|
# a String, Numeric, or Boolean it will be encoded with to_s
|
28
30
|
def set_tag(key, value)
|
29
|
-
|
31
|
+
sanitized_value = valid_tag_value?(value) ? value : value.to_s
|
32
|
+
@tags = @tags.merge(key.to_sym => sanitized_value)
|
30
33
|
end
|
31
34
|
|
32
35
|
# Set a baggage item on the span
|
@@ -69,5 +72,14 @@ module Zipkin
|
|
69
72
|
def finish(end_time: Time.now)
|
70
73
|
@collector.send_span(self, end_time)
|
71
74
|
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def valid_tag_value?(value)
|
79
|
+
value.is_a?(String) ||
|
80
|
+
value.is_a?(Numeric) ||
|
81
|
+
value.is_a?(TrueClass) ||
|
82
|
+
value.is_a?(FalseClass)
|
83
|
+
end
|
72
84
|
end
|
73
85
|
end
|
data/lib/zipkin/span_context.rb
CHANGED
data/lib/zipkin/trace_id.rb
CHANGED
data/lib/zipkin/tracer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'opentracing'
|
2
4
|
require 'logger'
|
3
5
|
|
@@ -8,6 +10,8 @@ require_relative 'trace_id'
|
|
8
10
|
require_relative 'json_client'
|
9
11
|
require_relative 'endpoint'
|
10
12
|
require_relative 'collector'
|
13
|
+
require_relative 'scope_manager'
|
14
|
+
require_relative 'scope'
|
11
15
|
|
12
16
|
module Zipkin
|
13
17
|
class Tracer
|
@@ -29,30 +33,50 @@ module Zipkin
|
|
29
33
|
@collector = collector
|
30
34
|
@sender = sender
|
31
35
|
@logger = logger
|
36
|
+
@scope_manager = ScopeManager.new
|
32
37
|
end
|
33
38
|
|
34
39
|
def stop
|
35
40
|
@sender.stop
|
36
41
|
end
|
37
42
|
|
38
|
-
#
|
43
|
+
# @return [ScopeManager] the current ScopeManager, which may be a no-op but
|
44
|
+
# may not be nil.
|
45
|
+
attr_reader :scope_manager
|
46
|
+
|
47
|
+
# @return [Span, nil] the active span. This is a shorthand for
|
48
|
+
# `scope_manager.active.span`, and nil will be returned if
|
49
|
+
# Scope#active is nil.
|
50
|
+
def active_span
|
51
|
+
scope = scope_manager.active
|
52
|
+
scope.span if scope
|
53
|
+
end
|
54
|
+
|
55
|
+
# Starts a new span
|
56
|
+
#
|
57
|
+
# This is similar to #start_active_span, but the returned Span will not be
|
58
|
+
# registered via the ScopeManager.
|
39
59
|
#
|
40
60
|
# @param operation_name [String] The operation name for the Span
|
41
61
|
# @param child_of [SpanContext, Span] SpanContext that acts as a parent to
|
42
|
-
#
|
43
|
-
#
|
62
|
+
# the newly-started Span. If a Span instance is provided, its
|
63
|
+
# context is automatically substituted.
|
44
64
|
# @param start_time [Time] When the Span started, if not now
|
45
65
|
# @param tags [Hash] Tags to assign to the Span at start time
|
66
|
+
# @param ignore_active_scope [Boolean] whether to create an implicit
|
67
|
+
# References#CHILD_OF reference to the ScopeManager#active.
|
46
68
|
#
|
47
69
|
# @return [Span] The newly-started Span
|
48
|
-
def start_span(operation_name,
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
70
|
+
def start_span(operation_name,
|
71
|
+
child_of: nil,
|
72
|
+
start_time: Time.now,
|
73
|
+
tags: {},
|
74
|
+
ignore_active_scope: false,
|
75
|
+
**)
|
76
|
+
context = prepare_span_context(
|
77
|
+
child_of: child_of,
|
78
|
+
ignore_active_scope: ignore_active_scope
|
79
|
+
)
|
56
80
|
Span.new(
|
57
81
|
context,
|
58
82
|
operation_name,
|
@@ -62,6 +86,61 @@ module Zipkin
|
|
62
86
|
)
|
63
87
|
end
|
64
88
|
|
89
|
+
# Creates a newly started and activated Scope
|
90
|
+
#
|
91
|
+
# If the Tracer's ScopeManager#active is not nil, no explicit references
|
92
|
+
# are provided, and `ignore_active_scope` is false, then an inferred
|
93
|
+
# References#CHILD_OF reference is created to the ScopeManager#active's
|
94
|
+
# SpanContext when start_active is invoked.
|
95
|
+
#
|
96
|
+
# @param operation_name [String] The operation name for the Span
|
97
|
+
# @param child_of [SpanContext, Span] SpanContext that acts as a parent to
|
98
|
+
# the newly-started Span. If a Span instance is provided, its
|
99
|
+
# context is automatically substituted. See [Reference] for more
|
100
|
+
# information.
|
101
|
+
#
|
102
|
+
# If specified, the `references` parameter must be omitted.
|
103
|
+
# @param references [Array<Reference>] An array of reference
|
104
|
+
# objects that identify one or more parent SpanContexts.
|
105
|
+
# @param start_time [Time] When the Span started, if not now
|
106
|
+
# @param tags [Hash] Tags to assign to the Span at start time
|
107
|
+
# @param ignore_active_scope [Boolean] whether to create an implicit
|
108
|
+
# References#CHILD_OF reference to the ScopeManager#active.
|
109
|
+
# @param finish_on_close [Boolean] whether span should automatically be
|
110
|
+
# finished when Scope#close is called
|
111
|
+
# @yield [Scope] If an optional block is passed to start_active it will
|
112
|
+
# yield the newly-started Scope. If `finish_on_close` is true then the
|
113
|
+
# Span will be finished automatically after the block is executed.
|
114
|
+
# @return [Scope] The newly-started and activated Scope
|
115
|
+
def start_active_span(operation_name,
|
116
|
+
child_of: nil,
|
117
|
+
references: nil,
|
118
|
+
start_time: Time.now,
|
119
|
+
tags: nil,
|
120
|
+
ignore_active_scope: false,
|
121
|
+
finish_on_close: true,
|
122
|
+
**)
|
123
|
+
span = start_span(
|
124
|
+
operation_name,
|
125
|
+
child_of: child_of,
|
126
|
+
references: references,
|
127
|
+
start_time: start_time,
|
128
|
+
tags: tags,
|
129
|
+
ignore_active_scope: ignore_active_scope
|
130
|
+
)
|
131
|
+
scope = @scope_manager.activate(span, finish_on_close: finish_on_close)
|
132
|
+
|
133
|
+
if block_given?
|
134
|
+
begin
|
135
|
+
yield scope
|
136
|
+
ensure
|
137
|
+
scope.close
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
scope
|
142
|
+
end
|
143
|
+
|
65
144
|
# Inject a SpanContext into the given carrier
|
66
145
|
#
|
67
146
|
# @param span_context [SpanContext]
|
@@ -123,5 +202,21 @@ module Zipkin
|
|
123
202
|
sampled: sampled
|
124
203
|
)
|
125
204
|
end
|
205
|
+
|
206
|
+
def prepare_span_context(child_of:, ignore_active_scope:)
|
207
|
+
if child_of
|
208
|
+
parent_context = child_of.respond_to?(:context) ? child_of.context : child_of
|
209
|
+
return SpanContext.create_from_parent_context(parent_context)
|
210
|
+
end
|
211
|
+
|
212
|
+
unless ignore_active_scope
|
213
|
+
active_scope = @scope_manager.active
|
214
|
+
if active_scope
|
215
|
+
return SpanContext.create_from_parent_context(active_scope.span.context)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
SpanContext.create_parent_context
|
220
|
+
end
|
126
221
|
end
|
127
222
|
end
|
data/zipkin.gemspec
CHANGED
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: 1.
|
4
|
+
version: 1.4.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: 2018-
|
11
|
+
date: 2018-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -132,6 +132,10 @@ files:
|
|
132
132
|
- lib/zipkin/collector/timestamp.rb
|
133
133
|
- lib/zipkin/endpoint.rb
|
134
134
|
- lib/zipkin/json_client.rb
|
135
|
+
- lib/zipkin/scope.rb
|
136
|
+
- lib/zipkin/scope_manager.rb
|
137
|
+
- lib/zipkin/scope_manager/scope_identifier.rb
|
138
|
+
- lib/zipkin/scope_manager/scope_stack.rb
|
135
139
|
- lib/zipkin/span.rb
|
136
140
|
- lib/zipkin/span_context.rb
|
137
141
|
- lib/zipkin/trace_id.rb
|