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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75c88fcea8c5fa02b502e8c2c6cb3838a246e714
4
- data.tar.gz: 12d8f676f98d486d1b9db5e73c7dc757e46477a8
3
+ metadata.gz: 180ed5153f692c630fd0e0006b3d6265c5839875
4
+ data.tar.gz: 98dea74437333796b07bf81afba0558652b51623
5
5
  SHA512:
6
- metadata.gz: 2eedd11ef42e96094a128fd32df3c3bf5a152d498dd09933a667930caa5af7f287c00bddf9524cc87429898ff78a7e3cc1d2da1b38f560be9f3731bfe0f42ac1
7
- data.tar.gz: c478b9e68a708fd6a093d08b38c844136535a4b3723dd717392dd7ce5852ac01ba2a6b0948f954924cbe9a46daf6ea9e13f8d87242bb58a647fb44a0d0695d6f
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
- # Jaeger::Client
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
- span = OpenTracing.start_span('span name')
20
- span.finish
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.
@@ -1,4 +1,3 @@
1
-
2
1
  lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
 
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', port: 6831, service_name:, flush_interval: DEFAULT_FLUSH_INTERVAL)
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
  module Jaeger
2
4
  module Client
3
5
  # Carriers are used for inject and extract operations. A carrier should be a
@@ -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' => build_tags(span.tags),
25
- 'logs' => build_logs(span.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,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'samplers/const'
4
+ require_relative 'samplers/probabilistic'
@@ -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
@@ -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
- @tags = @tags.merge(key => value)
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 log(timestamp: Time.now, **fields)
55
- @logs << { timestamp: timestamp, fields: fields }
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Jaeger
2
4
  module Client
3
5
  module TraceId
@@ -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
- # the newly-started Span. If a Span instance is provided, its
18
- # context is automatically substituted.
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, child_of: nil, start_time: Time.now, tags: {}, **)
24
- context =
25
- if child_of
26
- parent_context = child_of.respond_to?(:context) ? child_of.context : child_of
27
- SpanContext.create_from_parent_context(parent_context)
28
- else
29
- SpanContext.create_parent_context
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
- Span.new(context, operation_name, @collector, start_time: start_time, tags: tags)
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,5 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './udp_sender/transport'
2
- require 'jaeger/thrift/agent'
3
4
  require 'socket'
4
5
  require 'thread'
5
6
 
@@ -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
- @socket.connect(host, port)
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'
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Jaeger
2
4
  module Client
3
- VERSION = '0.4.2'.freeze
5
+ VERSION = '0.5.0'.freeze
4
6
  end
5
7
  end
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.log(event: 'woop di doop', count: 5)
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.2
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-04-06 00:00:00.000000000 Z
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