aws-xray 0.11.0 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e2db1f1c47ffff23ff5b3ba4907d7db96f00ac8
4
- data.tar.gz: 53a29948b35d186813d7266ce6c4953d4738ea3a
3
+ metadata.gz: 2ecfbca12fbd25e263e57ef71b541a24e305fd51
4
+ data.tar.gz: 693d7427b8e08fb09c7ef44c6fce33feab3cfb21
5
5
  SHA512:
6
- metadata.gz: b611a69af5a88fe9aeac5e87cc82b65667b23a465307ad1e48cb1fe69d525675ba7390903548119d5d276db3ead306c0d1802169cb32fd57e02ce3df1c95cbb2
7
- data.tar.gz: 1ed14d0833d3634882b1283652a98128784994f7d603047ed625e26869cd9aeb76013db6423ac6eaaa7c6ffde89bd291b207fdd7dd383d1de29546b472b285ec
6
+ metadata.gz: '081c37ab015b24bdbdd4c2e1b150c0bfd8b6f039cab16dfb15f93ba5549cc47fe12a49e39e01cbe87f19f9a168956d1368e87ec85ded71f5aa2927eba3477ee4'
7
+ data.tar.gz: 20c0d925ebb6d9ecbf81a8f0b73d9a07587f2f4661174586892f44e170665b372a2730871f673ecfeb11d2d06acd5e78d178cf3ad329b3337a3da27ea7ff61d9
data/README.md CHANGED
@@ -10,7 +10,7 @@ AWS X-Ray is a ditributed tracing system. See more detail about AWS X-Ray at [of
10
10
  ## Features
11
11
  - Rack middleware.
12
12
  - Faraday middleware.
13
- - Propagatin support limited in single thread environment.
13
+ - Propagatin support in both single and multi thread environment.
14
14
  - Tracing HTTP request/response.
15
15
  - Tracing errors.
16
16
  - Annotation and metadata support.
@@ -88,6 +88,16 @@ Aws::Xray.trace(name: 'my-app-batch') do |seg|
88
88
  end
89
89
  ```
90
90
 
91
+ ### Multi threaded environment
92
+ Tracing context is thread local. To pass current tracing context, copy current tracing context:
93
+
94
+ ```ruby
95
+ Thread.new(Aws::Xray::Context.current.copy) do |context|
96
+ Aws::Xray::Context.set_current(context)
97
+ # Do something
98
+ end
99
+ ```
100
+
91
101
  ## Configurations
92
102
  ### X-Ray agent location
93
103
  aws-xray does not send any trace data dby efault. Set `AWS_XRAY_LOCATION` environment variable like `AWS_XRAY_LOCATION=localhost:2000`
@@ -28,8 +28,6 @@ module Aws
28
28
  yield seg
29
29
  end
30
30
  end
31
- ensure
32
- client.close
33
31
  end
34
32
  end
35
33
  end
@@ -2,28 +2,28 @@ require 'socket'
2
2
 
3
3
  module Aws
4
4
  module Xray
5
+ # Own the responsibility of holding destination address and sending
6
+ # segments.
5
7
  class Client
6
- # sock is for test
7
- #
8
- # XXX: keep options for implmenting copying later.
8
+ # sock is for test.
9
9
  def initialize(host: nil, port: nil, sock: nil)
10
- @host, @port = host, port
11
- @sock = sock || UDPSocket.new
10
+ @host, @port = host.freeze, port.freeze
11
+ @sock = sock
12
+ freeze
12
13
  end
13
14
 
15
+ # When UDPSocket#send can not send all bytes, just give up it.
14
16
  # @param [Aws::Xray::Segment] segment
15
17
  def send_segment(segment)
16
- segment.finish
17
18
  payload = %!{"format": "json", "version": 1}\n#{segment.to_json}\n!
18
- len = @sock.send(payload, 0, @host, @port)
19
- # TODO: retry
20
- if payload.size != len
21
- $stderr.puts("Can not send all bytes: #{len} sent")
22
- end
23
- end
19
+ sock = @sock || UDPSocket.new
24
20
 
25
- def close
26
- @sock.close
21
+ begin
22
+ len = sock.send(payload, 0, @host, @port)
23
+ $stderr.puts("Can not send all bytes: #{len} sent") if payload.size != len
24
+ ensure
25
+ sock.close
26
+ end
27
27
  end
28
28
  end
29
29
  end
@@ -4,31 +4,40 @@ require 'aws/xray/sub_segment'
4
4
  module Aws
5
5
  module Xray
6
6
  class Context
7
- class << self
8
- VAR_NAME = :_aws_xray_context_
7
+ VAR_NAME = :_aws_xray_context_
8
+
9
+ class BaseError < ::StandardError; end
10
+
11
+ class NotSetError < BaseError
12
+ def initialize
13
+ super('Context is not set for this thread')
14
+ end
15
+ end
9
16
 
10
- class NotSetError < ::StandardError
11
- def initialize
12
- super('Context is not set for this thread')
13
- end
17
+ class SegmentDidNotStartError < BaseError
18
+ def initialize
19
+ super('Segment did not start yet')
14
20
  end
21
+ end
15
22
 
23
+ class << self
16
24
  # @return [Aws::Xray::Context]
17
25
  def current
18
26
  Thread.current.thread_variable_get(VAR_NAME) || raise(NotSetError)
19
27
  end
20
28
 
29
+ # @param [Aws::Xray::Context] context
30
+ def set_current(context)
31
+ Thread.current.thread_variable_set(VAR_NAME, context)
32
+ end
33
+
21
34
  # @return [Boolean]
22
35
  def started?
23
36
  !!Thread.current.thread_variable_get(VAR_NAME)
24
37
  end
25
38
 
26
39
  # @param [String] name logical name of this tracing context.
27
- # @param [Aws::Xray::Client] client Require this parameter because the
28
- # socket inside client can live longer than this context. For example
29
- # the life-cycle of context is HTTP request based but the socket can
30
- # live over HTTP requests cycle, it is opened when application starts
31
- # then is closed when application exits.
40
+ # @param [Aws::Xray::Client] client
32
41
  # @param [Aws::Xray::Trace] trace newly generated trace or created with
33
42
  # HTTP request header.
34
43
  # @yield [Aws::Xray::Context] newly created context.
@@ -52,11 +61,23 @@ module Aws
52
61
 
53
62
  attr_reader :name
54
63
 
55
- def initialize(name, client, trace)
56
- @name = name
64
+ # client and trace are frozen by default.
65
+ def initialize(name, client, trace, base_segment_id = nil)
66
+ @name = name.freeze
57
67
  @client = client
58
68
  @trace = trace
59
- @base_segment = Segment.build(@name, trace)
69
+ @base_segment_id = base_segment_id
70
+ end
71
+
72
+ # Curretly context object is thread safe, so copying is not necessary,
73
+ # but in case we need this, offer copy interface for multi threaded
74
+ # environment.
75
+ #
76
+ # client and trace should be imutable and thread-safe.
77
+ #
78
+ # See README for example.
79
+ def copy
80
+ self.class.new(@name, @client, @trace, @base_segment_id)
60
81
  end
61
82
 
62
83
  # Rescue standard errors and record the error to the segment.
@@ -65,13 +86,18 @@ module Aws
65
86
  # @yield [Aws::Xray::Segment]
66
87
  # @return [Object] A value which given block returns.
67
88
  def base_trace
68
- res = yield @base_segment
69
- @client.send_segment(@base_segment)
70
- res
71
- rescue => e
72
- @base_segment.set_error(fault: true, e: e)
73
- @client.send_segment(@base_segment)
74
- raise e
89
+ base_segment = Segment.build(@name, @trace)
90
+ @base_segment_id = base_segment.id.freeze
91
+
92
+ begin
93
+ yield base_segment
94
+ rescue => e
95
+ base_segment.set_error(fault: true, e: e)
96
+ raise e
97
+ ensure
98
+ base_segment.finish
99
+ @client.send_segment(base_segment)
100
+ end
75
101
  end
76
102
 
77
103
  # Rescue standard errors and record the error to the sub segment.
@@ -82,14 +108,18 @@ module Aws
82
108
  # @yield [Aws::Xray::SubSegment]
83
109
  # @return [Object] A value which given block returns.
84
110
  def child_trace(remote:, name:)
85
- sub = SubSegment.build(@trace, @base_segment, remote: remote, name: name)
86
- res = yield sub
87
- @client.send_segment(sub)
88
- res
89
- rescue => e
90
- sub.set_error(fault: true, e: e)
91
- @client.send_segment(sub)
92
- raise e
111
+ raise SegmentDidNotStartError unless @base_segment_id
112
+ sub = SubSegment.build(@trace, @base_segment_id, remote: remote, name: name)
113
+
114
+ begin
115
+ yield sub
116
+ rescue => e
117
+ sub.set_error(fault: true, e: e)
118
+ raise e
119
+ ensure
120
+ sub.finish
121
+ @client.send_segment(sub)
122
+ end
93
123
  end
94
124
  end
95
125
  end
@@ -5,8 +5,8 @@ module Aws
5
5
  # http://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html
6
6
  class SubSegment < Segment
7
7
  # @param [Boolean] remote
8
- def self.build(trace, parent, remote:, name:)
9
- new(name: name, trace: trace, parent_id: parent.id, remote: remote)
8
+ def self.build(trace, parent_id, remote:, name:)
9
+ new(name: name, trace: trace, parent_id: parent_id, remote: remote)
10
10
  end
11
11
 
12
12
  TYPE_NAME = 'subsegment'.freeze
@@ -3,6 +3,7 @@ require 'securerandom'
3
3
 
4
4
  module Aws
5
5
  module Xray
6
+ # Imutable
6
7
  class Trace
7
8
  class << self
8
9
  def generate(now = Time.now)
@@ -25,9 +26,10 @@ module Aws
25
26
  attr_reader :root, :parent
26
27
 
27
28
  def initialize(root:, sampled: true, parent: nil)
28
- @root = root
29
+ @root = root.freeze
29
30
  @sampled = sampled
30
- @parent = parent
31
+ @parent = parent.freeze
32
+ freeze
31
33
  end
32
34
 
33
35
  def to_header_value
@@ -46,7 +48,7 @@ module Aws
46
48
  end
47
49
 
48
50
  def copy(parent:)
49
- self.class.new(root: @root, sampled: @sampled, parent: parent)
51
+ self.class.new(root: @root.dup, sampled: @sampled, parent: parent.freeze)
50
52
  end
51
53
  end
52
54
  end
@@ -1,5 +1,5 @@
1
1
  module Aws
2
2
  module Xray
3
- VERSION = '0.11.0'
3
+ VERSION = '0.12.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-xray
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taiki Ono
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-06 00:00:00.000000000 Z
11
+ date: 2017-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday