aws-xray-sdk 0.11.1 → 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
  SHA256:
3
- metadata.gz: 3ef8621b715e92340eb2dfe27f470fd8e4c92d45d0b21f20d814d3a0b298d323
4
- data.tar.gz: dc4471eebd695a0e4c7fd31cd7b84709ba166a395f6c31785a482272c0a162b6
3
+ metadata.gz: cd1eb76edb60040386a2f0742b166868cd136cb758937b270d9387ff00b9284c
4
+ data.tar.gz: 26a8ca7ef0a34cccc9542b83c2454d2577760d171118a79a20567dd765b8955c
5
5
  SHA512:
6
- metadata.gz: 656c7425f811713ea11d7e4fb8515d597513c8412f1f77b6a2445c0695b7ff91772815efc349695c49688cb3a1ee07408c4e863811ad40dcde58e8585942dff5
7
- data.tar.gz: fbab0222d5abc0048c0fd32a443b1974ad72072386779e858ef88aa541b2bc2797f44ac9ae3a1ae21c066e44973fa30f0c5d78c7e2523a1d32f26d8b1c417f6f
6
+ metadata.gz: f6f3c2945fb499e53d5a6b4b4d3ad9467b6ed541934aae2fa1b02a13dd13a7052644985391c809308edc02715067de2103664b3336f39d1819c77c83e0867629
7
+ data.tar.gz: a61d068ec3c5536d884f4848712fe48aaa9774b7d89dc2a42475b70fcee5b534b38ac75d532727d98d09c0cc71518f4497449bcd08e71f73c79a876a866b627c
@@ -42,7 +42,7 @@ module XRay
42
42
  # setting daemon address for components communicate with X-Ray daemon.
43
43
  def daemon_address=(v)
44
44
  v = ENV[DaemonConfig::DAEMON_ADDRESS_KEY] || v
45
- config = DaemonConfig.new(v)
45
+ config = DaemonConfig.new(addr: v)
46
46
  emitter.daemon_config = config
47
47
  sampler.daemon_config = config if sampler.respond_to?(:daemon_config=)
48
48
  end
@@ -12,7 +12,7 @@ module XRay
12
12
 
13
13
  LOCAL_KEY = '_aws_xray_entity'.freeze
14
14
  CONTEXT_MISSING_KEY = 'AWS_XRAY_CONTEXT_MISSING'.freeze
15
- SUPPORTED_STRATEGY = %w[RUNTIME_ERROR LOG_ERROR].freeze
15
+ SUPPORTED_STRATEGY = %w[RUNTIME_ERROR LOG_ERROR IGNORE_ERROR].freeze
16
16
  DEFAULT_STRATEGY = SUPPORTED_STRATEGY[0]
17
17
 
18
18
  attr_reader :context_missing
@@ -57,7 +57,7 @@ module XRay
57
57
  when 'RUNTIME_ERROR'
58
58
  raise ContextMissingError
59
59
  when 'LOG_ERROR'
60
- logger.error %(can not find the current context.)
60
+ logger.error %(cannot find the current context.)
61
61
  end
62
62
  nil
63
63
  end
@@ -10,7 +10,7 @@ module XRay
10
10
 
11
11
  class ContextMissingError < AwsXRaySdkError
12
12
  def initialize
13
- super('Can not find any active segment or subsegment.')
13
+ super('Cannot find any active segment or subsegment.')
14
14
  end
15
15
  end
16
16
 
@@ -28,4 +28,7 @@ module XRay
28
28
 
29
29
  class UnsupportedPatchingTargetError < AwsXRaySdkError
30
30
  end
31
+
32
+ class UnsupportedOperationError < AwsXRaySdkError
33
+ end
31
34
  end
@@ -2,7 +2,7 @@ require 'aws-xray-sdk/model/trace_header'
2
2
 
3
3
  module XRay
4
4
  module Facets
5
- # Hepler functions shared for all external frameworks/libraries
5
+ # Helper functions shared for all external frameworks/libraries
6
6
  # like make sampling decisions from incoming http requests etc.
