From b4fbcb2326b698c2713d025e5d0af97571107b03 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Thu, 30 Apr 2026 20:07:32 +0200 Subject: [PATCH 1/7] Add AppSec integration for AWS Lambda Initialize AppSec context around each Lambda invocation, push request and response events through the AppSec gateway, and record security events on the aws.lambda span. The extension handles tag propagation to inferred spans. Co-Authored-By: Claude Opus 4.6 (1M context) --- .rubocop.yml | 2 + Dockerfile | 7 + integration_tests/appsec_request.rb | 19 ++ .../api-gateway-appsec-blocking.json | 31 +++ .../input_events/api-gateway-appsec.json | 31 +++ integration_tests/serverless.yml | 12 + lib/datadog/lambda.rb | 10 +- lib/datadog/lambda/appsec.rb | 100 +++++++ lib/datadog/lambda/appsec/request.rb | 47 ++++ lib/datadog/lambda/trace/listener.rb | 9 + scripts/run_integration_tests.sh | 2 +- test/datadog/lambda/appsec.spec.rb | 263 ++++++++++++++++++ test/datadog/lambda/appsec/request.spec.rb | 63 +++++ 13 files changed, 594 insertions(+), 2 deletions(-) create mode 100644 integration_tests/appsec_request.rb create mode 100644 integration_tests/input_events/api-gateway-appsec-blocking.json create mode 100644 integration_tests/input_events/api-gateway-appsec.json create mode 100644 lib/datadog/lambda/appsec.rb create mode 100644 lib/datadog/lambda/appsec/request.rb create mode 100644 test/datadog/lambda/appsec.spec.rb create mode 100644 test/datadog/lambda/appsec/request.spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index 2d9f108b..64ecb10b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,7 @@ AllCops: TargetRubyVersion: 3.2 + Exclude: + - 'test/**/*' Metrics/MethodLength: Max: 20 diff --git a/Dockerfile b/Dockerfile index cbf0f769..38b1efb0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,6 +41,13 @@ RUN gem uninstall ffi --all --ignore-dependencies --executables --force \ RUN MAKEFLAGS="-j$(nproc)" \ gem install ffi --platform ruby --install-dir "/opt/ruby/gems/$runtime" --no-document +# Recompile FFI from source — precompiled binaries have glibc mismatch with Lambda AL2 +# NOTE: runs after datadog gem as a defensive measure — force-replaces whatever +# transitive FFI variant was pulled, regardless of version resolution. +RUN gem install ffi --platform ruby --force --install-dir "/opt/ruby/gems/$runtime" --no-document +RUN rm -rf /opt/ruby/gems/$runtime/gems/ffi-*-*-linux-* \ + /opt/ruby/gems/$runtime/specifications/ffi-*-*-linux-*.gemspec + WORKDIR /opt # Remove native extension debase-ruby_core_source (25MB) runtimes below Ruby 2.6 RUN rm -rf ./ruby/gems/$runtime/gems/debase-ruby_core_source*/ diff --git a/integration_tests/appsec_request.rb b/integration_tests/appsec_request.rb new file mode 100644 index 00000000..9b510909 --- /dev/null +++ b/integration_tests/appsec_request.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'datadog/lambda' + +Datadog::Lambda.configure_apm do |c| + c.appsec.enabled = true +end + +def handle(event:, context:) + Datadog::Lambda.wrap(event, context) do + Datadog::Lambda.metric('serverless.integration_test.execution', 1, function: 'appsec-request') + + { + 'statusCode' => 200, + 'message' => 'hello, dog!', + 'eventType' => 'APIGateway' + } + end +end diff --git a/integration_tests/input_events/api-gateway-appsec-blocking.json b/integration_tests/input_events/api-gateway-appsec-blocking.json new file mode 100644 index 00000000..b6f94900 --- /dev/null +++ b/integration_tests/input_events/api-gateway-appsec-blocking.json @@ -0,0 +1,31 @@ +{ + "path": "/test/hello", + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", + "X-Forwarded-For": "192.168.100.1, 192.168.1.1", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "pathParameters": { + "proxy": "hello" + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "us4z18", + "stage": "test", + "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", + "identity": { + "sourceIp": "192.168.100.1" + }, + "resourcePath": "/{proxy+}", + "httpMethod": "GET", + "apiId": "wt6mne2s9k" + }, + "resource": "/{proxy+}", + "httpMethod": "GET", + "queryStringParameters": { + "q": "1' OR '1'='1" + }, + "stageVariables": null +} diff --git a/integration_tests/input_events/api-gateway-appsec.json b/integration_tests/input_events/api-gateway-appsec.json new file mode 100644 index 00000000..f369c564 --- /dev/null +++ b/integration_tests/input_events/api-gateway-appsec.json @@ -0,0 +1,31 @@ +{ + "path": "/test/hello", + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", + "User-Agent": "Arachni/v1.0", + "X-Forwarded-For": "192.168.100.1, 192.168.1.1", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "pathParameters": { + "proxy": "hello" + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "us4z18", + "stage": "test", + "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", + "identity": { + "sourceIp": "192.168.100.1", + "userAgent": "Arachni/v1.0" + }, + "resourcePath": "/{proxy+}", + "httpMethod": "GET", + "apiId": "wt6mne2s9k" + }, + "resource": "/{proxy+}", + "httpMethod": "GET", + "queryStringParameters": null, + "stageVariables": null +} diff --git a/integration_tests/serverless.yml b/integration_tests/serverless.yml index ec15e1a8..e87bf86c 100644 --- a/integration_tests/serverless.yml +++ b/integration_tests/serverless.yml @@ -60,3 +60,15 @@ functions: - { Ref: RubyLambdaLayer } environment: DD_FLUSH_TO_LOG: true + + # appsec-request + appsec-request_ruby: + name: integration-tests-rb-${sls:stage}-appsec-request_${env:RUNTIME} + handler: appsec_request.handle + runtime: ${env:SERVERLESS_RUNTIME} + memorySize: 1024 + layers: + - { Ref: RubyLambdaLayer } + environment: + DD_FLUSH_TO_LOG: true + DD_APPSEC_ENABLED: true diff --git a/lib/datadog/lambda.rb b/lib/datadog/lambda.rb index 4eee6d42..604c3856 100644 --- a/lib/datadog/lambda.rb +++ b/lib/datadog/lambda.rb @@ -29,6 +29,8 @@ module Lambda # Configures Datadog's APM tracer with lambda specific defaults. # Same options can be given as Datadog.configure in tracer # See https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md#quickstart-for-ruby-applications + # + # rubocop:disable Metrics/AbcSize def self.configure_apm require 'datadog/tracing' require 'datadog/tracing/transport/io' @@ -48,30 +50,36 @@ def self.configure_apm c.tracing.instrument :aws if trace_managed_services? yield(c) if block_given? + + c.appsec.instrument(:aws_lambda) end end + # rubocop:enable Metrics/AbcSize # Wrap the body of a lambda invocation # @param event [Object] event sent to lambda # @param context [Object] lambda context # @param block [Proc] implementation of the handler function. + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def self.wrap(event, context, &block) @listener ||= initialize_listener record_enhanced('invocations', context) begin cold = @is_cold_start @listener&.on_start(event:, request_context: context, cold_start: cold) - @response = block.call + @response = @listener&.response_override || block.call rescue StandardError => e record_enhanced('errors', context) raise e ensure @listener&.on_end(response: @response, request_context: context) + @response = @listener&.response_override || @response @is_cold_start = false @metrics_client.close end @response end + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity # Gets the current tracing context def self.trace_context diff --git a/lib/datadog/lambda/appsec.rb b/lib/datadog/lambda/appsec.rb new file mode 100644 index 00000000..93a5d5d8 --- /dev/null +++ b/lib/datadog/lambda/appsec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require_relative 'appsec/request' + +module Datadog + module Lambda + # AppSec integration for AWS Lambda invocations. + module AppSec + class << self + def on_start(event, trace:, span:) + @request = nil + return unless enabled? + + context = create_context(trace, span) + return unless Datadog::AppSec::Context.active + + @request = Request.from_event(event) + + payload = Datadog::AppSec::Instrumentation::Gateway::DataContainer.new( + event, context: context + ) + + interrupt_params = catch(Datadog::AppSec::Ext::INTERRUPT) do + Datadog::AppSec::Instrumentation.gateway.push('aws_lambda.request.start', payload) + nil + end + + return unless interrupt_params + + context.mark_as_interrupted! + response_override(interrupt_params, headers: @request.headers) + rescue StandardError => e + Datadog::Utils.logger.debug("failed to start AppSec: #{e}") + end + + def on_finish(response) + return unless enabled? + + context = Datadog::AppSec::Context.active + return unless context + + payload = Datadog::AppSec::Instrumentation::Gateway::DataContainer.new( + response, context: context + ) + + interrupt_params = catch(Datadog::AppSec::Ext::INTERRUPT) do + Datadog::AppSec::Instrumentation.gateway.push('aws_lambda.response.start', payload) + nil + end + + context.mark_as_interrupted! if interrupt_params + + Datadog::AppSec::Event.record(context, request: @request) + context.export_metrics + context.export_request_telemetry + + response_override(interrupt_params, headers: @request.headers) if interrupt_params + rescue StandardError => e + Datadog::Utils.logger.debug "failed to finish AppSec: #{e}" + ensure + Datadog::AppSec::Context.deactivate if context + end + + private + + def enabled? + defined?(Datadog::AppSec) && + Datadog::AppSec.respond_to?(:enabled?) && + Datadog::AppSec.enabled? + end + + def create_context(trace, span) + return if trace.nil? || span.nil? + + security_engine = Datadog::AppSec.security_engine + return unless security_engine + + context = Datadog::AppSec::Context.new(trace, span, security_engine.new_runner) + Datadog::AppSec::Context.activate(context) + + span.set_metric(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, 1) + + context + end + + def response_override(interrupt_params, headers:) + response = Datadog::AppSec::Response.from_interrupt_params( + interrupt_params, headers['accept'] + ) + + { + 'statusCode' => response.status, + 'headers' => response.headers, + 'body' => response.body.join + } + end + end + end + end +end diff --git a/lib/datadog/lambda/appsec/request.rb b/lib/datadog/lambda/appsec/request.rb new file mode 100644 index 00000000..c74d55a9 --- /dev/null +++ b/lib/datadog/lambda/appsec/request.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Datadog + module Lambda + module AppSec + # Minimal request object for AppSec event recording. + # + # WARNING: It's a minimal data for interface compliance + # + # @see Datadog::AppSec::Event.record + # @see Datadog::AppSec::Contrib::Rack::Gateway::Request + class Request + attr_reader :host, :user_agent, :remote_addr, :headers + + class << self + def from_event(event) + headers = normalize_headers(event) + remote_addres = event.dig('requestContext', 'identity', 'sourceIp') || + event.dig('requestContext', 'http', 'sourceIp') + + new( + host: headers['host'], + user_agent: headers['user-agent'], + remote_addr: remote_addres, + headers: headers + ) + end + + private + + def normalize_headers(event) + event.fetch('headers', {}).each_with_object({}) do |(key, value), hash| + hash[key.downcase] = value + end + end + end + + def initialize(host:, user_agent:, remote_addr:, headers:) + @host = host + @user_agent = user_agent + @remote_addr = remote_addr + @headers = headers + end + end + end + end +end diff --git a/lib/datadog/lambda/trace/listener.rb b/lib/datadog/lambda/trace/listener.rb index e4ac5640..89c1b4b6 100644 --- a/lib/datadog/lambda/trace/listener.rb +++ b/lib/datadog/lambda/trace/listener.rb @@ -11,11 +11,16 @@ require 'datadog/lambda/trace/context' require 'datadog/lambda/trace/patch_http' require 'datadog/lambda/trace/ddtrace' +require 'datadog/lambda/appsec' module Datadog module Trace # TraceListener tracks tracing context information class Listener + # AppSec blocking response that replaces the handler result. + # Set during either on_start or on_end when WAF decides to block. + attr_reader :response_override + @trace = nil def initialize(handler_name:, function_name:, patch_http:, merge_xray_traces:) @@ -50,10 +55,14 @@ def on_start(event:, request_context:, cold_start:) @trace = Datadog::Tracing.trace('aws.lambda', **options) Datadog::Trace.apply_datadog_trace_context(Datadog::Trace.trace_context) + @response_override = Datadog::Lambda::AppSec.on_start( + event, trace: Datadog::Tracing.active_trace, span: @trace + ) end # rubocop:enable Metrics/AbcSize def on_end(response:, request_context:) + @response_override = Datadog::Lambda::AppSec.on_finish(response) Datadog::Utils.send_end_invocation_request(response:, span_id: @trace.id, request_context:) @trace&.finish end diff --git a/scripts/run_integration_tests.sh b/scripts/run_integration_tests.sh index 6bbf594a..b39088c5 100755 --- a/scripts/run_integration_tests.sh +++ b/scripts/run_integration_tests.sh @@ -10,7 +10,7 @@ set -e # These values need to be in sync with serverless.yml, where there needs to be a function # defined for every handler_runtime combination -LAMBDA_HANDLERS=("async-metrics" "sync-metrics" "http-requests" "process-input-traced") +LAMBDA_HANDLERS=("async-metrics" "sync-metrics" "http-requests" "process-input-traced" "appsec-request") RUNTIMES=("ruby32" "ruby33" "ruby34" "ruby40") LOGS_WAIT_SECONDS=45 diff --git a/test/datadog/lambda/appsec.spec.rb b/test/datadog/lambda/appsec.spec.rb new file mode 100644 index 00000000..30f9c15d --- /dev/null +++ b/test/datadog/lambda/appsec.spec.rb @@ -0,0 +1,263 @@ +# frozen_string_literal: true + +require 'datadog/lambda' +require 'datadog/lambda/appsec' + +RSpec.describe Datadog::Lambda::AppSec do + before do + allow(Datadog::AppSec::Instrumentation).to receive(:gateway).and_return(gateway) + allow(gateway).to receive(:push) + end + + let(:gateway) { instance_double(Datadog::AppSec::Instrumentation::Gateway) } + let(:appsec_context) do + instance_double( + Datadog::AppSec::Context, + span: instance_double(Datadog::Tracing::SpanOperation, get_tag: nil, get_metric: nil), + state: {}, + export_metrics: nil, + export_request_telemetry: nil + ) + end + + describe '.on_start' do + subject(:on_start) { described_class.on_start(event, trace: trace, span: span) } + + let(:event) { { 'httpMethod' => 'GET', 'path' => '/' } } + let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } + let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil) } + + context 'when appsec is disabled' do + before { allow(Datadog::AppSec).to receive(:enabled?).and_return(false) } + + it 'does not push to gateway' do + on_start + + expect(gateway).not_to have_received(:push) + end + end + + context 'when appsec is enabled' do + before do + allow(Datadog::AppSec).to receive(:enabled?).and_return(true) + allow(Datadog::AppSec).to receive(:security_engine).and_return(security_engine) + allow(Datadog::AppSec::Context).to receive(:activate) + allow(Datadog::AppSec::Context).to receive(:active).and_return(appsec_context) + end + + let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } + let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner) } + + it 'marks span as appsec-enabled' do + on_start + + expect(span).to have_received(:set_metric).with(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, 1) + end + + it 'pushes event to gateway' do + on_start + + expect(gateway).to have_received(:push).with( + 'aws_lambda.request.start', kind_of(Datadog::AppSec::Instrumentation::Gateway::DataContainer) + ) + end + + context 'when security_engine is nil' do + before do + allow(Datadog::AppSec).to receive(:security_engine).and_return(nil) + allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) + end + + it 'skips context activation and gateway push' do + on_start + + aggregate_failures('skipped activation') do + expect(Datadog::AppSec::Context).not_to have_received(:activate) + expect(gateway).not_to have_received(:push) + end + end + end + + context 'when trace is nil' do + subject(:on_start) { described_class.on_start(event, trace: nil, span: span) } + + before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } + + it 'skips context activation and gateway push' do + on_start + + aggregate_failures('skipped activation') do + expect(Datadog::AppSec::Context).not_to have_received(:activate) + expect(gateway).not_to have_received(:push) + end + end + end + + context 'when span is nil' do + subject(:on_start) { described_class.on_start(event, trace: trace, span: nil) } + + before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } + + it 'skips context activation and gateway push' do + on_start + + aggregate_failures('skipped activation') do + expect(Datadog::AppSec::Context).not_to have_received(:activate) + expect(gateway).not_to have_received(:push) + end + end + end + + context 'when gateway push triggers a blocking interrupt' do + before do + allow(Datadog::AppSec::Context).to receive(:new).and_return(appsec_context) + allow(appsec_context).to receive(:mark_as_interrupted!) + + allow(gateway).to receive(:push).and_invoke(lambda { |_name, _payload| + throw(Datadog::AppSec::Ext::INTERRUPT, {'status_code' => 403, 'type' => 'auto'}) + }) + end + + it 'returns a Lambda-shaped blocking response' do + expect(on_start).to include( + 'statusCode' => 403, + 'headers' => {'Content-Type' => 'application/json'}, + 'body' => include('blocked') + ) + end + end + + context 'when an error occurs' do + before { allow(Datadog::AppSec::Context).to receive(:new).and_raise(StandardError, 'boom') } + + it { expect { on_start }.not_to raise_error } + end + end + end + + describe '.on_finish' do + subject(:on_finish) { described_class.on_finish(response) } + + let(:response) { { 'statusCode' => 200 } } + + context 'when appsec is disabled' do + before do + allow(Datadog::AppSec).to receive(:enabled?).and_return(false) + allow(Datadog::AppSec::Context).to receive(:active).and_return(appsec_context) + end + + it 'does not push to gateway' do + on_finish + + expect(gateway).not_to have_received(:push) + end + end + + context 'when no active context exists' do + before do + allow(Datadog::AppSec).to receive(:enabled?).and_return(true) + allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) + end + + it 'does not push to gateway' do + on_finish + + expect(gateway).not_to have_received(:push) + end + end + + context 'when active context exists' do + before do + allow(Datadog::AppSec).to receive(:enabled?).and_return(true) + allow(Datadog::AppSec::Context).to receive(:active).and_return(appsec_context) + allow(Datadog::AppSec::Context).to receive(:deactivate) + allow(Datadog::AppSec::Event).to receive(:record) + end + + it 'pushes response and records events' do + on_finish + + aggregate_failures('response processing') do + expect(gateway).to have_received(:push).with( + 'aws_lambda.response.start', kind_of(Datadog::AppSec::Instrumentation::Gateway::DataContainer) + ) + expect(Datadog::AppSec::Event).to have_received(:record).with(appsec_context, request: nil) + end + end + + it 'exports telemetry and deactivates' do + on_finish + + aggregate_failures('AppSec deactivation') do + expect(appsec_context).to have_received(:export_metrics) + expect(appsec_context).to have_received(:export_request_telemetry) + expect(Datadog::AppSec::Context).to have_received(:deactivate) + end + end + + context 'when a security event occurs' do + before do + allow(Datadog::AppSec).to receive(:security_engine).and_return(security_engine) + allow(Datadog::AppSec::Context).to receive(:activate) + + described_class.on_start(event, trace: trace, span: span) + end + + let(:event) do + { + 'headers' => { 'Host' => 'example.com', 'User-Agent' => 'TestBot' }, + 'requestContext' => { 'identity' => { 'sourceIp' => '1.2.3.4' } } + } + end + let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } + let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil) } + let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } + let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner) } + + it 'records security event with request' do + on_finish + + expect(Datadog::AppSec::Event).to have_received(:record).with( + appsec_context, request: kind_of(Datadog::Lambda::AppSec::Request) + ) + end + end + + context 'when gateway push triggers a blocking interrupt' do + before do + allow(gateway).to receive(:push).and_invoke(lambda { |_name, _payload| + throw(Datadog::AppSec::Ext::INTERRUPT, {'status_code' => 403, 'type' => 'auto'}) + }) + allow(appsec_context).to receive(:mark_as_interrupted!) + end + + it 'returns a Lambda-shaped blocking response' do + expect(on_finish).to include( + 'statusCode' => 403, + 'headers' => {'Content-Type' => 'application/json'} + ) + end + + it 'still records events and deactivates' do + on_finish + + aggregate_failures('cleanup after interrupt') do + expect(Datadog::AppSec::Event).to have_received(:record) + expect(appsec_context).to have_received(:export_metrics) + expect(Datadog::AppSec::Context).to have_received(:deactivate) + end + end + end + + context 'when an error occurs' do + before { allow(gateway).to receive(:push).and_raise(StandardError, 'boom') } + + it 'still deactivates the context' do + on_finish + + expect(Datadog::AppSec::Context).to have_received(:deactivate) + end + end + end + end +end diff --git a/test/datadog/lambda/appsec/request.spec.rb b/test/datadog/lambda/appsec/request.spec.rb new file mode 100644 index 00000000..eaf9524f --- /dev/null +++ b/test/datadog/lambda/appsec/request.spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'datadog/lambda/appsec/request' + +RSpec.describe Datadog::Lambda::AppSec::Request do + subject(:request) { described_class.from_event(event) } + + let(:event) do + { + 'headers' => { 'Host' => 'example.com', 'User-Agent' => 'TestBot/1.0', 'Accept' => 'text/html' }, + 'requestContext' => { + 'identity' => { 'sourceIp' => '10.0.0.1' } + } + } + end + + describe '#headers' do + it 'normalizes header keys to lowercase' do + expect(request.headers).to eq( + 'host' => 'example.com', + 'user-agent' => 'TestBot/1.0', + 'accept' => 'text/html' + ) + end + + context 'when event has no headers' do + let(:event) { { 'requestContext' => {} } } + + it { expect(request.headers).to eq({}) } + end + end + + describe '#host' do + it { expect(request.host).to eq('example.com') } + end + + describe '#user_agent' do + it { expect(request.user_agent).to eq('TestBot/1.0') } + end + + describe '#remote_addr' do + it { expect(request.remote_addr).to eq('10.0.0.1') } + + context 'when event is API Gateway v2 format' do + let(:event) do + { + 'headers' => {}, + 'requestContext' => { + 'http' => { 'sourceIp' => '10.0.0.2' } + } + } + end + + it { expect(request.remote_addr).to eq('10.0.0.2') } + end + + context 'when event has no requestContext' do + let(:event) { { 'headers' => {} } } + + it { expect(request.remote_addr).to be_nil } + end + end +end From 6ebb06b854bc2d6384502e3d7f28a598f7e86770 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Tue, 5 May 2026 11:39:25 +0200 Subject: [PATCH 2/7] Add EventNormalizer for API Gateway v1/v2 events Normalize raw AWS event payloads into a standard key set before passing to DataContainer and Request. This removes v1/v2 detection from Request and aligns with dd-trace-rb's simplified WAFAddresses that consume standard keys. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/datadog/lambda/appsec.rb | 4 +- lib/datadog/lambda/appsec/event_normalizer.rb | 48 +++++++ lib/datadog/lambda/appsec/request.rb | 12 +- test/datadog/lambda/appsec.spec.rb | 5 +- .../lambda/appsec/event_normalizer.spec.rb | 120 ++++++++++++++++++ test/datadog/lambda/appsec/request.spec.rb | 29 +---- 6 files changed, 186 insertions(+), 32 deletions(-) create mode 100644 lib/datadog/lambda/appsec/event_normalizer.rb create mode 100644 test/datadog/lambda/appsec/event_normalizer.spec.rb diff --git a/lib/datadog/lambda/appsec.rb b/lib/datadog/lambda/appsec.rb index 93a5d5d8..be3a50eb 100644 --- a/lib/datadog/lambda/appsec.rb +++ b/lib/datadog/lambda/appsec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative 'appsec/request' +require_relative 'appsec/event_normalizer' module Datadog module Lambda @@ -14,7 +15,8 @@ def on_start(event, trace:, span:) context = create_context(trace, span) return unless Datadog::AppSec::Context.active - @request = Request.from_event(event) + event = EventNormalizer.normalize(event) + @request = Request.from_normalized(event) payload = Datadog::AppSec::Instrumentation::Gateway::DataContainer.new( event, context: context diff --git a/lib/datadog/lambda/appsec/event_normalizer.rb b/lib/datadog/lambda/appsec/event_normalizer.rb new file mode 100644 index 00000000..e05eeb10 --- /dev/null +++ b/lib/datadog/lambda/appsec/event_normalizer.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Datadog + module Lambda + module AppSec + # Normalizes API Gateway v1/v2 event payloads into a standard key set. + module EventNormalizer + module_function + + def normalize(event) + event.key?('httpMethod') ? normalize_v1(event) : normalize_v2(event) + end + + def normalize_v1(event) + data = { + 'method' => event['httpMethod'], + 'path' => event['path'], + 'headers' => event['headers'], + 'query' => event['multiValueQueryStringParameters'] || event['queryStringParameters'], + 'source_ip' => event.dig('requestContext', 'identity', 'sourceIp'), + 'body' => event['body'], + 'base64_encoded' => event['isBase64Encoded'], + 'path_params' => event['pathParameters'] + } + data.compact! + data + end + + def normalize_v2(event) + data = { + 'method' => event.dig('requestContext', 'http', 'method'), + 'path' => event['rawPath'], + 'headers' => event['headers'], + 'cookies' => event['cookies'], + 'query' => event['queryStringParameters'], + 'query_string' => event['rawQueryString'], + 'source_ip' => event.dig('requestContext', 'http', 'sourceIp'), + 'body' => event['body'], + 'base64_encoded' => event['isBase64Encoded'], + 'path_params' => event['pathParameters'] + } + data.compact! + data + end + end + end + end +end diff --git a/lib/datadog/lambda/appsec/request.rb b/lib/datadog/lambda/appsec/request.rb index c74d55a9..42926f29 100644 --- a/lib/datadog/lambda/appsec/request.rb +++ b/lib/datadog/lambda/appsec/request.rb @@ -13,23 +13,21 @@ class Request attr_reader :host, :user_agent, :remote_addr, :headers class << self - def from_event(event) - headers = normalize_headers(event) - remote_addres = event.dig('requestContext', 'identity', 'sourceIp') || - event.dig('requestContext', 'http', 'sourceIp') + def from_normalized(event) + headers = lowercase_headers(event) new( host: headers['host'], user_agent: headers['user-agent'], - remote_addr: remote_addres, + remote_addr: event['source_ip'], headers: headers ) end private - def normalize_headers(event) - event.fetch('headers', {}).each_with_object({}) do |(key, value), hash| + def lowercase_headers(event) + (event['headers'] || {}).each_with_object({}) do |(key, value), hash| hash[key.downcase] = value end end diff --git a/test/datadog/lambda/appsec.spec.rb b/test/datadog/lambda/appsec.spec.rb index 30f9c15d..19ddda17 100644 --- a/test/datadog/lambda/appsec.spec.rb +++ b/test/datadog/lambda/appsec.spec.rb @@ -205,8 +205,9 @@ let(:event) do { - 'headers' => { 'Host' => 'example.com', 'User-Agent' => 'TestBot' }, - 'requestContext' => { 'identity' => { 'sourceIp' => '1.2.3.4' } } + 'httpMethod' => 'GET', + 'headers' => {'Host' => 'example.com', 'User-Agent' => 'TestBot'}, + 'requestContext' => {'identity' => {'sourceIp' => '1.2.3.4'}}, } end let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } diff --git a/test/datadog/lambda/appsec/event_normalizer.spec.rb b/test/datadog/lambda/appsec/event_normalizer.spec.rb new file mode 100644 index 00000000..2a421b09 --- /dev/null +++ b/test/datadog/lambda/appsec/event_normalizer.spec.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true + +require 'datadog/lambda/appsec/event_normalizer' + +RSpec.describe Datadog::Lambda::AppSec::EventNormalizer do + describe '.normalize' do + subject(:result) { described_class.normalize(event) } + + context 'when event is API Gateway v1' do + let(:event) do + { + 'httpMethod' => 'POST', + 'path' => '/users/123', + 'headers' => {'Host' => 'example.com', 'Cookie' => 'session=abc'}, + 'queryStringParameters' => {'page' => '1'}, + 'multiValueQueryStringParameters' => {'page' => ['1']}, + 'pathParameters' => {'id' => '123'}, + 'body' => '{"name":"john"}', + 'isBase64Encoded' => false, + 'requestContext' => {'identity' => {'sourceIp' => '10.0.0.1'}}, + } + end + + it { expect(result['method']).to eq('POST') } + it { expect(result['path']).to eq('/users/123') } + it { expect(result['headers']).to eq('Host' => 'example.com', 'Cookie' => 'session=abc') } + it { expect(result['query']).to eq('page' => ['1']) } + it { expect(result['source_ip']).to eq('10.0.0.1') } + it { expect(result['body']).to eq('{"name":"john"}') } + it { expect(result['base64_encoded']).to eq(false) } + it { expect(result['path_params']).to eq('id' => '123') } + it { expect(result).not_to have_key('cookies') } + it { expect(result).not_to have_key('query_string') } + end + + context 'when event is API Gateway v1 without multiValueQueryStringParameters' do + let(:event) do + { + 'httpMethod' => 'GET', + 'path' => '/health', + 'headers' => {}, + 'queryStringParameters' => {'page' => '1'}, + 'requestContext' => {'identity' => {}}, + } + end + + it { expect(result['query']).to eq('page' => '1') } + end + + context 'when event is API Gateway v2' do + let(:event) do + { + 'rawPath' => '/users/123', + 'rawQueryString' => 'page=1&sort=asc', + 'queryStringParameters' => {'page' => '1', 'sort' => 'asc'}, + 'headers' => {'host' => 'example.com'}, + 'cookies' => ['session=abc', 'theme=dark'], + 'pathParameters' => {'id' => '123'}, + 'body' => 'hello', + 'isBase64Encoded' => false, + 'requestContext' => {'http' => {'method' => 'GET', 'sourceIp' => '10.0.0.2'}}, + } + end + + it { expect(result['method']).to eq('GET') } + it { expect(result['path']).to eq('/users/123') } + it { expect(result['headers']).to eq('host' => 'example.com') } + it { expect(result['cookies']).to eq(['session=abc', 'theme=dark']) } + it { expect(result['query']).to eq('page' => '1', 'sort' => 'asc') } + it { expect(result['query_string']).to eq('page=1&sort=asc') } + it { expect(result['source_ip']).to eq('10.0.0.2') } + it { expect(result['body']).to eq('hello') } + it { expect(result['base64_encoded']).to eq(false) } + it { expect(result['path_params']).to eq('id' => '123') } + end + + context 'when v1 event has nil fields' do + let(:event) do + { + 'httpMethod' => 'GET', + 'path' => '/health', + 'headers' => nil, + 'queryStringParameters' => nil, + 'multiValueQueryStringParameters' => nil, + 'pathParameters' => nil, + 'body' => nil, + 'isBase64Encoded' => false, + 'requestContext' => {'identity' => {'sourceIp' => '127.0.0.1'}}, + } + end + + it { expect(result['method']).to eq('GET') } + it { expect(result['path']).to eq('/health') } + it { expect(result['source_ip']).to eq('127.0.0.1') } + it { expect(result).not_to have_key('headers') } + it { expect(result).not_to have_key('query') } + it { expect(result).not_to have_key('path_params') } + it { expect(result).not_to have_key('body') } + end + + context 'when v2 event has minimal fields' do + let(:event) do + { + 'rawPath' => '/health', + 'headers' => {}, + 'requestContext' => {'http' => {'method' => 'GET', 'sourceIp' => '127.0.0.1'}}, + } + end + + it { expect(result['method']).to eq('GET') } + it { expect(result['path']).to eq('/health') } + it { expect(result['source_ip']).to eq('127.0.0.1') } + it { expect(result).not_to have_key('cookies') } + it { expect(result).not_to have_key('query') } + it { expect(result).not_to have_key('query_string') } + it { expect(result).not_to have_key('body') } + it { expect(result).not_to have_key('path_params') } + end + end +end diff --git a/test/datadog/lambda/appsec/request.spec.rb b/test/datadog/lambda/appsec/request.spec.rb index eaf9524f..265f6e2a 100644 --- a/test/datadog/lambda/appsec/request.spec.rb +++ b/test/datadog/lambda/appsec/request.spec.rb @@ -3,19 +3,17 @@ require 'datadog/lambda/appsec/request' RSpec.describe Datadog::Lambda::AppSec::Request do - subject(:request) { described_class.from_event(event) } + subject(:request) { described_class.from_normalized(event) } let(:event) do { - 'headers' => { 'Host' => 'example.com', 'User-Agent' => 'TestBot/1.0', 'Accept' => 'text/html' }, - 'requestContext' => { - 'identity' => { 'sourceIp' => '10.0.0.1' } - } + 'headers' => {'Host' => 'example.com', 'User-Agent' => 'TestBot/1.0', 'Accept' => 'text/html'}, + 'source_ip' => '10.0.0.1', } end describe '#headers' do - it 'normalizes header keys to lowercase' do + it 'lowercases header keys' do expect(request.headers).to eq( 'host' => 'example.com', 'user-agent' => 'TestBot/1.0', @@ -24,7 +22,7 @@ end context 'when event has no headers' do - let(:event) { { 'requestContext' => {} } } + let(:event) { {'source_ip' => '10.0.0.1'} } it { expect(request.headers).to eq({}) } end @@ -41,21 +39,8 @@ describe '#remote_addr' do it { expect(request.remote_addr).to eq('10.0.0.1') } - context 'when event is API Gateway v2 format' do - let(:event) do - { - 'headers' => {}, - 'requestContext' => { - 'http' => { 'sourceIp' => '10.0.0.2' } - } - } - end - - it { expect(request.remote_addr).to eq('10.0.0.2') } - end - - context 'when event has no requestContext' do - let(:event) { { 'headers' => {} } } + context 'when source_ip is absent' do + let(:event) { {'headers' => {}} } it { expect(request.remote_addr).to be_nil } end From ba1436fb26bb2c04271f0ba711ec4b597a0b5684 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Wed, 6 May 2026 21:03:39 +0200 Subject: [PATCH 3/7] Refactor AppSec tag_and_keep with cold_start parameter - Rename add_appsec_tags to tag_and_keep, move from create_context to on_start for visibility - Pass cold_start flag from listener through to AppSec.on_start instead of tracking @oneshot_tags_sent module state - Align guard clause with Rack: return unless trace && span - Improve test quality: inline event values, use receive_messages, remove instance_variable_set for @request, relax unrelated assertions Co-Authored-By: Claude Opus 4.6 (1M context) --- .rubocop.yml | 1 + Dockerfile | 9 +- .../snapshots/logs/appsec-request_ruby32.log | 29 +++ .../snapshots/logs/appsec-request_ruby33.log | 29 +++ .../snapshots/logs/appsec-request_ruby34.log | 29 +++ .../snapshots/logs/async-metrics_ruby32.log | 24 +++ .../snapshots/logs/async-metrics_ruby33.log | 24 +++ .../snapshots/logs/async-metrics_ruby34.log | 28 +++ .../snapshots/logs/http-requests_ruby32.log | 25 +++ .../snapshots/logs/http-requests_ruby33.log | 25 +++ .../snapshots/logs/http-requests_ruby34.log | 29 +++ .../logs/process-input-traced_ruby32.log | 23 +++ .../logs/process-input-traced_ruby33.log | 23 +++ .../logs/process-input-traced_ruby34.log | 27 +++ .../snapshots/logs/sync-metrics_ruby32.log | 24 +++ .../snapshots/logs/sync-metrics_ruby33.log | 24 +++ .../snapshots/logs/sync-metrics_ruby34.log | 28 +++ ...c-request_api-gateway-appsec-blocking.json | 5 + .../appsec-request_api-gateway-appsec.json | 5 + .../appsec-request_api-gateway-get.json | 5 + .../return_values/appsec-request_sns.json | 5 + .../return_values/appsec-request_sqs.json | 5 + ...c-metrics_api-gateway-appsec-blocking.json | 5 + .../async-metrics_api-gateway-appsec.json | 5 + ...-requests_api-gateway-appsec-blocking.json | 3 + .../http-requests_api-gateway-appsec.json | 3 + ...ut-traced_api-gateway-appsec-blocking.json | 5 + ...ocess-input-traced_api-gateway-appsec.json | 5 + ...c-metrics_api-gateway-appsec-blocking.json | 5 + .../sync-metrics_api-gateway-appsec.json | 5 + lib/datadog/lambda.rb | 1 + lib/datadog/lambda/appsec.rb | 35 +++- lib/datadog/lambda/trace/listener.rb | 2 +- test/datadog/lambda/appsec.spec.rb | 191 +++++++++++++++--- 34 files changed, 651 insertions(+), 40 deletions(-) create mode 100644 integration_tests/snapshots/logs/appsec-request_ruby32.log create mode 100644 integration_tests/snapshots/logs/appsec-request_ruby33.log create mode 100644 integration_tests/snapshots/logs/appsec-request_ruby34.log create mode 100644 integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec-blocking.json create mode 100644 integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec.json create mode 100644 integration_tests/snapshots/return_values/appsec-request_api-gateway-get.json create mode 100644 integration_tests/snapshots/return_values/appsec-request_sns.json create mode 100644 integration_tests/snapshots/return_values/appsec-request_sqs.json create mode 100644 integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec-blocking.json create mode 100644 integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec.json create mode 100644 integration_tests/snapshots/return_values/http-requests_api-gateway-appsec-blocking.json create mode 100644 integration_tests/snapshots/return_values/http-requests_api-gateway-appsec.json create mode 100644 integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec-blocking.json create mode 100644 integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec.json create mode 100644 integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec-blocking.json create mode 100644 integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec.json diff --git a/.rubocop.yml b/.rubocop.yml index 64ecb10b..4f079a08 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,7 @@ AllCops: TargetRubyVersion: 3.2 Exclude: - 'test/**/*' + - 'vendor/**/*' Metrics/MethodLength: Max: 20 diff --git a/Dockerfile b/Dockerfile index 38b1efb0..8d968a67 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ RUN set -eux; \ if [ -z "${git_ref:-}" ]; then \ # NOTE: datadog gem must be >= 2.24 to install on Ruby 4.0.x. MAKEFLAGS="-j$(nproc)" \ - gem install datadog -v 2.30 --install-dir "/opt/ruby/gems/$runtime" --no-document; \ + gem install datadog -v 2.33 --install-dir "/opt/ruby/gems/$runtime" --no-document; \ else \ echo "building tracer from ref: $git_ref\n"; \ git clone https://github.com/DataDog/dd-trace-rb.git --depth 1 --single-branch -b $git_ref /tmp/dd-trace-rb; \ @@ -41,13 +41,6 @@ RUN gem uninstall ffi --all --ignore-dependencies --executables --force \ RUN MAKEFLAGS="-j$(nproc)" \ gem install ffi --platform ruby --install-dir "/opt/ruby/gems/$runtime" --no-document -# Recompile FFI from source — precompiled binaries have glibc mismatch with Lambda AL2 -# NOTE: runs after datadog gem as a defensive measure — force-replaces whatever -# transitive FFI variant was pulled, regardless of version resolution. -RUN gem install ffi --platform ruby --force --install-dir "/opt/ruby/gems/$runtime" --no-document -RUN rm -rf /opt/ruby/gems/$runtime/gems/ffi-*-*-linux-* \ - /opt/ruby/gems/$runtime/specifications/ffi-*-*-linux-*.gemspec - WORKDIR /opt # Remove native extension debase-ruby_core_source (25MB) runtimes below Ruby 2.6 RUN rm -rf ./ruby/gems/$runtime/gems/debase-ruby_core_source*/ diff --git a/integration_tests/snapshots/logs/appsec-request_ruby32.log b/integration_tests/snapshots/logs/appsec-request_ruby32.log new file mode 100644 index 00000000..6248a3b6 --- /dev/null +++ b/integration_tests/snapshots/logs/appsec-request_ruby32.log @@ -0,0 +1,29 @@ + +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} +START +START +START +START +START +W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-appsec-request_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-appsec-request_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-appsec-request_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-appsec-request_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-appsec-request_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-appsec-request_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-appsec-request_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-appsec-request_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-appsec-request_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-appsec-request_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:appsec-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},\"on_match\":[]},\"rule_matches\":[{\"operator\":\"is_sqli\",\"operator_value\":\"\",\"parameters\":[{\"address\":\"server.request.query\",\"key_path\":[\"q\"],\"value\":\"1' OR '1'='1\",\"highlight\":[\"s&sos\"]}]}]}]}"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},\"on_match\":[]},\"rule_matches\":[{\"operator\":\"match_regex\",\"operator_value\":\"^Arachni\\\\/v\",\"parameters\":[{\"address\":\"server.request.headers.no_cookies\",\"key_path\":[\"user-agent\"],\"value\":\"Arachni/v1.0\",\"highlight\":[\"Arachni/v\"]}]}]}]}"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} diff --git a/integration_tests/snapshots/logs/appsec-request_ruby33.log b/integration_tests/snapshots/logs/appsec-request_ruby33.log new file mode 100644 index 00000000..ae402d34 --- /dev/null +++ b/integration_tests/snapshots/logs/appsec-request_ruby33.log @@ -0,0 +1,29 @@ + +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} +START +START +START +START +START +W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-appsec-request_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-appsec-request_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-appsec-request_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-appsec-request_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-appsec-request_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-appsec-request_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-appsec-request_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-appsec-request_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-appsec-request_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-appsec-request_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:appsec-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},\"on_match\":[]},\"rule_matches\":[{\"operator\":\"is_sqli\",\"operator_value\":\"\",\"parameters\":[{\"address\":\"server.request.query\",\"key_path\":[\"q\"],\"value\":\"1' OR '1'='1\",\"highlight\":[\"s&sos\"]}]}]}]}"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},\"on_match\":[]},\"rule_matches\":[{\"operator\":\"match_regex\",\"operator_value\":\"^Arachni\\\\/v\",\"parameters\":[{\"address\":\"server.request.headers.no_cookies\",\"key_path\":[\"user-agent\"],\"value\":\"Arachni/v1.0\",\"highlight\":[\"Arachni/v\"]}]}]}]}"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} diff --git a/integration_tests/snapshots/logs/appsec-request_ruby34.log b/integration_tests/snapshots/logs/appsec-request_ruby34.log new file mode 100644 index 00000000..90d970d0 --- /dev/null +++ b/integration_tests/snapshots/logs/appsec-request_ruby34.log @@ -0,0 +1,29 @@ + +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} +START +START +START +START +START +W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-appsec-request_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-appsec-request_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-appsec-request_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-appsec-request_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-appsec-request_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-appsec-request_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-appsec-request_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-appsec-request_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-appsec-request_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-appsec-request_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:appsec-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:appsec-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},\"on_match\":[]},\"rule_matches\":[{\"operator\":\"is_sqli\",\"operator_value\":\"\",\"parameters\":[{\"address\":\"server.request.query\",\"key_path\":[\"q\"],\"value\":\"1' OR '1'='1\",\"highlight\":[\"s&sos\"]}]}]}]}"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},\"on_match\":[]},\"rule_matches\":[{\"operator\":\"match_regex\",\"operator_value\":\"^Arachni\\\\/v\",\"parameters\":[{\"address\":\"server.request.headers.no_cookies\",\"key_path\":[\"user-agent\"],\"value\":\"Arachni/v1.0\",\"highlight\":[\"Arachni/v\"]}]}]}]}"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} diff --git a/integration_tests/snapshots/logs/async-metrics_ruby32.log b/integration_tests/snapshots/logs/async-metrics_ruby32.log index 26339d2d..c61f3967 100644 --- a/integration_tests/snapshots/logs/async-metrics_ruby32.log +++ b/integration_tests/snapshots/logs/async-metrics_ruby32.log @@ -2,19 +2,38 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} Processed APIGateway request +Processed APIGateway request +Processed APIGateway request Processed SNS request Processed SQS request START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-async-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-async-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-async-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-async-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-async-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-async-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-async-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-async-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-async-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-async-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-async-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-async-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:SNS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:SQS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:SNS"],"v":1} @@ -23,3 +42,8 @@ W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::In {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +<<<<<<< HEAD +======= +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) diff --git a/integration_tests/snapshots/logs/async-metrics_ruby33.log b/integration_tests/snapshots/logs/async-metrics_ruby33.log index 950a021a..4210e168 100644 --- a/integration_tests/snapshots/logs/async-metrics_ruby33.log +++ b/integration_tests/snapshots/logs/async-metrics_ruby33.log @@ -2,19 +2,38 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} Processed APIGateway request +Processed APIGateway request +Processed APIGateway request Processed SNS request Processed SQS request START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-async-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-async-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-async-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-async-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-async-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-async-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-async-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-async-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-async-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-async-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-async-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-async-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:SNS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:SQS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:SNS"],"v":1} @@ -23,3 +42,8 @@ W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::In {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +<<<<<<< HEAD +======= +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) diff --git a/integration_tests/snapshots/logs/async-metrics_ruby34.log b/integration_tests/snapshots/logs/async-metrics_ruby34.log index 8c986ca5..ae65d550 100644 --- a/integration_tests/snapshots/logs/async-metrics_ruby34.log +++ b/integration_tests/snapshots/logs/async-metrics_ruby34.log @@ -2,19 +2,42 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.32.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 52643af (Update integration test snapshots for AppSec) +======= +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} Processed APIGateway request +Processed APIGateway request +Processed APIGateway request Processed SNS request Processed SQS request START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-async-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-async-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-async-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-async-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-async-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-async-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-async-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-async-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-async-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-async-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-async-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-async-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +>>>>>>> 52643af (Update integration test snapshots for AppSec) {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:SNS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:SQS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:SNS"],"v":1} @@ -23,3 +46,8 @@ W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::In {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +<<<<<<< HEAD +======= +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 52643af (Update integration test snapshots for AppSec) diff --git a/integration_tests/snapshots/logs/http-requests_ruby32.log b/integration_tests/snapshots/logs/http-requests_ruby32.log index a3e62ac5..5cd520a4 100644 --- a/integration_tests/snapshots/logs/http-requests_ruby32.log +++ b/integration_tests/snapshots/logs/http-requests_ruby32.log @@ -2,21 +2,46 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} START START START +<<<<<<< HEAD +======= +START +START +Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] +Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] +>>>>>>> 38e93e9 (Update snapshots) Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-http-requests_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-http-requests_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-http-requests_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-http-requests_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-http-requests_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-http-requests_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-http-requests_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-http-requests_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-http-requests_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-http-requests_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} diff --git a/integration_tests/snapshots/logs/http-requests_ruby33.log b/integration_tests/snapshots/logs/http-requests_ruby33.log index c319ec04..1ee3d01b 100644 --- a/integration_tests/snapshots/logs/http-requests_ruby33.log +++ b/integration_tests/snapshots/logs/http-requests_ruby33.log @@ -2,21 +2,46 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} START START START +<<<<<<< HEAD +======= +START +START +Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] +Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] +>>>>>>> 38e93e9 (Update snapshots) Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-http-requests_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-http-requests_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-http-requests_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-http-requests_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-http-requests_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-http-requests_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-http-requests_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-http-requests_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-http-requests_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-http-requests_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} diff --git a/integration_tests/snapshots/logs/http-requests_ruby34.log b/integration_tests/snapshots/logs/http-requests_ruby34.log index 389935d9..cee4db64 100644 --- a/integration_tests/snapshots/logs/http-requests_ruby34.log +++ b/integration_tests/snapshots/logs/http-requests_ruby34.log @@ -2,21 +2,50 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.32.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 52643af (Update integration test snapshots for AppSec) +======= +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} START START START +<<<<<<< HEAD +======= +START +START +Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] +Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] +>>>>>>> 52643af (Update integration test snapshots for AppSec) Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] Snapshot test http requests successfully made to URLs: ["ip-ranges.datadoghq.com", "ip-ranges.datadoghq.eu"] W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-http-requests_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-http-requests_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-http-requests_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-http-requests_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-http-requests_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-http-requests_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-http-requests_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-http-requests_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +>>>>>>> 52643af (Update integration test snapshots for AppSec) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-http-requests_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-http-requests_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 52643af (Update integration test snapshots for AppSec) {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} diff --git a/integration_tests/snapshots/logs/process-input-traced_ruby32.log b/integration_tests/snapshots/logs/process-input-traced_ruby32.log index 523391b4..fd66a2f1 100644 --- a/integration_tests/snapshots/logs/process-input-traced_ruby32.log +++ b/integration_tests/snapshots/logs/process-input-traced_ruby32.log @@ -2,18 +2,41 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-process-input-traced_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-process-input-traced_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-process-input-traced_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-process-input-traced_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-process-input-traced_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} +<<<<<<< HEAD {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +======= +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","function:http-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) diff --git a/integration_tests/snapshots/logs/process-input-traced_ruby33.log b/integration_tests/snapshots/logs/process-input-traced_ruby33.log index 0794a58f..a836e3f0 100644 --- a/integration_tests/snapshots/logs/process-input-traced_ruby33.log +++ b/integration_tests/snapshots/logs/process-input-traced_ruby33.log @@ -2,18 +2,41 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-process-input-traced_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-process-input-traced_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-process-input-traced_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-process-input-traced_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-process-input-traced_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} +<<<<<<< HEAD {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +======= +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","function:http-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) diff --git a/integration_tests/snapshots/logs/process-input-traced_ruby34.log b/integration_tests/snapshots/logs/process-input-traced_ruby34.log index 2c0257bc..51416143 100644 --- a/integration_tests/snapshots/logs/process-input-traced_ruby34.log +++ b/integration_tests/snapshots/logs/process-input-traced_ruby34.log @@ -2,18 +2,45 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.32.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 52643af (Update integration test snapshots for AppSec) +======= +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-process-input-traced_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-process-input-traced_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-process-input-traced_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-process-input-traced_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +>>>>>>> 52643af (Update integration test snapshots for AppSec) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-process-input-traced_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-process-input-traced_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} +<<<<<<< HEAD {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +======= +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","function:http-request"],"v":1} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_record_ids","parent_id":"XXXX","resource":"get_record_ids","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"get_api_gateway_request_id","parent_id":"XXXX","resource":"get_api_gateway_request_id","service":"index","span_id":"XXXX","trace_id":"XXXX","type":null,"span_links":[],"start":XXXX,"duration":XXXX},{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 52643af (Update integration test snapshots for AppSec) diff --git a/integration_tests/snapshots/logs/sync-metrics_ruby32.log b/integration_tests/snapshots/logs/sync-metrics_ruby32.log index 58b9b073..f0944339 100644 --- a/integration_tests/snapshots/logs/sync-metrics_ruby32.log +++ b/integration_tests/snapshots/logs/sync-metrics_ruby32.log @@ -2,19 +2,38 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.2.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.2.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} Processed APIGateway request +Processed APIGateway request +Processed APIGateway request Processed SNS request Processed SQS request START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-sync-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-sync-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-sync-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-sync-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-sync-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby32","functionname:integration-tests-rb-XXXX-sync-metrics_ruby32","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.2.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby32","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:SNS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:SQS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["dd_lambda_layer:datadog-ruby32","tagkey:tagvalue","eventsource:SNS"],"v":1} @@ -23,3 +42,8 @@ W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::In {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +<<<<<<< HEAD +======= +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) diff --git a/integration_tests/snapshots/logs/sync-metrics_ruby33.log b/integration_tests/snapshots/logs/sync-metrics_ruby33.log index 46d2f1a4..06754a22 100644 --- a/integration_tests/snapshots/logs/sync-metrics_ruby33.log +++ b/integration_tests/snapshots/logs/sync-metrics_ruby33.log @@ -2,19 +2,38 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.3.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.3.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} Processed APIGateway request +Processed APIGateway request +Processed APIGateway request Processed SNS request Processed SQS request START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-sync-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-sync-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-sync-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-sync-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-sync-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby33","functionname:integration-tests-rb-XXXX-sync-metrics_ruby33","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.3.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby33","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +>>>>>>> 38e93e9 (Update snapshots) {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:SNS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:SQS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["dd_lambda_layer:datadog-ruby33","tagkey:tagvalue","eventsource:SNS"],"v":1} @@ -23,3 +42,8 @@ W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::In {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +<<<<<<< HEAD +======= +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 38e93e9 (Update snapshots) diff --git a/integration_tests/snapshots/logs/sync-metrics_ruby34.log b/integration_tests/snapshots/logs/sync-metrics_ruby34.log index 05bb4bff..a36e4b0a 100644 --- a/integration_tests/snapshots/logs/sync-metrics_ruby34.log +++ b/integration_tests/snapshots/logs/sync-metrics_ruby34.log @@ -2,19 +2,42 @@ END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.30.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +======= +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +END Duration: XXXX ms (init: XXXX) Memory Used: XXXX MB +<<<<<<< HEAD +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.32.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 52643af (Update integration test snapshots for AppSec) +======= +I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - CORE - {"date":"XXXX","os_name":"XXXX","version":"2.33.0","lang":"ruby","lang_version":"3.4.X","env":null,"service":"index","dd_version":null,"debug":false,"tags":"_dd.origin:lambda","runtime_metrics_enabled":false,"vm":"ruby-3.4.X","health_metrics_enabled":false,"profiling_enabled":false,"dynamic_instrumentation_enabled":false} +>>>>>>> 38e93e9 (Update snapshots) I, [XXXX] INFO XXXX[datadog] DATADOG CONFIGURATION - TRACING - {"enabled":true,"agent_url":null,"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,"integrations_loaded":"aws@","partial_flushing_enabled":false} Processed APIGateway request +Processed APIGateway request +Processed APIGateway request Processed SNS request Processed SQS request START START START +START +START W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::Integration (Available?: false, Loaded? false, Compatible? false, Patchable? false) {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-sync-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-sync-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +<<<<<<< HEAD +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-sync-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +======= +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-sync-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-sync-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:false","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["dd_lambda_layer:datadog-ruby34","functionname:integration-tests-rb-XXXX-sync-metrics_ruby34","region:eu-west-1","account_id:XXXX","memorysize:1024","cold_start:true","runtime:Ruby 3.4.X","resource:integration-tests-rb-XXXX-sync-metrics_ruby34","datadog_lambda:X.X.X","dd_trace:2.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +{"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:APIGateway"],"v":1} +>>>>>>> 52643af (Update integration test snapshots for AppSec) {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:SNS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:SQS"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["dd_lambda_layer:datadog-ruby34","tagkey:tagvalue","eventsource:SNS"],"v":1} @@ -23,3 +46,8 @@ W, [XXXX] WARN XXXX[datadog] Unable to patch Datadog::Tracing::Contrib::Aws::In {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} {"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +<<<<<<< HEAD +======= +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +{"traces":[[{"error":0,"meta":{"XXXX": "XXXX"},"metrics":{"XXXX": "XXXX"},"meta_struct":{},"name":"aws.lambda","parent_id":"XXXX","resource":"dd-tracer-serverless-span","service":"aws.lambda","span_id":"XXXX","trace_id":"XXXX","type":"serverless","span_links":[],"start":XXXX,"duration":XXXX}]]} +>>>>>>> 52643af (Update integration test snapshots for AppSec) diff --git a/integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec-blocking.json b/integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec-blocking.json new file mode 100644 index 00000000..eb8ee038 --- /dev/null +++ b/integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec-blocking.json @@ -0,0 +1,5 @@ +{ + "statusCode": 200, + "message": "hello, dog!", + "eventType": "APIGateway" +} diff --git a/integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec.json b/integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec.json new file mode 100644 index 00000000..eb8ee038 --- /dev/null +++ b/integration_tests/snapshots/return_values/appsec-request_api-gateway-appsec.json @@ -0,0 +1,5 @@ +{ + "statusCode": 200, + "message": "hello, dog!", + "eventType": "APIGateway" +} diff --git a/integration_tests/snapshots/return_values/appsec-request_api-gateway-get.json b/integration_tests/snapshots/return_values/appsec-request_api-gateway-get.json new file mode 100644 index 00000000..eb8ee038 --- /dev/null +++ b/integration_tests/snapshots/return_values/appsec-request_api-gateway-get.json @@ -0,0 +1,5 @@ +{ + "statusCode": 200, + "message": "hello, dog!", + "eventType": "APIGateway" +} diff --git a/integration_tests/snapshots/return_values/appsec-request_sns.json b/integration_tests/snapshots/return_values/appsec-request_sns.json new file mode 100644 index 00000000..eb8ee038 --- /dev/null +++ b/integration_tests/snapshots/return_values/appsec-request_sns.json @@ -0,0 +1,5 @@ +{ + "statusCode": 200, + "message": "hello, dog!", + "eventType": "APIGateway" +} diff --git a/integration_tests/snapshots/return_values/appsec-request_sqs.json b/integration_tests/snapshots/return_values/appsec-request_sqs.json new file mode 100644 index 00000000..eb8ee038 --- /dev/null +++ b/integration_tests/snapshots/return_values/appsec-request_sqs.json @@ -0,0 +1,5 @@ +{ + "statusCode": 200, + "message": "hello, dog!", + "eventType": "APIGateway" +} diff --git a/integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec-blocking.json b/integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec-blocking.json new file mode 100644 index 00000000..6f453e96 --- /dev/null +++ b/integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec-blocking.json @@ -0,0 +1,5 @@ +{ + "message": "hello, dog!", + "eventType": "APIGateway", + "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9" +} diff --git a/integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec.json b/integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec.json new file mode 100644 index 00000000..6f453e96 --- /dev/null +++ b/integration_tests/snapshots/return_values/async-metrics_api-gateway-appsec.json @@ -0,0 +1,5 @@ +{ + "message": "hello, dog!", + "eventType": "APIGateway", + "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9" +} diff --git a/integration_tests/snapshots/return_values/http-requests_api-gateway-appsec-blocking.json b/integration_tests/snapshots/return_values/http-requests_api-gateway-appsec-blocking.json new file mode 100644 index 00000000..eb1e9d31 --- /dev/null +++ b/integration_tests/snapshots/return_values/http-requests_api-gateway-appsec-blocking.json @@ -0,0 +1,3 @@ +{ + "message": "hello, dog!" +} diff --git a/integration_tests/snapshots/return_values/http-requests_api-gateway-appsec.json b/integration_tests/snapshots/return_values/http-requests_api-gateway-appsec.json new file mode 100644 index 00000000..eb1e9d31 --- /dev/null +++ b/integration_tests/snapshots/return_values/http-requests_api-gateway-appsec.json @@ -0,0 +1,3 @@ +{ + "message": "hello, dog!" +} diff --git a/integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec-blocking.json b/integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec-blocking.json new file mode 100644 index 00000000..12d7e1a1 --- /dev/null +++ b/integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec-blocking.json @@ -0,0 +1,5 @@ +{ + "message": "hello, dog!", + "recordIds": [], + "eventType": "APIGateway" +} diff --git a/integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec.json b/integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec.json new file mode 100644 index 00000000..12d7e1a1 --- /dev/null +++ b/integration_tests/snapshots/return_values/process-input-traced_api-gateway-appsec.json @@ -0,0 +1,5 @@ +{ + "message": "hello, dog!", + "recordIds": [], + "eventType": "APIGateway" +} diff --git a/integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec-blocking.json b/integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec-blocking.json new file mode 100644 index 00000000..6f453e96 --- /dev/null +++ b/integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec-blocking.json @@ -0,0 +1,5 @@ +{ + "message": "hello, dog!", + "eventType": "APIGateway", + "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9" +} diff --git a/integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec.json b/integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec.json new file mode 100644 index 00000000..6f453e96 --- /dev/null +++ b/integration_tests/snapshots/return_values/sync-metrics_api-gateway-appsec.json @@ -0,0 +1,5 @@ +{ + "message": "hello, dog!", + "eventType": "APIGateway", + "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9" +} diff --git a/lib/datadog/lambda.rb b/lib/datadog/lambda.rb index 604c3856..30e78cc4 100644 --- a/lib/datadog/lambda.rb +++ b/lib/datadog/lambda.rb @@ -62,6 +62,7 @@ def self.configure_apm # @param block [Proc] implementation of the handler function. # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def self.wrap(event, context, &block) + @response = nil @listener ||= initialize_listener record_enhanced('invocations', context) begin diff --git a/lib/datadog/lambda/appsec.rb b/lib/datadog/lambda/appsec.rb index be3a50eb..a27831ab 100644 --- a/lib/datadog/lambda/appsec.rb +++ b/lib/datadog/lambda/appsec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'json' require_relative 'appsec/request' require_relative 'appsec/event_normalizer' @@ -8,13 +9,16 @@ module Lambda # AppSec integration for AWS Lambda invocations. module AppSec class << self - def on_start(event, trace:, span:) + # rubocop:disable Metrics/AbcSize + def on_start(event, trace:, span:, cold_start: false) @request = nil return unless enabled? context = create_context(trace, span) return unless Datadog::AppSec::Context.active + tag_and_keep(context, cold_start: cold_start) + event = EventNormalizer.normalize(event) @request = Request.from_normalized(event) @@ -34,6 +38,7 @@ def on_start(event, trace:, span:) rescue StandardError => e Datadog::Utils.logger.debug("failed to start AppSec: #{e}") end + # rubocop:enable Metrics/AbcSize def on_finish(response) return unless enabled? @@ -80,9 +85,35 @@ def create_context(trace, span) context = Datadog::AppSec::Context.new(trace, span, security_engine.new_runner) Datadog::AppSec::Context.activate(context) + context + end + + def tag_and_keep(context, cold_start:) + span = context.span + trace = context.trace + + return unless trace && span + span.set_metric(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, 1) + span.set_tag('_dd.runtime_family', 'ruby') + span.set_tag('_dd.appsec.waf.version', Datadog::AppSec::WAF::VERSION::BASE_STRING) - context + ruleset_version = context.waf_runner_ruleset_version + return unless ruleset_version + + span.set_tag('_dd.appsec.event_rules.version', ruleset_version) + + return unless cold_start + + span.set_tag( + '_dd.appsec.event_rules.addresses', JSON.dump(context.waf_runner_known_addresses) + ) + + trace.keep! + trace.set_tag( + Datadog::Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, + Datadog::Tracing::Sampling::Ext::Decision::ASM + ) end def response_override(interrupt_params, headers:) diff --git a/lib/datadog/lambda/trace/listener.rb b/lib/datadog/lambda/trace/listener.rb index 89c1b4b6..078e3de6 100644 --- a/lib/datadog/lambda/trace/listener.rb +++ b/lib/datadog/lambda/trace/listener.rb @@ -56,7 +56,7 @@ def on_start(event:, request_context:, cold_start:) Datadog::Trace.apply_datadog_trace_context(Datadog::Trace.trace_context) @response_override = Datadog::Lambda::AppSec.on_start( - event, trace: Datadog::Tracing.active_trace, span: @trace + event, trace: Datadog::Tracing.active_trace, span: @trace, cold_start: cold_start ) end # rubocop:enable Metrics/AbcSize diff --git a/test/datadog/lambda/appsec.spec.rb b/test/datadog/lambda/appsec.spec.rb index 19ddda17..c1d3eea4 100644 --- a/test/datadog/lambda/appsec.spec.rb +++ b/test/datadog/lambda/appsec.spec.rb @@ -5,15 +5,17 @@ RSpec.describe Datadog::Lambda::AppSec do before do + stub_const('Datadog::AppSec::WAF::VERSION::BASE_STRING', '1.30.0') allow(Datadog::AppSec::Instrumentation).to receive(:gateway).and_return(gateway) allow(gateway).to receive(:push) end let(:gateway) { instance_double(Datadog::AppSec::Instrumentation::Gateway) } + let(:context_span) { instance_double(Datadog::Tracing::SpanOperation, set_tag: nil, set_metric: nil) } let(:appsec_context) do instance_double( Datadog::AppSec::Context, - span: instance_double(Datadog::Tracing::SpanOperation, get_tag: nil, get_metric: nil), + span: context_span, state: {}, export_metrics: nil, export_request_telemetry: nil @@ -21,11 +23,12 @@ end describe '.on_start' do - subject(:on_start) { described_class.on_start(event, trace: trace, span: span) } + subject(:on_start) do + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) + end - let(:event) { { 'httpMethod' => 'GET', 'path' => '/' } } let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } - let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil) } + let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil, set_tag: nil) } context 'when appsec is disabled' do before { allow(Datadog::AppSec).to receive(:enabled?).and_return(false) } @@ -39,14 +42,12 @@ context 'when appsec is enabled' do before do - allow(Datadog::AppSec).to receive(:enabled?).and_return(true) - allow(Datadog::AppSec).to receive(:security_engine).and_return(security_engine) - allow(Datadog::AppSec::Context).to receive(:activate) - allow(Datadog::AppSec::Context).to receive(:active).and_return(appsec_context) + allow(Datadog::AppSec).to receive_messages(enabled?: true, security_engine: security_engine) + allow(Datadog::AppSec::Context).to receive_messages(activate: nil, active: appsec_context) end let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } - let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner) } + let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } it 'marks span as appsec-enabled' do on_start @@ -79,7 +80,9 @@ end context 'when trace is nil' do - subject(:on_start) { described_class.on_start(event, trace: nil, span: span) } + subject(:on_start) do + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: nil, span: span) + end before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } @@ -94,7 +97,9 @@ end context 'when span is nil' do - subject(:on_start) { described_class.on_start(event, trace: trace, span: nil) } + subject(:on_start) do + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: nil) + end before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } @@ -111,7 +116,11 @@ context 'when gateway push triggers a blocking interrupt' do before do allow(Datadog::AppSec::Context).to receive(:new).and_return(appsec_context) - allow(appsec_context).to receive(:mark_as_interrupted!) + allow(appsec_context).to receive_messages( + trace: trace, + waf_runner_ruleset_version: nil, + mark_as_interrupted!: nil + ) allow(gateway).to receive(:push).and_invoke(lambda { |_name, _payload| throw(Datadog::AppSec::Ext::INTERRUPT, {'status_code' => 403, 'type' => 'auto'}) @@ -132,13 +141,126 @@ it { expect { on_start }.not_to raise_error } end + + context 'when waf ruleset is loaded' do + before do + allow(Datadog::AppSec::Context).to receive(:new).and_return(appsec_context) + allow(appsec_context).to receive_messages( + waf_runner_ruleset_version: '1.12.0', + waf_runner_known_addresses: ['server.request.headers.no_cookies'] + ) + + allow(trace).to receive_messages(keep!: nil, set_tag: nil) + allow(span).to receive(:set_tag) + end + + let(:appsec_context) do + instance_double( + Datadog::AppSec::Context, + span: span, + trace: trace, + state: {}, + export_metrics: nil, + export_request_telemetry: nil + ) + end + + it 'sets runtime family and WAF version on the span' do + on_start + + aggregate_failures('appsec span tags') do + expect(span).to have_received(:set_tag).with('_dd.runtime_family', 'ruby') + expect(span).to have_received(:set_tag).with('_dd.appsec.waf.version', '1.30.0') + end + end + + it 'sets event rules version from the WAF runner' do + on_start + + expect(span).to have_received(:set_tag).with('_dd.appsec.event_rules.version', '1.12.0') + end + + context 'when cold_start is true' do + subject(:on_start) do + described_class.on_start( + {'httpMethod' => 'GET', 'path' => '/'}, + trace: trace, span: span, cold_start: true + ) + end + + it 'sets known addresses and keeps trace' do + on_start + + aggregate_failures('cold start tags') do + expect(span).to have_received(:set_tag).with( + '_dd.appsec.event_rules.addresses', + '["server.request.headers.no_cookies"]' + ) + expect(trace).to have_received(:keep!) + expect(trace).to have_received(:set_tag).with( + Datadog::Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, + Datadog::Tracing::Sampling::Ext::Decision::ASM + ) + end + end + end + + context 'when cold_start is false' do + it 'does not send cold start tags' do + on_start + + aggregate_failures('no cold start tags') do + expect(span).not_to have_received(:set_tag).with('_dd.appsec.event_rules.addresses', anything) + expect(trace).not_to have_received(:keep!) + end + end + end + + context 'when ruleset version is not set' do + before { allow(appsec_context).to receive(:waf_runner_ruleset_version).and_return(nil) } + + it 'skips event rules tags' do + on_start + + aggregate_failures('skipped rules tags') do + expect(span).not_to have_received(:set_tag).with('_dd.appsec.event_rules.version', anything) + expect(span).not_to have_received(:set_tag).with('_dd.appsec.event_rules.addresses', anything) + end + end + end + + context 'when span is not set' do + subject(:on_start) do + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: nil) + end + + before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } + + it 'does not set any appsec tags' do + on_start + + expect(span).not_to have_received(:set_tag) + end + end + + context 'when context trace is not set' do + before { allow(appsec_context).to receive(:trace).and_return(nil) } + + it 'does not set any tags' do + on_start + + aggregate_failures('no tags when trace nil') do + expect(span).not_to have_received(:set_tag) + expect(span).not_to have_received(:set_metric).with(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, anything) + end + end + end + end end end describe '.on_finish' do - subject(:on_finish) { described_class.on_finish(response) } - - let(:response) { { 'statusCode' => 200 } } + subject(:on_finish) { described_class.on_finish({ 'statusCode' => 200 }) } context 'when appsec is disabled' do before do @@ -169,8 +291,7 @@ context 'when active context exists' do before do allow(Datadog::AppSec).to receive(:enabled?).and_return(true) - allow(Datadog::AppSec::Context).to receive(:active).and_return(appsec_context) - allow(Datadog::AppSec::Context).to receive(:deactivate) + allow(Datadog::AppSec::Context).to receive_messages(active: appsec_context, deactivate: nil) allow(Datadog::AppSec::Event).to receive(:record) end @@ -181,7 +302,7 @@ expect(gateway).to have_received(:push).with( 'aws_lambda.response.start', kind_of(Datadog::AppSec::Instrumentation::Gateway::DataContainer) ) - expect(Datadog::AppSec::Event).to have_received(:record).with(appsec_context, request: nil) + expect(Datadog::AppSec::Event).to have_received(:record).with(appsec_context, request: anything) end end @@ -200,20 +321,20 @@ allow(Datadog::AppSec).to receive(:security_engine).and_return(security_engine) allow(Datadog::AppSec::Context).to receive(:activate) - described_class.on_start(event, trace: trace, span: span) + described_class.on_start( + { + 'httpMethod' => 'GET', + 'headers' => {'Host' => 'example.com', 'User-Agent' => 'TestBot'}, + 'requestContext' => {'identity' => {'sourceIp' => '1.2.3.4'}} + }, + trace: trace, span: span + ) end - let(:event) do - { - 'httpMethod' => 'GET', - 'headers' => {'Host' => 'example.com', 'User-Agent' => 'TestBot'}, - 'requestContext' => {'identity' => {'sourceIp' => '1.2.3.4'}}, - } - end let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } - let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil) } + let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil, set_tag: nil) } let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } - let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner) } + let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } it 'records security event with request' do on_finish @@ -226,12 +347,24 @@ context 'when gateway push triggers a blocking interrupt' do before do + allow(Datadog::AppSec).to receive(:security_engine).and_return(security_engine) + allow(Datadog::AppSec::Context).to receive(:activate) + allow(appsec_context).to receive(:mark_as_interrupted!) allow(gateway).to receive(:push).and_invoke(lambda { |_name, _payload| throw(Datadog::AppSec::Ext::INTERRUPT, {'status_code' => 403, 'type' => 'auto'}) }) - allow(appsec_context).to receive(:mark_as_interrupted!) + + described_class.on_start( + {'httpMethod' => 'GET', 'headers' => {'Accept' => 'application/json'}}, + trace: trace, span: span + ) end + let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } + let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil, set_tag: nil) } + let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } + let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } + it 'returns a Lambda-shaped blocking response' do expect(on_finish).to include( 'statusCode' => 403, From b6d15a89f3c47cf9787c091c6ea6de0aa9202dea Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Thu, 21 May 2026 10:08:21 +0200 Subject: [PATCH 4/7] Bump Tracer version to 2.34 with fixed AppSec --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8d968a67..6f8c2d60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ RUN set -eux; \ if [ -z "${git_ref:-}" ]; then \ # NOTE: datadog gem must be >= 2.24 to install on Ruby 4.0.x. MAKEFLAGS="-j$(nproc)" \ - gem install datadog -v 2.33 --install-dir "/opt/ruby/gems/$runtime" --no-document; \ + gem install datadog -v 2.34 --install-dir "/opt/ruby/gems/$runtime" --no-document; \ else \ echo "building tracer from ref: $git_ref\n"; \ git clone https://github.com/DataDog/dd-trace-rb.git --depth 1 --single-branch -b $git_ref /tmp/dd-trace-rb; \ From 6ccefc07c44a155904956d6286c6401aa97efdf2 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Thu, 21 May 2026 10:05:54 +0200 Subject: [PATCH 5/7] Add response normalizer module --- lib/datadog/lambda/appsec.rb | 4 + lib/datadog/lambda/appsec/event_normalizer.rb | 5 ++ .../lambda/appsec/response_normalizer.rb | 37 +++++++++ .../lambda/appsec/response_normalizer.spec.rb | 76 +++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 lib/datadog/lambda/appsec/response_normalizer.rb create mode 100644 test/datadog/lambda/appsec/response_normalizer.spec.rb diff --git a/lib/datadog/lambda/appsec.rb b/lib/datadog/lambda/appsec.rb index a27831ab..146804e5 100644 --- a/lib/datadog/lambda/appsec.rb +++ b/lib/datadog/lambda/appsec.rb @@ -3,6 +3,7 @@ require 'json' require_relative 'appsec/request' require_relative 'appsec/event_normalizer' +require_relative 'appsec/response_normalizer' module Datadog module Lambda @@ -40,12 +41,14 @@ def on_start(event, trace:, span:, cold_start: false) end # rubocop:enable Metrics/AbcSize + # rubocop:disable Metrics/AbcSize def on_finish(response) return unless enabled? context = Datadog::AppSec::Context.active return unless context + response = ResponseNormalizer.normalize(response) payload = Datadog::AppSec::Instrumentation::Gateway::DataContainer.new( response, context: context ) @@ -67,6 +70,7 @@ def on_finish(response) ensure Datadog::AppSec::Context.deactivate if context end + # rubocop:enable Metrics/AbcSize private diff --git a/lib/datadog/lambda/appsec/event_normalizer.rb b/lib/datadog/lambda/appsec/event_normalizer.rb index e05eeb10..68bf38ee 100644 --- a/lib/datadog/lambda/appsec/event_normalizer.rb +++ b/lib/datadog/lambda/appsec/event_normalizer.rb @@ -4,6 +4,11 @@ module Datadog module Lambda module AppSec # Normalizes API Gateway v1/v2 event payloads into a standard key set. + # + # NOTE: The REST API (v1) event does NOT have a version field. + # Only the HTTP API events have "version": "1.0" or "version": "2.0". + # + # @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.proxy-format-structure module EventNormalizer module_function diff --git a/lib/datadog/lambda/appsec/response_normalizer.rb b/lib/datadog/lambda/appsec/response_normalizer.rb new file mode 100644 index 00000000..322b8320 --- /dev/null +++ b/lib/datadog/lambda/appsec/response_normalizer.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Datadog + module Lambda + module AppSec + # Normalizes Lambda handler return values into a standard key set. + # + # @see https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format + module ResponseNormalizer + module_function + + def normalize(response) + data = { + 'status_code' => response['statusCode'], + 'headers' => merge_headers(response), + 'body' => response['body'], + 'base64_encoded' => response['isBase64Encoded'] + } + data.compact! + data + end + + # Merges single-value and multi-value headers into one hash with + # multi-value entries take priority when a key appears in both. + def merge_headers(response) + headers = response['headers'] + multi_headers = response['multiValueHeaders'] + + return headers unless multi_headers + return multi_headers unless headers + + headers.merge(multi_headers) + end + end + end + end +end diff --git a/test/datadog/lambda/appsec/response_normalizer.spec.rb b/test/datadog/lambda/appsec/response_normalizer.spec.rb new file mode 100644 index 00000000..885d0edc --- /dev/null +++ b/test/datadog/lambda/appsec/response_normalizer.spec.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require 'datadog/lambda/appsec/response_normalizer' + +RSpec.describe Datadog::Lambda::AppSec::ResponseNormalizer do + describe '.normalize' do + subject(:result) { described_class.normalize(response) } + + context 'when response has all fields' do + let(:response) do + { + 'statusCode' => 200, + 'headers' => {'content-type' => 'application/json'}, + 'body' => '{"ok":true}', + 'isBase64Encoded' => false + } + end + + it { expect(result['status_code']).to eq(200) } + it { expect(result['headers']).to eq('content-type' => 'application/json') } + it { expect(result['body']).to eq('{"ok":true}') } + it { expect(result['base64_encoded']).to eq(false) } + end + + context 'when response has multiValueHeaders only' do + let(:response) do + { + 'statusCode' => 200, + 'multiValueHeaders' => {'set-cookie' => ['a=1', 'b=2']} + } + end + + it { expect(result['headers']).to eq('set-cookie' => ['a=1', 'b=2']) } + end + + context 'when response has both headers and multiValueHeaders' do + let(:response) do + { + 'statusCode' => 200, + 'headers' => {'content-type' => 'text/html', 'set-cookie' => 'a=1'}, + 'multiValueHeaders' => {'set-cookie' => ['a=1', 'b=2']} + } + end + + it 'merges headers with multi-value taking priority' do + expect(result['headers']).to eq( + 'content-type' => 'text/html', + 'set-cookie' => ['a=1', 'b=2'] + ) + end + end + + context 'when response has nil fields' do + let(:response) do + { + 'statusCode' => 502, + 'headers' => nil, + 'body' => nil, + 'isBase64Encoded' => nil + } + end + + it { expect(result['status_code']).to eq(502) } + it { expect(result).not_to have_key('headers') } + it { expect(result).not_to have_key('body') } + it { expect(result).not_to have_key('base64_encoded') } + end + + context 'when response has only statusCode' do + let(:response) { {'statusCode' => 204} } + + it { expect(result).to eq('status_code' => 204) } + end + + end +end From 6c85f0cc252a1844663b70f380676d59ad565a30 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Thu, 21 May 2026 10:44:48 +0200 Subject: [PATCH 6/7] Fix response resetting between invocations --- test/datadog/lambda.spec.rb | 18 ++++++ test/datadog/lambda/appsec.spec.rb | 88 ++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/test/datadog/lambda.spec.rb b/test/datadog/lambda.spec.rb index b8354cfd..804f5411 100644 --- a/test/datadog/lambda.spec.rb +++ b/test/datadog/lambda.spec.rb @@ -39,6 +39,24 @@ end end + context 'when previous invocation successful response followed by a failing invocation' do + before do + Datadog::Lambda.instance_variable_set(:@listener, listener) + Datadog::Lambda.wrap('1', ctx) { {'statusCode' => 200} } + Datadog::Lambda.wrap('1', ctx) { raise 'boom' } rescue nil + end + + after { Datadog::Lambda.instance_variable_set(:@listener, nil) } + + let(:listener) do + instance_double(Datadog::Trace::Listener, on_start: nil, on_end: nil, response_override: nil) + end + + it 'passes response of the failing invocation as nil' do + expect(listener).to have_received(:on_end).with(response: nil, request_context: ctx) + end + end + context 'with a handler that sends a custom metric' do subject(:handler) do Datadog::Lambda.wrap(event, context) do diff --git a/test/datadog/lambda/appsec.spec.rb b/test/datadog/lambda/appsec.spec.rb index c1d3eea4..15ceb1da 100644 --- a/test/datadog/lambda/appsec.spec.rb +++ b/test/datadog/lambda/appsec.spec.rb @@ -392,6 +392,94 @@ expect(Datadog::AppSec::Context).to have_received(:deactivate) end end + + context 'when request-time override is clobbered by on_finish returning nil' do + before do + allow(Datadog::AppSec).to receive(:security_engine).and_return(security_engine) + allow(Datadog::AppSec::Context).to receive(:activate) + allow(appsec_context).to receive_messages( + trace: trace, + waf_runner_ruleset_version: nil, + mark_as_interrupted!: nil + ) + + allow(gateway).to receive(:push).and_invoke( + lambda { |name, _payload| + if name == 'aws_lambda.request.start' + throw(Datadog::AppSec::Ext::INTERRUPT, {'status_code' => 403, 'type' => 'auto'}) + end + } + ) + + described_class.on_start( + {'httpMethod' => 'GET', 'headers' => {'Accept' => 'application/json'}}, + trace: trace, span: span + ) + + allow(Datadog::Trace).to receive(:extract_trace_context).and_return({}) + allow(Datadog::Trace).to receive(:trace_context).and_return({}) + allow(Datadog::Trace).to receive(:apply_datadog_trace_context) + allow(Datadog::Tracing).to receive(:trace).and_return(span) + allow(Datadog::Tracing).to receive(:active_trace).and_return(trace) + allow(Datadog::Utils).to receive_messages( + send_start_invocation_request: nil, + send_end_invocation_request: nil + ) + allow(span).to receive(:id).and_return(1) + allow(span).to receive(:finish) + end + + let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } + let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil, set_tag: nil) } + let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } + let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } + let(:request_context) do + instance_double( + 'LambdaContext', + invoked_function_arn: 'arn:aws:lambda:us-east-1:123:function:test', + function_name: 'test', + aws_request_id: 'req-1', + function_version: '$LATEST' + ) + end + + it 'preserves request-time override after on_end with no response-time interrupt' do + listener = Datadog::Trace::Listener.new( + handler_name: 'handler', function_name: 'test', + patch_http: false, merge_xray_traces: false + ) + listener.instance_variable_set(:@response_override, {'statusCode' => 403}) + listener.instance_variable_set(:@trace, span) + + listener.on_end(response: {'statusCode' => 200}, request_context: request_context) + + expect(listener.response_override).to include('statusCode' => 403) + end + end + end + end + + describe 'cross-invocation context cleanup' do + context 'when on_start raises after activating context' do + before do + allow(Datadog::AppSec).to receive_messages(enabled?: true, security_engine: security_engine) + allow(Datadog::AppSec::Context).to receive_messages(activate: nil, active: appsec_context, deactivate: nil) + allow(Datadog::Lambda::AppSec::EventNormalizer).to receive(:normalize).and_raise(StandardError, 'bad event') + end + + let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } + let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil, set_tag: nil) } + let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } + let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } + + it 'deactivates context so next invocation gets a fresh one' do + described_class.on_start( + {'httpMethod' => 'GET', 'path' => '/'}, + trace: trace, span: span + ) + + expect(Datadog::AppSec::Context).to have_received(:deactivate) + end end end end From 461c1e8f2e9bbaf333eaf781b2abb8175e33ca02 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Thu, 21 May 2026 11:24:20 +0200 Subject: [PATCH 7/7] Fix clobbering of response override * Fix cleanup of AppSec on unsuccessful start --- lib/datadog/lambda/appsec.rb | 5 +- lib/datadog/lambda/trace/listener.rb | 5 +- test/datadog/lambda/appsec.spec.rb | 188 ++++++++++----------------- 3 files changed, 78 insertions(+), 120 deletions(-) diff --git a/lib/datadog/lambda/appsec.rb b/lib/datadog/lambda/appsec.rb index 146804e5..dbad9b84 100644 --- a/lib/datadog/lambda/appsec.rb +++ b/lib/datadog/lambda/appsec.rb @@ -37,11 +37,12 @@ def on_start(event, trace:, span:, cold_start: false) context.mark_as_interrupted! response_override(interrupt_params, headers: @request.headers) rescue StandardError => e + Datadog::AppSec::Context.deactivate if context Datadog::Utils.logger.debug("failed to start AppSec: #{e}") end # rubocop:enable Metrics/AbcSize - # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity def on_finish(response) return unless enabled? @@ -70,7 +71,7 @@ def on_finish(response) ensure Datadog::AppSec::Context.deactivate if context end - # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity private diff --git a/lib/datadog/lambda/trace/listener.rb b/lib/datadog/lambda/trace/listener.rb index 078e3de6..c89a8be6 100644 --- a/lib/datadog/lambda/trace/listener.rb +++ b/lib/datadog/lambda/trace/listener.rb @@ -62,7 +62,10 @@ def on_start(event:, request_context:, cold_start:) # rubocop:enable Metrics/AbcSize def on_end(response:, request_context:) - @response_override = Datadog::Lambda::AppSec.on_finish(response) + if (override = Datadog::Lambda::AppSec.on_finish(response)) + @response_override = override + end + Datadog::Utils.send_end_invocation_request(response:, span_id: @trace.id, request_context:) @trace&.finish end diff --git a/test/datadog/lambda/appsec.spec.rb b/test/datadog/lambda/appsec.spec.rb index 15ceb1da..8628f52b 100644 --- a/test/datadog/lambda/appsec.spec.rb +++ b/test/datadog/lambda/appsec.spec.rb @@ -6,6 +6,7 @@ RSpec.describe Datadog::Lambda::AppSec do before do stub_const('Datadog::AppSec::WAF::VERSION::BASE_STRING', '1.30.0') + allow(Datadog::AppSec::Instrumentation).to receive(:gateway).and_return(gateway) allow(gateway).to receive(:push) end @@ -15,27 +16,21 @@ let(:appsec_context) do instance_double( Datadog::AppSec::Context, - span: context_span, - state: {}, - export_metrics: nil, - export_request_telemetry: nil + span: context_span, state: {}, export_metrics: nil, export_request_telemetry: nil ) end describe '.on_start' do - subject(:on_start) do - described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) - end - let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil, set_tag: nil) } context 'when appsec is disabled' do - before { allow(Datadog::AppSec).to receive(:enabled?).and_return(false) } + before do + allow(Datadog::AppSec).to receive(:enabled?).and_return(false) + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) + end it 'does not push to gateway' do - on_start - expect(gateway).not_to have_received(:push) end end @@ -50,13 +45,13 @@ let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } it 'marks span as appsec-enabled' do - on_start + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) expect(span).to have_received(:set_metric).with(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, 1) end it 'pushes event to gateway' do - on_start + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) expect(gateway).to have_received(:push).with( 'aws_lambda.request.start', kind_of(Datadog::AppSec::Instrumentation::Gateway::DataContainer) @@ -67,11 +62,10 @@ before do allow(Datadog::AppSec).to receive(:security_engine).and_return(nil) allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) end it 'skips context activation and gateway push' do - on_start - aggregate_failures('skipped activation') do expect(Datadog::AppSec::Context).not_to have_received(:activate) expect(gateway).not_to have_received(:push) @@ -80,15 +74,12 @@ end context 'when trace is nil' do - subject(:on_start) do + before do + allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: nil, span: span) end - before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } - it 'skips context activation and gateway push' do - on_start - aggregate_failures('skipped activation') do expect(Datadog::AppSec::Context).not_to have_received(:activate) expect(gateway).not_to have_received(:push) @@ -97,15 +88,12 @@ end context 'when span is nil' do - subject(:on_start) do + before do + allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: nil) end - before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } - it 'skips context activation and gateway push' do - on_start - aggregate_failures('skipped activation') do expect(Datadog::AppSec::Context).not_to have_received(:activate) expect(gateway).not_to have_received(:push) @@ -128,7 +116,11 @@ end it 'returns a Lambda-shaped blocking response' do - expect(on_start).to include( + result = described_class.on_start( + {'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span + ) + + expect(result).to include( 'statusCode' => 403, 'headers' => {'Content-Type' => 'application/json'}, 'body' => include('blocked') @@ -137,9 +129,16 @@ end context 'when an error occurs' do - before { allow(Datadog::AppSec::Context).to receive(:new).and_raise(StandardError, 'boom') } + before do + allow(Datadog::AppSec::Context).to receive(:new).and_raise(StandardError, 'boom') + allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) + end - it { expect { on_start }.not_to raise_error } + it 'does not raise' do + expect { + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) + }.not_to raise_error + end end context 'when waf ruleset is loaded' do @@ -157,16 +156,12 @@ let(:appsec_context) do instance_double( Datadog::AppSec::Context, - span: span, - trace: trace, - state: {}, - export_metrics: nil, - export_request_telemetry: nil + span: span, trace: trace, state: {}, export_metrics: nil, export_request_telemetry: nil ) end it 'sets runtime family and WAF version on the span' do - on_start + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) aggregate_failures('appsec span tags') do expect(span).to have_received(:set_tag).with('_dd.runtime_family', 'ruby') @@ -175,27 +170,25 @@ end it 'sets event rules version from the WAF runner' do - on_start + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) expect(span).to have_received(:set_tag).with('_dd.appsec.event_rules.version', '1.12.0') end context 'when cold_start is true' do - subject(:on_start) do + before do described_class.on_start( - {'httpMethod' => 'GET', 'path' => '/'}, - trace: trace, span: span, cold_start: true + {'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span, cold_start: true ) end it 'sets known addresses and keeps trace' do - on_start - aggregate_failures('cold start tags') do expect(span).to have_received(:set_tag).with( '_dd.appsec.event_rules.addresses', '["server.request.headers.no_cookies"]' ) + expect(trace).to have_received(:keep!) expect(trace).to have_received(:set_tag).with( Datadog::Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, @@ -206,9 +199,11 @@ end context 'when cold_start is false' do - it 'does not send cold start tags' do - on_start + before do + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) + end + it 'does not send cold start tags' do aggregate_failures('no cold start tags') do expect(span).not_to have_received(:set_tag).with('_dd.appsec.event_rules.addresses', anything) expect(trace).not_to have_received(:keep!) @@ -217,11 +212,12 @@ end context 'when ruleset version is not set' do - before { allow(appsec_context).to receive(:waf_runner_ruleset_version).and_return(nil) } + before do + allow(appsec_context).to receive(:waf_runner_ruleset_version).and_return(nil) + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) + end it 'skips event rules tags' do - on_start - aggregate_failures('skipped rules tags') do expect(span).not_to have_received(:set_tag).with('_dd.appsec.event_rules.version', anything) expect(span).not_to have_received(:set_tag).with('_dd.appsec.event_rules.addresses', anything) @@ -230,25 +226,23 @@ end context 'when span is not set' do - subject(:on_start) do + before do + allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: nil) end - before { allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) } - it 'does not set any appsec tags' do - on_start - expect(span).not_to have_received(:set_tag) end end context 'when context trace is not set' do - before { allow(appsec_context).to receive(:trace).and_return(nil) } + before do + allow(appsec_context).to receive(:trace).and_return(nil) + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) + end it 'does not set any tags' do - on_start - aggregate_failures('no tags when trace nil') do expect(span).not_to have_received(:set_tag) expect(span).not_to have_received(:set_metric).with(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, anything) @@ -260,17 +254,14 @@ end describe '.on_finish' do - subject(:on_finish) { described_class.on_finish({ 'statusCode' => 200 }) } - context 'when appsec is disabled' do before do allow(Datadog::AppSec).to receive(:enabled?).and_return(false) allow(Datadog::AppSec::Context).to receive(:active).and_return(appsec_context) + described_class.on_finish({'statusCode' => 200}) end it 'does not push to gateway' do - on_finish - expect(gateway).not_to have_received(:push) end end @@ -279,11 +270,10 @@ before do allow(Datadog::AppSec).to receive(:enabled?).and_return(true) allow(Datadog::AppSec::Context).to receive(:active).and_return(nil) + described_class.on_finish({'statusCode' => 200}) end it 'does not push to gateway' do - on_finish - expect(gateway).not_to have_received(:push) end end @@ -296,7 +286,7 @@ end it 'pushes response and records events' do - on_finish + described_class.on_finish({'statusCode' => 200}) aggregate_failures('response processing') do expect(gateway).to have_received(:push).with( @@ -307,7 +297,7 @@ end it 'exports telemetry and deactivates' do - on_finish + described_class.on_finish({'statusCode' => 200}) aggregate_failures('AppSec deactivation') do expect(appsec_context).to have_received(:export_metrics) @@ -329,6 +319,7 @@ }, trace: trace, span: span ) + described_class.on_finish({'statusCode' => 200}) end let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } @@ -337,8 +328,6 @@ let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } it 'records security event with request' do - on_finish - expect(Datadog::AppSec::Event).to have_received(:record).with( appsec_context, request: kind_of(Datadog::Lambda::AppSec::Request) ) @@ -366,14 +355,14 @@ let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } it 'returns a Lambda-shaped blocking response' do - expect(on_finish).to include( + expect(described_class.on_finish({'statusCode' => 200})).to include( 'statusCode' => 403, 'headers' => {'Content-Type' => 'application/json'} ) end it 'still records events and deactivates' do - on_finish + described_class.on_finish({'statusCode' => 200}) aggregate_failures('cleanup after interrupt') do expect(Datadog::AppSec::Event).to have_received(:record) @@ -384,75 +373,43 @@ end context 'when an error occurs' do - before { allow(gateway).to receive(:push).and_raise(StandardError, 'boom') } + before do + allow(gateway).to receive(:push).and_raise(StandardError, 'boom') + described_class.on_finish({'statusCode' => 200}) + end it 'still deactivates the context' do - on_finish - expect(Datadog::AppSec::Context).to have_received(:deactivate) end end context 'when request-time override is clobbered by on_finish returning nil' do before do - allow(Datadog::AppSec).to receive(:security_engine).and_return(security_engine) - allow(Datadog::AppSec::Context).to receive(:activate) - allow(appsec_context).to receive_messages( - trace: trace, - waf_runner_ruleset_version: nil, - mark_as_interrupted!: nil - ) + allow(Datadog::Utils).to receive(:send_end_invocation_request) + allow(span).to receive_messages(id: 1, finish: nil) - allow(gateway).to receive(:push).and_invoke( - lambda { |name, _payload| - if name == 'aws_lambda.request.start' - throw(Datadog::AppSec::Ext::INTERRUPT, {'status_code' => 403, 'type' => 'auto'}) - end - } - ) - - described_class.on_start( - {'httpMethod' => 'GET', 'headers' => {'Accept' => 'application/json'}}, - trace: trace, span: span - ) + listener.instance_variable_set(:@response_override, {'statusCode' => 403}) + listener.instance_variable_set(:@trace, span) + listener.on_end(response: {'statusCode' => 200}, request_context: request_context) + end - allow(Datadog::Trace).to receive(:extract_trace_context).and_return({}) - allow(Datadog::Trace).to receive(:trace_context).and_return({}) - allow(Datadog::Trace).to receive(:apply_datadog_trace_context) - allow(Datadog::Tracing).to receive(:trace).and_return(span) - allow(Datadog::Tracing).to receive(:active_trace).and_return(trace) - allow(Datadog::Utils).to receive_messages( - send_start_invocation_request: nil, - send_end_invocation_request: nil + let(:listener) do + Datadog::Trace::Listener.new( + handler_name: 'handler', function_name: 'test', + patch_http: false, merge_xray_traces: false ) - allow(span).to receive(:id).and_return(1) - allow(span).to receive(:finish) end - - let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } let(:span) { instance_double(Datadog::Tracing::SpanOperation, set_metric: nil, set_tag: nil) } - let(:security_engine) { instance_double(Datadog::AppSec::SecurityEngine::Engine, new_runner: waf_runner) } - let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } let(:request_context) do instance_double( 'LambdaContext', invoked_function_arn: 'arn:aws:lambda:us-east-1:123:function:test', function_name: 'test', - aws_request_id: 'req-1', - function_version: '$LATEST' + aws_request_id: 'req-1' ) end it 'preserves request-time override after on_end with no response-time interrupt' do - listener = Datadog::Trace::Listener.new( - handler_name: 'handler', function_name: 'test', - patch_http: false, merge_xray_traces: false - ) - listener.instance_variable_set(:@response_override, {'statusCode' => 403}) - listener.instance_variable_set(:@trace, span) - - listener.on_end(response: {'statusCode' => 200}, request_context: request_context) - expect(listener.response_override).to include('statusCode' => 403) end end @@ -465,6 +422,8 @@ allow(Datadog::AppSec).to receive_messages(enabled?: true, security_engine: security_engine) allow(Datadog::AppSec::Context).to receive_messages(activate: nil, active: appsec_context, deactivate: nil) allow(Datadog::Lambda::AppSec::EventNormalizer).to receive(:normalize).and_raise(StandardError, 'bad event') + + described_class.on_start({'httpMethod' => 'GET', 'path' => '/'}, trace: trace, span: span) end let(:trace) { instance_double(Datadog::Tracing::TraceOperation) } @@ -473,11 +432,6 @@ let(:waf_runner) { instance_double(Datadog::AppSec::SecurityEngine::Runner, ruleset_version: nil) } it 'deactivates context so next invocation gets a fresh one' do - described_class.on_start( - {'httpMethod' => 'GET', 'path' => '/'}, - trace: trace, span: span - ) - expect(Datadog::AppSec::Context).to have_received(:deactivate) end end