jaeger-client 0.4.2 → 0.5.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 +15 -0
- data/README.md +23 -3
- data/jaeger-client.gemspec +0 -1
- data/lib/jaeger/client.rb +12 -2
- data/lib/jaeger/client/carrier.rb +2 -0
- data/lib/jaeger/client/collector.rb +5 -23
- data/lib/jaeger/client/samplers.rb +4 -0
- data/lib/jaeger/client/samplers/const.rb +29 -0
- data/lib/jaeger/client/samplers/probabilistic.rb +30 -0
- data/lib/jaeger/client/scope.rb +40 -0
- data/lib/jaeger/client/scope_manager.rb +49 -0
- data/lib/jaeger/client/scope_manager/scope_identifier.rb +15 -0
- data/lib/jaeger/client/scope_manager/scope_stack.rb +35 -0
- data/lib/jaeger/client/span.rb +20 -12
- data/lib/jaeger/client/span/thrift_log_builder.rb +20 -0
- data/lib/jaeger/client/span/thrift_tag_builder.rb +45 -0
- data/lib/jaeger/client/span_context.rb +13 -2
- data/lib/jaeger/client/trace_id.rb +2 -0
- data/lib/jaeger/client/tracer.rb +117 -11
- data/lib/jaeger/client/udp_sender.rb +2 -1
- data/lib/jaeger/client/udp_sender/transport.rb +5 -2
- data/lib/jaeger/client/version.rb +3 -1
- data/script/create_trace +2 -1
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 180ed5153f692c630fd0e0006b3d6265c5839875
|
4
|
+
data.tar.gz: 98dea74437333796b07bf81afba0558652b51623
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef49bfeb6aee4d16534c256580efe859d6468f7f68c748db31166c10ba700416a8035d18c51d26d5b863dccae71c036f6e7a3645eb49c323d2a1ed80a9507f0f
|
7
|
+
data.tar.gz: 1965becd08d299d65067e503e64d926dfffe95b216b306334c562c3a9db703eba2bc4171e53586c4b180e262a3fda7bb9ceed38ec9b021ba475b680e5728ebe9
|
data/.rubocop.yml
CHANGED
@@ -16,6 +16,9 @@ RSpec/NestedGroups:
|
|
16
16
|
RSpec/ExampleLength:
|
17
17
|
Enabled: no
|
18
18
|
|
19
|
+
RSpec/MultipleExpectations:
|
20
|
+
Enabled: no
|
21
|
+
|
19
22
|
Metrics/BlockLength:
|
20
23
|
Enabled: no
|
21
24
|
|
@@ -25,8 +28,20 @@ Metrics/MethodLength:
|
|
25
28
|
Metrics/AbcSize:
|
26
29
|
Enabled: no
|
27
30
|
|
31
|
+
Metrics/ClassLength:
|
32
|
+
Enabled: no
|
33
|
+
|
34
|
+
Metrics/ParameterLists:
|
35
|
+
Enabled: no
|
36
|
+
|
28
37
|
Lint/UnusedMethodArgument:
|
29
38
|
Enabled: no
|
30
39
|
|
40
|
+
Style/FrozenStringLiteralComment:
|
41
|
+
Enabled: yes
|
42
|
+
EnforcedStyle: always
|
43
|
+
Include:
|
44
|
+
- 'lib/**/*'
|
45
|
+
|
31
46
|
Metrics/LineLength:
|
32
47
|
Max: 120
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
Jaeger::Client
|
2
|
+
================
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/jaeger-client.svg)](https://rubygems.org/gems/jaeger-client)
|
4
|
+
[![Build Status](https://travis-ci.org/salemove/jaeger-client-ruby.svg)](https://travis-ci.org/salemove/jaeger-client-ruby)
|
2
5
|
|
3
6
|
OpenTracing Tracer implementation for Jaeger in Ruby
|
4
7
|
|
@@ -16,10 +19,27 @@ gem 'jaeger-client'
|
|
16
19
|
require 'jaeger/client'
|
17
20
|
OpenTracing.global_tracer = Jaeger::Client.build(host: 'localhost', port: 6831, service_name: 'echo')
|
18
21
|
|
19
|
-
|
20
|
-
|
22
|
+
OpenTracing.start_active_span('span name') do
|
23
|
+
# do something
|
24
|
+
|
25
|
+
OpenTracing.start_active_span('inner span name') do
|
26
|
+
# do something else
|
27
|
+
end
|
28
|
+
end
|
21
29
|
```
|
22
30
|
|
31
|
+
See [opentracing-ruby](https://github.com/opentracing/opentracing-ruby) for more examples.
|
32
|
+
|
33
|
+
### Samplers
|
34
|
+
|
35
|
+
#### Const sampler
|
36
|
+
|
37
|
+
`Const` sampler always makes the same decision for new traces depending on the initialization value. Set `sampler` to: `Jaeger::Client::Samplers::Const.new(true)` to mark all new traces as sampled.
|
38
|
+
|
39
|
+
#### Probabilistic sampler
|
40
|
+
|
41
|
+
`Probabilistic` sampler samples traces with probability equal to `rate` (must be between 0.0 and 1.0). This can be enabled by setting `Jaeger::Client::Samplers::Probabilistic.new(rate: 0.1)`
|
42
|
+
|
23
43
|
## Development
|
24
44
|
|
25
45
|
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/jaeger-client.gemspec
CHANGED
data/lib/jaeger/client.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
$LOAD_PATH.push(File.dirname(__FILE__) + '/../../thrift/gen-rb')
|
2
4
|
|
3
5
|
require 'opentracing'
|
6
|
+
require 'jaeger/thrift/agent'
|
4
7
|
|
5
8
|
require_relative 'client/tracer'
|
6
9
|
require_relative 'client/span'
|
7
10
|
require_relative 'client/span_context'
|
11
|
+
require_relative 'client/scope'
|
12
|
+
require_relative 'client/scope_manager'
|
8
13
|
require_relative 'client/carrier'
|
9
14
|
require_relative 'client/trace_id'
|
10
15
|
require_relative 'client/udp_sender'
|
11
16
|
require_relative 'client/collector'
|
12
17
|
require_relative 'client/version'
|
18
|
+
require_relative 'client/samplers'
|
13
19
|
|
14
20
|
module Jaeger
|
15
21
|
module Client
|
16
22
|
DEFAULT_FLUSH_INTERVAL = 10
|
17
23
|
|
18
|
-
def self.build(host: '127.0.0.1',
|
24
|
+
def self.build(host: '127.0.0.1',
|
25
|
+
port: 6831,
|
26
|
+
service_name:,
|
27
|
+
flush_interval: DEFAULT_FLUSH_INTERVAL,
|
28
|
+
sampler: Samplers::Const.new(true))
|
19
29
|
collector = Collector.new
|
20
30
|
sender = UdpSender.new(
|
21
31
|
service_name: service_name,
|
@@ -25,7 +35,7 @@ module Jaeger
|
|
25
35
|
flush_interval: flush_interval
|
26
36
|
)
|
27
37
|
sender.start
|
28
|
-
Tracer.new(collector, sender)
|
38
|
+
Tracer.new(collector, sender, sampler)
|
29
39
|
end
|
30
40
|
end
|
31
41
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thread'
|
2
4
|
|
3
5
|
module Jaeger
|
@@ -10,6 +12,7 @@ module Jaeger
|
|
10
12
|
def send_span(span, end_time)
|
11
13
|
context = span.context
|
12
14
|
start_ts, duration = build_timestamps(span, end_time)
|
15
|
+
return if !context.sampled? && !context.debug?
|
13
16
|
|
14
17
|
@buffer << Jaeger::Thrift::Span.new(
|
15
18
|
'traceIdLow' => context.trace_id,
|
@@ -21,8 +24,8 @@ module Jaeger
|
|
21
24
|
'flags' => context.flags,
|
22
25
|
'startTime' => start_ts,
|
23
26
|
'duration' => duration,
|
24
|
-
'tags' =>
|
25
|
-
'logs' =>
|
27
|
+
'tags' => span.tags,
|
28
|
+
'logs' => span.logs
|
26
29
|
)
|
27
30
|
end
|
28
31
|
|
@@ -32,27 +35,6 @@ module Jaeger
|
|
32
35
|
|
33
36
|
private
|
34
37
|
|
35
|
-
def build_tags(tags)
|
36
|
-
tags.map { |name, value| build_tag(name, value) }
|
37
|
-
end
|
38
|
-
|
39
|
-
def build_logs(logs)
|
40
|
-
logs.map do |timestamp:, fields:|
|
41
|
-
Jaeger::Thrift::Log.new(
|
42
|
-
'timestamp' => (timestamp.to_f * 1_000_000).to_i,
|
43
|
-
'fields' => fields.map { |name, value| build_tag(name, value) }
|
44
|
-
)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def build_tag(name, value)
|
49
|
-
Jaeger::Thrift::Tag.new(
|
50
|
-
'key' => name.to_s,
|
51
|
-
'vType' => Jaeger::Thrift::TagType::STRING,
|
52
|
-
'vStr' => value.to_s
|
53
|
-
)
|
54
|
-
end
|
55
|
-
|
56
38
|
def build_timestamps(span, end_time)
|
57
39
|
start_ts = (span.start_time.to_f * 1_000_000).to_i
|
58
40
|
end_ts = (end_time.to_f * 1_000_000).to_i
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jaeger
|
4
|
+
module Client
|
5
|
+
module Samplers
|
6
|
+
# Const sampler
|
7
|
+
#
|
8
|
+
# A sampler that always makes the same decision for new traces depending
|
9
|
+
# on the initialization value. Use `Jaeger::Client::Samplers::Const.new(true)`
|
10
|
+
# to mark all new traces as sampled.
|
11
|
+
class Const
|
12
|
+
def initialize(decision)
|
13
|
+
@decision = decision
|
14
|
+
@param = decision ? '1' : '0'
|
15
|
+
end
|
16
|
+
|
17
|
+
def sample?(*)
|
18
|
+
@decision
|
19
|
+
end
|
20
|
+
|
21
|
+
def type
|
22
|
+
'const'
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :param
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jaeger
|
4
|
+
module Client
|
5
|
+
module Samplers
|
6
|
+
# Probabilistic sampler
|
7
|
+
#
|
8
|
+
# Sample a portion of traces using trace_id as the random decision
|
9
|
+
class Probabilistic
|
10
|
+
def initialize(rate: 0.001)
|
11
|
+
@param = rate.to_s
|
12
|
+
if rate < 0.0 || rate > 1.0
|
13
|
+
raise "Sampling rate must be between 0.0 and 1.0, got #{rate.inspect}"
|
14
|
+
end
|
15
|
+
@boundary = TraceId::TRACE_ID_UPPER_BOUND * rate
|
16
|
+
end
|
17
|
+
|
18
|
+
def sample?(trace_id)
|
19
|
+
@boundary >= trace_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def type
|
23
|
+
'probabilistic'
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :param
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jaeger
|
4
|
+
module Client
|
5
|
+
# Scope represents an OpenTracing Scope
|
6
|
+
#
|
7
|
+
# See http://www.opentracing.io for more information.
|
8
|
+
class Scope
|
9
|
+
def initialize(span, scope_stack, finish_on_close:)
|
10
|
+
@span = span
|
11
|
+
@scope_stack = scope_stack
|
12
|
+
@finish_on_close = finish_on_close
|
13
|
+
@closed = false
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return the Span scoped by this Scope
|
17
|
+
#
|
18
|
+
# @return [Span]
|
19
|
+
attr_reader :span
|
20
|
+
|
21
|
+
# Close scope
|
22
|
+
#
|
23
|
+
# Mark the end of the active period for the current thread and Scope,
|
24
|
+
# updating the ScopeManager#active in the process.
|
25
|
+
def close
|
26
|
+
raise "Tried to close already closed span: #{inspect}" if @closed
|
27
|
+
@closed = true
|
28
|
+
|
29
|
+
@span.finish if @finish_on_close
|
30
|
+
removed_scope = @scope_stack.pop
|
31
|
+
|
32
|
+
if removed_scope != self # rubocop:disable Style/GuardClause
|
33
|
+
raise 'Removed non-active scope, ' \
|
34
|
+
"removed: #{removed_scope.inspect}, "\
|
35
|
+
"expected: #{inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'scope_manager/scope_stack'
|
4
|
+
require_relative 'scope_manager/scope_identifier'
|
5
|
+
|
6
|
+
module Jaeger
|
7
|
+
module Client
|
8
|
+
# ScopeManager represents an OpenTracing ScopeManager
|
9
|
+
#
|
10
|
+
# See http://www.opentracing.io for more information.
|
11
|
+
#
|
12
|
+
# The ScopeManager interface abstracts both the activation of Span instances
|
13
|
+
# via ScopeManager#activate and access to an active Span/Scope via
|
14
|
+
# ScopeManager#active
|
15
|
+
#
|
16
|
+
class ScopeManager
|
17
|
+
def initialize
|
18
|
+
@scope_stack = ScopeStack.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# Make a span instance active
|
22
|
+
#
|
23
|
+
# @param span [Span] the Span that should become active
|
24
|
+
# @param finish_on_close [Boolean] whether the Span should automatically be
|
25
|
+
# finished when Scope#close is called
|
26
|
+
# @return [Scope] instance to control the end of the active period for the
|
27
|
+
# Span. It is a programming error to neglect to call Scope#close on the
|
28
|
+
# returned instance.
|
29
|
+
def activate(span, finish_on_close: true)
|
30
|
+
return active if active && active.span == span
|
31
|
+
scope = Scope.new(span, @scope_stack, finish_on_close: finish_on_close)
|
32
|
+
@scope_stack.push(scope)
|
33
|
+
scope
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return active scope
|
37
|
+
#
|
38
|
+
# If there is a non-null Scope, its wrapped Span becomes an implicit parent
|
39
|
+
# (as Reference#CHILD_OF) of any newly-created Span at
|
40
|
+
# Tracer#start_active_span or Tracer#start_span time.
|
41
|
+
#
|
42
|
+
# @return [Scope] the currently active Scope which can be used to access the
|
43
|
+
# currently active Span.
|
44
|
+
def active
|
45
|
+
@scope_stack.peek
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jaeger
|
4
|
+
module Client
|
5
|
+
class ScopeManager
|
6
|
+
# @api private
|
7
|
+
class ScopeIdentifier
|
8
|
+
def self.generate
|
9
|
+
# 65..90.chr are characters between A and Z
|
10
|
+
"opentracing_#{(0...8).map { rand(65..90).chr }.join}".to_sym
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jaeger
|
4
|
+
module Client
|
5
|
+
class ScopeManager
|
6
|
+
# @api private
|
7
|
+
class ScopeStack
|
8
|
+
def initialize
|
9
|
+
# Generate a random identifier to use as the Thread.current key. This is
|
10
|
+
# needed so that it would be possible to create multiple tracers in one
|
11
|
+
# thread (mostly useful for testing purposes)
|
12
|
+
@scope_identifier = ScopeIdentifier.generate
|
13
|
+
end
|
14
|
+
|
15
|
+
def push(scope)
|
16
|
+
store << scope
|
17
|
+
end
|
18
|
+
|
19
|
+
def pop
|
20
|
+
store.pop
|
21
|
+
end
|
22
|
+
|
23
|
+
def peek
|
24
|
+
store.last
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def store
|
30
|
+
Thread.current[@scope_identifier] ||= []
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/jaeger/client/span.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'span/thrift_tag_builder'
|
4
|
+
require_relative 'span/thrift_log_builder'
|
5
|
+
|
1
6
|
module Jaeger
|
2
7
|
module Client
|
3
8
|
class Span
|
@@ -17,7 +22,7 @@ module Jaeger
|
|
17
22
|
@operation_name = operation_name
|
18
23
|
@collector = collector
|
19
24
|
@start_time = start_time
|
20
|
-
@tags = tags
|
25
|
+
@tags = tags.map { |key, value| ThriftTagBuilder.build(key, value) }
|
21
26
|
@logs = []
|
22
27
|
end
|
23
28
|
|
@@ -27,7 +32,8 @@ module Jaeger
|
|
27
32
|
# @param value [String, Numeric, Boolean] the value of the tag. If it's not
|
28
33
|
# a String, Numeric, or Boolean it will be encoded with to_s
|
29
34
|
def set_tag(key, value)
|
30
|
-
|
35
|
+
# Using Thrift::Tag to avoid unnecessary memory allocations
|
36
|
+
@tags << ThriftTagBuilder.build(key, value)
|
31
37
|
end
|
32
38
|
|
33
39
|
# Set a baggage item on the span
|
@@ -47,12 +53,22 @@ module Jaeger
|
|
47
53
|
nil
|
48
54
|
end
|
49
55
|
|
56
|
+
# Add a log entry to this span
|
57
|
+
#
|
58
|
+
# @deprecated Use {#log_kv} instead.
|
59
|
+
def log(*args)
|
60
|
+
warn 'Span#log is deprecated. Please use Span#log_kv instead.'
|
61
|
+
log_kv(*args)
|
62
|
+
end
|
63
|
+
|
50
64
|
# Add a log entry to this span
|
51
65
|
#
|
52
66
|
# @param timestamp [Time] time of the log
|
53
67
|
# @param fields [Hash] Additional information to log
|
54
|
-
def
|
55
|
-
|
68
|
+
def log_kv(timestamp: Time.now, **fields)
|
69
|
+
# Using Thrift::Log to avoid unnecessary memory allocations
|
70
|
+
@logs << ThriftLogBuilder.build(timestamp, fields)
|
71
|
+
nil
|
56
72
|
end
|
57
73
|
|
58
74
|
# Finish the {Span}
|
@@ -61,14 +77,6 @@ module Jaeger
|
|
61
77
|
def finish(end_time: Time.now)
|
62
78
|
@collector.send_span(self, end_time)
|
63
79
|
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def build_binary_annotations
|
68
|
-
@tags.map do |name, value|
|
69
|
-
{ key: name, value: value.to_s }
|
70
|
-
end
|
71
|
-
end
|
72
80
|
end
|
73
81
|
end
|
74
82
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jaeger
|
4
|
+
module Client
|
5
|
+
class Span
|
6
|
+
class ThriftLogBuilder
|
7
|
+
FIELDS = Jaeger::Thrift::Log::FIELDS
|
8
|
+
TIMESTAMP = FIELDS[Jaeger::Thrift::Log::TIMESTAMP].fetch(:name)
|
9
|
+
LOG_FIELDS = FIELDS[Jaeger::Thrift::Log::LOG_FIELDS].fetch(:name)
|
10
|
+
|
11
|
+
def self.build(timestamp, fields)
|
12
|
+
Jaeger::Thrift::Log.new(
|
13
|
+
TIMESTAMP => (timestamp.to_f * 1_000_000).to_i,
|
14
|
+
LOG_FIELDS => fields.map { |key, value| ThriftTagBuilder.build(key, value) }
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jaeger
|
4
|
+
module Client
|
5
|
+
class Span
|
6
|
+
class ThriftTagBuilder
|
7
|
+
FIELDS = Jaeger::Thrift::Tag::FIELDS
|
8
|
+
KEY = FIELDS[Jaeger::Thrift::Tag::KEY].fetch(:name)
|
9
|
+
VTYPE = FIELDS[Jaeger::Thrift::Tag::VTYPE].fetch(:name)
|
10
|
+
VLONG = FIELDS[Jaeger::Thrift::Tag::VLONG].fetch(:name)
|
11
|
+
VDOUBLE = FIELDS[Jaeger::Thrift::Tag::VDOUBLE].fetch(:name)
|
12
|
+
VBOOL = FIELDS[Jaeger::Thrift::Tag::VBOOL].fetch(:name)
|
13
|
+
VSTR = FIELDS[Jaeger::Thrift::Tag::VSTR].fetch(:name)
|
14
|
+
|
15
|
+
def self.build(key, value)
|
16
|
+
if value.is_a?(Integer)
|
17
|
+
Jaeger::Thrift::Tag.new(
|
18
|
+
KEY => key.to_s,
|
19
|
+
VTYPE => Jaeger::Thrift::TagType::LONG,
|
20
|
+
VLONG => value
|
21
|
+
)
|
22
|
+
elsif value.is_a?(Float)
|
23
|
+
Jaeger::Thrift::Tag.new(
|
24
|
+
KEY => key.to_s,
|
25
|
+
VTYPE => Jaeger::Thrift::TagType::DOUBLE,
|
26
|
+
VDOUBLE => value
|
27
|
+
)
|
28
|
+
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
29
|
+
Jaeger::Thrift::Tag.new(
|
30
|
+
KEY => key.to_s,
|
31
|
+
VTYPE => Jaeger::Thrift::TagType::BOOL,
|
32
|
+
VBOOL => value
|
33
|
+
)
|
34
|
+
else
|
35
|
+
Jaeger::Thrift::Tag.new(
|
36
|
+
KEY => key.to_s,
|
37
|
+
VTYPE => Jaeger::Thrift::TagType::STRING,
|
38
|
+
VSTR => value.to_s
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,16 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Jaeger
|
2
4
|
module Client
|
3
5
|
# SpanContext holds the data for a span that gets inherited to child spans
|
4
6
|
class SpanContext
|
5
7
|
module Flags
|
8
|
+
NONE = 0x00
|
6
9
|
SAMPLED = 0x01
|
7
10
|
DEBUG = 0x02
|
8
11
|
end
|
9
12
|
|
10
|
-
def self.create_parent_context
|
13
|
+
def self.create_parent_context(sampler = Samplers::Const.new(true))
|
11
14
|
trace_id = TraceId.generate
|
12
15
|
span_id = TraceId.generate
|
13
|
-
flags = Flags::SAMPLED
|
16
|
+
flags = sampler.sample?(trace_id) ? Flags::SAMPLED : Flags::NONE
|
14
17
|
new(trace_id: trace_id, span_id: span_id, flags: flags)
|
15
18
|
end
|
16
19
|
|
@@ -32,6 +35,14 @@ module Jaeger
|
|
32
35
|
@flags = flags
|
33
36
|
end
|
34
37
|
|
38
|
+
def sampled?
|
39
|
+
@flags & Flags::SAMPLED == Flags::SAMPLED
|
40
|
+
end
|
41
|
+
|
42
|
+
def debug?
|
43
|
+
@flags & Flags::DEBUG == Flags::DEBUG
|
44
|
+
end
|
45
|
+
|
35
46
|
def inspect
|
36
47
|
to_s
|
37
48
|
end
|
data/lib/jaeger/client/tracer.rb
CHANGED
@@ -1,34 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Jaeger
|
2
4
|
module Client
|
3
5
|
class Tracer
|
4
|
-
def initialize(collector, sender)
|
6
|
+
def initialize(collector, sender, sampler)
|
5
7
|
@collector = collector
|
6
8
|
@sender = sender
|
9
|
+
@sampler = sampler
|
10
|
+
@scope_manager = ScopeManager.new
|
7
11
|
end
|
8
12
|
|
9
13
|
def stop
|
10
14
|
@sender.stop
|
11
15
|
end
|
12
16
|
|
17
|
+
# @return [ScopeManager] the current ScopeManager, which may be a no-op
|
18
|
+
# but may not be nil.
|
19
|
+
attr_reader :scope_manager
|
20
|
+
|
21
|
+
# @return [Span, nil] the active span. This is a shorthand for
|
22
|
+
# `scope_manager.active.span`, and nil will be returned if
|
23
|
+
# Scope#active is nil.
|
24
|
+
def active_span
|
25
|
+
scope = scope_manager.active
|
26
|
+
scope.span if scope
|
27
|
+
end
|
28
|
+
|
13
29
|
# Starts a new span.
|
14
30
|
#
|
31
|
+
# This is similar to #start_active_span, but the returned Span will not
|
32
|
+
# be registered via the ScopeManager.
|
33
|
+
#
|
15
34
|
# @param operation_name [String] The operation name for the Span
|
16
35
|
# @param child_of [SpanContext, Span] SpanContext that acts as a parent to
|
17
|
-
#
|
18
|
-
#
|
36
|
+
# the newly-started Span. If a Span instance is provided, its
|
37
|
+
# context is automatically substituted.
|
38
|
+
# @param references [Array<Reference>] An array of reference
|
39
|
+
# objects that identify one or more parent SpanContexts.
|
19
40
|
# @param start_time [Time] When the Span started, if not now
|
20
41
|
# @param tags [Hash] Tags to assign to the Span at start time
|
42
|
+
# @param ignore_active_scope [Boolean] whether to create an implicit
|
43
|
+
# References#CHILD_OF reference to the ScopeManager#active.
|
21
44
|
#
|
22
45
|
# @return [Span] The newly-started Span
|
23
|
-
def start_span(operation_name,
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
46
|
+
def start_span(operation_name,
|
47
|
+
child_of: nil,
|
48
|
+
references: nil,
|
49
|
+
start_time: Time.now,
|
50
|
+
tags: {},
|
51
|
+
ignore_active_scope: false,
|
52
|
+
**)
|
53
|
+
context = prepare_span_context(
|
54
|
+
child_of: child_of,
|
55
|
+
ignore_active_scope: ignore_active_scope
|
56
|
+
)
|
57
|
+
Span.new(
|
58
|
+
context,
|
59
|
+
operation_name,
|
60
|
+
@collector,
|
61
|
+
start_time: start_time,
|
62
|
+
tags: tags.merge(
|
63
|
+
:'sampler.type' => @sampler.type,
|
64
|
+
:'sampler.param' => @sampler.param
|
65
|
+
)
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Creates a newly started and activated Scope
|
70
|
+
#
|
71
|
+
# If the Tracer's ScopeManager#active is not nil, no explicit references
|
72
|
+
# are provided, and `ignore_active_scope` is false, then an inferred
|
73
|
+
# References#CHILD_OF reference is created to the ScopeManager#active's
|
74
|
+
# SpanContext when start_active is invoked.
|
75
|
+
#
|
76
|
+
# @param operation_name [String] The operation name for the Span
|
77
|
+
# @param child_of [SpanContext, Span] SpanContext that acts as a parent to
|
78
|
+
# the newly-started Span. If a Span instance is provided, its
|
79
|
+
# context is automatically substituted. See [Reference] for more
|
80
|
+
# information.
|
81
|
+
#
|
82
|
+
# If specified, the `references` parameter must be omitted.
|
83
|
+
# @param references [Array<Reference>] An array of reference
|
84
|
+
# objects that identify one or more parent SpanContexts.
|
85
|
+
# @param start_time [Time] When the Span started, if not now
|
86
|
+
# @param tags [Hash] Tags to assign to the Span at start time
|
87
|
+
# @param ignore_active_scope [Boolean] whether to create an implicit
|
88
|
+
# References#CHILD_OF reference to the ScopeManager#active.
|
89
|
+
# @param finish_on_close [Boolean] whether span should automatically be
|
90
|
+
# finished when Scope#close is called
|
91
|
+
# @yield [Scope] If an optional block is passed to start_active it will
|
92
|
+
# yield the newly-started Scope. If `finish_on_close` is true then the
|
93
|
+
# Span will be finished automatically after the block is executed.
|
94
|
+
# @return [Scope] The newly-started and activated Scope
|
95
|
+
def start_active_span(operation_name,
|
96
|
+
child_of: nil,
|
97
|
+
references: nil,
|
98
|
+
start_time: Time.now,
|
99
|
+
tags: {},
|
100
|
+
ignore_active_scope: false,
|
101
|
+
finish_on_close: true,
|
102
|
+
**)
|
103
|
+
span = start_span(
|
104
|
+
operation_name,
|
105
|
+
child_of: child_of,
|
106
|
+
references: references,
|
107
|
+
start_time: start_time,
|
108
|
+
tags: tags,
|
109
|
+
ignore_active_scope: ignore_active_scope
|
110
|
+
)
|
111
|
+
scope = @scope_manager.activate(span, finish_on_close: finish_on_close)
|
112
|
+
|
113
|
+
if block_given?
|
114
|
+
begin
|
115
|
+
yield scope
|
116
|
+
ensure
|
117
|
+
scope.close
|
30
118
|
end
|
31
|
-
|
119
|
+
end
|
120
|
+
|
121
|
+
scope
|
32
122
|
end
|
33
123
|
|
34
124
|
# Inject a SpanContext into the given carrier
|
@@ -91,6 +181,22 @@ module Jaeger
|
|
91
181
|
mask = 2**(bits - 1)
|
92
182
|
(num & ~mask) - (num & mask)
|
93
183
|
end
|
184
|
+
|
185
|
+
def prepare_span_context(child_of:, ignore_active_scope:)
|
186
|
+
if child_of
|
187
|
+
parent_context = child_of.respond_to?(:context) ? child_of.context : child_of
|
188
|
+
return SpanContext.create_from_parent_context(parent_context)
|
189
|
+
end
|
190
|
+
|
191
|
+
unless ignore_active_scope
|
192
|
+
active_scope = @scope_manager.active
|
193
|
+
if active_scope
|
194
|
+
return SpanContext.create_from_parent_context(active_scope.span.context)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
SpanContext.create_parent_context(@sampler)
|
199
|
+
end
|
94
200
|
end
|
95
201
|
end
|
96
202
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Jaeger
|
2
4
|
module Client
|
3
5
|
class UdpSender
|
@@ -6,7 +8,8 @@ module Jaeger
|
|
6
8
|
|
7
9
|
def initialize(host, port)
|
8
10
|
@socket = UDPSocket.new
|
9
|
-
@
|
11
|
+
@host = host
|
12
|
+
@port = port
|
10
13
|
@buffer = ::Thrift::MemoryBufferTransport.new
|
11
14
|
end
|
12
15
|
|
@@ -26,7 +29,7 @@ module Jaeger
|
|
26
29
|
private
|
27
30
|
|
28
31
|
def send_bytes(bytes)
|
29
|
-
@socket.send(bytes, FLAGS)
|
32
|
+
@socket.send(bytes, FLAGS, @host, @port)
|
30
33
|
@socket.flush
|
31
34
|
rescue Errno::ECONNREFUSED
|
32
35
|
warn 'Unable to connect to Jaeger Agent'
|
data/script/create_trace
CHANGED
@@ -16,7 +16,7 @@ outer_span = tracer1.start_span(
|
|
16
16
|
tags: { 'span.kind' => 'server' }
|
17
17
|
)
|
18
18
|
sleep 0.1
|
19
|
-
outer_span.
|
19
|
+
outer_span.log_kv(event: 'woop di doop', count: 5)
|
20
20
|
sleep 1
|
21
21
|
|
22
22
|
inner_span = tracer1.start_span(
|
@@ -29,6 +29,7 @@ inner_span = tracer1.start_span(
|
|
29
29
|
'peer.port' => 443
|
30
30
|
}
|
31
31
|
)
|
32
|
+
inner_span.set_tag('error', false)
|
32
33
|
sleep 0.3 # emulate network delay
|
33
34
|
|
34
35
|
downstream_span = tracer2.start_span(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jaeger-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.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
|
@@ -129,7 +129,16 @@ files:
|
|
129
129
|
- lib/jaeger/client.rb
|
130
130
|
- lib/jaeger/client/carrier.rb
|
131
131
|
- lib/jaeger/client/collector.rb
|
132
|
+
- lib/jaeger/client/samplers.rb
|
133
|
+
- lib/jaeger/client/samplers/const.rb
|
134
|
+
- lib/jaeger/client/samplers/probabilistic.rb
|
135
|
+
- lib/jaeger/client/scope.rb
|
136
|
+
- lib/jaeger/client/scope_manager.rb
|
137
|
+
- lib/jaeger/client/scope_manager/scope_identifier.rb
|
138
|
+
- lib/jaeger/client/scope_manager/scope_stack.rb
|
132
139
|
- lib/jaeger/client/span.rb
|
140
|
+
- lib/jaeger/client/span/thrift_log_builder.rb
|
141
|
+
- lib/jaeger/client/span/thrift_tag_builder.rb
|
133
142
|
- lib/jaeger/client/span_context.rb
|
134
143
|
- lib/jaeger/client/trace_id.rb
|
135
144
|
- lib/jaeger/client/tracer.rb
|