7
7
  module Helper
8
8
  TRACE_HEADER = 'X-Amzn-Trace-Id'.freeze
@@ -42,12 +42,7 @@ module XRay
42
42
 
43
43
  # Prepares a X-Ray header string based on the provided Segment/Subsegment.
44
44
  def prep_header_str(entity:)
45
- return '' if entity.nil?
46
- root = entity.segment.trace_id
47
- parent_id = entity.id
48
- sampled = entity.sampled ? 1 : 0
49
- header = TraceHeader.new root: root, parent_id: parent_id, sampled: sampled
50
- header.header_string
45
+ TraceHeader.from_entity(entity: entity).header_string
51
46
  end
52
47
  end
53
48
  end
@@ -20,8 +20,25 @@ module XRay
20
20
  super(*options)
21
21
  end
22
22
 
23
+ # HTTP requests to AWS Lambda Ruby Runtime will have the address and port
24
+ # matching the value set in ENV['AWS_LAMBDA_RUNTIME_API']
25
+ def lambda_runtime_request?
26
+ ENV['AWS_LAMBDA_RUNTIME_API'] == "#{address}:#{port}"
27
+ end
28
+
29
+ def xray_sampling_request?(req)
30
+ req.path && (req.path == ('/GetSamplingRules') || req.path == ('/SamplingTargets'))
31
+ end
32
+
33
+ # Instance Metadata Service provides endpoint 169.254.169.254 to
34
+ # provide EC2 metadata
35
+ def ec2_metadata_request?(req)
36
+ req.uri && req.uri.hostname == '169.254.169.254'
37
+ end
38
+
23
39
  def request(req, body = nil, &block)
24
- if req.path && (req.path == ('/GetSamplingRules') || req.path == ('/SamplingTargets'))
40
+ # Do not trace requests to xray or aws lambda runtime or ec2 metadata endpoint
41
+ if xray_sampling_request?(req) || lambda_runtime_request? || ec2_metadata_request?(req)
25
42
  return super
26
43
  end
27
44
 
@@ -49,6 +49,8 @@ module XRay
49
49
  resp_meta[:content_length] = len
50
50
  end
51
51
  segment.merge_http_response response: resp_meta
52
+ trace_header = {TRACE_HEADER => TraceHeader.from_entity(entity: segment).root_string}
53
+ headers.merge!(trace_header)
52
54
  [status, headers, body]
53
55
  rescue Exception => e
54
56
  segment.apply_status_code status: 500
@@ -17,7 +17,12 @@ module XRay
17
17
  pool, conn = get_pool_n_conn(payload[:connection_id])
18
18
 
19
19
  return if IGNORE_OPS.include?(payload[:name]) || pool.nil? || conn.nil?
20
- db_config = pool.spec.config
20
+ # The spec notation is Rails < 6.1, later this can be found in the db_config
21
+ db_config = if pool.respond_to?(:spec)
22
+ pool.spec.config
23
+ else
24
+ pool.db_config.configuration_hash
25
+ end
21
26
  name, sql = build_name_sql_meta config: db_config, conn: conn
22
27
  subsegment = XRay.recorder.begin_subsegment name, namespace: 'remote'
23
28
  # subsegment is nil in case of context missing
@@ -52,6 +57,7 @@ module XRay
52
57
  ::ActiveRecord::Base.connection_handler.connection_pool_list.each do |p|
53
58
  conn = p.connections.select { |c| c.object_id == conn_id }
54
59
  pool = p unless conn.nil?
60
+ return [pool, conn] if !conn.nil? && !conn.empty? && !pool.nil?
55
61
  end
56
62
  [pool, conn]
57
63
  end
@@ -7,7 +7,7 @@ module XRay
7
7
  RAILS_OPTIONS = %I[active_record].freeze
8
8
 
9
9
  initializer("aws-xray-sdk.rack_middleware") do |app|
10
- app.middleware.insert 0, Rack::Middleware
10
+ app.middleware.insert 0, XRay::Rack::Middleware
11
11
  app.middleware.use XRay::Rails::ExceptionMiddleware
