datadog-lambda 2.20.0 → 2.22.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
  SHA256:
3
- metadata.gz: 7190d039044c87a9835b29f812e930cc6c3fee9cdc5348226df7fe603b15a7bf
4
- data.tar.gz: 35c495079f2b934ba036008084765d92a376f6924f7a4c5468ad34303ee1912c
3
+ metadata.gz: 1ff16978e295234189602cab59d2c4f2adbff91edc9bcb9a52bbde91fb744369
4
+ data.tar.gz: 4e89c094a7c0fb2e6161f7179266831df23dd4f665ccaafcc9b1d233fcce0860
5
5
  SHA512:
6
- metadata.gz: c51f7c325e147d68a713d763c9550f2bf11b3ba9f7492f48c4b5195302f4c5fd4c0da20a9893ea19c27be24c4adf8740186f394250f830cfe8b6d8890c861d7b
7
- data.tar.gz: 58f67b709d96a5b9e8ce628c4c1d0c02385508de007772a2560da26dc8cc7e90d23562063e3a8e73a5c90f73e71fd7c0cc0fac305c36cca6d901977d39c3fd6f
6
+ metadata.gz: 3738d873ac92162f632b6457ad1d188397eec4a3a59d9a523fcdf9b2f53eadd559f92f388f8d5d4a96da6cc38024124efb828b714c0cd44ed050a347eb246150
7
+ data.tar.gz: 37cfd0a36ae52012ebdc14cab31b1d22b20e968413ef136010fa21f0ee6be2b965257b2066d5d93ed7c3eabdf9989a2a40c84e5341f48aa1bb1ae0e0cffb29d9
@@ -17,9 +17,11 @@ module Datadog
17
17
  DD_TRACE_ID_HEADER = 'x-datadog-trace-id'
18
18
  DD_PARENT_ID_HEADER = 'x-datadog-parent-id'
19
19
  DD_SAMPLING_PRIORITY_HEADER = 'x-datadog-sampling-priority'
20
+ DD_ORIGIN = 'x-datadog-origin'
20
21
  DD_XRAY_SUBSEGMENT_NAME = 'datadog-metadata'
21
22
  DD_XRAY_SUBSEGMENT_KEY = 'trace'
22
23
  DD_XRAY_SUBSEGMENT_NAMESPACE = 'datadog'
24
+ DD_TRACE_MANAGED_SERVICES = 'DD_TRACE_MANAGED_SERVICES'
23
25
  SOURCE_XRAY = 'XRAY'
24
26
  SOURCE_EVENT = 'EVENT'
25
27
  XRAY_ENV_VAR = '_X_AMZN_TRACE_ID'
@@ -16,6 +16,7 @@ module Datadog
16
16
  module Trace
17
17
  # TraceListener tracks tracing context information
18
18
  class Listener
19
+ @trace = nil
19
20
  def initialize(handler_name:, function_name:, patch_http:,
20
21
  merge_xray_traces:)
21
22
  @handler_name = handler_name
@@ -25,18 +26,11 @@ module Datadog
25
26
  Datadog::Trace.patch_http if patch_http
26
27
  end
27
28
 
28
- def on_start(event:)
29
- trace_context = Datadog::Trace.extract_trace_context(event,
30
- @merge_xray_traces)
29
+ # rubocop:disable Metrics/AbcSize
30
+ def on_start(event:, request_context:, cold_start:)
31
+ trace_context = Datadog::Trace.extract_trace_context(event, @merge_xray_traces)
31
32
  Datadog::Trace.trace_context = trace_context
32
33
  Datadog::Utils.logger.debug "extracted trace context #{trace_context}"
