datadog-lambda 2.20.0 → 2.21.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 +4 -4
- data/lib/datadog/lambda/trace/constants.rb +1 -0
- data/lib/datadog/lambda/trace/listener.rb +12 -13
- data/lib/datadog/lambda/utils/extension.rb +41 -11
- data/lib/datadog/lambda/version.rb +1 -1
- data/lib/datadog/lambda.rb +32 -14
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c867a4e0858e0ba773829993e4c60b2d84b26f8afe4e69a766ac75f6ef454c5
|
4
|
+
data.tar.gz: feaa85e2d5d998b32602b74958792a656f692eab4950fdc7da0cccb7d12542bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd5062d00ae5f88a8c5021f6c76c3b87fa9236d035508e04dbd33113cf51a5b7bec006060ab6dc12ea27da46feaf78ae3eb98d9bd4c907b5a972c7176ca40ee7
|
7
|
+
data.tar.gz: 823cc2efc44cfefd3e0829ca038e966f6b999fd5c2648131a91a2b8b805dbd8ae5aeb5cdba1c14d3c8579aafffb719679b8e1bdd60306f37c80c3bc176f154d2
|
@@ -20,6 +20,7 @@ module Datadog
|
|
20
20
|
DD_XRAY_SUBSEGMENT_NAME = 'datadog-metadata'
|
21
21
|
DD_XRAY_SUBSEGMENT_KEY = 'trace'
|
22
22
|
DD_XRAY_SUBSEGMENT_NAMESPACE = 'datadog'
|
23
|
+
DD_TRACE_MANAGED_SERVICES = 'DD_TRACE_MANAGED_SERVICES'
|
23
24
|
SOURCE_XRAY = 'XRAY'
|
24
25
|
SOURCE_EVENT = 'EVENT'
|
25
26
|
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
|
-
|
29
|
-
|
30
|
-
|
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,14 @@ 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::
|
52
|
-
|
53
|
-
|
45
|
+
@trace = Datadog::Tracing.trace('aws.lambda', **options)
|
46
|
+
Datadog::Utils.send_start_invocation_request(event: event)
|
47
|
+
end
|
48
|
+
# rubocop:enable Metrics/AbcSize
|
49
|
+
|
50
|
+
def on_end(response:)
|
51
|
+
Datadog::Utils.send_end_invocation_request(response: response)
|
52
|
+
@trace&.finish
|
54
53
|
end
|
55
54
|
|
56
55
|
private
|
@@ -12,12 +12,14 @@ require 'net/http'
|
|
12
12
|
module Datadog
|
13
13
|
# Utils contains utility functions shared between modules
|
14
14
|
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
15
|
EXTENSION_PATH = '/opt/extensions/datadog-agent'
|
16
|
+
EXTENSION_BASE_URL = 'http://127.0.0.1:8124'
|
19
17
|
|
20
|
-
|
18
|
+
START_INVOCATION_PATH = '/lambda/start-invocation'
|
19
|
+
END_INVOCATION_PATH = '/lambda/end-invocation'
|
20
|
+
|
21
|
+
START_INVOCATION_URI = URI(EXTENSION_BASE_URL + START_INVOCATION_PATH).freeze
|
22
|
+
END_INVOCATION_URI = URI(EXTENSION_BASE_URL + END_INVOCATION_PATH).freeze
|
21
23
|
|
22
24
|
def self.extension_running?
|
23
25
|
return @is_extension_running unless @is_extension_running.nil?
|
@@ -26,16 +28,44 @@ module Datadog
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def self.check_extension_running
|
29
|
-
|
31
|
+
File.exist?(EXTENSION_PATH)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.send_start_invocation_request(event:)
|
35
|
+
return unless extension_running?
|
30
36
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
response = Net::HTTP.post(START_INVOCATION_URI, event.to_json, request_headers)
|
38
|
+
|
39
|
+
trace_digest = Tracing::Propagation::HTTP.extract(response)
|
40
|
+
# Only continue trace from a new one if it exist, or else,
|
41
|
+
# it will create a new trace, which is not ideal here.
|
42
|
+
Tracing.continue_trace!(trace_digest) if trace_digest
|
43
|
+
rescue StandardError => e
|
44
|
+
Datadog::Utils.logger.debug "failed on start invocation request to extension: #{e}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.send_end_invocation_request(response:)
|
48
|
+
return unless extension_running?
|
49
|
+
|
50
|
+
request = Net::HTTP::Post.new(END_INVOCATION_URI)
|
51
|
+
request.body = response.to_json
|
52
|
+
request[Datadog::Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST] = 1
|
53
|
+
|
54
|
+
trace = Datadog::Tracing.active_trace
|
55
|
+
Tracing::Propagation::HTTP.inject!(trace, request)
|
56
|
+
Net::HTTP.start(END_INVOCATION_URI.host, END_INVOCATION_URI.port) do |http|
|
57
|
+
http.request(request)
|
36
58
|
end
|
59
|
+
rescue StandardError => e
|
60
|
+
Datadog::Utils.logger.debug "failed on end invocation request to extension: #{e}"
|
61
|
+
end
|
37
62
|
|
38
|
-
|
63
|
+
def self.request_headers
|
64
|
+
{
|
65
|
+
# Header used to avoid tracing requests that are internal to
|
66
|
+
# Datadog products.
|
67
|
+
Datadog::Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST.to_sym => 'true'
|
68
|
+
}
|
39
69
|
end
|
40
70
|
end
|
41
71
|
end
|
data/lib/datadog/lambda.rb
CHANGED
@@ -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 '
|
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
|
-
|
62
|
-
|
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
|
70
|
+
@listener&.on_end(response: @response)
|
69
71
|
@is_cold_start = false
|
70
72
|
@metrics_client.close
|
71
73
|
end
|
72
|
-
|
74
|
+
@response
|
73
75
|
end
|
74
76
|
|
75
77
|
# Gets the current tracing context
|
76
78
|
def self.trace_context
|
77
|
-
|
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
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
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.
|
4
|
+
version: 2.21.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-
|
11
|
+
date: 2023-10-16 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.
|
47
|
+
version: 1.15.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.
|
54
|
+
version: 1.15.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|