12
12
  end
13
13
 
@@ -329,6 +329,24 @@ module XRay
329
329
  ]
330
330
  }
331
331
  }
332
+ },
333
+ SageMakerRuntime: {
334
+ operations: {
335
+ invoke_endpoint: {
336
+ request_parameters: %I[
337
+ endpoint_name
338
+ ]
339
+ }
340
+ }
341
+ },
342
+ SNS: {
343
+ operations: {
344
+ publish: {
345
+ request_parameters: %I[
346
+ topic_arn
347
+ ]
348
+ }
349
+ }
332
350
  }
333
351
  }
334
352
  }
@@ -3,20 +3,32 @@ module XRay
3
3
  module AwsServices
4
4
  # exausted list can be tracked at http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Seahorse/Client/Base.html
5
5
  @whitelist = %I[
6
+ AccessAnalyzer
6
7
  ACM
7
- APIGateway
8
+ ACMPCA
8
9
  AlexaForBusiness
9
- AppStream
10
- AppSync
10
+ Amplify
11
+ APIGateway
12
+ ApiGatewayManagementApi
13
+ ApiGatewayV2
14
+ AppConfig
11
15
  ApplicationAutoScaling
12
16
  ApplicationDiscoveryService
17
+ ApplicationInsights
18
+ AppMesh
19
+ AppStream
20
+ AppSync
13
21
  Athena
22
+ AugmentedAIRuntime
14
23
  AutoScaling
24
+ AutoScalingPlans
25
+ Backup
15
26
  Batch
16
27
  Budgets
28
+ Chime
17
29
  Cloud9
18
30
  CloudDirectory
19
- CloudFormatioin
31
+ CloudFormation
20
32
  CloudFront
21
33
  CloudHSM
22
34
  CloudHSMV2
@@ -29,109 +41,191 @@ module XRay
29
41
  CodeBuild
30
42
  CodeCommit
31
43
  CodeDeploy
44
+ CodeGuruProfiler
45
+ CodeGuruReviewer
32
46
  CodePipeline
33
47
  CodeStar
48
+ CodeStarconnections
49
+ CodeStarNotifications
34
50
  CognitoIdentity
35
51
  CognitoIdentityProvider
36
52
  CognitoSync
37
53
  Comprehend
54
+ ComprehendMedical
55
+ ComputeOptimizer
38
56
  ConfigService
39
- CostExplore
57
+ Connect
58
+ ConnectParticipant
40
59
  CostandUsageReportService
41
- DAX
42
- DataPipeline
60
+ CostExplore
61
+ CostExplorer
43
62
  DatabaseMigrationService
63
+ DataExchange
64
+ DataPipeline
65
+ DataSync
66
+ DAX
67
+ Detective
44
68
  DeviceFarm
45
69
  DirectConnect
46
70
  DirectoryService
71
+ DLM
72
+ DocDB
47
73
  DynamoDB
48
74
  DynamoDBStreams
75
+ EBS
49
76
  EC2
77
+ EC2InstanceConnect
50
78
  ECR
51
79
  ECS
52
80
  EFS
53
- EMR
81
+ EKS
54
82
  ElastiCache
55
83
  ElasticBeanstalk
84
+ ElasticInference
56
85
  ElasticLoadBalancing
57
86
  ElasticLoadBalancingV2
58
- ElasticTranscoder
59
87
  ElasticsearchService
60
- Firehost
88
+ ElasticTranscoder
89
+ EMR
90
+ EventBridge
91
+ Firehose
92
+ FMS
93
+ ForecastQueryService
94
+ ForecastService
95
+ FraudDetector
96
+ FSx
61
97
  GameLift
62
98
  Glacier
99
+ GlobalAccelerator
63
100
  Glue
64
101
  Greengrass
102
+ GroundStation
65
103
  GuardDuty
66
104
  Health
67
105
  IAM
106
+ Imagebuilder
68
107
  ImportExport
69
108
  Inspector
70
109
  IoT
110
+ IoT1ClickDevicesService
111
+ IoT1ClickProjects
112
+ IoTAnalytics
71
113
  IoTDataPlane
114
+ IoTEvents
115
+ IoTEventsData
72
116
  IoTJobsDataPlane
73
- KMS
117
+ IoTSecureTunneling
118
+ IoTThingsGraph
119
+ Kafka
120
+ Kendra
74
121
  Kinesis
75
122
  KinesisAnalytics
123
+ KinesisAnalyticsV2
76
124
  KinesisVideo
125
+ KinesisVideoArchivedMedia
77
126
  KinesisVideoArchiveMedia
78
127
  KinesisVideoMedia
128
+ KinesisVideoSignalingChannels
129
+ KMS
130
+ LakeFormation
79
131
  Lambda
80
132
  LambdaPreview
81
133
  Lex
82
134
  LexModelBuildingService
83
135
  LexRuntimeService
136
+ LicenseManager
84
137
  Lightsail
85
- MQ
86
- MTurk
87
138
  MachineLearning
139
+ Macie
140
+ ManagedBlockchain
141
+ MarketplaceCatalog
88
142
  MarketplaceCommerceAnalytics
89
143
  MarketplaceEntitlementService
90
144
  MarketplaceMetering
145
+ MediaConnect
91
146
  MediaConvert
92
147
  MediaLive
93
148
  MediaPackage
149
+ MediaPackageVod
94
150
  MediaStore
95
151
  MediaStoreData
152
+ MediaTailor
96
153
  MigrationHub
154
+ MigrationHubConfig
97
155
  Mobile
156
+ MQ
157
+ MTurk
158
+ Neptune
159
+ NetworkManager
98
160
  OpsWorks
99
161
  OpsWorksCM
100
162
  Organizations
163
+ Outposts
164
+ Personalize
165
+ PersonalizeEvents
166
+ PersonalizeRuntime
167
+ PI
101
168
  Pinpoint
169
+ PinpointEmail
170
+ PinpointSMSVoice
102
171
  Polly
103
172
  Pricing
173
+ QLDB
174
+ QLDBSession
175
+ QuickSight
176
+ RAM
104
177
  RDS
178
+ RDSDataService
105
179
  Redshift
106
180
  Rekognition
107
181
  ResourceGroups
108
182
  ResourceGroupsTaggingAPI
183
+ RoboMaker
109
184
  Route53
110
185
  Route53Domains
186
+ Route53Resolver
111
187
  S3
112
- SES
113
- SFN
114
- SMS
115
- SNS
116
- SQS
117
- SSM
118
- STS
119
- SWF
188
+ S3Control
120
189
  SageMaker
121
190
  SageMakerRuntime
191
+ SavingsPlans
192
+ Schemas
193
+ SecretsManager
194
+ SecurityHub
122
195
  ServerlessApplicationRepository
123
196
  ServiceCatalog
124
197
  ServiceDiscovery
198
+ ServiceQuotas
199
+ SES
200
+ SESV2
201
+ SFN
125
202
  Shield
203
+ Signer
126
204
  SimpleDB
205
+ SMS
127
206
  Snowball
207
+ SNS
208
+ SQS
209
+ SSM
210
+ SSO
211
+ SSOOIDC
128
212
  States
129
213
  StorageGateway
214
+ STS
130
215
  Support
216
+ SWF
217
+ Textract
218
+ TranscribeService
219
+ TranscribeStreamingService
220
+ Transfer
131
221
  Translate
132
222
  WAF
133
223
  WAFRegional
224
+ WAFV2
134
225
  WorkDocs
226
+ WorkLink
227
+ WorkMail
228
+ WorkMailMessageFlow
135
229
  WorkSpaces
136
230
  XRay
137
231
  ]