33
- rescue StandardError => e
34
- Datadog::Utils.logger.error "couldn't read tracing context #{e}"
35
- end
36
-
37
- def on_end; end
38
-
39
- def on_wrap(request_context:, cold_start:, &block)
40
34
  options = get_option_tags(
41
35
  request_context: request_context,
42
36
  cold_start: cold_start
@@ -48,9 +42,19 @@ module Datadog
48
42
  options[:service] = 'aws.lambda'
49
43
  options[:span_type] = 'serverless'
50
44
  Datadog::Trace.apply_datadog_trace_context(Datadog::Trace.trace_context)
51
- Datadog::Trace.wrap_datadog(options) do
52
- block.call
53
- end
45
+
46
+ trace_digest = Datadog::Utils.send_start_invocation_request(event: event)
47
+ # Only continue trace from a new one if it exist, or else,
48
+ # it will create a new trace, which is not ideal here.
49
+ options[:continue_from] = trace_digest if trace_digest
50
+
51
+ @trace = Datadog::Tracing.trace('aws.lambda', **options)
52
+ end
53
+ # rubocop:enable Metrics/AbcSize
54
+
55
+ def on_end(response:)
56
+ Datadog::Utils.send_end_invocation_request(response: response)
57
+ @trace&.finish
54
58
  end
55
59
 
56
60
  private
@@ -8,16 +8,24 @@
8
8
  # Copyright 2023 Datadog, Inc.
9
9
  #
10
10
  require 'net/http'
11
+ require 'datadog/tracing/contrib/http/distributed/fetcher'
11
12
 
12
13
  module Datadog
13
14
  # Utils contains utility functions shared between modules
14
15
  module Utils
15
- AGENT_URL = 'http://127.0.0.1:8124'
16
- HELLO_PATH = '/lambda/hello'
17
- EXTENSION_CHECK_URI = URI(AGENT_URL + HELLO_PATH).freeze
18
16
  EXTENSION_PATH = '/opt/extensions/datadog-agent'
17
+ EXTENSION_BASE_URL = 'http://127.0.0.1:8124'
19
18
 
20
- @is_extension_running = nil
19
+ START_INVOCATION_PATH = '/lambda/start-invocation'
20
+ END_INVOCATION_PATH = '/lambda/end-invocation'
21
+
22
+ START_INVOCATION_URI = URI(EXTENSION_BASE_URL + START_INVOCATION_PATH).freeze
23
+ END_INVOCATION_URI = URI(EXTENSION_BASE_URL + END_INVOCATION_PATH).freeze
24
+
25
+ # Internal communications use Datadog tracing headers
26
+ PROPAGATOR = Tracing::Distributed::Datadog.new(
27
+ fetcher: Tracing::Contrib::HTTP::Distributed::Fetcher
28
+ )
21
29
 
22
30
  def self.extension_running?
23
31
  return @is_extension_running unless @is_extension_running.nil?
@@ -26,16 +34,44 @@ module Datadog
26
34
  end
27
35
 
28
36
  def self.check_extension_running
29
- return false unless File.exist?(EXTENSION_PATH)
37
+ File.exist?(EXTENSION_PATH)
38
+ end
30
39
 
31
- begin
32
- Net::HTTP.get(EXTENSION_CHECK_URI)
33
- rescue StandardError => e
34
- Datadog::Utils.logger.debug "extension is not running, returned with error #{e}"
35
- return false
40
+ def self.send_start_invocation_request(event:)
41
+ return unless extension_running?
42
+
43
+ response = Net::HTTP.post(START_INVOCATION_URI, event.to_json, request_headers)
44
+ # Add origin, since tracer expects it for extraction
45
+ response[Datadog::Trace::DD_ORIGIN] = 'lambda'
46
+
47
+ PROPAGATOR.extract(response)
48
+ rescue StandardError => e
49
+ Datadog::Utils.logger.debug "failed on start invocation request to extension: #{e}"
50
+ end
51
+
52
+ def self.send_end_invocation_request(response:)
53
+ return unless extension_running?
54
+
55
+ request = Net::HTTP::Post.new(END_INVOCATION_URI)
56
+ request.body = response.to_json
57
+ request[Datadog::Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST] = 1
58
+
59
+ trace_digest = Datadog::Tracing.active_trace&.to_digest
60
+
61
+ PROPAGATOR.inject!(trace_digest, request)
62
+ Net::HTTP.start(END_INVOCATION_URI.host, END_INVOCATION_URI.port) do |http|
63
+ http.request(request)
36
64
  end
65
+ rescue StandardError => e
66
+ Datadog::Utils.logger.debug "failed on end invocation request to extension: #{e}"
67
+ end
37
68
 
38
- true
69
+ def self.request_headers
70
+ {
71
+ # Header used to avoid tracing requests that are internal to
72
+ # Datadog products.
73
+ Datadog::Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST.to_sym => 'true'
74
+ }
39
75
  end
40
76
  end
41
77
  end
@@ -12,7 +12,7 @@ module Datadog
12
12
  module Lambda
13
13
  module VERSION
14
14
  MAJOR = 2
15
- MINOR = 20
15
+ MINOR = 22
16
16
  PATCH = 0
17
17
  PRE = nil
18
18
 
@@ -21,6 +21,7 @@ module Datadog
21
21
  # Instruments AWS Lambda functions with Datadog distributed tracing and
22
22
  # custom metrics
23
23
  module Lambda
24
+ @response = nil
24
25
  @is_cold_start = true
25
26
  @patch_http = true
26
27
  @metrics_client = Metrics::Client.instance
@@ -30,7 +31,7 @@ module Datadog
30
31
  # See https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md#quickstart-for-ruby-applications
31
32
  def self.configure_apm
32
33
  require 'datadog/tracing'
33
- require 'ddtrace/transport/io'
34
+ require 'datadog/tracing/transport/io'
34
35
 
35
36
  @patch_http = false
36
37
  # Needed to keep trace flushes on a single line
@@ -39,10 +40,13 @@ module Datadog
39
40
  Datadog.configure do |c|
40
41
  unless Datadog::Utils.extension_running?
41
42
  c.tracing.writer = Datadog::Tracing::SyncWriter.new(
42
- transport: Datadog::Transport::IO.default
43
+ transport: Datadog::Tracing::Transport::IO.default
43
44
  )
44
45
  end
45
46
  c.tags = { "_dd.origin": 'lambda' }
47
+ # Enable AWS SDK instrumentation
48
+ c.tracing.instrument :aws if trace_managed_services?
49
+
46
50
  yield(c) if block_given?
47
51
  end
48
52
  end
@@ -54,28 +58,25 @@ module Datadog
54
58
  def self.wrap(event, context, &block)
55
59
  Datadog::Utils.update_log_level
56
60
  @listener ||= initialize_listener
57
- @listener.on_start(event: event)
58
61
  record_enhanced('invocations', context)
59
62
  begin
60
63
  cold = @is_cold_start
61
- res = @listener.on_wrap(request_context: context, cold_start: cold) do
62
- block.call
63
- end
64
+ @listener&.on_start(event: event, request_context: context, cold_start: cold)
65
+ @response = block.call
64
66
  rescue StandardError => e
65
67
  record_enhanced('errors', context)
66
68
  raise e
67
69
  ensure
68
- @listener.on_end
70
+ @listener&.on_end(response: @response)
69
71
  @is_cold_start = false
70
72
  @metrics_client.close
71
73
  end
72
- res
74
+ @response
73
75
  end
74
76
 
75
77
  # Gets the current tracing context
76
78
  def self.trace_context
77
- context = Hash[Datadog::Trace.trace_context]
78
- context
79
+ Hash[Datadog::Trace.trace_context]
79
80
  end
80
81
 
81
82
  # Send a custom distribution metric
@@ -166,6 +167,15 @@ module Datadog
166
167
  dd_enhanced_metrics.downcase == 'true'
167
168
  end
168
169
 
170
+ # Read DD_TRACE_MANAGED_SERVICES environment variable
171
+ # @return [boolean] true if we should trace AWS services
172
+ def self.trace_managed_services?
173
+ dd_trace_managed_services = ENV[Trace::DD_TRACE_MANAGED_SERVICES]
174
+ return true if dd_trace_managed_services.nil?
175
+
176
+ dd_trace_managed_services.downcase == 'true'
177
+ end
178
+
169
179
  def self.initialize_listener
170
180
  handler = ENV['_HANDLER'].nil? ? 'handler' : ENV['_HANDLER']
171
181
  function = ENV['AWS_LAMBDA_FUNCTION_NAME']
@@ -176,10 +186,18 @@ module Datadog
176
186
  Datadog::Utils.logger.debug("Setting merge traces #{merge_xray_traces}")
177
187
  end
178
188
 
179
- Trace::Listener.new(handler_name: handler,
180
- function_name: function,
181
- patch_http: @patch_http,
182
- merge_xray_traces: merge_xray_traces)
189
+ # Only initialize listener if Tracing enabled.
190
+ unless Datadog::Tracing.enabled?
191
+ Datadog::Utils.logger.debug 'dd-trace unavailable'
192
+ return nil
193
+ end
194
+
195
+ Trace::Listener.new(
196
+ handler_name: handler,
197
+ function_name: function,
198
+ patch_http: @patch_http,
199
+ merge_xray_traces: merge_xray_traces
200
+ )
183
201
  end
184
202
  end
185
203
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog-lambda
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.20.0
4
+ version: 2.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-08 00:00:00.000000000 Z
11
+ date: 2023-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-xray-sdk
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.12.0
47
+ version: 1.17.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.12.0
54
+ version: 1.17.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement