Skip to content

Commit 5074cee

Browse files
Add request-id as header to start/end invocation (#129)
* Adding aws request id to headers on start and end invocation requests * linted * unbroke unit tests * added request id to expected headers in start invocation request unit tests * adding logs * fixed assignment to headers in send start invocation
1 parent 878d785 commit 5074cee

File tree

4 files changed

+31
-14
lines changed

4 files changed

+31
-14
lines changed

lib/datadog/lambda.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def self.wrap(event, context, &block)
6666
record_enhanced('errors', context)
6767
raise e
6868
ensure
69-
@listener&.on_end(response: @response)
69+
@listener&.on_end(response: @response, request_context: context)
7070
@is_cold_start = false
7171
@metrics_client.close
7272
end

lib/datadog/lambda/trace/listener.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def on_start(event:, request_context:, cold_start:)
4242
options[:service] = 'aws.lambda'
4343
options[:type] = 'serverless'
4444

45-
trace_digest = Datadog::Utils.send_start_invocation_request(event:)
45+
trace_digest = Datadog::Utils.send_start_invocation_request(event:, request_context:)
4646
# Only continue trace from a new one if it exist, or else,
4747
# it will create a new trace, which is not ideal here.
4848
options[:continue_from] = trace_digest if trace_digest
@@ -53,8 +53,8 @@ def on_start(event:, request_context:, cold_start:)
5353
end
5454
# rubocop:enable Metrics/AbcSize
5555

56-
def on_end(response:)
57-
Datadog::Utils.send_end_invocation_request(response:, span_id: @trace.id)
56+
def on_end(response:, request_context:)
57+
Datadog::Utils.send_end_invocation_request(response:, span_id: @trace.id, request_context:)
5858
@trace&.finish
5959
end
6060

lib/datadog/lambda/utils/extension.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module Utils
2222
DD_SPAN_ID_HEADER = 'x-datadog-span-id'
2323
DD_PARENT_ID_HEADER = Datadog::Tracing::Distributed::Datadog::PARENT_ID_KEY
2424

25+
LAMBDA_RUNTIME_AWS_REQUEST_HEADER_ID = 'lambda-runtime-aws-request-id'
26+
2527
START_INVOCATION_URI = URI(EXTENSION_BASE_URL + START_INVOCATION_PATH).freeze
2628
END_INVOCATION_URI = URI(EXTENSION_BASE_URL + END_INVOCATION_PATH).freeze
2729

@@ -40,10 +42,13 @@ def self.check_extension_running
4042
File.exist?(EXTENSION_PATH)
4143
end
4244

43-
def self.send_start_invocation_request(event:)
45+
def self.send_start_invocation_request(event:, request_context:)
4446
return unless extension_running?
4547

46-
response = Net::HTTP.post(START_INVOCATION_URI, event.to_json, request_headers)
48+
headers = request_headers
49+
headers[LAMBDA_RUNTIME_AWS_REQUEST_HEADER_ID] = request_context.aws_request_id
50+
response = Net::HTTP.post(START_INVOCATION_URI, event.to_json, headers)
51+
4752
# Add origin, since tracer expects it for extraction
4853
response[Datadog::Trace::DD_ORIGIN] = 'lambda'
4954

@@ -53,7 +58,7 @@ def self.send_start_invocation_request(event:)
5358
end
5459

5560
# rubocop:disable Metrics/AbcSize
56-
def self.send_end_invocation_request(response:, span_id:)
61+
def self.send_end_invocation_request(response:, span_id:, request_context:)
5762
return unless extension_running?
5863

5964
request = Net::HTTP::Post.new(END_INVOCATION_URI)
@@ -66,6 +71,9 @@ def self.send_end_invocation_request(response:, span_id:)
6671
# Propagator doesn't inject span_id, so we do it manually
6772
# It is needed for the extension to take this span id
6873
request[DD_SPAN_ID_HEADER] = span_id.to_s
74+
75+
request[LAMBDA_RUNTIME_AWS_REQUEST_HEADER_ID] = request_context.aws_request_id
76+
6977
# Remove Parent ID if it is the same as the Span ID
7078
request.delete(DD_PARENT_ID_HEADER) if request[DD_PARENT_ID_HEADER] == span_id.to_s
7179
Datadog::Utils.logger.debug "End invocation request headers: #{request.to_hash}"

test/datadog/lambda/utils/extension.spec.rb

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
require 'datadog/lambda'
66
require 'net/http'
7+
require_relative '../../lambdacontextversion'
78

89
describe Datadog::Utils do
910
let(:headers) do
@@ -25,6 +26,7 @@
2526

2627
describe '#send_start_invocation_request' do
2728
context 'when extension is running' do
29+
ctx = LambdaContextVersion.new
2830
before(:each) do
2931
# Stub the extension_running? method to return true
3032
allow(Datadog::Utils).to receive(:extension_running?).and_return(true)
@@ -39,11 +41,13 @@
3941

4042
it 'applies trace context from extension' do
4143
# Stub POST request to return a trace context
44+
all_headers = Datadog::Utils.request_headers
45+
all_headers['lambda-runtime-aws-request-id'] = ctx.aws_request_id
4246
expect(Net::HTTP).to receive(:post)
43-
.with(Datadog::Utils::START_INVOCATION_URI, 'null', Datadog::Utils.request_headers) { headers }
47+
.with(Datadog::Utils::START_INVOCATION_URI, 'null', all_headers) { headers }
4448

4549
# Call the start request with an empty event
46-
digest = Datadog::Utils.send_start_invocation_request(event: nil)
50+
digest = Datadog::Utils.send_start_invocation_request(event: nil, request_context: ctx)
4751

4852
expect(digest.trace_id.to_s).to eq('4110911582297405557')
4953
expect(digest.span_id.to_s).to eq('797643193680388254')
@@ -52,11 +56,13 @@
5256

5357
it 'skips applying trace context when headers are not present' do
5458
# Stub POST request to return a trace context
59+
all_headers = Datadog::Utils.request_headers
60+
all_headers['lambda-runtime-aws-request-id'] = ctx.aws_request_id
5561
expect(Net::HTTP).to receive(:post)
56-
.with(Datadog::Utils::START_INVOCATION_URI, 'null', Datadog::Utils.request_headers) { {} }
62+
.with(Datadog::Utils::START_INVOCATION_URI, 'null', all_headers) { {} }
5763

5864
# Call the start request with an empty event
59-
Datadog::Utils.send_start_invocation_request(event: nil)
65+
Datadog::Utils.send_start_invocation_request(event: nil, request_context: ctx)
6066

6167
digest = Datadog::Tracing.active_trace.to_digest
6268

@@ -66,15 +72,17 @@
6672
end
6773

6874
context 'when extension is not running' do
75+
ctx = LambdaContextVersion.new
6976
it 'does nothing' do
70-
result = Datadog::Utils.send_start_invocation_request(event: nil)
77+
result = Datadog::Utils.send_start_invocation_request(event: nil, request_context: ctx)
7178
expect(result).to eq(nil)
7279
end
7380
end
7481
end
7582

7683
describe '#send_end_invocation_request' do
7784
context 'when extension is running' do
85+
ctx = LambdaContextVersion.new
7886
before(:each) do
7987
# Stub the extension_running? method to return true
8088
allow(Datadog::Utils).to receive(:extension_running?).and_return(true)
@@ -92,13 +100,14 @@
92100
allow(Net::HTTP).to receive(:post) { nil }
93101

94102
# Call the start request with an empty event
95-
Datadog::Utils.send_end_invocation_request(response: nil, span_id: nil)
103+
Datadog::Utils.send_end_invocation_request(response: nil, span_id: nil, request_context: ctx)
96104
end
97105
end
98106

99107
context 'when extension is not running' do
108+
ctx = LambdaContextVersion.new
100109
it 'does nothing' do
101-
result = Datadog::Utils.send_end_invocation_request(response: nil, span_id: nil)
110+
result = Datadog::Utils.send_end_invocation_request(response: nil, span_id: nil, request_context: ctx)
102111
expect(result).to eq(nil)
103112
end
104113
end

0 commit comments

Comments
 (0)