@@ -0,0 +1,35 @@
1
+ # AWS Lambda functions should require this file to configure the XRay.recorder
2
+ # for use within the function.
3
+
4
+ require_relative 'lambda/lambda_recorder'
5
+ require_relative 'lambda/facade_segment'
6
+ require_relative 'lambda/lambda_context'
7
+ require_relative 'lambda/lambda_streamer'
8
+
9
+ module XRay
10
+ @recorder = LambdaRecorder.new
11
+
12
+ # provide an instance of LambdaRecorder as the global XRay.recorder
13
+ def self.recorder
14
+ @recorder
15
+ end
16
+ end
17
+
18
+
19
+ # Set `XRAY_LAMBDA_PATCH_CONFIG` before requiring `aws-xray-sdk/lambda`
20
+ # to configure which libraries (if any) to instrument.
21
+ #
22
+ # By default, both `net_http` and `aws_sdk` will be instrumented
23
+ unless defined? XRAY_LAMBDA_PATCH_CONFIG
24
+ XRAY_LAMBDA_PATCH_CONFIG = %I[net_http aws_sdk]
25
+ end
26
+
27
+ # Configure the XRay.recorder with Lambda specific config.
28
+ #
29
+ # From here, a lambda may create subsegments manually, or via
30
+ # the instrumented libraries setup by XRAY_LAMBDA_PATCH_CONFIG
31
+ XRay.recorder.configure(
32
+ patch: XRAY_LAMBDA_PATCH_CONFIG,
33
+ context: XRay::LambdaContext.new,
34
+ streamer: XRay::LambdaStreamer.new
35
+ )
@@ -0,0 +1,109 @@
1
+ module XRay
2
+ class FacadeSegment < XRay::Segment
3
+
4
+ class ImmutableEmptyCollection
5
+ def [](key)
6
+ nil
7
+ end
8
+
9
+ def []=(k, v)
10
+ raise UnsupportedOperationError
11
+ end
12
+
13
+ def update(h)
14
+ raise UnsupportedOperationError
15
+ end
16
+
17
+ def to_h
18
+ {}
19
+ end
20
+ end
21
+
22
+
23
+ def initialize(trace_id: nil, name: nil, parent_id: nil, id: nil, sampled: true)
24
+ super(trace_id: trace_id, name: name, parent_id: parent_id)
25
+ @id = id
26
+ @sampled = sampled
27
+ @empty_collection = ImmutableEmptyCollection.new
28
+ end
29
+
30
+ def ready_to_send?
31
+ false #never send this facade. AWS Lambda has already created a Segment with these ids
32
+ end
33
+
34
+ #
35
+ #Methods from Entity that are not supported
36
+ #
37
+ def close(end_time: nil)
38
+ raise UnsupportedOperationError
39
+ end
40
+ def apply_status_code(status:)
41
+ raise UnsupportedOperationError
42
+ end
43
+ def merge_http_request(request:)
44
+ raise UnsupportedOperationError
45
+ end
46
+ def merge_http_response(response:)
47
+ raise UnsupportedOperationError
48
+ end
49
+ def add_exception(exception:, remote: false)
50
+ raise UnsupportedOperationError
51
+ end
52
+
53
+ #
54
+ # Mutation accessors from Entity that are not supported
55
+ #
56
+ def parent=(value)
57
+ raise UnsupportedOperationError
58
+ end
59
+ def throttle=(value)
60
+ raise UnsupportedOperationError
61
+ end
62
+ def error=(value)
63
+ raise UnsupportedOperationError
64
+ end
65
+ def fault=(value)
66
+ raise UnsupportedOperationError
67
+ end
68
+ def sampled=(value)
69
+ raise UnsupportedOperationError
70
+ end
71
+ def aws=(value)
72
+ raise UnsupportedOperationError
73
+ end
74
+ def start_time=(value)
75
+ raise UnsupportedOperationError
76
+ end
77
+ def end_time=(value)
78
+ raise UnsupportedOperationError
79
+ end
80
+
81
+ #
82
+ # Mutation accessors from Segment that are not supported
83
+ #
84
+ def origin=(value)
85
+ raise UnsupportedOperationError
86
+ end
87
+ def user=(value)
88
+ raise UnsupportedOperationError
89
+ end
90
+ def service=(value)
91
+ raise UnsupportedOperationError
92
+ end
93
+
94
+ #
95
+ # Annotations are read only
96
+ #
97
+ def annotations
98
+ @empty_collection
99
+ end
100
+
101
+ #
102
+ # Metadata is read only
103
+ #
104
+ def metadata(namespace: :default)
105
+ @empty_collection
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,37 @@
1
+ require_relative '../model/trace_header'
2
+
3
+ module XRay
4
+ # LambdaContext extends the default context so that
5
+ # we can provide an appropriate FacadeSegment as the
6
+ # root context for each function invocation.
7
+ class LambdaContext < XRay::DefaultContext
8
+
9
+ TRACE_ID_ENV_VAR = '_X_AMZN_TRACE_ID'.freeze
10
+
11
+ def lambda_trace_id
12
+ ENV[TRACE_ID_ENV_VAR]
13
+ end
14
+
15
+ # If the environment trace id changes, create a new facade for that
16
+ # segment and make it the context's current entity
17
+ def check_context
18
+ #Create a new FacadeSegment if the _X_AMZN_TRACE_ID changes.
19
+ return if lambda_trace_id == @current_trace_id
20
+
21
+ @current_trace_id = lambda_trace_id
22
+ trace_header = XRay::TraceHeader.from_header_string(header_str: @current_trace_id)
23
+ segment = FacadeSegment.new(trace_id: trace_header.root,
24
+ parent_id: trace_header.parent_id,
25
+ id: trace_header.parent_id,
26
+ name: 'lambda_context',
27
+ sampled: trace_header.sampled == 1
28
+ )
29
+ store_entity(entity: segment)
30
+ end
31
+
32
+ def current_entity
33
+ check_context #ensure the FacadeSegment is current whenever the current_entity is retrieved
34
+ super
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ require 'aws-xray-sdk/recorder'
2
+
3
+ module XRay
4
+ class LambdaRecorder < Recorder
5
+ include Logging
6
+
7
+ def begin_segment(name, trace_id: nil, parent_id: nil, sampled: nil)
8
+ # no-op
9
+ logger.warn('Cannot create segments inside Lambda function. Returning current segment.')
10
+ return current_segment
11
+ end
12
+
13
+ def end_segment(end_time: nil)
14
+ # no-op
15
+ logger.warn('Cannot end segment inside Lambda function. Ignored.')
16
+ nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ module XRay
2
+ # LambdaStreamer extends DefaultStreamer so that subsegments
3
+ # are sent to the XRay endpoint as they are available.
4
+ class LambdaStreamer < XRay::DefaultStreamer
5
+ def initialize
6
+ @stream_threshold = 1 #Stream every subsegment as it is available
7
+ end
8
+ end
9
+ end
@@ -143,7 +143,9 @@ module XRay
143
143
  else
