aws-xray 0.11.0 → 0.12.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: 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