144
144
  h[:in_progress] = true
145
145
  end
146
- h[:subsegments] = subsegments unless subsegments.empty?
146
+
147
+ h[:subsegments] = subsegments.map(&:to_h) unless subsegments.empty?
148
+
147
149
  h[:aws] = aws if aws
148
150
  if http_request || http_response
149
151
  h[:http] = {}
@@ -17,7 +17,11 @@ module XRay
17
17
  end
18
18
 
19
19
  def to_h
20
- @data
20
+ @data.keys.each_with_object({}) do |key, h|
21
+ h[key] = @data[key].to_h
22
+ h
23
+ end
24
+
21
25
  end
22
26
  end
23
27
 
@@ -18,6 +18,14 @@ module XRay
18
18
  @sampled = sampled.to_i if sampled
19
19
  end
20
20
 
21
+ def self.from_entity(entity:)
22
+ return empty_header if entity.nil?
23
+ root = entity.segment.trace_id
24
+ parent_id = entity.id
25
+ sampled = entity.sampled ? 1 : 0
26
+ new root: root, parent_id: parent_id, sampled: sampled
27
+ end
28
+
21
29
  def self.from_header_string(header_str:)
22
30
  empty_header if header_str.to_s.empty?
23
31
  header = header_str.delete(' ').downcase
@@ -35,15 +43,20 @@ module XRay
35
43
  end
36
44
  end
37
45
 
46
+ # @return [String] The header string of the root object
47
+ def root_string
48
+ %(Root=#{root})
49
+ end
50
+
38
51
  # @return [String] The heading string constructed based on this header object.
39
52
  def header_string
40
53
  return '' unless root
41
54
  if !parent_id
42
- %(Root=#{root};Sampled=#{sampled})
55
+ %(#{root_string};Sampled=#{sampled})
43
56
  elsif !sampled
44
- %(Root=#{root};Parent=#{parent_id})
57
+ %(#{root_string};Parent=#{parent_id})
45
58
  else
46
- %(Root=#{root};Parent=#{parent_id};Sampled=#{sampled})
59
+ %(#{root_string};Parent=#{parent_id};Sampled=#{sampled})
47
60
  end
48
61
  end
49
62
 
@@ -1,36 +1,91 @@
1
- require 'open-uri'
1
+ require 'net/http'
2
+ require 'json'
2
3
  require 'aws-xray-sdk/logger'
3
4
 
4
5
  module XRay
5
6
  module Plugins
6
- # A plugin that gets the EC2 instance-id and AZ if running on an EC2 instance.
7
+ # A plugin that gets the EC2 instance_id, availabiity_zone, instance_type, and ami_id if running on an EC2 instance.
7
8
  module EC2
8
9
  include Logging
9
10
 
10
11
  ORIGIN = 'AWS::EC2::Instance'.freeze
12
+
11
13
  # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-retrieval
12
- ID_ADDR = 'http://169.254.169.254/latest/meta-data/instance-id'.freeze
13
- AZ_ADDR = 'http://169.254.169.254/latest/meta-data/placement/availability-zone'.freeze
14
+ METADATA_BASE_URL = 'http://169.254.169.254/latest'.freeze
14
15
 
15
16
  def self.aws
16
- @@aws ||= begin
17
- instance_id = open(ID_ADDR, open_timeout: 1).read
18
- az = open(AZ_ADDR, open_timeout: 1).read
19
- {
20
- ec2: {
21
- instance_id: instance_id,
22
- availability_zone: az
23
- }
17
+ @@aws = {}
18
+ token = get_token
19
+ ec2_metadata = get_metadata(token)
20
+ @@aws = {
21
+ ec2: ec2_metadata
22
+ }
23
+ end
24
+
25
+
26
+ private # private methods
27
+
28
+ def self.get_token
29
+ token_uri = URI(METADATA_BASE_URL + '/api/token')
30
+
31
+ req = Net::HTTP::Put.new(token_uri)
32
+ req['X-aws-ec2-metadata-token-ttl-seconds'] = '60'
33
+ begin
34
+ return do_request(req)
35
+ rescue StandardError => e
36
+ Logging.logger.warn %(cannot get the IMDSv2 token due to: #{e.message}.)
37
+ ''
38
+ end
39
+ end
40
+
41
+ def self.get_metadata(token)
42
+ metadata_uri = URI(METADATA_BASE_URL + '/dynamic/instance-identity/document')
43
+
44
+ req = Net::HTTP::Get.new(metadata_uri)
45
+ if token != ''
46
+ req['X-aws-ec2-metadata-token'] = token
47
+ end
48
+
49
+ begin
50
+ metadata_json = do_request(req)
51
+ return parse_metadata(metadata_json)
52
+ rescue StandardError => e
53
+ Logging.logger.warn %(cannot get the ec2 instance metadata due to: #{e.message}.)
54
+ {}
55
+ end
56
+ end
57
+
58
+ def self.parse_metadata(json_str)
59
+ metadata = {}
60
+ data = JSON(json_str)
61
+ metadata['instance_id'] = data['instanceId']
62
+ metadata['availability_zone'] = data['availabilityZone']
63
+ metadata['instance_type'] = data['instanceType']
64
+ metadata['ami_id'] = data['imageId']
65
+
66
+ metadata
67
+ end
68
+
69
+ def self.do_request(request)
70
+ begin
71
+ response = Net::HTTP.start(request.uri.hostname, read_timeout: 1) { |http|
72
+ http.request(request)
24
73
  }
74
+
75
+ if response.code == '200'
76
+ return response.body
77
+ else
78
+ raise(StandardError.new('Unsuccessful response::' + response.code + '::' + response.message))
79
+ end
25
80
  rescue StandardError => e
26
- # Two attempts in total to get EC2 metadata
81
+ # Two attempts in total to complete the request successfully
27
82
  @retries ||= 0
28
83
  if @retries < 1
29
84
  @retries += 1
30
85
  retry
31
86
  else
32
- @@aws = {}
33
- Logging.logger.warn %(can not get the ec2 instance metadata due to: #{e.message}.)
87
+ Logging.logger.warn %(Failed to complete request due to: #{e.message}.)
88
+ raise e
34
89
  end
35
90
  end
36
91
  end
@@ -15,7 +15,7 @@ module XRay
15
15
  { ecs: { container: Socket.gethostname } }
16
16
  rescue StandardError => e
17
17
  @@aws = {}
18
- Logging.logger.warn %(can not get the ecs container hostname due to: #{e.message}.)
18
+ Logging.logger.warn %(cannot get the ecs container hostname due to: #{e.message}.)
19
19
  end
20
20
  end
21
21
  end
@@ -17,7 +17,7 @@ module XRay
17
17
  { elastic_beanstalk: MultiJson.load(file) }
18
18
  rescue StandardError => e
19
19
  @@aws = {}
20
- Logging.logger.warn %(can not get the environment config due to: #{e.message}.)
20
+ Logging.logger.warn %(cannot get the environment config due to: #{e.message}.)
21
21
  end
22
22
  end
23
23
  end
@@ -58,7 +58,7 @@ module XRay
58
58
  return sample if sampling_req.nil? || sampling_req.empty?
59
59
  @custom_rules ||= []
60
60
  @custom_rules.each do |c|
61
- return should_sample?(c) if c.applies?(sampling_req: sampling_req)
61
+ return should_sample?(c) if c.applies?(sampling_req)
62
62
  end
63
63
  # use previously made decision based on default rule
64
64
  # if no path-based rule has been matched
@@ -1,3 +1,3 @@
1
1
  module XRay
2
- VERSION = '0.11.1'
2
+ VERSION = '0.12.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-xray-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amazon Web Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-11 00:00:00.000000000 Z
11
+ date: 2021-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-xray
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.0'
75
+ version: '2.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.0'
82
+ version: '2.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: minitest
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -188,6 +188,11 @@ files:
188
188
  - lib/aws-xray-sdk/facets/rails/railtie.rb
189
189
  - lib/aws-xray-sdk/facets/resources/aws_params_whitelist.rb
190
190
  - lib/aws-xray-sdk/facets/resources/aws_services_whitelist.rb
191
+ - lib/aws-xray-sdk/lambda.rb
192
+ - lib/aws-xray-sdk/lambda/facade_segment.rb
193
+ - lib/aws-xray-sdk/lambda/lambda_context.rb
194
+ - lib/aws-xray-sdk/lambda/lambda_recorder.rb
195
+ - lib/aws-xray-sdk/lambda/lambda_streamer.rb
191
196
  - lib/aws-xray-sdk/logger.rb
192
197
  - lib/aws-xray-sdk/model/annotations.rb
193
198
  - lib/aws-xray-sdk/model/cause.rb
@@ -239,8 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
239
244
  - !ruby/object:Gem::Version
240
245
  version: '0'
241
246
  requirements: []
242
- rubyforge_project:
243
- rubygems_version: 2.7.6
247
+ rubygems_version: 3.1.6
244
248
  signing_key:
245
249
  specification_version: 4
246
250
  summary: AWS X-Ray SDK for Ruby