diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..a7f48dfeb --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @DataDog/serverless-aws @DataDog/apm-serverless diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7cf30ef26..050624478 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,8 @@ on: branches: - "main" pull_request: + schedule: + - cron: '0 0,12 * * *' # Runs every day at midnight and noon utc jobs: lint: @@ -12,10 +14,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: 3.9 @@ -41,14 +43,14 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.6, 3.7, 3.8, 3.9] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -62,73 +64,4 @@ jobs: - name: Run tests run: | source venv/bin/activate - nose2 -v - - integration-test: - runs-on: ubuntu-latest - strategy: - matrix: - runtime-param: [3.6, 3.7, 3.8, 3.9] - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Node 14 - uses: actions/setup-node@v1 - with: - node-version: 14 - - - name: Cache Node modules - id: cache-node-modules - uses: actions/cache@v2 - with: - path: "**/node_modules" - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - - name: Install Python dependencies - run: | - pip install virtualenv - virtualenv venv - source venv/bin/activate - pip install .[dev] - - - name: Install Serverless Framework - run: sudo yarn global add serverless --prefix /usr/local - - name: Install Crossbuild Deps - run: sudo apt install -y qemu-user-static binfmt-support - - - name: Install dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - working-directory: tests/integration - run: yarn install - - - name: Run tests - env: - BUILD_LAYERS: true - DD_API_KEY: ${{ secrets.DD_API_KEY }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - RUNTIME_PARAM: ${{ matrix.runtime-param }} - run: ./scripts/run_integration_tests.sh - - - name: Send success metric - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - run: ./scripts/send_status_metric.sh 0 $DD_API_KEY - - integration-test-failure: - runs-on: ubuntu-latest - needs: [integration-test] - if: always() && (needs.integration-test.result == 'failure') - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Send a failure metric - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - run: ./scripts/send_status_metric.sh 1 $DD_API_KEY + pytest -vv diff --git a/.github/workflows/build_layer.yml b/.github/workflows/build_layer.yml new file mode 100644 index 000000000..789868ed0 --- /dev/null +++ b/.github/workflows/build_layer.yml @@ -0,0 +1,35 @@ +name: Build Layers for system-Tests + +on: + push: + branches: + - "main" + +jobs: + build: + runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} + + strategy: + matrix: + arch: [arm64, amd64] + python_version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Patch pyproject.toml + run: | + echo "Patching pyproject.toml to use main branch of dd-trace-py" + sed -i 's|^ddtrace =.*$|ddtrace = { git = "https://github.com/DataDog/dd-trace-py.git" }|' pyproject.toml + + - name: Build layer for Python ${{ matrix.python_version }} on ${{ matrix.arch }} + run: | + echo "Building layer for Python ${{ matrix.python_version }} on ${{ matrix.arch }}" + ARCH=${{ matrix.arch }} PYTHON_VERSION=${{ matrix.python_version }} ./scripts/build_layers.sh + + - name: Upload layer artifact + uses: actions/upload-artifact@v4 + with: + path: .layers/datadog_lambda_py-${{ matrix.arch }}-${{ matrix.python_version }}.zip + name: datadog-lambda-python-${{ matrix.python_version }}-${{ matrix.arch }} diff --git a/.github/workflows/check-size.yml b/.github/workflows/check-size.yml deleted file mode 100644 index 69d578d05..000000000 --- a/.github/workflows/check-size.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: check-size - -on: pull_request - -jobs: - check-size: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.7 - - - name: Install Crossbuild Deps - run: sudo apt install -y qemu-user-static binfmt-support - - - name: Install dependencies - run: | - pip install virtualenv - virtualenv venv - source venv/bin/activate - pip install .[dev] - - - name: Build Layers - run: ./scripts/build_layers.sh - - - name: Check Size - run: ./scripts/check_layer_size.sh diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..985f09f22 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '37 1 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/system_tests.yml b/.github/workflows/system_tests.yml new file mode 100644 index 000000000..b61725b1a --- /dev/null +++ b/.github/workflows/system_tests.yml @@ -0,0 +1,38 @@ +name: System Tests + +on: + push: + branches: + - main + pull_request: + branches: + - "**" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build layer + run: | + ARCH=amd64 PYTHON_VERSION=3.13 ./scripts/build_layers.sh + + - uses: actions/upload-artifact@v4 + with: + path: .layers/datadog_lambda_py-amd64-3.13.zip + name: binaries + + system-tests: + needs: + - build + uses: DataDog/system-tests/.github/workflows/system-tests.yml@main + secrets: inherit + permissions: + contents: read + packages: write + with: + library: python_lambda + binaries_artifact: binaries + scenarios_groups: appsec + skip_empty_scenarios: true diff --git a/.github/workflows/update-snapshots.yml b/.github/workflows/update-snapshots.yml new file mode 100644 index 000000000..ed7097aed --- /dev/null +++ b/.github/workflows/update-snapshots.yml @@ -0,0 +1,66 @@ +name: update-snapshots + +on: + schedule: + - cron: "0 15 * * *" # every day 11am EST + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up Node 14 + uses: actions/setup-node@v3 + with: + node-version: 14 + + - name: Cache Node modules + id: cache-node-modules + uses: actions/cache@v3 + with: + path: "**/node_modules" + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.9 + + - name: Install Python dependencies + run: | + pip install virtualenv + virtualenv venv + source venv/bin/activate + pip install .[dev] + + - name: Install Serverless Framework + run: sudo yarn global add serverless@^3.7.0 --prefix /usr/local + - name: Install Crossbuild Deps + run: | + sudo apt-get update --allow-releaseinfo-change --fix-missing + sudo apt install -y qemu-user-static binfmt-support + + - name: Install dependencies + if: steps.cache-node-modules.outputs.cache-hit != 'true' + working-directory: tests/integration + run: yarn install + + - name: Update Snapshots + env: + UPDATE_SNAPSHOTS: true + BUILD_LAYERS: true + DD_API_KEY: ${{ secrets.DD_API_KEY }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: ./scripts/run_integration_tests.sh + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + commit-message: update snapshots + title: Update Snapshots + body: | + Autogenerated PR to update integration test snapshots. Make sure no difference when run in local environment before merging. + branch: update-snapshots diff --git a/.github/workflows/update_deps.yml b/.github/workflows/update_deps.yml index 0c2197557..15a3ac665 100644 --- a/.github/workflows/update_deps.yml +++ b/.github/workflows/update_deps.yml @@ -3,30 +3,39 @@ name: update-deps on: schedule: - cron: "0 10 * * *" # Run at 10 am every day + workflow_dispatch: jobs: check: runs-on: ubuntu-latest + environment: + name: protected-main-env steps: - - uses: actions/checkout@v2 + - name: Generate token + id: generate_token + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 with: - ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} + app-id: ${{ secrets.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v3 + with: + token: ${{ steps.generate_token.outputs.token }} - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.13 - name: Update Dependencies run: | - curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python - - source $HOME/.poetry/env - poetry build + pip install poetry poetry update - name: Create Pull Request uses: peter-evans/create-pull-request@v3 with: + token: ${{ steps.generate_token.outputs.token }} commit-message: update dependencies title: Update Dependencies body: | diff --git a/.gitignore b/.gitignore index d6b01dbff..ff0272ba6 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,6 @@ pip-log.txt # Unit test / coverage reports .coverage .tox -nosetests.xml #Misc .cache/ @@ -42,3 +41,5 @@ nosetests.xml node_modules yarn-lock.json + +.benchmarks diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..0f36a781d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,29 @@ +stages: + - pre + - build + +.go-cache: &go-cache + key: datadog-lambda-python-go-cache + policy: pull + +generator: + stage: pre + image: registry.ddbuild.io/images/mirror/golang:alpine + tags: ["arch:amd64"] + cache: *go-cache + script: + - apk add --no-cache gomplate + - gomplate --config ci/config.yaml + artifacts: + paths: + - ci/*-pipeline.yaml + +build-layers: + stage: build + trigger: + include: + - artifact: ci/build-pipeline.yaml + job: generator + strategy: depend + rules: + - when: on_success diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..fb1d43eb9 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Module", + "type": "python", + "request": "launch", + "module": "unittest", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index db92ccf34..e58c4de23 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { "python.pythonPath": "/usr/local/bin/python3", - "python.formatting.provider": "black" + "python.formatting.provider": "black", + "python.testing.unittestArgs": ["-v", "-s", "./tests", "-p", "test*.py"], + "python.testing.pytestEnabled": false, + "python.testing.unittestEnabled": true } diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index e340f1ed6..000000000 --- a/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @DataDog/serverless \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index befae3ca1..d632d1513 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ We love pull requests. For new features, consider opening an issue to discuss th ./scripts/build_layers.sh # Publish the a testing layer to your own AWS account, and the ARN will be returned - # Example: VERSION=1 REGIONS=us-east-1 LAYERS=Datadog-Python37 ./scripts/publish_layers.sh + # Example: VERSION=1 REGIONS=us-east-1 LAYERS=Datadog-Python313 ./scripts/publish_layers.sh VERSION= REGIONS= LAYERS= ./scripts/publish_layers.sh ``` diff --git a/Dockerfile b/Dockerfile index 5955a2958..cc9e9d70f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ARG image -FROM $image +FROM $image as builder ARG runtime @@ -7,17 +7,78 @@ ARG runtime RUN mkdir -p /build/python/lib/$runtime/site-packages WORKDIR /build +# Install newer version of GCC on AL2 +RUN set -eux; \ + if command -v yum >/dev/null 2>&1; then \ + yum -y install git gcc10 gcc10-c++; \ + cd /usr/bin; \ + rm gcc && ln -s gcc10-gcc gcc; \ + rm g++ && ln -s gcc10-g++ g++; \ + rm cc && ln -s gcc10-cc cc; \ + fi + +# Add Rust compiler which is needed to build dd-trace-py from source +RUN curl https://sh.rustup.rs -sSf | \ + sh -s -- --default-toolchain stable -y +ENV PATH=/root/.cargo/bin:$PATH + # Install datadog_lambda and dependencies from local COPY . . -RUN pip install . -t ./python/lib/$runtime/site-packages - -# Remove *.pyc files -RUN find ./python/lib/$runtime/site-packages -name \*.pyc -delete +RUN pip install --no-cache-dir . -t ./python/lib/$runtime/site-packages # Remove botocore (40MB) to reduce package size. aws-xray-sdk # installs it, while it's already provided by the Lambda Runtime. RUN rm -rf ./python/lib/$runtime/site-packages/botocore* +RUN rm -rf ./python/lib/$runtime/site-packages/setuptools +RUN rm -rf ./python/lib/$runtime/site-packages/jsonschema/tests +RUN rm -f ./python/lib/$runtime/site-packages/ddtrace/appsec/_iast/_ast/iastpatch*.so +RUN rm -f ./python/lib/$runtime/site-packages/ddtrace/appsec/_iast/_taint_tracking/*.so +RUN rm -f ./python/lib/$runtime/site-packages/ddtrace/appsec/_iast/_stacktrace*.so +# _stack_v2 may not exist for some versions of ddtrace (e.g. under python 3.13) +RUN rm -f ./python/lib/$runtime/site-packages/ddtrace/internal/datadog/profiling/stack_v2/_stack_v2.*.so +# remove *.dist-info directories except any entry_points.txt files and METADATA files required for Appsec Software Composition Analysis +RUN find ./python/lib/$runtime/site-packages/*.dist-info \ + -type f \ + ! \( -name 'entry_points.txt' -o -name 'METADATA' \) \ + -delete +RUN find ./python/lib/$runtime/site-packages -type d -empty -delete + +# Remove requests and dependencies +RUN rm -rf \ + ./python/lib/$runtime/site-packages/requests* \ + ./python/lib/$runtime/site-packages/urllib3* \ + ./python/lib/$runtime/site-packages/certifi* \ + ./python/lib/$runtime/site-packages/idna* \ + ./python/lib/$runtime/site-packages/charset_normalizer* + +# Precompile all .pyc files and remove .py files. This speeds up load time. +# Compile with optimization level 2 (-OO) and PYTHONNODEBUGRANGES=1 to redtce +# size of .pyc files. +# See https://docs.python.org/3/tutorial/modules.html#compiled-python-files +# https://docs.python.org/3.11/using/cmdline.html#cmdoption-O +# https://docs.python.org/3/using/cmdline.html#envvar-PYTHONNODEBUGRANGES +RUN PYTHONNODEBUGRANGES=1 python -OO -m compileall -b ./python/lib/$runtime/site-packages +# remove all .py files except ddtrace/contrib/*/patch.py which are necessary +# for ddtrace.patch to discover instrumationation packages. +RUN find ./python/lib/$runtime/site-packages -name \*.py | grep -v ddtrace/contrib | xargs rm -rf +RUN find ./python/lib/$runtime/site-packages/ddtrace/contrib -name \*.py | grep -v patch.py | xargs rm -rf +RUN find ./python/lib/$runtime/site-packages -name __pycache__ -type d -exec rm -r {} \+ + +# When building ddtrace from branch, remove extra source files. These are +# removed by the ddtrace build process before publishing a wheel to PyPI. +RUN find ./python/lib/$runtime/site-packages/ddtrace -name \*.c -delete +RUN find ./python/lib/$runtime/site-packages/ddtrace -name \*.cpp -delete +RUN find ./python/lib/$runtime/site-packages/ddtrace -name \*.cc -delete +RUN find ./python/lib/$runtime/site-packages/ddtrace -name \*.h -delete +RUN find ./python/lib/$runtime/site-packages/ddtrace -name \*.hpp -delete +RUN find ./python/lib/$runtime/site-packages/ddtrace -name \*.pyx -delete + +# Strip debug symbols and symbols that are not needed for relocation +# processing using strip --strip-unneeded for all .so files. This is to +# reduce the size when ddtrace is built from sources. The release wheels are +# already stripped of debug symbols. We should revisit this when serverless +# benchmark uses pre-built wheels instead of building from sources. +RUN find ./python/lib/$runtime/site-packages -name "*.so" -exec strip --strip-unneeded {} \; -# Remove profiling (7MB) to reduce package size. -# Continous profiling is not yet supported anyway. -RUN rm -rf ./python/lib/$runtime/site-packages/ddtrace/profiling \ No newline at end of file +FROM scratch +COPY --from=builder /build/python / diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index e15ac6e59..1cfacb703 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -1,4 +1,13 @@ Component,Origin,License,Copyright +datadog,github.com/DataDog/datadogpy,BSD-3-Clause,"Copyright (c) 2015-Present Datadog, Inc " +wrapt,github.com/GrahamDumpleton/wrapt,BSD-2-Clause,"Copyright (c) 2013-2019, Graham Dumpleton" +ddtrace,github.com/DataDog/dd-trace-py,BSD-3-Clause,"Copyright (c) 2016, Datadog " +urllib3,github.com/urllib3/urllib3,MIT,Copyright (c) 2008-2020 Andrey Petrov and contributors. +ujson,github.com/ultrajson/ultrajson,BSD-3-Clause,"Copyright (c) 2014, Electronic Arts Inc" +importlib_metadata,github.com/python/importlib_metadata,Apache-2.0,Copyright © Jason R. Coombs +boto3,github.com/boto/boto3,Apache-2.0,"Copyright 2013-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved." +typing_extensions,github.com/python/typing_extensions,PSF-2.0,"Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved" +requests,github.com/psf/requests,Apache-2.0,"Copyright 2018 Kenneth Reitz" +pytest,github.com/pytest-dev/pytest,MIT,Copyright (c) 2004 Holger Krekel and others +pytest-benchmark,github.com/ionelmc/pytest-benchmark,BSD-2-Clause,"Copyright (c) 2014-2023, Ionel Cristian Mărieș. All rights reserved." flake8,gitlab.com/pycqa/flake8,MIT,"Copyright (C) 2011-2013 Tarek Ziade . Copyright (C) 2012-2016 Ian Cordasco ." -nose2,github.com/nose-devs/nose2,BSD-2-Clause,"Copyright (c) 2012, Jason Pellerin. All rights reserved." -wrapt,github.com/GrahamDumpleton/wrapt,BSD-2-Clause,"Copyright (c) 2013-2019, Graham Dumpleton" \ No newline at end of file diff --git a/README.md b/README.md index c40bcca8b..658babc28 100644 --- a/README.md +++ b/README.md @@ -6,94 +6,59 @@ [![Slack](https://chat.datadoghq.com/badge.svg?bg=632CA6)](https://chat.datadoghq.com/) [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/DataDog/datadog-lambda-python/blob/main/LICENSE) -Datadog Lambda Library for Python (3.6, 3.7, 3.8, and 3.9) enables enhanced Lambda metrics, distributed tracing, and custom metric submission from AWS Lambda functions. - -**IMPORTANT NOTE:** AWS Lambda is expected to receive a [breaking change](https://aws.amazon.com/blogs/compute/upcoming-changes-to-the-python-sdk-in-aws-lambda/) on **March 31, 2021**. If you are using Datadog Python Lambda layer version 7 or below, please upgrade to the latest. +Datadog Lambda Library for Python (3.8, 3.9, 3.10, 3.11, 3.12, and 3.13) enables [enhanced Lambda metrics](https://docs.datadoghq.com/serverless/enhanced_lambda_metrics), [distributed tracing](https://docs.datadoghq.com/serverless/distributed_tracing), and [custom metric submission](https://docs.datadoghq.com/serverless/custom_metrics) from AWS Lambda functions. ## Installation Follow the [installation instructions](https://docs.datadoghq.com/serverless/installation/python/), and view your function's enhanced metrics, traces and logs in Datadog. -## Custom Metrics - -Once [installed](#installation), you should be able to submit custom metrics from your Lambda function. - -Check out the instructions for [submitting custom metrics from AWS Lambda functions](https://docs.datadoghq.com/integrations/amazon_lambda/?tab=python#custom-metrics). - -## Tracing - -Once [installed](#installation), you should be able to view your function's traces in Datadog, and your function's logs should be automatically connected to the traces. - -For additional details on trace collection, take a look at [collecting traces from AWS Lambda functions](https://docs.datadoghq.com/integrations/amazon_lambda/?tab=python#trace-collection). - -For additional details on trace and log connection, see [connecting logs and traces](https://docs.datadoghq.com/tracing/connect_logs_and_traces/python/). - -For additional details on the tracer, check out the [official documentation for Datadog trace client](http://pypi.datadoghq.com/trace/docs/index.html). - -## Enhanced Metrics - -Once [installed](#installation), you should be able to view enhanced metrics for your Lambda function in Datadog. - -Check out the official documentation on [Datadog Lambda enhanced metrics](https://docs.datadoghq.com/integrations/amazon_lambda/?tab=python#real-time-enhanced-lambda-metrics). - -## Environment Variables - -### DD_FLUSH_TO_LOG - -Set to `true` (recommended) to send custom metrics asynchronously (with no added latency to your Lambda function executions) through CloudWatch Logs with the help of [Datadog Forwarder](https://github.com/DataDog/datadog-serverless-functions/tree/main/aws/logs_monitoring). Defaults to `false`. If set to `false`, you also need to set `DD_API_KEY` and `DD_SITE`. - -### DD_API_KEY +## Configuration -If `DD_FLUSH_TO_LOG` is set to `false` (not recommended), the Datadog API Key must be defined by setting one of the following environment variables: +Follow the [configuration instructions](https://docs.datadoghq.com/serverless/configuration) to tag your telemetry, capture request/response payloads, filter or scrub sensitive information from logs or traces, and more. -- DD_API_KEY - the Datadog API Key in plain-text, NOT recommended -- DD_KMS_API_KEY - the KMS-encrypted API Key, requires the `kms:Decrypt` permission -- DD_API_KEY_SECRET_ARN - the Secret ARN to fetch API Key from the Secrets Manager, requires the `secretsmanager:GetSecretValue` permission (and `kms:Decrypt` if using a customer managed CMK) -- DD_API_KEY_SSM_NAME - the Parameter Name to fetch API Key from the Systems Manager Parameter Store, requires the `ssm:GetParameter` permission (and `kms:Decrypt` if using a SecureString with a customer managed CMK) +For additional tracing configuration options, check out the [official documentation for Datadog trace client](https://ddtrace.readthedocs.io/en/stable/configuration.html). -You can also supply or override the API key at runtime (not recommended): +Besides the environment variables supported by dd-trace-py, the datadog-lambda-python library added following environment variables. -```python -# Override DD API Key after importing datadog_lambda packages -from datadog import api -api._api_key = "MY_API_KEY" -``` +| Environment Variables | Description | Default Value | +| -------------------- | ------------ | ------------- | +| DD_ENCODE_AUTHORIZER_CONTEXT | When set to `true` for Lambda authorizers, the tracing context will be encoded into the response for propagation. Supported for NodeJS and Python. | `true` | +| DD_DECODE_AUTHORIZER_CONTEXT | When set to `true` for Lambdas that are authorized via Lambda authorizers, it will parse and use the encoded tracing context (if found). Supported for NodeJS and Python. | `true` | +| DD_COLD_START_TRACING | When true (default), tracing occurs during cold start which creates many child spans. When false, only one cold start span is created. Used in NodeJS and Python. | `true` | +| DD_MIN_COLD_START_DURATION | Sets the minimum duration (in milliseconds) for a module load event to be traced via Cold Start Tracing. Number. | `3` | +| DD_COLD_START_TRACE_SKIP_LIB | optionally skip creating Cold Start Spans for a comma-separated list of libraries. Useful to limit depth or skip known libraries. | `ddtrace.internal.compat,ddtrace.filters` | +| DD_CAPTURE_LAMBDA_PAYLOAD | [Captures incoming and outgoing AWS Lambda payloads][1] in the Datadog APM spans for Lambda invocations. | `false` | +| DD_CAPTURE_LAMBDA_PAYLOAD_MAX_DEPTH | Determines the level of detail captured from AWS Lambda payloads, which are then assigned as tags for the `aws.lambda` span. It specifies the nesting depth of the JSON payload structure to process. Once the specified maximum depth is reached, the tag's value is set to the stringified value of any nested elements beyond this level.
For example, given the input payload:
{
"lv1" : {
"lv2": {
"lv3": "val"
}
}
}
If the depth is set to `2`, the resulting tag's key is set to `function.request.lv1.lv2` and the value is `{\"lv3\": \"val\"}`.
If the depth is set to `0`, the resulting tag's key is set to `function.request` and value is `{\"lv1\":{\"lv2\":{\"lv3\": \"val\"}}}` | `10` | +| DD_EXCEPTION_REPLAY_ENABLED | When set to `true`, the Lambda will run with Error Tracking Exception Replay enabled, capturing local variables. | `false` | -### DD_SITE -If `DD_FLUSH_TO_LOG` is set to `false` (not recommended), you must set `DD_SITE`. Possible values are `datadoghq.com`, `datadoghq.eu`, `us3.datadoghq.com`, `us5.datadoghq.com`, and `ddog-gov.com`. The default is `datadoghq.com`. - -### DD_LOGS_INJECTION - -Inject Datadog trace id into logs for [correlation](https://docs.datadoghq.com/tracing/connect_logs_and_traces/python/) if you are using a `logging.Formatter` in the default `LambdaLoggerHandler` by the Lambda runtime. Defaults to `true`. - -### DD_LOG_LEVEL - -Set to `debug` enable debug logs from the Datadog Lambda Library. Defaults to `info`. - -### DD_ENHANCED_METRICS +## Opening Issues -Generate enhanced Datadog Lambda integration metrics, such as, `aws.lambda.enhanced.invocations` and `aws.lambda.enhanced.errors`. Defaults to `true`. +If you encounter a bug with this package, we want to hear about it. Before opening a new issue, search the existing issues to avoid duplicates. -### DD_LAMBDA_HANDLER +When opening an issue, include the Datadog Lambda Library version, Python version, and stack trace if available. In addition, include the steps to reproduce when appropriate. -Your original Lambda handler. +You can also open an issue for a feature request. -### DD_TRACE_ENABLED +## Lambda Profiling Beta -Initialize the Datadog tracer when set to `true`. Defaults to `false`. +Datadog's [Continuous Profiler](https://www.datadoghq.com/product/code-profiling/) is now available in beta for Python in version 4.62.0 and layer version 62 and above. This optional feature is enabled by setting the `DD_PROFILING_ENABLED` environment variable to `true`. During the beta period, profiling is available at no additional cost. -### DD_MERGE_XRAY_TRACES +The Continuous Profiler works by spawning a thread which periodically wakes up and takes a snapshot of the CPU and Heap of all running python code. This can include the profiler itself. If you want the Profiler to ignore itself, set `DD_PROFILING_IGNORE_PROFILER` to `true`. -Set to `true` to merge the X-Ray trace and the Datadog trace, when using both the X-Ray and Datadog tracing. Defaults to `false`. +## Major Version Notes -## Opening Issues +### 6.x / Layer version 95+ +- The release changed how Lambda's traceID is hashed if the incoming payload contains Step Functions context object. This change only affects those who uses inject Step Functions context object into Lambda payload. -If you encounter a bug with this package, we want to hear about it. Before opening a new issue, search the existing issues to avoid duplicates. +### 5.x / Layer version 86+ +- Python3.7 support has been [deprecated](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) by AWS, and support removed from this library. -When opening an issue, include the Datadog Lambda Library version, Python version, and stack trace if available. In addition, include the steps to reproduce when appropriate. +### 4.x / Layer version 61+ -You can also open an issue for a feature request. +- Python3.6 support has been [deprecated](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) by AWS, and support removed from this library. +- `dd-trace` upgraded from 0.61 to 1.4, full release notes are available [here](https://ddtrace.readthedocs.io/en/stable/release_notes.html#v1-0-0) + - `get_correlation_ids()` has been changed to `get_log_correlation_context()`, which now returns a dictionary containing the active `span_id`, `trace_id`, as well as `service` and `env`. ## Contributing @@ -108,3 +73,5 @@ For product feedback and questions, join the `#serverless` channel in the [Datad Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2019 Datadog, Inc. + +[1]: https://www.datadoghq.com/blog/troubleshoot-lambda-function-request-response-payloads/ diff --git a/ci/config.yaml b/ci/config.yaml new file mode 100644 index 000000000..d37a0f316 --- /dev/null +++ b/ci/config.yaml @@ -0,0 +1,13 @@ +inputFiles: + - ci/input_files/build.yaml.tpl + +outputFiles: + - ci/build-pipeline.yaml + +datasources: + runtimes: + url: ci/datasources/runtimes.yaml + regions: + url: ci/datasources/regions.yaml + environments: + url: ci/datasources/environments.yaml diff --git a/ci/datasources/environments.yaml b/ci/datasources/environments.yaml new file mode 100644 index 000000000..1ae2b4d71 --- /dev/null +++ b/ci/datasources/environments.yaml @@ -0,0 +1,9 @@ +environments: + sandbox: + external_id: sandbox-publish-externalid + role_to_assume: sandbox-layer-deployer + account: 425362996713 + prod: + external_id: prod-publish-externalid + role_to_assume: dd-serverless-layer-deployer-role + account: 464622532012 diff --git a/ci/datasources/regions.yaml b/ci/datasources/regions.yaml new file mode 100644 index 000000000..d41bade3a --- /dev/null +++ b/ci/datasources/regions.yaml @@ -0,0 +1,33 @@ +regions: + - code: "us-east-1" + - code: "us-east-2" + - code: "us-west-1" + - code: "us-west-2" + - code: "af-south-1" + - code: "ap-east-1" + - code: "ap-south-1" + - code: "ap-south-2" + - code: "ap-southeast-1" + - code: "ap-southeast-2" + - code: "ap-southeast-3" + - code: "ap-southeast-4" + - code: "ap-southeast-5" + - code: "ap-southeast-7" + - code: "ap-northeast-1" + - code: "ap-northeast-2" + - code: "ap-northeast-3" + - code: "ca-central-1" + - code: "ca-west-1" + - code: "eu-central-1" + - code: "eu-central-2" + - code: "eu-north-1" + - code: "eu-west-1" + - code: "eu-west-2" + - code: "eu-west-3" + - code: "eu-south-1" + - code: "eu-south-2" + - code: "il-central-1" + - code: "me-south-1" + - code: "me-central-1" + - code: "mx-central-1" + - code: "sa-east-1" diff --git a/ci/datasources/runtimes.yaml b/ci/datasources/runtimes.yaml new file mode 100644 index 000000000..f9456d396 --- /dev/null +++ b/ci/datasources/runtimes.yaml @@ -0,0 +1,49 @@ +runtimes: + - name: "python38" + python_version: "3.8" + arch: "amd64" + image: "3.8" + - name: "python38" + python_version: "3.8" + arch: "arm64" + image: "3.8" + - name: "python39" + python_version: "3.9" + arch: "amd64" + image: "3.9" + - name: "python39" + python_version: "3.9" + arch: "arm64" + image: "3.9" + - name: "python310" + python_version: "3.10" + arch: "amd64" + image: "3.10" + - name: "python310" + python_version: "3.10" + arch: "arm64" + image: "3.10" + - name: "python311" + python_version: "3.11" + arch: "amd64" + image: "3.11.6" + - name: "python311" + python_version: "3.11" + arch: "arm64" + image: "3.11.6" + - name: "python312" + python_version: "3.12" + arch: "amd64" + image: "3.12.0" + - name: "python312" + python_version: "3.12" + arch: "arm64" + image: "3.12.0" + - name: "python313" + python_version: "3.13" + arch: "amd64" + image: "3.13.0" + - name: "python313" + python_version: "3.13" + arch: "arm64" + image: "3.13.0" diff --git a/ci/get_secrets.sh b/ci/get_secrets.sh new file mode 100755 index 000000000..9d9c957c0 --- /dev/null +++ b/ci/get_secrets.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Unless explicitly stated otherwise all files in this repository are licensed +# under the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2023 Datadog, Inc. + +set -e + +if [ -z "$EXTERNAL_ID_NAME" ]; then + printf "[Error] No EXTERNAL_ID_NAME found.\n" + printf "Exiting script...\n" + exit 1 +fi + +if [ -z "$ROLE_TO_ASSUME" ]; then + printf "[Error] No ROLE_TO_ASSUME found.\n" + printf "Exiting script...\n" + exit 1 +fi + +printf "Getting AWS External ID...\n" + +EXTERNAL_ID=$(aws ssm get-parameter \ + --region us-east-1 \ + --name "ci.datadog-lambda-python.$EXTERNAL_ID_NAME" \ + --with-decryption \ + --query "Parameter.Value" \ + --out text) + +printf "Getting DD API KEY...\n" + +export DD_API_KEY=$(aws ssm get-parameter \ + --region us-east-1 \ + --name ci.datadog-lambda-python.dd-api-key \ + --with-decryption \ + --query "Parameter.Value" \ + --out text) + +printf "Assuming role...\n" + +export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" \ + $(aws sts assume-role \ + --role-arn "arn:aws:iam::$AWS_ACCOUNT:role/$ROLE_TO_ASSUME" \ + --role-session-name "ci.datadog-lambda-python-$CI_JOB_ID-$CI_JOB_STAGE" \ + --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \ + --external-id $EXTERNAL_ID \ + --output text)) diff --git a/ci/input_files/build.yaml.tpl b/ci/input_files/build.yaml.tpl new file mode 100644 index 000000000..599160fbf --- /dev/null +++ b/ci/input_files/build.yaml.tpl @@ -0,0 +1,296 @@ +{{- $e2e_region := "us-west-2" -}} + +stages: + - build + - test + - sign + - publish + - e2e + +.python-before-script: &python-before-script + - pip install virtualenv + - virtualenv venv + - source venv/bin/activate + - pip install .[dev] + - pip install poetry + +default: + retry: + max: 1 + when: + # Retry when the runner fails to start + - runner_system_failure + +# This is for serverless framework +.install-node: &install-node + - apt-get update + - apt-get install -y ca-certificates curl gnupg xxd + - mkdir -p /etc/apt/keyrings + - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg + # We are explicitly setting the node_20.x version for the installation + - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list + - apt-get update + - apt-get install nodejs -y + - npm install --global yarn + +{{ range $runtime := (ds "runtimes").runtimes }} + +# TODO(astuyve) - figure out python build cache +.{{ $runtime.name }}-{{ $runtime.arch }}-cache: &{{ $runtime.name }}-{{ $runtime.arch }}-cache + key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG" + paths: + - $CI_PROJECT_DIR/.yarn-cache + policy: pull + +build-layer ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: build + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10 + artifacts: + expire_in: 1 hr # Unsigned zips expire in 1 hour + paths: + - .layers/datadog_lambda_py-{{ $runtime.arch }}-{{ $runtime.python_version }}.zip + variables: + CI_ENABLE_CONTAINER_IMAGE_BUILDS: "true" + script: + - PYTHON_VERSION={{ $runtime.python_version }} ARCH={{ $runtime.arch }} ./scripts/build_layers.sh + +check-layer-size ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: test + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10 + needs: + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) + dependencies: + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) + script: + - PYTHON_VERSION={{ $runtime.python_version }} ARCH={{ $runtime.arch }} ./scripts/check_layer_size.sh + +lint python: + stage: test + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/mirror/python:{{ $runtime.image }} + cache: &{{ $runtime.name }}-{{ $runtime.arch }}-cache + before_script: *python-before-script + script: + - source venv/bin/activate + - ./scripts/check_format.sh + +unit-test ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: test + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/mirror/python:{{ $runtime.image }} + cache: &{{ $runtime.name }}-{{ $runtime.arch }}-cache + before_script: *python-before-script + script: + - source venv/bin/activate + - pytest -vv + +integration-test ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: test + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10-py3 + needs: + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) + dependencies: + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) + cache: &{{ $runtime.name }}-{{ $runtime.arch }}-cache + variables: + CI_ENABLE_CONTAINER_IMAGE_BUILDS: "true" + before_script: + - *install-node + - EXTERNAL_ID_NAME=integration-test-externalid ROLE_TO_ASSUME=sandbox-integration-test-deployer AWS_ACCOUNT=425362996713 source ./ci/get_secrets.sh + - yarn global add serverless@^3.38.0 --prefix /usr/local + - yarn global add serverless-python-requirements@^6.1.1 --prefix /usr/local + - cd integration_tests && yarn install && cd .. + script: + - RUNTIME_PARAM={{ $runtime.python_version }} ARCH={{ $runtime.arch }} ./scripts/run_integration_tests.sh + +sign-layer ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: sign + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10-py3 + rules: + - if: '$CI_COMMIT_TAG =~ /^v.*/' + when: manual + needs: + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) + - check-layer-size ({{ $runtime.name }}-{{ $runtime.arch }}) + - lint python + - unit-test ({{ $runtime.name }}-{{ $runtime.arch }}) + - integration-test ({{ $runtime.name }}-{{ $runtime.arch }}) + dependencies: + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) + artifacts: # Re specify artifacts so the modified signed file is passed + expire_in: 1 day # Signed layers should expire after 1 day + paths: + - .layers/datadog_lambda_py-{{ $runtime.arch }}-{{ $runtime.python_version }}.zip + before_script: + - apt-get update + - apt-get install -y uuid-runtime + {{ with $environment := (ds "environments").environments.prod }} + - EXTERNAL_ID_NAME={{ $environment.external_id }} ROLE_TO_ASSUME={{ $environment.role_to_assume }} AWS_ACCOUNT={{ $environment.account }} source ./ci/get_secrets.sh + {{ end }} + script: + - LAYER_FILE=datadog_lambda_py-{{ $runtime.arch}}-{{ $runtime.python_version }}.zip ./scripts/sign_layers.sh prod + +{{ range $environment_name, $environment := (ds "environments").environments }} +{{ $dotenv := print $runtime.name "_" $runtime.arch "_" $environment_name ".env" }} + +publish-layer-{{ $environment_name }} ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: publish + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10-py3 + rules: + - if: '"{{ $environment_name }}" == "sandbox" && $REGION == "{{ $e2e_region }}" && "{{ $runtime.arch }}" == "amd64"' + when: on_success + - if: '"{{ $environment_name }}" == "sandbox"' + when: manual + allow_failure: true + - if: '$CI_COMMIT_TAG =~ /^v.*/' + artifacts: + reports: + dotenv: {{ $dotenv }} + needs: +{{ if or (eq $environment_name "prod") }} + - sign-layer ({{ $runtime.name }}-{{ $runtime.arch}}) +{{ else }} + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) + - check-layer-size ({{ $runtime.name }}-{{ $runtime.arch }}) + - lint python + - unit-test ({{ $runtime.name }}-{{ $runtime.arch }}) + - integration-test ({{ $runtime.name }}-{{ $runtime.arch }}) +{{ end }} + dependencies: +{{ if or (eq $environment_name "prod") }} + - sign-layer ({{ $runtime.name }}-{{ $runtime.arch}}) +{{ else }} + - build-layer ({{ $runtime.name }}-{{ $runtime.arch }}) +{{ end }} + parallel: + matrix: + - REGION: {{ range (ds "regions").regions }} + - {{ .code }} + {{- end}} + before_script: + - EXTERNAL_ID_NAME={{ $environment.external_id }} ROLE_TO_ASSUME={{ $environment.role_to_assume }} AWS_ACCOUNT={{ $environment.account }} source ./ci/get_secrets.sh + script: + - STAGE={{ $environment_name }} PYTHON_VERSION={{ $runtime.python_version }} ARCH={{ $runtime.arch }} DOTENV={{ $dotenv }} ./ci/publish_layers.sh + +{{- end }} + +{{- end }} + +publish-pypi-package: + stage: publish + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10-py3 + before_script: *python-before-script + cache: [] + rules: + - if: '$CI_COMMIT_TAG =~ /^v.*/' + when: manual + needs: {{ range $runtime := (ds "runtimes").runtimes }} + - sign-layer ({{ $runtime.name }}-{{ $runtime.arch}}) + {{- end }} + script: + - ./ci/publish_pypi.sh + +layer bundle: + stage: build + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10 + needs: + {{ range (ds "runtimes").runtimes }} + - build-layer ({{ .name }}-{{ .arch }}) + {{ end }} + dependencies: + {{ range (ds "runtimes").runtimes }} + - build-layer ({{ .name }}-{{ .arch }}) + {{ end }} + artifacts: + expire_in: 1 hr + paths: + - datadog_lambda_py-bundle-${CI_JOB_ID}/ + name: datadog_lambda_py-bundle-${CI_JOB_ID} + script: + - rm -rf datadog_lambda_py-bundle-${CI_JOB_ID} + - mkdir -p datadog_lambda_py-bundle-${CI_JOB_ID} + - cp .layers/datadog_lambda_py-*.zip datadog_lambda_py-bundle-${CI_JOB_ID} + +signed layer bundle: + stage: sign + image: registry.ddbuild.io/images/docker:20.10-py3 + tags: ["arch:amd64"] + rules: + - if: '$CI_COMMIT_TAG =~ /^v.*/' + needs: + {{ range (ds "runtimes").runtimes }} + - sign-layer ({{ .name }}-{{ .arch }}) + {{ end }} + dependencies: + {{ range (ds "runtimes").runtimes }} + - sign-layer ({{ .name }}-{{ .arch }}) + {{ end }} + artifacts: + expire_in: 1 day + paths: + - datadog_lambda_py-signed-bundle-${CI_JOB_ID}/ + name: datadog_lambda_py-signed-bundle-${CI_JOB_ID} + script: + - rm -rf datadog_lambda_py-signed-bundle-${CI_JOB_ID} + - mkdir -p datadog_lambda_py-signed-bundle-${CI_JOB_ID} + - cp .layers/datadog_lambda_py-*.zip datadog_lambda_py-signed-bundle-${CI_JOB_ID} + +e2e-test: + stage: e2e + trigger: + project: DataDog/serverless-e2e-tests + strategy: depend + variables: + LANGUAGES_SUBSET: python + # These env vars are inherited from the dotenv reports of the publish-layer jobs + {{- range (ds "runtimes").runtimes }} + {{- if eq .arch "amd64" }} + {{- $version := print (.name | strings.Trim "python") }} + PYTHON_{{ $version }}_VERSION: $PYTHON_{{ $version }}_VERSION + {{- end }} + {{- end }} + needs: {{ range (ds "runtimes").runtimes }} + {{- if eq .arch "amd64" }} + - "publish-layer-sandbox ({{ .name }}-{{ .arch }}): [{{ $e2e_region }}]" + {{- end }} + {{- end }} + +e2e-test-status: + stage: e2e + image: registry.ddbuild.io/images/docker:20.10-py3 + tags: ["arch:amd64"] + timeout: 3h + script: | + GITLAB_API_TOKEN=$(aws ssm get-parameter --region us-east-1 --name "ci.${CI_PROJECT_NAME}.serverless-e2e-gitlab-token" --with-decryption --query "Parameter.Value" --out text) + URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/bridges" + echo "Fetching E2E job status from: $URL" + while true; do + RESPONSE=$(curl -s --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" "$URL") + E2E_JOB_STATUS=$(echo "$RESPONSE" | jq -r '.[] | select(.name=="e2e-test") | .downstream_pipeline.status') + echo -n "E2E job status: $E2E_JOB_STATUS, " + if [ "$E2E_JOB_STATUS" == "success" ]; then + echo "✅ E2E tests completed successfully" + exit 0 + elif [ "$E2E_JOB_STATUS" == "failed" ]; then + echo "❌ E2E tests failed" + exit 1 + elif [ "$E2E_JOB_STATUS" == "running" ]; then + echo "⏳ E2E tests are still running, retrying in 1 minute..." + elif [ "$E2E_JOB_STATUS" == "canceled" ]; then + echo "🚫 E2E tests were canceled" + exit 1 + elif [ "$E2E_JOB_STATUS" == "skipped" ]; then + echo "⏭️ E2E tests were skipped" + exit 0 + else + echo "❓ Unknown E2E test status: $E2E_JOB_STATUS, retrying in 1 minute..." + fi + sleep 60 + done diff --git a/ci/publish_layers.sh b/ci/publish_layers.sh new file mode 100755 index 000000000..9654582a2 --- /dev/null +++ b/ci/publish_layers.sh @@ -0,0 +1,220 @@ +#!/bin/bash + +# Unless explicitly stated otherwise all files in this repository are licensed +# under the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2023 Datadog, Inc. + +# PYTHON_VERSION=20.9 REGION=us-east-1 + +set -e + +# Available runtimes: https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html +AWS_CLI_PYTHON_VERSIONS=( + "python3.8" + "python3.8" + "python3.9" + "python3.9" + "python3.10" + "python3.10" + "python3.11" + "python3.11" + "python3.12" + "python3.12" + "python3.13" + "python3.13" +) +PYTHON_VERSIONS=( + "3.8-amd64" + "3.8-arm64" + "3.9-amd64" + "3.9-arm64" + "3.10-amd64" + "3.10-arm64" + "3.11-amd64" + "3.11-arm64" + "3.12-amd64" + "3.12-arm64" + "3.13-amd64" + "3.13-arm64" +) +LAYER_PATHS=( + ".layers/datadog_lambda_py-amd64-3.8.zip" + ".layers/datadog_lambda_py-arm64-3.8.zip" + ".layers/datadog_lambda_py-amd64-3.9.zip" + ".layers/datadog_lambda_py-arm64-3.9.zip" + ".layers/datadog_lambda_py-amd64-3.10.zip" + ".layers/datadog_lambda_py-arm64-3.10.zip" + ".layers/datadog_lambda_py-amd64-3.11.zip" + ".layers/datadog_lambda_py-arm64-3.11.zip" + ".layers/datadog_lambda_py-amd64-3.12.zip" + ".layers/datadog_lambda_py-arm64-3.12.zip" + ".layers/datadog_lambda_py-amd64-3.13.zip" + ".layers/datadog_lambda_py-arm64-3.13.zip" +) +LAYERS=( + "Datadog-Python38" + "Datadog-Python38-ARM" + "Datadog-Python39" + "Datadog-Python39-ARM" + "Datadog-Python310" + "Datadog-Python310-ARM" + "Datadog-Python311" + "Datadog-Python311-ARM" + "Datadog-Python312" + "Datadog-Python312-ARM" + "Datadog-Python313" + "Datadog-Python313-ARM" +) +STAGES=('prod', 'sandbox', 'staging', 'gov-staging', 'gov-prod') + +printf "Starting script...\n\n" + +if [ -z "$SKIP_PIP_INSTALL" ]; then + echo "Installing dependencies" + pip install awscli +else + echo "Skipping pip install" +fi + +publish_layer() { + region=$1 + layer_name=$2 + compatible_runtimes=$3 + layer_path=$4 + + version_nbr=$(aws lambda publish-layer-version --layer-name $layer_name \ + --description "Datadog Lambda Layer for Python" \ + --zip-file "fileb://$layer_path" \ + --region $region \ + --compatible-runtimes $compatible_runtimes \ + | jq -r '.Version') + + permission=$(aws lambda add-layer-version-permission --layer-name $layer_name \ + --version-number $version_nbr \ + --statement-id "release-$version_nbr" \ + --action lambda:GetLayerVersion --principal "*" \ + --region $region) + + echo $version_nbr +} + +# Target Python version +if [ -z $PYTHON_VERSION ]; then + printf "[Error] PYTHON_VERSION version not specified.\n" + exit 1 +fi + +printf "Python version specified: $PYTHON_VERSION\n" +if [[ ! ${PYTHON_VERSIONS[@]} =~ $PYTHON_VERSION ]]; then + printf "[Error] Unsupported PYTHON_VERSION found: $PYTHON_VERSION.\n" + exit 1 +fi + +if [ -z $ARCH ]; then + printf "[Error] ARCH architecture not specified.\n" + exit 1 +fi + +index=0 +for i in "${!PYTHON_VERSIONS[@]}"; do + if [[ "${PYTHON_VERSIONS[$i]}" = "${PYTHON_VERSION}-${ARCH}" ]]; then + index=$i + fi +done + +REGIONS=$(aws ec2 describe-regions | jq -r '.[] | .[] | .RegionName') + +# Target region +if [ -z "$REGION" ]; then + printf "REGION not specified.\n" + exit 1 +fi + +printf "Region specified, region is: $REGION\n" +if [[ ! "$REGIONS" == *"$REGION"* ]]; then + printf "[Error] Could not find $REGION in AWS available regions: \n${REGIONS[@]}\n" + exit 1 +fi + +# Deploy stage +if [ -z "$STAGE" ]; then + printf "[Error] STAGE not specified.\n" + printf "Exiting script...\n" + exit 1 +fi + +printf "Stage specified: $STAGE\n" +if [[ ! ${STAGES[@]} =~ $STAGE ]]; then + printf "[Error] Unsupported STAGE found.\n" + exit 1 +fi + +layer="${LAYERS[$index]}" +if [ -z "$LAYER_NAME_SUFFIX" ]; then + echo "No layer name suffix" +else + layer="${layer}-${LAYER_NAME_SUFFIX}" +fi +echo "layer name: $layer" + +if [[ "$STAGE" =~ ^(staging|sandbox|gov-staging)$ ]]; then + # Deploy latest version + latest_version=$(aws lambda list-layer-versions --region $REGION --layer-name $layer --query 'LayerVersions[0].Version || `0`') + VERSION=$(($latest_version + 1)) +else + # Running on prod + if [ -z "$CI_COMMIT_TAG" ]; then + printf "[Error] No CI_COMMIT_TAG found.\n" + printf "Exiting script...\n" + exit 1 + else + printf "Tag found in environment: $CI_COMMIT_TAG\n" + fi + + VERSION=$(echo "${CI_COMMIT_TAG##*v}" | cut -d. -f2) +fi + +# Target layer version +if [ -z "$VERSION" ]; then + printf "[Error] VERSION for layer version not specified.\n" + printf "Exiting script...\n" + exit 1 +else + printf "Layer version parsed: $VERSION\n" +fi + +printf "[$REGION] Starting publishing layers...\n" +aws_cli_python_version_key="${AWS_CLI_PYTHON_VERSIONS[$index]}" +layer_path="${LAYER_PATHS[$index]}" + +latest_version=$(aws lambda list-layer-versions --region $REGION --layer-name $layer --query 'LayerVersions[0].Version || `0`') +if [ $latest_version -ge $VERSION ]; then + printf "[$REGION] Layer $layer version $VERSION already exists in region $REGION, skipping...\n" + exit 0 +elif [ $latest_version -lt $((VERSION-1)) ]; then + printf "[$REGION][WARNING] The latest version of layer $layer in region $REGION is $latest_version, this will publish all the missing versions including $VERSION\n" +fi + +while [ $latest_version -lt $VERSION ]; do + latest_version=$(publish_layer $REGION $layer $aws_cli_python_version_key $layer_path) + printf "[$REGION] Published version $latest_version for layer $layer in region $REGION\n" + latest_arn=$(aws lambda get-layer-version --layer-name $layer --version-number $latest_version --region $REGION --query 'LayerVersionArn' --output text) + printf "[$REGION] Published arn $latest_arn\n" + + # This shouldn't happen unless someone manually deleted the latest version, say 28, and + # then tries to republish 28 again. The published version would actually be 29, because + # Lambda layers are immutable and AWS will skip deleted version and use the next number. + if [ $latest_version -gt $VERSION ]; then + printf "[$REGION] Published version $latest_version is greater than the desired version $VERSION!" + exit 1 + fi +done + +if [ -n "$DOTENV" ]; then + printf "[$REGION] Exporting layer version to $DOTENV file...\n" + echo "PYTHON_${PYTHON_VERSION/./}_VERSION=$latest_arn" >> "$DOTENV" + cat "$DOTENV" +fi + +printf "[$REGION] Finished publishing layers...\n\n" diff --git a/ci/publish_pypi.sh b/ci/publish_pypi.sh new file mode 100755 index 000000000..c01df7ef7 --- /dev/null +++ b/ci/publish_pypi.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Unless explicitly stated otherwise all files in this repository are licensed +# under the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2023 Datadog, Inc. +set -e +PYPI_TOKEN=$(aws ssm get-parameter \ + --region us-east-1 \ + --name "ci.datadog-lambda-python.pypi-token" \ + --with-decryption \ + --query "Parameter.Value" \ + --out text) +# Builds the lambda layer and upload to Pypi + +if [ -z "$CI_COMMIT_TAG" ]; then + printf "[Error] No CI_COMMIT_TAG found.\n" + printf "Exiting script...\n" + exit 1 +else + printf "Tag found in environment: $CI_COMMIT_TAG\n" +fi + +# Clear previously built distributions +if [ -d "dist" ]; then + echo "Removing folder 'dist' to clear previously built distributions" + rm -rf dist; +fi + +# Publish to pypi +poetry publish --build --username __token__ --password $PYPI_TOKEN diff --git a/datadog_lambda/__init__.py b/datadog_lambda/__init__.py index cbec8f4fb..059cead9e 100644 --- a/datadog_lambda/__init__.py +++ b/datadog_lambda/__init__.py @@ -1,14 +1,20 @@ +import datadog_lambda.config # noqa: F401 needs to be imported before `ddtrace` +from datadog_lambda.cold_start import initialize_cold_start_tracing + + +initialize_cold_start_tracing() + # The minor version corresponds to the Lambda layer version. # E.g.,, version 0.5.0 gets packaged into layer version 5. -try: - import importlib.metadata as importlib_metadata -except ModuleNotFoundError: - import importlib_metadata +from datadog_lambda.version import __version__ # noqa: E402 F401 +from datadog_lambda.logger import initialize_logging # noqa: E402 + + +initialize_logging(__name__) -__version__ = importlib_metadata.version(__name__) -import os -import logging +from datadog_lambda.patch import patch_all # noqa: E402 -logger = logging.getLogger(__name__) -logger.setLevel(logging.getLevelName(os.environ.get("DD_LOG_LEVEL", "INFO").upper())) +# Patch third-party libraries for tracing, must be done before importing any +# handler code. +patch_all() diff --git a/datadog_lambda/api.py b/datadog_lambda/api.py index 079f69dab..4921dae90 100644 --- a/datadog_lambda/api.py +++ b/datadog_lambda/api.py @@ -1,13 +1,16 @@ -import os import logging -import base64 -from datadog_lambda.extension import should_use_extension +import os + +from datadog_lambda.config import config logger = logging.getLogger(__name__) KMS_ENCRYPTION_CONTEXT_KEY = "LambdaFunctionName" +api_key = None def decrypt_kms_api_key(kms_client, ciphertext): + import base64 + from botocore.exceptions import ClientError """ @@ -26,7 +29,6 @@ def decrypt_kms_api_key(kms_client, ciphertext): is added. We need to try decrypting the API key both with and without the encryption context. """ # Try without encryption context, in case API key was encrypted using the AWS CLI - function_name = os.environ.get("AWS_LAMBDA_FUNCTION_NAME") try: plaintext = kms_client.decrypt(CiphertextBlob=decoded_bytes)[ "Plaintext" @@ -40,46 +42,89 @@ def decrypt_kms_api_key(kms_client, ciphertext): plaintext = kms_client.decrypt( CiphertextBlob=decoded_bytes, EncryptionContext={ - KMS_ENCRYPTION_CONTEXT_KEY: function_name, + KMS_ENCRYPTION_CONTEXT_KEY: config.function_name, }, )["Plaintext"].decode("utf-8") return plaintext +def get_api_key() -> str: + """ + Gets the Datadog API key from the environment variables or secrets manager. + Extracts the result to a global value to avoid repeated calls to the + secrets manager from different products. + """ + global api_key + if api_key: + return api_key + + DD_API_KEY_SECRET_ARN = os.environ.get("DD_API_KEY_SECRET_ARN", "") + DD_API_KEY_SSM_NAME = os.environ.get("DD_API_KEY_SSM_NAME", "") + DD_KMS_API_KEY = os.environ.get("DD_KMS_API_KEY", "") + DD_API_KEY = os.environ.get("DD_API_KEY", os.environ.get("DATADOG_API_KEY", "")) + + LAMBDA_REGION = os.environ.get("AWS_REGION", "") + if config.fips_mode_enabled: + logger.debug( + "FIPS mode is enabled, using FIPS endpoints for secrets management." + ) + + if DD_API_KEY_SECRET_ARN: + # Secrets manager endpoints: https://docs.aws.amazon.com/general/latest/gr/asm.html + try: + secrets_region = DD_API_KEY_SECRET_ARN.split(":")[3] + except Exception: + logger.debug( + "Invalid secret arn in DD_API_KEY_SECRET_ARN. Unable to get API key." + ) + return "" + endpoint_url = ( + f"https://secretsmanager-fips.{secrets_region}.amazonaws.com/" + if config.fips_mode_enabled + else None + ) + secrets_manager_client = _boto3_client( + "secretsmanager", endpoint_url=endpoint_url, region_name=secrets_region + ) + api_key = secrets_manager_client.get_secret_value( + SecretId=DD_API_KEY_SECRET_ARN + )["SecretString"] + elif DD_API_KEY_SSM_NAME: + # SSM endpoints: https://docs.aws.amazon.com/general/latest/gr/ssm.html + fips_endpoint = ( + f"https://ssm-fips.{lambda_region}.amazonaws.com/" + if config.fips_mode_enabled + else None + ) + ssm_client = _boto3_client("ssm", endpoint_url=fips_endpoint) + api_key = ssm_client.get_parameter( + Name=DD_API_KEY_SSM_NAME, WithDecryption=True + )["Parameter"]["Value"] + elif DD_KMS_API_KEY: + # KMS endpoints: https://docs.aws.amazon.com/general/latest/gr/kms.html + fips_endpoint = ( + f"https://kms-fips.{lambda_region}.amazonaws.com/" + if config.fips_mode_enabled + else None + ) + kms_client = _boto3_client("kms", endpoint_url=fips_endpoint) + api_key = decrypt_kms_api_key(kms_client, DD_KMS_API_KEY) + else: + api_key = DD_API_KEY + + return api_key + + def init_api(): - if ( - not should_use_extension - and not os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true" - ): + if not config.flush_to_log: # Make sure that this package would always be lazy-loaded/outside from the critical path # since underlying packages are quite heavy to load - # and useless when the extension is present + # and useless with the extension unless sending metrics with timestamps from datadog import api if not api._api_key: - import boto3 - - DD_API_KEY_SECRET_ARN = os.environ.get("DD_API_KEY_SECRET_ARN", "") - DD_API_KEY_SSM_NAME = os.environ.get("DD_API_KEY_SSM_NAME", "") - DD_KMS_API_KEY = os.environ.get("DD_KMS_API_KEY", "") - DD_API_KEY = os.environ.get( - "DD_API_KEY", os.environ.get("DATADOG_API_KEY", "") - ) - - if DD_API_KEY_SECRET_ARN: - api._api_key = boto3.client("secretsmanager").get_secret_value( - SecretId=DD_API_KEY_SECRET_ARN - )["SecretString"] - elif DD_API_KEY_SSM_NAME: - api._api_key = boto3.client("ssm").get_parameter( - Name=DD_API_KEY_SSM_NAME, WithDecryption=True - )["Parameter"]["Value"] - elif DD_KMS_API_KEY: - kms_client = boto3.client("kms") - api._api_key = decrypt_kms_api_key(kms_client, DD_KMS_API_KEY) - else: - api._api_key = DD_API_KEY + api._api_key = get_api_key() logger.debug("Setting DATADOG_API_KEY of length %d", len(api._api_key)) @@ -91,3 +136,9 @@ def init_api(): # Unmute exceptions from datadog api client, so we can catch and handle them api._mute = False + + +def _boto3_client(*args, **kwargs): + import botocore.session + + return botocore.session.get_session().create_client(*args, **kwargs) diff --git a/datadog_lambda/asm.py b/datadog_lambda/asm.py new file mode 100644 index 000000000..6c65a9465 --- /dev/null +++ b/datadog_lambda/asm.py @@ -0,0 +1,251 @@ +import logging +import urllib.parse +from copy import deepcopy +from typing import Any, Dict, List, Optional, Union + +from ddtrace.contrib.internal.trace_utils import _get_request_header_client_ip +from ddtrace.internal import core +from ddtrace.internal.utils import get_blocked +from ddtrace.internal.utils import http as http_utils +from ddtrace.trace import Span + +from datadog_lambda.trigger import ( + EventSubtypes, + EventTypes, + _EventSource, + _http_event_types, +) + +logger = logging.getLogger(__name__) + + +def _to_single_value_headers(headers: Dict[str, List[str]]) -> Dict[str, str]: + """ + Convert multi-value headers to single-value headers. + If a header has multiple values, join them with commas. + """ + single_value_headers = {} + for key, values in headers.items(): + single_value_headers[key] = ", ".join(values) + return single_value_headers + + +def _merge_single_and_multi_value_headers( + single_value_headers: Dict[str, str], + multi_value_headers: Dict[str, List[str]], +): + """ + Merge single-value headers with multi-value headers. + If a header exists in both, we merge them removing duplicates + """ + merged_headers = deepcopy(multi_value_headers) + for key, value in single_value_headers.items(): + if key not in merged_headers: + merged_headers[key] = [value] + elif value not in merged_headers[key]: + merged_headers[key].append(value) + return _to_single_value_headers(merged_headers) + + +def asm_set_context(event_source: _EventSource): + """Add asm specific items to the ExecutionContext. + + This allows the AppSecSpanProcessor to know information about the event + at the moment the span is created and skip it when not relevant. + """ + + if event_source.event_type not in _http_event_types: + core.set_item("appsec_skip_next_lambda_event", True) + + +def asm_start_request( + span: Span, + event: Dict[str, Any], + event_source: _EventSource, + trigger_tags: Dict[str, str], +): + if event_source.event_type not in _http_event_types: + return + + request_headers: Dict[str, str] = {} + peer_ip: Optional[str] = None + request_path_parameters: Optional[Dict[str, Any]] = None + route: Optional[str] = None + + if event_source.event_type == EventTypes.ALB: + raw_uri = event.get("path") + + if event_source.subtype == EventSubtypes.ALB: + request_headers = event.get("headers", {}) + parsed_query = event.get("queryStringParameters") + if event_source.subtype == EventSubtypes.ALB_MULTI_VALUE_HEADERS: + request_headers = _to_single_value_headers( + event.get("multiValueHeaders", {}) + ) + parsed_query = event.get("multiValueQueryStringParameters") + + elif event_source.event_type == EventTypes.LAMBDA_FUNCTION_URL: + request_headers = event.get("headers", {}) + peer_ip = event.get("requestContext", {}).get("http", {}).get("sourceIp") + raw_uri = event.get("rawPath") + parsed_query = event.get("queryStringParameters") + + elif event_source.event_type == EventTypes.API_GATEWAY: + request_context = event.get("requestContext", {}) + request_path_parameters = event.get("pathParameters") + route = trigger_tags.get("http.route") + + if event_source.subtype == EventSubtypes.API_GATEWAY: + request_headers = event.get("headers", {}) + peer_ip = request_context.get("identity", {}).get("sourceIp") + raw_uri = event.get("path") + parsed_query = event.get("multiValueQueryStringParameters") + + elif event_source.subtype == EventSubtypes.HTTP_API: + request_headers = event.get("headers", {}) + peer_ip = request_context.get("http", {}).get("sourceIp") + raw_uri = event.get("rawPath") + parsed_query = event.get("queryStringParameters") + + elif event_source.subtype == EventSubtypes.WEBSOCKET: + request_headers = _to_single_value_headers( + event.get("multiValueHeaders", {}) + ) + peer_ip = request_context.get("identity", {}).get("sourceIp") + raw_uri = event.get("path") + parsed_query = event.get("multiValueQueryStringParameters") + + else: + return + + else: + return + + body = event.get("body") + is_base64_encoded = event.get("isBase64Encoded", False) + + request_ip = _get_request_header_client_ip(request_headers, peer_ip, True) + if request_ip is not None: + span.set_tag("http.client_ip", request_ip) + span.set_tag("network.client.ip", request_ip) + + # Encode the parsed query and append it to reconstruct the original raw URI expected by AppSec. + if parsed_query: + try: + encoded_query = urllib.parse.urlencode(parsed_query, doseq=True) + raw_uri += "?" + encoded_query # type: ignore + except Exception: + pass + + core.dispatch( + # The matching listener is registered in ddtrace.appsec._handlers + "aws_lambda.start_request", + ( + span, + request_headers, + request_ip, + body, + is_base64_encoded, + raw_uri, + route, + trigger_tags.get("http.method"), + parsed_query, + request_path_parameters, + ), + ) + + +def asm_start_response( + span: Span, + status_code: str, + event_source: _EventSource, + response: Union[Dict[str, Any], str, None], +): + if event_source.event_type not in _http_event_types: + return + + if isinstance(response, dict) and ( + "headers" in response or "multiValueHeaders" in response + ): + headers = response.get("headers", {}) + multi_value_request_headers = response.get("multiValueHeaders") + if isinstance(multi_value_request_headers, dict) and isinstance(headers, dict): + response_headers = _merge_single_and_multi_value_headers( + headers, multi_value_request_headers + ) + elif isinstance(headers, dict): + response_headers = headers + else: + response_headers = { + "content-type": "application/json", + } + else: + response_headers = { + "content-type": "application/json", + } + + core.dispatch( + # The matching listener is registered in ddtrace.appsec._handlers + "aws_lambda.start_response", + ( + span, + status_code, + response_headers, + ), + ) + + if isinstance(response, dict) and "statusCode" in response: + body = response.get("body") + else: + body = response + + core.dispatch( + # The matching listener is registered in ddtrace.appsec._handlers + "aws_lambda.parse_body", + (body,), + ) + + +def get_asm_blocked_response( + event_source: _EventSource, +) -> Optional[Dict[str, Any]]: + """Get the blocked response for the given event source.""" + if event_source.event_type not in _http_event_types: + return None + + blocked = get_blocked() + if not blocked: + return None + + desired_type = blocked.get("type", "auto") + if desired_type == "none": + content_type = "text/plain; charset=utf-8" + content = "" + else: + content_type = blocked.get("content-type", "application/json") + content = http_utils._get_blocked_template(content_type) + + response = { + "statusCode": blocked.get("status_code", 403), + "body": content, + "isBase64Encoded": False, + } + + needs_multi_value_headers = event_source.equals( + EventTypes.ALB, EventSubtypes.ALB_MULTI_VALUE_HEADERS + ) + + if needs_multi_value_headers: + response["multiValueHeaders"] = { + "content-type": [content_type], + } + if "location" in blocked: + response["multiValueHeaders"]["location"] = [blocked["location"]] + else: + response["headers"] = { + "content-type": content_type, + } + if "location" in blocked: + response["headers"]["location"] = blocked["location"] + + return response diff --git a/datadog_lambda/cold_start.py b/datadog_lambda/cold_start.py index c8862bf1f..a40e2fcb3 100644 --- a/datadog_lambda/cold_start.py +++ b/datadog_lambda/cold_start.py @@ -1,16 +1,38 @@ +import time +from typing import List, Hashable +import logging + +from datadog_lambda.config import config + +logger = logging.getLogger(__name__) + _cold_start = True +_proactive_initialization = False _lambda_container_initialized = False +_tracer = None -def set_cold_start(): +def set_cold_start(init_timestamp_ns): """Set the value of the cold start global This should be executed once per Lambda execution before the execution """ global _cold_start global _lambda_container_initialized - _cold_start = not _lambda_container_initialized + global _proactive_initialization + global _tracer + if not _lambda_container_initialized: + now = time.time_ns() + if (now - init_timestamp_ns) // 1_000_000_000 > 10: + _cold_start = False + _proactive_initialization = True + else: + _cold_start = not _lambda_container_initialized + else: + _cold_start = False + _proactive_initialization = False _lambda_container_initialized = True + from ddtrace.trace import tracer as _tracer def is_cold_start(): @@ -18,6 +40,217 @@ def is_cold_start(): return _cold_start +def is_proactive_init(): + """Returns the value of the global proactive_initialization""" + return _proactive_initialization + + +def is_new_sandbox(): + return is_cold_start() or is_proactive_init() + + def get_cold_start_tag(): """Returns the cold start tag to be used in metrics""" - return "cold_start:{}".format(str(is_cold_start()).lower()) + return "cold_start:true" if _cold_start else "cold_start:false" + + +def get_proactive_init_tag(): + """Returns the proactive init tag to be used in metrics""" + return ( + "proactive_initialization:true" + if _proactive_initialization + else "proactive_initialization:false" + ) + + +class ImportNode(object): + def __init__(self, module_name, full_file_path, start_time_ns, end_time_ns=None): + self.module_name = module_name + self.full_file_path = full_file_path + self.start_time_ns = start_time_ns + self.end_time_ns = end_time_ns + self.children = [] + self.context = None + if _lambda_container_initialized: + self.context = _tracer.context_provider.active() + + +root_nodes: List[ImportNode] = [] +import_stack: List[ImportNode] = [] +already_wrapped_loaders = set() + + +def reset_node_stacks(): + root_nodes.clear() + import_stack.clear() + + +def push_node(module_name, file_path): + node = ImportNode(module_name, file_path, time.time_ns()) + if import_stack: + import_stack[-1].children.append(node) + import_stack.append(node) + + +def pop_node(module_name): + if not import_stack: + return + node = import_stack.pop() + if node.module_name != module_name: + return + end_time_ns = time.time_ns() + node.end_time_ns = end_time_ns + if not import_stack: # import_stack empty, a root node has been found + root_nodes.append(node) + + +def wrap_exec_module(original_exec_module): + def wrapped_method(module): + should_pop = False + try: + spec = module.__spec__ + push_node(spec.name, spec.origin) + should_pop = True + except Exception: + pass + try: + return original_exec_module(module) + finally: + if should_pop: + pop_node(spec.name) + + return wrapped_method + + +def wrap_find_spec(original_find_spec): + def wrapped_find_spec(*args, **kwargs): + spec = original_find_spec(*args, **kwargs) + if spec is None: + return None + loader = getattr(spec, "loader", None) + if ( + loader is not None + and isinstance(loader, Hashable) + and loader not in already_wrapped_loaders + ): + if hasattr(loader, "exec_module"): + try: + loader.exec_module = wrap_exec_module(loader.exec_module) + already_wrapped_loaders.add(loader) + except Exception as e: + logger.debug("Failed to wrap the loader. %s", e) + return spec + + return wrapped_find_spec + + +def initialize_cold_start_tracing(): + if is_new_sandbox() and config.cold_start_tracing: + from sys import meta_path + + for importer in meta_path: + try: + importer.find_spec = wrap_find_spec(importer.find_spec) + except Exception: + pass + + +class ColdStartTracer(object): + def __init__( + self, + tracer, + function_name, + current_span_start_time_ns, + trace_ctx, + min_duration_ms: int, + ignored_libs: List[str] = None, + ): + if ignored_libs is None: + ignored_libs = [] + self._tracer = tracer + self.function_name = function_name + self.current_span_start_time_ns = current_span_start_time_ns + self.min_duration_ms = min_duration_ms + self.trace_ctx = trace_ctx + self.ignored_libs = ignored_libs + self.need_to_reactivate_context = True + + def trace(self, root_nodes: List[ImportNode] = root_nodes): + if not root_nodes: + return + cold_start_span_start_time_ns = root_nodes[0].start_time_ns + cold_start_span_end_time_ns = min( + root_nodes[-1].end_time_ns, self.current_span_start_time_ns + ) + cold_start_span = self.create_cold_start_span(cold_start_span_start_time_ns) + while root_nodes: + root_node = root_nodes.pop() + parent = root_node.context or cold_start_span + self.trace_tree(root_node, parent) + self.finish_span(cold_start_span, cold_start_span_end_time_ns) + + def trace_tree(self, import_node: ImportNode, parent_span): + if ( + not self.trace_ctx + or import_node.end_time_ns - import_node.start_time_ns + < self.min_duration_ms * 1e6 + or import_node.module_name in self.ignored_libs + ): + return + + span = self.start_span( + "aws.lambda.import", import_node.module_name, import_node.start_time_ns + ) + tags = { + "resource_names": import_node.module_name, + "resource.name": import_node.module_name, + "filename": import_node.full_file_path, + "operation_name": self.get_operation_name(import_node.full_file_path), + } + span.set_tags(tags) + if parent_span: + span.parent_id = parent_span.span_id + for child_node in import_node.children: + self.trace_tree(child_node, span) + self.finish_span(span, import_node.end_time_ns) + + def create_cold_start_span(self, start_time_ns): + span = self.start_span("aws.lambda.load", self.function_name, start_time_ns) + tags = { + "resource_names": self.function_name, + "resource.name": self.function_name, + "operation_name": "aws.lambda.load", + } + span.set_tags(tags) + return span + + def start_span(self, span_type, resource, start_time_ns): + if self.need_to_reactivate_context: + self._tracer.context_provider.activate( + self.trace_ctx + ) # reactivate required after each finish() call + self.need_to_reactivate_context = False + span_kwargs = { + "service": "aws.lambda", + "resource": resource, + "span_type": span_type, + } + span = self._tracer.trace(span_type, **span_kwargs) + span.start_ns = start_time_ns + return span + + def finish_span(self, span, finish_time_ns): + span.finish(finish_time_ns / 1e9) + self.need_to_reactivate_context = True + + def get_operation_name(self, filename: str): + if filename is None: + return "aws.lambda.import_core_module" + if not isinstance(filename, str): + return "aws.lambda.import" + if filename.startswith("/opt/"): + return "aws.lambda.import_layer" + elif filename.startswith("/var/lang/"): + return "aws.lambda.import_runtime" + else: + return "aws.lambda.import" diff --git a/datadog_lambda/config.py b/datadog_lambda/config.py new file mode 100644 index 000000000..eda6b5828 --- /dev/null +++ b/datadog_lambda/config.py @@ -0,0 +1,149 @@ +# Unless explicitly stated otherwise all files in this repository are licensed +# under the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019 Datadog, Inc. + +import logging +import os + +logger = logging.getLogger(__name__) + + +def _get_env(key, default=None, cast=None, depends_on_tracing=False): + @property + def _getter(self): + if not hasattr(self, prop_key): + val = self._resolve_env(key, default, cast, depends_on_tracing) + setattr(self, prop_key, val) + return getattr(self, prop_key) + + prop_key = f"_config_{key}" + return _getter + + +def as_bool(val): + return val.lower() == "true" or val == "1" + + +def as_list(val): + return [val.strip() for val in val.split(",") if val.strip()] + + +class Config: + def _resolve_env(self, key, default=None, cast=None, depends_on_tracing=False): + if depends_on_tracing and not self.trace_enabled: + return False + val = os.environ.get(key, default) + if cast is not None: + try: + val = cast(val) + except (ValueError, TypeError): + msg = ( + "Failed to cast environment variable '%s' with " + "value '%s' to type %s. Using default value '%s'." + ) + logger.warning(msg, key, val, cast.__name__, default) + val = default + return val + + service = _get_env("DD_SERVICE") + env = _get_env("DD_ENV") + + cold_start_tracing = _get_env( + "DD_COLD_START_TRACING", "true", as_bool, depends_on_tracing=True + ) + min_cold_start_trace_duration = _get_env("DD_MIN_COLD_START_DURATION", 3, int) + cold_start_trace_skip_lib = _get_env( + "DD_COLD_START_TRACE_SKIP_LIB", + "ddtrace.internal.compat,ddtrace.filters", + as_list, + ) + + capture_payload_max_depth = _get_env("DD_CAPTURE_LAMBDA_PAYLOAD_MAX_DEPTH", 10, int) + capture_payload_enabled = _get_env("DD_CAPTURE_LAMBDA_PAYLOAD", "false", as_bool) + + trace_enabled = _get_env("DD_TRACE_ENABLED", "true", as_bool) + make_inferred_span = _get_env( + "DD_TRACE_MANAGED_SERVICES", "true", as_bool, depends_on_tracing=True + ) + encode_authorizer_context = _get_env( + "DD_ENCODE_AUTHORIZER_CONTEXT", "true", as_bool, depends_on_tracing=True + ) + decode_authorizer_context = _get_env( + "DD_DECODE_AUTHORIZER_CONTEXT", "true", as_bool, depends_on_tracing=True + ) + add_span_pointers = _get_env("DD_BOTOCORE_ADD_SPAN_POINTERS", "true", as_bool) + trace_extractor = _get_env("DD_TRACE_EXTRACTOR") + + enhanced_metrics_enabled = _get_env("DD_ENHANCED_METRICS", "true", as_bool) + + flush_in_thread = _get_env("DD_FLUSH_IN_THREAD", "false", as_bool) + flush_to_log = _get_env("DD_FLUSH_TO_LOG", "false", as_bool) + logs_injection = _get_env("DD_LOGS_INJECTION", "true", as_bool) + merge_xray_traces = _get_env("DD_MERGE_XRAY_TRACES", "false", as_bool) + + otel_enabled = _get_env("DD_TRACE_OTEL_ENABLED", "false", as_bool) + profiling_enabled = _get_env("DD_PROFILING_ENABLED", "false", as_bool) + llmobs_enabled = _get_env("DD_LLMOBS_ENABLED", "false", as_bool) + exception_replay_enabled = _get_env("DD_EXCEPTION_REPLAY_ENABLED", "false", as_bool) + data_streams_enabled = _get_env( + "DD_DATA_STREAMS_ENABLED", "false", as_bool, depends_on_tracing=True + ) + appsec_enabled = _get_env("DD_APPSEC_ENABLED", "false", as_bool) + sca_enabled = _get_env("DD_APPSEC_SCA_ENABLED", "false", as_bool) + + is_gov_region = _get_env("AWS_REGION", "", lambda x: x.startswith("us-gov-")) + + local_test = _get_env("DD_LOCAL_TEST", "false", as_bool) + integration_test = _get_env("DD_INTEGRATION_TEST", "false", as_bool) + + aws_lambda_function_name = _get_env("AWS_LAMBDA_FUNCTION_NAME") + + @property + def function_name(self): + if not hasattr(self, "_config_function_name"): + if self.aws_lambda_function_name is None: + self._config_function_name = "function" + else: + self._config_function_name = self.aws_lambda_function_name + return self._config_function_name + + @property + def is_lambda_context(self): + if not hasattr(self, "_config_is_lambda_context"): + self._config_is_lambda_context = bool(self.aws_lambda_function_name) + return self._config_is_lambda_context + + @property + def fips_mode_enabled(self): + if not hasattr(self, "_config_fips_mode_enabled"): + self._config_fips_mode_enabled = ( + os.environ.get( + "DD_LAMBDA_FIPS_MODE", + "true" if self.is_gov_region else "false", + ).lower() + == "true" + ) + return self._config_fips_mode_enabled + + def _reset(self): + for attr in dir(self): + if attr.startswith("_config_"): + delattr(self, attr) + + +config = Config() + +if config.is_gov_region or config.fips_mode_enabled: + logger.debug( + "Python Lambda Layer FIPS mode is %s.", + "enabled" if config.fips_mode_enabled else "not enabled", + ) + + +if ( + "DD_INSTRUMENTATION_TELEMETRY_ENABLED" not in os.environ + and not config.sca_enabled + and not config.appsec_enabled +): + os.environ["DD_INSTRUMENTATION_TELEMETRY_ENABLED"] = "false" diff --git a/datadog_lambda/constants.py b/datadog_lambda/constants.py index d2c853783..6ab627384 100644 --- a/datadog_lambda/constants.py +++ b/datadog_lambda/constants.py @@ -17,6 +17,7 @@ class TraceHeader(object): TRACE_ID = "x-datadog-trace-id" PARENT_ID = "x-datadog-parent-id" SAMPLING_PRIORITY = "x-datadog-sampling-priority" + TAGS = "x-datadog-tags" # X-Ray subsegment to save Datadog trace metadata @@ -41,3 +42,12 @@ class XrayDaemon(object): XRAY_TRACE_ID_HEADER_NAME = "_X_AMZN_TRACE_ID" XRAY_DAEMON_ADDRESS = "AWS_XRAY_DAEMON_ADDRESS" FUNCTION_NAME_HEADER_NAME = "AWS_LAMBDA_FUNCTION_NAME" + + +class Headers(object): + Parent_Span_Finish_Time = "x-datadog-parent-span-finish-time" + + # For one request from the client, the event.requestContext.requestIds in the authorizer lambda + # invocation and the main function invocation are IDENTICAL. Therefore we can use it to tell + # whether current invocation is the actual original authorizing request or a cached request. + Authorizing_Request_Id = "x-datadog-authorizing-requestid" diff --git a/datadog_lambda/dogstatsd.py b/datadog_lambda/dogstatsd.py index a627492dc..a08e25926 100644 --- a/datadog_lambda/dogstatsd.py +++ b/datadog_lambda/dogstatsd.py @@ -1,11 +1,10 @@ +import errno import logging import os -import socket -import errno import re +import socket from threading import Lock - MIN_SEND_BUFFER_SIZE = 32 * 1024 log = logging.getLogger("datadog_lambda.dogstatsd") @@ -55,14 +54,21 @@ def _get_udp_socket(cls, host, port): return sock - def distribution(self, metric, value, tags=None): + def distribution(self, metric, value, tags=None, timestamp=None): """ - Send a global distribution value, optionally setting tags. + Send a global distribution value, optionally setting tags. The optional + timestamp should be an integer representing seconds since the epoch + (January 1, 1970, 00:00:00 UTC). >>> statsd.distribution("uploaded.file.size", 1445) >>> statsd.distribution("album.photo.count", 26, tags=["gender:female"]) + >>> statsd.distribution( + >>> "historic.file.count", + >>> 5, + >>> timestamp=int(datetime(2020, 2, 14, 12, 0, 0).timestamp()), + >>> ) """ - self._report(metric, "d", value, tags) + self._report(metric, "d", value, tags, timestamp) def close_socket(self): """ @@ -84,20 +90,21 @@ def normalize_tags(self, tag_list): for tag in tag_list ] - def _serialize_metric(self, metric, metric_type, value, tags): + def _serialize_metric(self, metric, metric_type, value, tags, timestamp): # Create/format the metric packet - return "%s:%s|%s%s" % ( + return "%s:%s|%s%s%s" % ( metric, value, metric_type, ("|#" + ",".join(self.normalize_tags(tags))) if tags else "", + ("|T" + str(int(timestamp))) if timestamp is not None else "", ) - def _report(self, metric, metric_type, value, tags): + def _report(self, metric, metric_type, value, tags, timestamp): if value is None: return - payload = self._serialize_metric(metric, metric_type, value, tags) + payload = self._serialize_metric(metric, metric_type, value, tags, timestamp) # Send it self._send_to_server(payload) diff --git a/datadog_lambda/extension.py b/datadog_lambda/extension.py index d66848ff0..79c0031aa 100644 --- a/datadog_lambda/extension.py +++ b/datadog_lambda/extension.py @@ -1,36 +1,21 @@ import logging -from os import path - -try: - # only available in python 3 - # not an issue since the extension is not compatible with python 2.x runtime - # https://docs.aws.amazon.com/lambda/latest/dg/using-extensions.html - import urllib.request -except ImportError: - # safe since both calls to urllib are protected with try/expect and will return false - urllib = None +import os AGENT_URL = "http://127.0.0.1:8124/" -HELLO_PATH = "/lambda/hello" FLUSH_PATH = "/lambda/flush" EXTENSION_PATH = "/opt/extensions/datadog-agent" logger = logging.getLogger(__name__) -def is_extension_running(): - if not path.exists(EXTENSION_PATH): - return False - try: - urllib.request.urlopen(AGENT_URL + HELLO_PATH) - except Exception as e: - logger.debug("Extension is not running, returned with error %s", e) - return False - return True +def is_extension_present(): + return os.path.exists(EXTENSION_PATH) def flush_extension(): try: + import urllib.request + req = urllib.request.Request(AGENT_URL + FLUSH_PATH, "".encode("ascii")) urllib.request.urlopen(req) except Exception as e: @@ -39,4 +24,4 @@ def flush_extension(): return True -should_use_extension = is_extension_running() +should_use_extension = is_extension_present() diff --git a/datadog_lambda/handler.py b/datadog_lambda/handler.py index 09cc5e7d7..4f12b1ad8 100644 --- a/datadog_lambda/handler.py +++ b/datadog_lambda/handler.py @@ -3,10 +3,12 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2020 Datadog, Inc. -from __future__ import absolute_import from importlib import import_module import os +from time import time_ns + +from datadog_lambda.tracing import emit_telemetry_on_exception_outside_of_handler from datadog_lambda.wrapper import datadog_lambda_wrapper from datadog_lambda.module_name import modify_module_name @@ -22,10 +24,22 @@ class HandlerError(Exception): ) parts = path.rsplit(".", 1) if len(parts) != 2: - raise HandlerError("Value %s for DD_LAMBDA_HANDLER has invalid format." % path) + raise HandlerError(f"Value {path} for DD_LAMBDA_HANDLER has invalid format.") (mod_name, handler_name) = parts modified_mod_name = modify_module_name(mod_name) -handler_module = import_module(modified_mod_name) -handler = datadog_lambda_wrapper(getattr(handler_module, handler_name)) + +try: + handler_load_start_time_ns = time_ns() + handler_module = import_module(modified_mod_name) + handler_func = getattr(handler_module, handler_name) +except Exception as e: + emit_telemetry_on_exception_outside_of_handler( + e, + modified_mod_name, + handler_load_start_time_ns, + ) + raise + +handler = datadog_lambda_wrapper(handler_func) diff --git a/datadog_lambda/logger.py b/datadog_lambda/logger.py new file mode 100644 index 000000000..ae2b5d6d9 --- /dev/null +++ b/datadog_lambda/logger.py @@ -0,0 +1,27 @@ +import logging +import os + +try: + _level_mappping = logging.getLevelNamesMapping() +except AttributeError: + # python 3.8 + _level_mappping = {name: num for num, name in logging._levelToName.items()} +# https://docs.datadoghq.com/agent/troubleshooting/debug_mode/?tab=agentv6v7#agent-log-level +_level_mappping.update( + { + "TRACE": 5, + "WARN": logging.WARNING, + "OFF": 100, + } +) + + +def initialize_logging(name): + logger = logging.getLogger(name) + str_level = (os.environ.get("DD_LOG_LEVEL") or "INFO").upper() + level = _level_mappping.get(str_level) + if level is None: + logger.setLevel(logging.INFO) + logger.warning("Invalid log level: %s Defaulting to INFO", str_level) + else: + logger.setLevel(level) diff --git a/datadog_lambda/metric.py b/datadog_lambda/metric.py index c3e39c973..5df0812f1 100644 --- a/datadog_lambda/metric.py +++ b/datadog_lambda/metric.py @@ -3,34 +3,62 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -import os -import json -import time +import enum import logging +import time +from datetime import datetime, timedelta +import ujson as json + +from datadog_lambda.config import config from datadog_lambda.extension import should_use_extension -from datadog_lambda.tags import get_enhanced_metrics_tags, tag_dd_lambda_layer -from datadog_lambda.api import init_api +from datadog_lambda.tags import dd_lambda_layer_tag, get_enhanced_metrics_tags logger = logging.getLogger(__name__) -lambda_stats = None -init_api() +class MetricsHandler(enum.Enum): + EXTENSION = "extension" + FORWARDER = "forwarder" + DATADOG_API = "datadog_api" + NO_METRICS = "no_metrics" -if should_use_extension: + +def _select_metrics_handler(): + if should_use_extension: + return MetricsHandler.EXTENSION + if config.flush_to_log: + return MetricsHandler.FORWARDER + + if config.fips_mode_enabled: + logger.debug( + "With FIPS mode enabled, the Datadog API metrics handler is unavailable." + ) + return MetricsHandler.NO_METRICS + + return MetricsHandler.DATADOG_API + + +metrics_handler = _select_metrics_handler() +logger.debug("identified primary metrics handler as %s", metrics_handler) + + +lambda_stats = None +if metrics_handler == MetricsHandler.EXTENSION: from datadog_lambda.statsd_writer import StatsDWriter lambda_stats = StatsDWriter() -else: + +elif metrics_handler == MetricsHandler.DATADOG_API: # Periodical flushing in a background thread is NOT guaranteed to succeed # and leads to data loss. When disabled, metrics are only flushed at the # end of invocation. To make metrics submitted from a long-running Lambda # function available sooner, consider using the Datadog Lambda extension. + from datadog_lambda.api import init_api from datadog_lambda.thread_stats_writer import ThreadStatsWriter - flush_in_thread = os.environ.get("DD_FLUSH_IN_THREAD", "").lower() == "true" - lambda_stats = ThreadStatsWriter(flush_in_thread) + init_api() + lambda_stats = ThreadStatsWriter(config.flush_in_thread) def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=False): @@ -38,35 +66,96 @@ def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=Fal Submit a data point to Datadog distribution metrics. https://docs.datadoghq.com/graphing/metrics/distributions/ - When DD_FLUSH_TO_LOG is True, write metric to log, and - wait for the Datadog Log Forwarder Lambda function to submit - the metrics asynchronously. + If the Datadog Lambda Extension is present, metrics are submitted to its + dogstatsd endpoint. + + When DD_FLUSH_TO_LOG is True or force_async is True, write metric to log, + and wait for the Datadog Log Forwarder Lambda function to submit the + metrics asynchronously. Otherwise, the metrics will be submitted to the Datadog API periodically and at the end of the function execution in a background thread. - Note that if the extension is present, it will override the DD_FLUSH_TO_LOG value - and always use the layer to send metrics to the extension + Note that if the extension is present, it will override the DD_FLUSH_TO_LOG + value and always use the layer to send metrics to the extension """ - flush_to_logs = os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true" - tags = tag_dd_lambda_layer(tags) + if not metric_name or not isinstance(metric_name, str): + logger.warning( + "Ignoring metric submission. Invalid metric name: %s", metric_name + ) + return - if should_use_extension: + try: + float(value) + except (ValueError, TypeError): + logger.warning( + "Ignoring metric submission for metric '%s' because the value is not numeric: %r", + metric_name, + value, + ) + return + + tags = [] if tags is None else list(tags) + tags.append(dd_lambda_layer_tag) + + if metrics_handler == MetricsHandler.EXTENSION: + if timestamp is not None: + if isinstance(timestamp, datetime): + timestamp = int(timestamp.timestamp()) + + else: + try: + timestamp = int(timestamp) + except Exception: + logger.debug( + "Ignoring metric submission for metric '%s' because the timestamp cannot " + "be turned into an integer: %r", + metric_name, + timestamp, + ) + return + + timestamp_floor = int((datetime.now() - timedelta(hours=4)).timestamp()) + if timestamp < timestamp_floor: + logger.warning( + "Timestamp %s is older than 4 hours, not submitting metric %s", + timestamp, + metric_name, + ) + return + + logger.debug( + "Sending metric %s value %s to Datadog via extension", metric_name, value + ) + lambda_stats.distribution(metric_name, value, tags=tags, timestamp=timestamp) + + elif force_async or (metrics_handler == MetricsHandler.FORWARDER): + write_metric_point_to_stdout(metric_name, value, timestamp=timestamp, tags=tags) + + elif metrics_handler == MetricsHandler.DATADOG_API: lambda_stats.distribution(metric_name, value, tags=tags, timestamp=timestamp) + + elif metrics_handler == MetricsHandler.NO_METRICS: + logger.debug( + "Metric %s cannot be submitted because the metrics handler is disabled", + metric_name, + ), + else: - if flush_to_logs or force_async: - write_metric_point_to_stdout( - metric_name, value, timestamp=timestamp, tags=tags - ) - else: - lambda_stats.distribution( - metric_name, value, tags=tags, timestamp=timestamp - ) + # This should be qutie impossible, but let's at least log a message if + # it somehow happens. + logger.debug( + "Metric %s cannot be submitted because the metrics handler is not configured: %s", + metric_name, + metrics_handler, + ) -def write_metric_point_to_stdout(metric_name, value, timestamp=None, tags=[]): +def write_metric_point_to_stdout(metric_name, value, timestamp=None, tags=None): """Writes the specified metric point to standard output""" + tags = tags or [] + logger.debug( "Sending metric %s value %s to Datadog via log forwarder", metric_name, value ) @@ -77,23 +166,15 @@ def write_metric_point_to_stdout(metric_name, value, timestamp=None, tags=[]): "v": value, "e": timestamp or int(time.time()), "t": tags, - } + }, + escape_forward_slashes=False, ) ) -def flush_stats(): - lambda_stats.flush() - - -def are_enhanced_metrics_enabled(): - """Check env var to find if enhanced metrics should be submitted - - Returns: - boolean for whether enhanced metrics are enabled - """ - # DD_ENHANCED_METRICS defaults to true - return os.environ.get("DD_ENHANCED_METRICS", "true").lower() == "true" +def flush_stats(lambda_context=None): + if lambda_stats is not None: + lambda_stats.flush() def submit_enhanced_metric(metric_name, lambda_context): @@ -101,9 +182,9 @@ def submit_enhanced_metric(metric_name, lambda_context): Args: metric_name (str): metric name w/o enhanced prefix i.e. "invocations" or "errors" - lambda_context (dict): Lambda context dict passed to the function by AWS + lambda_context (object): Lambda context dict passed to the function by AWS """ - if not are_enhanced_metrics_enabled(): + if not config.enhanced_metrics_enabled: logger.debug( "Not submitting enhanced metric %s because enhanced metrics are disabled", metric_name, @@ -119,7 +200,7 @@ def submit_invocations_metric(lambda_context): """Increment aws.lambda.enhanced.invocations by 1, applying runtime, layer, and cold_start tags Args: - lambda_context (dict): Lambda context dict passed to the function by AWS + lambda_context (object): Lambda context dict passed to the function by AWS """ submit_enhanced_metric("invocations", lambda_context) @@ -128,6 +209,47 @@ def submit_errors_metric(lambda_context): """Increment aws.lambda.enhanced.errors by 1, applying runtime, layer, and cold_start tags Args: - lambda_context (dict): Lambda context dict passed to the function by AWS + lambda_context (object): Lambda context dict passed to the function by AWS """ submit_enhanced_metric("errors", lambda_context) + + +def submit_batch_item_failures_metric(response, lambda_context): + """Submit aws.lambda.enhanced.batch_item_failures metric with the count of batch item failures + + Args: + response (dict): Lambda function response object + lambda_context (object): Lambda context dict passed to the function by AWS + """ + if not config.enhanced_metrics_enabled: + logger.debug( + "Not submitting batch_item_failures metric because enhanced metrics are disabled" + ) + return + + if not isinstance(response, dict): + return + + batch_item_failures = response.get("batchItemFailures") + if batch_item_failures is not None and isinstance(batch_item_failures, list): + lambda_metric( + "aws.lambda.enhanced.batch_item_failures", + len(batch_item_failures), + timestamp=None, + tags=get_enhanced_metrics_tags(lambda_context), + force_async=True, + ) + + +def submit_dynamodb_stream_type_metric(event): + stream_view_type = ( + event.get("Records", [{}])[0].get("dynamodb", {}).get("StreamViewType") + ) + if stream_view_type: + lambda_metric( + "datadog.serverless.dynamodb.stream.type", + 1, + timestamp=None, + tags=[f"streamtype:{stream_view_type}"], + force_async=True, + ) diff --git a/datadog_lambda/patch.py b/datadog_lambda/patch.py index 0f6d28e96..6d2af0dcf 100644 --- a/datadog_lambda/patch.py +++ b/datadog_lambda/patch.py @@ -3,20 +3,17 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -import json -import os import sys import logging import zlib +import ujson as json from wrapt import wrap_function_wrapper as wrap from wrapt.importer import when_imported from ddtrace import patch_all as patch_all_dd -from datadog_lambda.tracing import ( - get_dd_trace_context, - dd_tracing_enabled, -) +from datadog_lambda.config import config +from datadog_lambda.tracing import get_dd_trace_context from collections.abc import MutableMapping logger = logging.getLogger(__name__) @@ -32,7 +29,7 @@ def patch_all(): """ _patch_for_integration_tests() - if dd_tracing_enabled: + if config.trace_enabled: patch_all_dd() else: _patch_http() @@ -44,8 +41,7 @@ def _patch_for_integration_tests(): Patch `requests` to log the outgoing requests for integration tests. """ global _integration_tests_patched - is_in_tests = os.environ.get("DD_INTEGRATION_TEST", "false").lower() == "true" - if not _integration_tests_patched and is_in_tests: + if not _integration_tests_patched and config.integration_test: wrap("requests", "Session.send", _log_request) _integration_tests_patched = True @@ -144,14 +140,14 @@ def _print_request_string(request): data = zlib.decompress(data) data_dict = json.loads(data) data_dict.get("series", []).sort(key=lambda series: series.get("metric")) - sorted_data = json.dumps(data_dict) + sorted_data = json.dumps(data_dict, escape_forward_slashes=False) # Sort headers to prevent any differences in ordering headers = request.headers or {} sorted_headers = sorted( "{}:{}".format(key, value) for key, value in headers.items() ) - sorted_header_str = json.dumps(sorted_headers) + sorted_header_str = json.dumps(sorted_headers, escape_forward_slashes=False) print( "HTTP {} {} Headers: {} Data: {}".format( method, url, sorted_header_str, sorted_data diff --git a/datadog_lambda/span_pointers.py b/datadog_lambda/span_pointers.py new file mode 100644 index 000000000..45925d929 --- /dev/null +++ b/datadog_lambda/span_pointers.py @@ -0,0 +1,200 @@ +from itertools import chain +import logging +from typing import List +from typing import Optional + +from ddtrace._trace._span_pointer import _SpanPointerDirection +from ddtrace._trace._span_pointer import _SpanPointerDescription + +from datadog_lambda.config import config +from datadog_lambda.metric import submit_dynamodb_stream_type_metric +from datadog_lambda.trigger import EventTypes + + +logger = logging.getLogger(__name__) + + +def calculate_span_pointers( + event_source, + event, + botocore_add_span_pointers=config.add_span_pointers, +) -> List[_SpanPointerDescription]: + try: + if botocore_add_span_pointers: + if event_source.equals(EventTypes.S3): + return _calculate_s3_span_pointers_for_event(event) + + elif event_source.equals(EventTypes.DYNAMODB): + # Temporary metric. TODO eventually remove(@nhulston) + submit_dynamodb_stream_type_metric(event) + return _calculate_dynamodb_span_pointers_for_event(event) + + except Exception as e: + logger.debug( + "failed to calculate span pointers for event: %s", + e, + ) + + return [] + + +def _calculate_s3_span_pointers_for_event(event) -> List[_SpanPointerDescription]: + # Example event: + # https://docs.aws.amazon.com/lambda/latest/dg/with-s3.html + + return list( + chain.from_iterable( + _calculate_s3_span_pointers_for_event_record(record) + for record in event.get("Records", []) + ) + ) + + +def _calculate_s3_span_pointers_for_event_record( + record, +) -> List[_SpanPointerDescription]: + # Event types: + # https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html + + if record.get("eventName").startswith("ObjectCreated:"): + s3_information = record.get("s3", None) + if s3_information is not None: + return _calculate_s3_span_pointers_for_object_created_s3_information( + s3_information + ) + + return [] + + +def _calculate_s3_span_pointers_for_object_created_s3_information( + s3_information, +) -> List[_SpanPointerDescription]: + try: + bucket = s3_information["bucket"]["name"] + key = s3_information["object"]["key"] + etag = s3_information["object"]["eTag"] + + except KeyError as e: + logger.debug( + "missing s3 information required to make a span pointer: %s", + e, + ) + return [] + + try: + from ddtrace._trace.utils_botocore.span_pointers.s3 import ( + _aws_s3_object_span_pointer_description, + ) + + try: + span_pointer_description = _aws_s3_object_span_pointer_description( + operation="S3.LambdaEvent", + pointer_direction=_SpanPointerDirection.UPSTREAM, + bucket=bucket, + key=key, + etag=etag, + ) + except TypeError: + # The older version of this function did not have an operation + # parameter. + span_pointer_description = _aws_s3_object_span_pointer_description( + pointer_direction=_SpanPointerDirection.UPSTREAM, + bucket=bucket, + key=key, + etag=etag, + ) + + if span_pointer_description is None: + return [] + + return [span_pointer_description] + + except Exception as e: + logger.debug( + "failed to generate S3 span pointer: %s", + e, + ) + return [] + + +def _calculate_dynamodb_span_pointers_for_event(event) -> List[_SpanPointerDescription]: + # Example event: + # https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html + + return list( + chain.from_iterable( + _calculate_dynamodb_span_pointers_for_event_record(record) + for record in event.get("Records", []) + ) + ) + + +def _calculate_dynamodb_span_pointers_for_event_record( + record, +) -> List[_SpanPointerDescription]: + try: + table_name = _extract_table_name_from_dynamodb_stream_record(record) + if table_name is None: + return [] + + primary_key = record["dynamodb"]["Keys"] + + except Exception as e: + logger.debug( + "missing DynamoDB information required to make a span pointer: %s", + e, + ) + return [] + + try: + from ddtrace._trace.utils_botocore.span_pointers.dynamodb import ( + _aws_dynamodb_item_span_pointer_description, + ) + + try: + span_pointer_description = _aws_dynamodb_item_span_pointer_description( + operation="DynamoDB.LambdaEvent", + pointer_direction=_SpanPointerDirection.UPSTREAM, + table_name=table_name, + primary_key=primary_key, + ) + except TypeError: + # The older version of this function did not have an operation + # parameter. + span_pointer_description = _aws_dynamodb_item_span_pointer_description( + pointer_direction=_SpanPointerDirection.UPSTREAM, + table_name=table_name, + primary_key=primary_key, + ) + + if span_pointer_description is None: + return [] + + return [span_pointer_description] + + except Exception as e: + logger.debug( + "failed to generate DynamoDB span pointer: %s", + e, + ) + return [] + + +def _extract_table_name_from_dynamodb_stream_record(record) -> Optional[str]: + # Example eventSourceARN: + # arn:aws:dynamodb:us-east-2:123456789012:table/my-table/stream/2024-06-10T19:26:16.525 + event_source_arn = record["eventSourceARN"] + + [_arn, _aws, _dynamodb, _region, _account, dynamodb_info] = event_source_arn.split( + ":", maxsplit=5 + ) + if _arn != "arn" or _aws != "aws" or _dynamodb != "dynamodb": + logger.debug("unexpected eventSourceARN format: %s", event_source_arn) + return None + + [_table, table_name, _stream, _timestamp] = dynamodb_info.split("/") + if _table != "table" or _stream != "stream": + logger.debug("unexpected eventSourceARN format: %s", event_source_arn) + return None + + return table_name diff --git a/datadog_lambda/stats_writer.py b/datadog_lambda/stats_writer.py index d3919c30f..563b1ae98 100644 --- a/datadog_lambda/stats_writer.py +++ b/datadog_lambda/stats_writer.py @@ -1,5 +1,5 @@ class StatsWriter: - def distribution(self, metric_name, value, tags=[], timestamp=None): + def distribution(self, metric_name, value, tags=None, timestamp=None): raise NotImplementedError() def flush(self): diff --git a/datadog_lambda/statsd_writer.py b/datadog_lambda/statsd_writer.py index 33843dc6a..4aaab8d53 100644 --- a/datadog_lambda/statsd_writer.py +++ b/datadog_lambda/statsd_writer.py @@ -1,5 +1,5 @@ -from datadog_lambda.stats_writer import StatsWriter from datadog_lambda.dogstatsd import statsd +from datadog_lambda.stats_writer import StatsWriter class StatsDWriter(StatsWriter): @@ -7,8 +7,8 @@ class StatsDWriter(StatsWriter): Writes distribution metrics using StatsD protocol """ - def distribution(self, metric_name, value, tags=[], timestamp=None): - statsd.distribution(metric_name, value, tags=tags) + def distribution(self, metric_name, value, tags=None, timestamp=None): + statsd.distribution(metric_name, value, tags=tags, timestamp=timestamp) def flush(self): pass diff --git a/datadog_lambda/tag_object.py b/datadog_lambda/tag_object.py index 7ca8512c3..744e48933 100644 --- a/datadog_lambda/tag_object.py +++ b/datadog_lambda/tag_object.py @@ -3,21 +3,20 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -import json -import logging +from decimal import Decimal +import ujson as json + +from datadog_lambda.config import config redactable_keys = ["authorization", "x-authorization", "password", "token"] -max_depth = 10 -logger = logging.getLogger(__name__) def tag_object(span, key, obj, depth=0): - if depth >= max_depth: - return - else: - depth += 1 if obj is None: return span.set_tag(key, obj) + if depth >= config.capture_payload_max_depth: + return span.set_tag(key, _redact_val(key, str(obj)[0:5000])) + depth += 1 if _should_try_string(obj): parsed = None try: @@ -26,19 +25,28 @@ def tag_object(span, key, obj, depth=0): except ValueError: redacted = _redact_val(key, obj[0:5000]) return span.set_tag(key, redacted) - if isinstance(obj, int) or isinstance(obj, float): - return span.set_tag(key, obj) + if isinstance(obj, int) or isinstance(obj, float) or isinstance(obj, Decimal): + return span.set_tag(key, str(obj)) if isinstance(obj, list): for k, v in enumerate(obj): - formatted_key = "{}.{}".format(key, k) + formatted_key = f"{key}.{k}" tag_object(span, formatted_key, v, depth) return - if isinstance(obj, object): - for k in obj: - v = obj.get(k) - formatted_key = "{}.{}".format(key, k) + if hasattr(obj, "items"): + for k, v in obj.items(): + formatted_key = f"{key}.{k}" tag_object(span, formatted_key, v, depth) return + if hasattr(obj, "to_dict"): + for k, v in obj.to_dict().items(): + formatted_key = f"{key}.{k}" + tag_object(span, formatted_key, v, depth) + return + try: + value_as_str = str(obj) + except Exception: + value_as_str = "UNKNOWN" + return span.set_tag(key, value_as_str) def _should_try_string(obj): diff --git a/datadog_lambda/tags.py b/datadog_lambda/tags.py index cdaeb4eda..5b3fe43e6 100644 --- a/datadog_lambda/tags.py +++ b/datadog_lambda/tags.py @@ -1,28 +1,13 @@ import sys -from platform import python_version_tuple - from datadog_lambda import __version__ from datadog_lambda.cold_start import get_cold_start_tag -def _format_dd_lambda_layer_tag(): - """ - Formats the dd_lambda_layer tag, e.g., 'dd_lambda_layer:datadog-python39_1' - """ - runtime = "python{}{}".format(sys.version_info[0], sys.version_info[1]) - return "dd_lambda_layer:datadog-{}_{}".format(runtime, __version__) - - -def tag_dd_lambda_layer(tags): - """ - Used by lambda_metric to insert the dd_lambda_layer tag - """ - dd_lambda_layer_tag = _format_dd_lambda_layer_tag() - if tags: - return tags + [dd_lambda_layer_tag] - else: - return [dd_lambda_layer_tag] +_major, _minor = sys.version_info[0], sys.version_info[1] +dd_lambda_layer_tag = f"dd_lambda_layer:datadog-python{_major}{_minor}_{__version__}" +runtime_tag = f"runtime:python{_major}.{_minor}" +library_version_tag = f"datadog_lambda:v{__version__}" def parse_lambda_tags_from_arn(lambda_context): @@ -32,64 +17,52 @@ def parse_lambda_tags_from_arn(lambda_context): ex: lambda_context.arn = arn:aws:lambda:us-east-1:123597598159:function:my-lambda:1 """ # Set up flag for extra testing to distinguish between a version or alias - hasAlias = False + has_alias = False # Cap the number of times to spli split_arn = lambda_context.invoked_function_arn.split(":") if len(split_arn) > 7: - hasAlias = True + has_alias = True _, _, _, region, account_id, _, function_name, alias = split_arn else: _, _, _, region, account_id, _, function_name = split_arn # Add the standard tags to a list tags = [ - "region:{}".format(region), - "account_id:{}".format(account_id), - "functionname:{}".format(function_name), + f"region:{region}", + f"account_id:{account_id}", + f"functionname:{function_name}", ] # Check if we have a version or alias - if hasAlias: + if has_alias: # If $Latest, drop the $ for datadog tag convention. A lambda alias can't start with $ if alias.startswith("$"): alias = alias[1:] # Versions are numeric. Aliases need the executed version tag elif not check_if_number(alias): - tags.append("executedversion:{}".format(lambda_context.function_version)) + tags.append(f"executedversion:{lambda_context.function_version}") # create resource tag with function name and alias/version - resource = "resource:{}:{}".format(function_name, alias) + resource = f"resource:{function_name}:{alias}" else: # Resource is only the function name otherwise - resource = "resource:{}".format(function_name) + resource = f"resource:{function_name}" tags.append(resource) return tags -def get_runtime_tag(): - """Get the runtime tag from the current Python version""" - major_version, minor_version, _ = python_version_tuple() - - return "runtime:python{major}.{minor}".format( - major=major_version, minor=minor_version - ) - - -def get_library_version_tag(): - """Get datadog lambda library tag""" - return "datadog_lambda:v{}".format(__version__) - - def get_enhanced_metrics_tags(lambda_context): """Get the list of tags to apply to enhanced metrics""" - return parse_lambda_tags_from_arn(lambda_context) + [ - get_cold_start_tag(), - "memorysize:{}".format(lambda_context.memory_limit_in_mb), - get_runtime_tag(), - get_library_version_tag(), - ] + tags = [] + if lambda_context: + tags = parse_lambda_tags_from_arn(lambda_context) + tags.append(f"memorysize:{lambda_context.memory_limit_in_mb}") + tags.append(get_cold_start_tag()) + tags.append(runtime_tag) + tags.append(library_version_tag) + return tags def check_if_number(alias): diff --git a/datadog_lambda/thread_stats_writer.py b/datadog_lambda/thread_stats_writer.py index bfcf3c992..f21ee31f9 100644 --- a/datadog_lambda/thread_stats_writer.py +++ b/datadog_lambda/thread_stats_writer.py @@ -3,6 +3,7 @@ # Make sure that this package would always be lazy-loaded/outside from the critical path # since underlying packages are quite heavy to load and useless when the extension is present from datadog.threadstats import ThreadStats + from datadog_lambda.stats_writer import StatsWriter logger = logging.getLogger(__name__) @@ -17,16 +18,21 @@ def __init__(self, flush_in_thread): self.thread_stats = ThreadStats(compress_payload=True) self.thread_stats.start(flush_in_thread=flush_in_thread) - def distribution(self, metric_name, value, tags=[], timestamp=None): + def distribution(self, metric_name, value, tags=None, timestamp=None): self.thread_stats.distribution( metric_name, value, tags=tags, timestamp=timestamp ) - def flush(self): + def flush(self, tags=None): """ "Flush distributions from ThreadStats to Datadog. Modified based on `datadog.threadstats.base.ThreadStats.flush()`, to gain better control over exception handling. """ + original_constant_tags = self.thread_stats.constant_tags.copy() + if tags: + # Temporarily add tags for this flush + self.thread_stats.constant_tags = original_constant_tags + tags + _, dists = self.thread_stats._get_aggregate_metrics_and_dists(float("inf")) count_dists = len(dists) if not count_dists: @@ -60,6 +66,9 @@ def flush(self): logger.debug( "Flush #%s failed", self.thread_stats.flush_count, exc_info=True ) + finally: + # Reset constant_tags to its original state + self.thread_stats.constant_tags = original_constant_tags def stop(self): self.thread_stats.stop() diff --git a/datadog_lambda/tracing.py b/datadog_lambda/tracing.py index 90cf7aac1..225f5dd82 100644 --- a/datadog_lambda/tracing.py +++ b/datadog_lambda/tracing.py @@ -2,61 +2,108 @@ # under the Apache License Version 2.0. # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. - import logging import os -import json +import re +import traceback +import ujson as json +from datetime import datetime, timezone +from typing import Optional, Dict + +from datadog_lambda.metric import submit_errors_metric + +try: + from typing import Literal +except ImportError: + # Literal was added to typing in python 3.8 + from typing_extensions import Literal from datadog_lambda.constants import ( SamplingPriority, - TraceHeader, TraceContextSource, XrayDaemon, + Headers, ) from datadog_lambda.xray import ( send_segment, parse_xray_header, ) -from ddtrace import tracer, patch + +from ddtrace import patch from ddtrace import __version__ as ddtrace_version from ddtrace.propagation.http import HTTPPropagator +from ddtrace.trace import Context, Span, tracer + +from datadog_lambda.config import config from datadog_lambda import __version__ as datadog_lambda_version +from datadog_lambda.trigger import ( + _EventSource, + parse_event_source, + get_first_record, + is_step_function_event, + EventTypes, + EventSubtypes, +) + +if config.otel_enabled: + from opentelemetry.trace import set_tracer_provider + from ddtrace.opentelemetry import TracerProvider + + set_tracer_provider(TracerProvider()) + logger = logging.getLogger(__name__) -dd_trace_context = {} -dd_tracing_enabled = os.environ.get("DD_TRACE_ENABLED", "false").lower() == "true" +dd_trace_context = None propagator = HTTPPropagator() +DD_TRACE_JAVA_TRACE_ID_PADDING = "00000000" +HIGHER_64_BITS = "HIGHER_64_BITS" +LOWER_64_BITS = "LOWER_64_BITS" + + +def _dsm_set_checkpoint(context_json, event_type, arn): + if not config.data_streams_enabled: + return + + if not arn: + return + + try: + from ddtrace.data_streams import set_consume_checkpoint + + carrier_get = lambda k: context_json and context_json.get(k) # noqa: E731 + set_consume_checkpoint(event_type, arn, carrier_get, manual_checkpoint=False) + except Exception as e: + logger.debug( + f"DSM:Failed to set consume checkpoint for {event_type} {arn}: {e}" + ) + def _convert_xray_trace_id(xray_trace_id): """ Convert X-Ray trace id (hex)'s last 63 bits to a Datadog trace id (int). """ - return str(0x7FFFFFFFFFFFFFFF & int(xray_trace_id[-16:], 16)) + return 0x7FFFFFFFFFFFFFFF & int(xray_trace_id[-16:], 16) def _convert_xray_entity_id(xray_entity_id): """ Convert X-Ray (sub)segement id (hex) to a Datadog span id (int). """ - return str(int(xray_entity_id, 16)) + return int(xray_entity_id, 16) def _convert_xray_sampling(xray_sampled): """ Convert X-Ray sampled (True/False) to its Datadog counterpart. """ - return ( - str(SamplingPriority.USER_KEEP) - if xray_sampled - else str(SamplingPriority.USER_REJECT) - ) + return SamplingPriority.USER_KEEP if xray_sampled else SamplingPriority.USER_REJECT def _get_xray_trace_context(): - if not is_lambda_context(): + if not config.is_lambda_context: return None xray_trace_entity = parse_xray_header( @@ -64,19 +111,15 @@ def _get_xray_trace_context(): ) if xray_trace_entity is None: return None - trace_context = { - "trace-id": _convert_xray_trace_id(xray_trace_entity["trace_id"]), - "parent-id": _convert_xray_entity_id(xray_trace_entity["parent_id"]), - "sampling-priority": _convert_xray_sampling(xray_trace_entity["sampled"]), - } + trace_context = Context( + trace_id=_convert_xray_trace_id(xray_trace_entity.get("trace_id")), + span_id=_convert_xray_entity_id(xray_trace_entity.get("parent_id")), + sampling_priority=_convert_xray_sampling(xray_trace_entity.get("sampled")), + ) logger.debug( "Converted trace context %s from X-Ray segment %s", trace_context, - ( - xray_trace_entity["trace_id"], - xray_trace_entity["parent_id"], - xray_trace_entity["sampled"], - ), + xray_trace_entity, ) return trace_context @@ -86,26 +129,21 @@ def _get_dd_trace_py_context(): if not span: return None - parent_id = span.context.span_id - trace_id = span.context.trace_id - sampling_priority = span.context.sampling_priority logger.debug( - "found dd trace context: %s", (span.context.trace_id, span.context.span_id) + "found dd trace context: trace_id=%s span_id=%s", + span.context.trace_id, + span.context.span_id, ) - return { - "parent-id": str(parent_id), - "trace-id": str(trace_id), - "sampling-priority": str(sampling_priority), - "source": TraceContextSource.DDTRACE, - } + return span.context -def _context_obj_to_headers(obj): - return { - TraceHeader.TRACE_ID: str(obj.get("trace-id")), - TraceHeader.PARENT_ID: str(obj.get("parent-id")), - TraceHeader.SAMPLING_PRIORITY: str(obj.get("sampling-priority")), - } +def _is_context_complete(context): + return ( + context + and context.trace_id + and context.span_id + and context.sampling_priority is not None + ) def create_dd_dummy_metadata_subsegment( @@ -126,67 +164,385 @@ def extract_context_from_lambda_context(lambda_context): dd_trace libraries inject this trace context on synchronous invocations """ + dd_data = None client_context = lambda_context.client_context - trace_id = None - parent_id = None - sampling_priority = None if client_context and client_context.custom: + dd_data = client_context.custom if "_datadog" in client_context.custom: # Legacy trace propagation dict - dd_data = client_context.custom.get("_datadog", {}) - trace_id = dd_data.get(TraceHeader.TRACE_ID) - parent_id = dd_data.get(TraceHeader.PARENT_ID) - sampling_priority = dd_data.get(TraceHeader.SAMPLING_PRIORITY) - elif ( - TraceHeader.TRACE_ID in client_context.custom - and TraceHeader.PARENT_ID in client_context.custom - and TraceHeader.SAMPLING_PRIORITY in client_context.custom - ): - # New trace propagation keys - trace_id = client_context.custom.get(TraceHeader.TRACE_ID) - parent_id = client_context.custom.get(TraceHeader.PARENT_ID) - sampling_priority = client_context.custom.get(TraceHeader.SAMPLING_PRIORITY) - - return trace_id, parent_id, sampling_priority + dd_data = client_context.custom.get("_datadog") + return propagator.extract(dd_data) -def extract_context_from_http_event_or_context(event, lambda_context): +def extract_context_from_http_event_or_context( + event, + lambda_context, + event_source: _EventSource, + decode_authorizer_context: bool = True, +): """ Extract Datadog trace context from the `headers` key in from the Lambda `event` object. Falls back to lambda context if no trace data is found in the `headers` """ - headers = event.get("headers", {}) - lowercase_headers = {k.lower(): v for k, v in headers.items()} + if decode_authorizer_context: + is_http_api = event_source.equals( + EventTypes.API_GATEWAY, subtype=EventSubtypes.HTTP_API + ) + injected_authorizer_data = get_injected_authorizer_data(event, is_http_api) + context = propagator.extract(injected_authorizer_data) + if _is_context_complete(context): + return context - trace_id = lowercase_headers.get(TraceHeader.TRACE_ID) - parent_id = lowercase_headers.get(TraceHeader.PARENT_ID) - sampling_priority = lowercase_headers.get(TraceHeader.SAMPLING_PRIORITY) + headers = event.get("headers") + context = propagator.extract(headers) - if not trace_id or not parent_id or not sampling_priority: + if not _is_context_complete(context): return extract_context_from_lambda_context(lambda_context) - return trace_id, parent_id, sampling_priority + return context -def extract_context_from_sqs_event_or_context(event, lambda_context): +def extract_context_from_request_header_or_context(event, lambda_context, event_source): + request = event.get("request") + if isinstance(request, (set, dict)) and "headers" in request: + context = extract_context_from_http_event_or_context( + request, + lambda_context, + event_source, + decode_authorizer_context=False, + ) + else: + context = extract_context_from_lambda_context(lambda_context) + return context + + +def create_sns_event(message): + return { + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "Sns": message, + } + ] + } + + +def extract_context_from_sqs_or_sns_event_or_context( + event, lambda_context, event_source +): """ - Extract Datadog trace context from the first SQS message attributes. + Extract Datadog trace context from an SQS event. + + The extraction chain goes as follows: + EB => SQS (First records body contains EB context), or + SNS => SQS (First records body contains SNS context), or + SQS or SNS (`messageAttributes` for SQS context, + `MessageAttributes` for SNS context), else + Lambda Context. Falls back to lambda context if no trace data is found in the SQS message attributes. + Set a DSM checkpoint if DSM is enabled and the method for context propagation is supported. """ + source_arn = "" + event_type = "sqs" if event_source.equals(EventTypes.SQS) else "sns" + + # EventBridge => SQS try: - first_record = event["Records"][0] - msg_attributes = first_record.get("messageAttributes", {}) - dd_json_data = msg_attributes.get("_datadog", {}).get("stringValue", r"{}") - dd_data = json.loads(dd_json_data) - trace_id = dd_data.get(TraceHeader.TRACE_ID) - parent_id = dd_data.get(TraceHeader.PARENT_ID) - sampling_priority = dd_data.get(TraceHeader.SAMPLING_PRIORITY) - - return trace_id, parent_id, sampling_priority + context = _extract_context_from_eventbridge_sqs_event(event) + if _is_context_complete(context): + return context except Exception: + logger.debug("Failed extracting context as EventBridge to SQS.") + + try: + first_record = event.get("Records")[0] + source_arn = first_record.get("eventSourceARN", "") + + # logic to deal with SNS => SQS event + if "body" in first_record: + body_str = first_record.get("body") + try: + body = json.loads(body_str) + if body.get("Type", "") == "Notification" and "TopicArn" in body: + logger.debug("Found SNS message inside SQS event") + first_record = get_first_record(create_sns_event(body)) + except Exception: + pass + + msg_attributes = first_record.get("messageAttributes") + if msg_attributes is None: + sns_record = first_record.get("Sns") or {} + # SNS->SQS event would extract SNS arn without this check + if event_source.equals(EventTypes.SNS): + source_arn = sns_record.get("TopicArn", "") + msg_attributes = sns_record.get("MessageAttributes") or {} + dd_payload = msg_attributes.get("_datadog") + if dd_payload: + # SQS uses dataType and binaryValue/stringValue + # SNS uses Type and Value + dd_json_data = None + dd_json_data_type = dd_payload.get("Type") or dd_payload.get("dataType") + if dd_json_data_type == "Binary": + import base64 + + dd_json_data = dd_payload.get("binaryValue") or dd_payload.get("Value") + if dd_json_data: + dd_json_data = base64.b64decode(dd_json_data) + elif dd_json_data_type == "String": + dd_json_data = dd_payload.get("stringValue") or dd_payload.get("Value") + else: + logger.debug( + "Datadog Lambda Python only supports extracting trace" + "context from String or Binary SQS/SNS message attributes" + ) + + if dd_json_data: + dd_data = json.loads(dd_json_data) + + if is_step_function_event(dd_data): + try: + return extract_context_from_step_functions(dd_data, None) + except Exception: + logger.debug( + "Failed to extract Step Functions context from SQS/SNS event." + ) + context = propagator.extract(dd_data) + _dsm_set_checkpoint(dd_data, event_type, source_arn) + return context + else: + # Handle case where trace context is injected into attributes.AWSTraceHeader + # example: Root=1-654321ab-000000001234567890abcdef;Parent=0123456789abcdef;Sampled=1 + attrs = event.get("Records")[0].get("attributes") + if attrs: + x_ray_header = attrs.get("AWSTraceHeader") + if x_ray_header: + x_ray_context = parse_xray_header(x_ray_header) + trace_id_parts = x_ray_context.get("trace_id", "").split("-") + if len(trace_id_parts) > 2 and trace_id_parts[2].startswith( + DD_TRACE_JAVA_TRACE_ID_PADDING + ): + # If it starts with eight 0's padding, + # then this AWSTraceHeader contains Datadog injected trace context + logger.debug( + "Found dd-trace injected trace context from AWSTraceHeader" + ) + return Context( + trace_id=int(trace_id_parts[2][8:], 16), + span_id=int(x_ray_context["parent_id"], 16), + sampling_priority=float(x_ray_context["sampled"]), + ) + # Still want to set a DSM checkpoint even if DSM context not propagated + _dsm_set_checkpoint(None, event_type, source_arn) + return extract_context_from_lambda_context(lambda_context) + except Exception as e: + logger.debug("The trace extractor returned with error %s", e) + # Still want to set a DSM checkpoint even if DSM context not propagated + _dsm_set_checkpoint(None, event_type, source_arn) + return extract_context_from_lambda_context(lambda_context) + + +def _extract_context_from_eventbridge_sqs_event(event): + """ + Extracts Datadog trace context from an SQS event triggered by + EventBridge. + + This is only possible if first record in `Records` contains a + `body` field which contains the EventBridge `detail` as a JSON string. + """ + first_record = event.get("Records")[0] + body_str = first_record.get("body") + body = json.loads(body_str) + detail = body.get("detail") + dd_context = detail.get("_datadog") + + if is_step_function_event(dd_context): + try: + return extract_context_from_step_functions(dd_context, None) + except Exception: + logger.debug( + "Failed to extract Step Functions context from EventBridge to SQS event." + ) + + return propagator.extract(dd_context) + + +def extract_context_from_eventbridge_event(event, lambda_context): + """ + Extract datadog trace context from an EventBridge message's Details. + This is only possible if Details is a JSON string. + + If we find a Step Function context, try to extract the trace context from + that header. + """ + try: + detail = event.get("detail") + dd_context = detail.get("_datadog") + if not dd_context: + return extract_context_from_lambda_context(lambda_context) + + try: + return extract_context_from_step_functions(dd_context, None) + except Exception: + logger.debug( + "Failed to extract Step Functions context from EventBridge event." + ) + + return propagator.extract(dd_context) + except Exception as e: + logger.debug("The trace extractor returned with error %s", e) + return extract_context_from_lambda_context(lambda_context) + + +def extract_context_from_kinesis_event(event, lambda_context): + """ + Extract datadog trace context from a Kinesis Stream's base64 encoded data string + Set a DSM checkpoint if DSM is enabled and the method for context propagation is supported. + """ + source_arn = "" + try: + record = get_first_record(event) + source_arn = record.get("eventSourceARN", "") + kinesis = record.get("kinesis") + if not kinesis: + return extract_context_from_lambda_context(lambda_context) + data = kinesis.get("data") + if data: + import base64 + + b64_bytes = data.encode("ascii") + str_bytes = base64.b64decode(b64_bytes) + data_str = str_bytes.decode("ascii") + data_obj = json.loads(data_str) + dd_ctx = data_obj.get("_datadog") + if dd_ctx: + context = propagator.extract(dd_ctx) + _dsm_set_checkpoint(dd_ctx, "kinesis", source_arn) + return context + except Exception as e: + logger.debug("The trace extractor returned with error %s", e) + # Still want to set a DSM checkpoint even if DSM context not propagated + _dsm_set_checkpoint(None, "kinesis", source_arn) + return extract_context_from_lambda_context(lambda_context) + + +def _deterministic_sha256_hash(s: str, part: str) -> int: + import hashlib + + sha256_hash = hashlib.sha256(s.encode()).hexdigest() + # First two chars is '0b'. zfill to ensure 256 bits, but we only care about the first 128 bits + binary_hash = bin(int(sha256_hash, 16))[2:].zfill(256) + if part == HIGHER_64_BITS: + updated_binary_hash = "0" + binary_hash[1:64] + else: + updated_binary_hash = "0" + binary_hash[65:128] + result = int(updated_binary_hash, 2) + if result == 0: + return 1 + return result + + +def _parse_high_64_bits(trace_tags: str) -> str: + """ + Parse a list of trace tags such as [_dd.p.tid=66bcb5eb00000000,_dd.p.dm=-0] and return the + value of the _dd.p.tid tag or an empty string if not found. + """ + if trace_tags: + for tag in trace_tags.split(","): + if "_dd.p.tid=" in tag: + return tag.split("=")[1] + + return "" + + +def _generate_sfn_parent_id(context: dict) -> int: + """ + Generates a stable parent span ID for a downstream Lambda invoked by a Step Function. The + upstream Step Function execution context is used to infer the parent's span ID, ensuring trace + continuity. + + `RetryCount` and `RedriveCount` are appended only when both are nonzero to maintain + compatibility with older Lambda layers that did not include these fields. + """ + execution_id = context.get("Execution").get("Id") + redrive_count = context.get("Execution").get("RedriveCount", 0) + state_name = context.get("State").get("Name") + state_entered_time = context.get("State").get("EnteredTime") + retry_count = context.get("State").get("RetryCount", 0) + + include_counts = not (retry_count == 0 and redrive_count == 0) + counts_suffix = f"#{retry_count}#{redrive_count}" if include_counts else "" + + return _deterministic_sha256_hash( + f"{execution_id}#{state_name}#{state_entered_time}{counts_suffix}", + HIGHER_64_BITS, + ) + + +def _generate_sfn_trace_id(execution_id: str, part: str): + """ + Take the SHA-256 hash of the execution_id to calculate the trace ID. If the high 64 bits are + specified, we take those bits and use hex to encode it. We also remove the first two characters + as they will be '0x in the hex string. + + We care about full 128 bits because they will break up into traditional traceID and + _dd.p.tid tag. + """ + if part == HIGHER_64_BITS: + return hex(_deterministic_sha256_hash(execution_id, part))[2:] + return _deterministic_sha256_hash(execution_id, part) + + +def extract_context_from_step_functions(event, lambda_context): + """ + Only extract datadog trace context when Step Functions Context Object is injected + into lambda's event dict. Unwrap "Payload" if it exists to handle Legacy Lambda cases. + + If '_datadog' header is present, we have two cases: + 1. Root is a Lambda and we use its traceID + 2. Root is a SFN, and we use its executionARN to calculate the traceID + We calculate the parentID the same in both cases by using the parent SFN's context object. + + Otherwise, we're dealing with the legacy case where we only have the parent SFN's context + object. + """ + try: + event = event.get("Payload", event) + event = event.get("_datadog", event) + + meta = {} + + if event.get("serverless-version") == "v1": + if "x-datadog-trace-id" in event: # lambda root + trace_id = int(event.get("x-datadog-trace-id")) + high_64_bit_trace_id = _parse_high_64_bits(event.get("x-datadog-tags")) + if high_64_bit_trace_id: + meta["_dd.p.tid"] = high_64_bit_trace_id + else: # sfn root + root_execution_id = event.get("RootExecutionId") + trace_id = _generate_sfn_trace_id(root_execution_id, LOWER_64_BITS) + meta["_dd.p.tid"] = _generate_sfn_trace_id( + root_execution_id, HIGHER_64_BITS + ) + + parent_id = _generate_sfn_parent_id(event) + else: + execution_id = event.get("Execution").get("Id") + trace_id = _generate_sfn_trace_id(execution_id, LOWER_64_BITS) + meta["_dd.p.tid"] = _generate_sfn_trace_id(execution_id, HIGHER_64_BITS) + parent_id = _generate_sfn_parent_id(event) + + sampling_priority = SamplingPriority.AUTO_KEEP + return Context( + trace_id=trace_id, + span_id=parent_id, + sampling_priority=sampling_priority, + meta=meta, + ) + except Exception as e: + logger.debug("The Step Functions trace extractor returned with error %s", e) return extract_context_from_lambda_context(lambda_context) @@ -195,19 +551,79 @@ def extract_context_custom_extractor(extractor, event, lambda_context): Extract Datadog trace context using a custom trace extractor function """ try: - ( - trace_id, - parent_id, - sampling_priority, - ) = extractor(event, lambda_context) - return trace_id, parent_id, sampling_priority + trace_id, parent_id, sampling_priority = extractor(event, lambda_context) + return Context( + trace_id=int(trace_id), + span_id=int(parent_id), + sampling_priority=int(sampling_priority), + ) except Exception as e: logger.debug("The trace extractor returned with error %s", e) - return None, None, None + +def is_authorizer_response(response) -> bool: + try: + return ( + response is not None + and response["principalId"] + and response["policyDocument"] + ) + except (KeyError, AttributeError): + pass + except Exception as e: + logger.debug("unknown error while checking is_authorizer_response %s", e) + return False + + +def get_injected_authorizer_data(event, is_http_api) -> dict: + try: + req_ctx = event.get("requestContext") + if not req_ctx: + return None + authorizer_headers = req_ctx.get("authorizer") + if not authorizer_headers: + return None + + if is_http_api: + lambda_hdr = authorizer_headers.get("lambda") + if not lambda_hdr: + return None + dd_data_raw = lambda_hdr.get("_datadog") + else: + dd_data_raw = authorizer_headers.get("_datadog") + + if not dd_data_raw: + return None + + import base64 + + injected_data = json.loads(base64.b64decode(dd_data_raw)) + + # Lambda authorizer's results can be cached. But the payload will still have the injected + # data in cached requests. How to distinguish cached case and ignore the injected data ? + # APIGateway automatically injects a integrationLatency data in some cases. If it's >0 we + # know that it's not cached. But integrationLatency is not available for Http API case. In + # that case, we use the injected Authorizing_Request_Id to tell if it's cached. But token + # authorizers don't pass on the requestId. The Authorizing_Request_Id can't work for all + # cases neither. As a result, we combine both methods as shown below. + if authorizer_headers.get("integrationLatency", 0) > 0: + return injected_data + req_ctx = event.get("requestContext") + if not req_ctx: + return None + if req_ctx.get("requestId") == injected_data.get( + Headers.Authorizing_Request_Id + ): + return injected_data + return None + + except Exception as e: + logger.debug("Failed to check if invocated by an authorizer. error %s", e) -def extract_dd_trace_context(event, lambda_context, extractor=None): +def extract_dd_trace_context( + event, lambda_context, extractor=None, decode_authorizer_context: bool = True +): """ Extract Datadog trace context from the Lambda `event` object. @@ -216,38 +632,34 @@ def extract_dd_trace_context(event, lambda_context, extractor=None): """ global dd_trace_context trace_context_source = None + event_source = parse_event_source(event) if extractor is not None: - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_custom_extractor(extractor, event, lambda_context) - elif "headers" in event: - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_from_http_event_or_context(event, lambda_context) - elif "Records" in event: - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_from_sqs_event_or_context(event, lambda_context) - else: - trace_id, parent_id, sampling_priority = extract_context_from_lambda_context( - lambda_context + context = extract_context_custom_extractor(extractor, event, lambda_context) + elif isinstance(event, (set, dict)) and "request" in event: + context = extract_context_from_request_header_or_context( + event, lambda_context, event_source + ) + elif isinstance(event, (set, dict)) and "headers" in event: + context = extract_context_from_http_event_or_context( + event, lambda_context, event_source, decode_authorizer_context + ) + elif event_source.equals(EventTypes.SNS) or event_source.equals(EventTypes.SQS): + context = extract_context_from_sqs_or_sns_event_or_context( + event, lambda_context, event_source ) + elif event_source.equals(EventTypes.EVENTBRIDGE): + context = extract_context_from_eventbridge_event(event, lambda_context) + elif event_source.equals(EventTypes.KINESIS): + context = extract_context_from_kinesis_event(event, lambda_context) + elif event_source.equals(EventTypes.STEPFUNCTIONS): + context = extract_context_from_step_functions(event, lambda_context) + else: + context = extract_context_from_lambda_context(lambda_context) - if trace_id and parent_id and sampling_priority: + if _is_context_complete(context): logger.debug("Extracted Datadog trace context from event or context") - metadata = { - "trace-id": trace_id, - "parent-id": parent_id, - "sampling-priority": sampling_priority, - } - dd_trace_context = metadata.copy() + dd_trace_context = context trace_context_source = TraceContextSource.EVENT else: # AWS Lambda runtime caches global variables between invocations, @@ -256,10 +668,10 @@ def extract_dd_trace_context(event, lambda_context, extractor=None): if dd_trace_context: trace_context_source = TraceContextSource.XRAY logger.debug("extracted dd trace context %s", dd_trace_context) - return dd_trace_context, trace_context_source + return dd_trace_context, trace_context_source, event_source -def get_dd_trace_context(): +def get_dd_trace_context_obj(): """ Return the Datadog trace context to be propagated on the outgoing requests. @@ -271,55 +683,68 @@ def get_dd_trace_context(): automatically, but this function can be used to manually inject the trace context to an outgoing request. """ - global dd_trace_context - - context = None - xray_context = None + if config.trace_enabled: + dd_trace_py_context = _get_dd_trace_py_context() + if _is_context_complete(dd_trace_py_context): + return dd_trace_py_context try: xray_context = _get_xray_trace_context() # xray (sub)segment except Exception as e: logger.debug( - "get_dd_trace_context couldn't read from segment from x-ray, with error %s" - % e + "get_dd_trace_context couldn't read from segment from x-ray, with error %s", + e, ) + if not xray_context: + return None - if xray_context and not dd_trace_context: - context = xray_context - elif xray_context and dd_trace_context: - context = dd_trace_context.copy() - context["parent-id"] = xray_context["parent-id"] - logger.debug("Set parent id from xray trace context: %s", context["parent-id"]) + if not _is_context_complete(dd_trace_context): + return xray_context - if dd_tracing_enabled: - dd_trace_py_context = _get_dd_trace_py_context() - if dd_trace_py_context is not None: - context = dd_trace_py_context + logger.debug("Set parent id from xray trace context: %s", xray_context.span_id) + return Context( + trace_id=dd_trace_context.trace_id, + span_id=xray_context.span_id, + sampling_priority=dd_trace_context.sampling_priority, + meta=dd_trace_context._meta.copy(), + metrics=dd_trace_context._metrics.copy(), + ) - return _context_obj_to_headers(context) if context is not None else {} + +def get_dd_trace_context(): + """ + Return the Datadog trace context to be propagated on the outgoing requests, + as a dict of headers. + """ + headers = {} + context = get_dd_trace_context_obj() + if not _is_context_complete(context): + return headers + propagator.inject(context, headers) + return headers def set_correlation_ids(): """ Create a dummy span, and overrides its trace_id and span_id, to make - ddtrace.helpers.get_correlation_ids() return the correct ids for both + ddtrace.helpers.get_log_correlation_context() return a dict containing the correct ids for both auto and manual log correlations. TODO: Remove me when Datadog tracer is natively supported in Lambda. """ - if not is_lambda_context(): + if not config.is_lambda_context: logger.debug("set_correlation_ids is only supported in LambdaContext") return - if dd_tracing_enabled: + if config.trace_enabled: logger.debug("using ddtrace implementation for spans") return - context = get_dd_trace_context() - - span = tracer.trace("dummy.span") - span.trace_id = int(context[TraceHeader.TRACE_ID]) - span.span_id = int(context[TraceHeader.PARENT_ID]) + context = get_dd_trace_context_obj() + if not _is_context_complete(context): + return + tracer.context_provider.activate(context) + tracer.trace("dummy.span") logger.debug("correlation ids set") @@ -328,15 +753,14 @@ def inject_correlation_ids(): Override the formatter of LambdaLoggerHandler to inject datadog trace and span id for log correlation. - For manual injections to custom log handlers, use `ddtrace.helpers.get_correlation_ids` - to retrieve correlation ids (trace_id, span_id). + For manual injections to custom log handlers, use `ddtrace.helpers.get_log_correlation_context` + to retrieve a dict containing correlation ids (trace_id, span_id). """ # Override the log format of the AWS provided LambdaLoggerHandler root_logger = logging.getLogger() for handler in root_logger.handlers: - if ( - handler.__class__.__name__ == "LambdaLoggerHandler" - and type(handler.formatter) == logging.Formatter + if handler.__class__.__name__ == "LambdaLoggerHandler" and isinstance( + handler.formatter, logging.Formatter ): handler.setFormatter( logging.Formatter( @@ -352,40 +776,672 @@ def inject_correlation_ids(): logger.debug("logs injection configured") -def is_lambda_context(): - """ - Return True if the X-Ray context is `LambdaContext`, rather than the - regular `Context` (e.g., when testing lambda functions locally). - """ - return os.environ.get(XrayDaemon.FUNCTION_NAME_HEADER_NAME, "") != "" - - def set_dd_trace_py_root(trace_context_source, merge_xray_traces): + if not _is_context_complete(dd_trace_context): + return if trace_context_source == TraceContextSource.EVENT or merge_xray_traces: - context = dict(dd_trace_context) + context = Context( + trace_id=dd_trace_context.trace_id, + span_id=dd_trace_context.span_id, + sampling_priority=dd_trace_context.sampling_priority, + ) if merge_xray_traces: xray_context = _get_xray_trace_context() - if xray_context is not None: - context["parent-id"] = xray_context["parent-id"] + if xray_context and xray_context.span_id: + context.span_id = xray_context.span_id - headers = _context_obj_to_headers(context) - span_context = propagator.extract(headers) - tracer.context_provider.activate(span_context) + tracer.context_provider.activate(context) + logger.debug( + "Set dd trace root context to: trace_id=%s span_id=%s", + context.trace_id, + context.span_id, + ) + + +def create_inferred_span( + event, + context, + event_source: _EventSource = None, + decode_authorizer_context: bool = True, +): + if event_source is None: + event_source = parse_event_source(event) + try: + if event_source.equals( + EventTypes.API_GATEWAY, subtype=EventSubtypes.API_GATEWAY + ): + logger.debug("API Gateway event detected. Inferring a span") + return create_inferred_span_from_api_gateway_event( + event, context, decode_authorizer_context + ) + elif event_source.equals(EventTypes.LAMBDA_FUNCTION_URL): + logger.debug("Function URL event detected. Inferring a span") + return create_inferred_span_from_lambda_function_url_event(event, context) + elif event_source.equals( + EventTypes.API_GATEWAY, subtype=EventSubtypes.HTTP_API + ): + logger.debug("HTTP API event detected. Inferring a span") + return create_inferred_span_from_http_api_event( + event, context, decode_authorizer_context + ) + elif event_source.equals( + EventTypes.API_GATEWAY, subtype=EventSubtypes.WEBSOCKET + ): + logger.debug("API Gateway Websocket event detected. Inferring a span") + return create_inferred_span_from_api_gateway_websocket_event( + event, context, decode_authorizer_context + ) + elif event_source.equals(EventTypes.SQS): + logger.debug("SQS event detected. Inferring a span") + return create_inferred_span_from_sqs_event(event, context) + elif event_source.equals(EventTypes.SNS): + logger.debug("SNS event detected. Inferring a span") + return create_inferred_span_from_sns_event(event, context) + elif event_source.equals(EventTypes.KINESIS): + logger.debug("Kinesis event detected. Inferring a span") + return create_inferred_span_from_kinesis_event(event, context) + elif event_source.equals(EventTypes.DYNAMODB): + logger.debug("Dynamodb event detected. Inferring a span") + return create_inferred_span_from_dynamodb_event(event, context) + elif event_source.equals(EventTypes.S3): + logger.debug("S3 event detected. Inferring a span") + return create_inferred_span_from_s3_event(event, context) + elif event_source.equals(EventTypes.EVENTBRIDGE): + logger.debug("Eventbridge event detected. Inferring a span") + return create_inferred_span_from_eventbridge_event(event, context) + except Exception as e: logger.debug( - "Set dd trace root context to: %s", - (span_context.trace_id, span_context.span_id), + "Unable to infer span. Detected type: %s. Reason: %s", + event_source.to_string(), + e, ) + logger.debug("Unable to infer a span: unknown event type") + + +def create_service_mapping(val): + new_service_mapping = {} + for entry in val.split(","): + parts = entry.split(":") + if len(parts) == 2: + key = parts[0].strip() + value = parts[1].strip() + if key != value and key and value: + new_service_mapping[key] = value + return new_service_mapping + + +def determine_service_name( + service_mapping, specific_key, generic_key, extracted_key, fallback=None +): + # Check for mapped service (specific key first, then generic key) + mapped_service = service_mapping.get(specific_key) or service_mapping.get( + generic_key + ) + if mapped_service: + return mapped_service + + # Check if AWS service representation is disabled + aws_service_representation = os.environ.get( + "DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED", "" + ).lower() + if aws_service_representation in ("false", "0"): + return fallback + + # Use extracted_key if it exists and is not empty, otherwise use fallback + return ( + extracted_key.strip() if extracted_key and extracted_key.strip() else fallback + ) + + +# Initialization code +service_mapping_str = os.environ.get("DD_SERVICE_MAPPING", "") +service_mapping = create_service_mapping(service_mapping_str) + +_dd_origin = {"_dd.origin": "lambda"} + + +def create_inferred_span_from_lambda_function_url_event(event, context): + request_context = event.get("requestContext") + api_id = request_context.get("apiId") + domain = request_context.get("domainName") + service_name = determine_service_name(service_mapping, api_id, "lambda_url", domain) + http = request_context.get("http") + method = http.get("method") if http else None + path = http.get("path") if http else None + http_url = f"https://{domain}{path}/" + resource = f"{method} {path}" + tags = { + "operation_name": "aws.lambda.url", + "http.url": http_url, + "endpoint": path, + "http.method": method, + "resource_names": resource, + "request_id": context.aws_request_id, + } + request_time_epoch = request_context.get("timeEpoch") + tracer.set_tags(_dd_origin) # function urls don't count as lambda_inferred, + # because they're in the same service as the inferring lambda function + span = tracer.trace( + "aws.lambda.url", service=service_name, resource=resource, span_type="http" + ) + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync") + if span: + span.set_tags(tags) + span.start_ns = int(request_time_epoch * 1e6) + return span + + +def is_api_gateway_invocation_async(event): + hdrs = event.get("headers") + if not hdrs: + return False + return hdrs.get("X-Amz-Invocation-Type") == "Event" + + +def insert_upstream_authorizer_span( + kwargs_to_start_span, other_tags_for_span, start_time_ns, finish_time_ns +): + """Insert the authorizer span. + Without this: parent span --child-> inferred span + With this insertion: parent span --child-> upstreamAuthorizerSpan --child-> inferred span + + Args: + kwargs_to_start_span (Dict): the same keyword arguments used for the inferred span + other_tags_for_span (Dict): the same tag keyword arguments used for the inferred span + start_time_ns (int): the start time of the span in nanoseconds + finish_time_ns (int): the finish time of the sapn in nanoseconds + """ + trace_ctx = tracer.current_trace_context() + upstream_authorizer_span = tracer.trace( + "aws.apigateway.authorizer", **kwargs_to_start_span + ) + upstream_authorizer_span.set_tags(other_tags_for_span) + upstream_authorizer_span.set_tag("operation_name", "aws.apigateway.authorizer") + # always sync for the authorizer invocation + InferredSpanInfo.set_tags_to_span(upstream_authorizer_span, synchronicity="sync") + upstream_authorizer_span.start_ns = int(start_time_ns) + upstream_authorizer_span.finish(finish_time_ns / 1e9) + # trace context needs to be set again as it is reset by finish() + tracer.context_provider.activate(trace_ctx) + return upstream_authorizer_span + + +def process_injected_data(event, request_time_epoch_ms, args, tags): + """ + This covers the ApiGateway RestAPI and Websocket cases. It doesn't cover Http API cases. + """ + injected_authorizer_data = get_injected_authorizer_data(event, False) + if injected_authorizer_data: + try: + start_time_ns = int( + injected_authorizer_data.get(Headers.Parent_Span_Finish_Time) + ) + finish_time_ns = ( + request_time_epoch_ms + + ( + int( + event["requestContext"]["authorizer"].get( + "integrationLatency", 0 + ) + ) + ) + ) * 1e6 + upstream_authorizer_span = insert_upstream_authorizer_span( + args, tags, start_time_ns, finish_time_ns + ) + return upstream_authorizer_span, finish_time_ns + except Exception as e: + logger.debug( + "Unable to insert authorizer span. Continue to generate the main span.\ + Reason: %s", + e, + ) + return None, None + else: + return None, None + + +def create_inferred_span_from_api_gateway_websocket_event( + event, context, decode_authorizer_context: bool = True +): + request_context = event.get("requestContext") + domain = request_context.get("domainName") + endpoint = request_context.get("routeKey") + http_url = f"https://{domain}{endpoint}/" + api_id = request_context.get("apiId") + + service_name = determine_service_name( + service_mapping, api_id, "lambda_api_gateway", domain + ) + tags = { + "operation_name": "aws.apigateway.websocket", + "http.url": http_url, + "endpoint": endpoint, + "resource_names": endpoint, + "span.kind": "server", + "apiid": api_id, + "apiname": api_id, + "stage": request_context.get("stage"), + "request_id": context.aws_request_id, + "connection_id": request_context.get("connectionId"), + "event_type": request_context.get("eventType"), + "message_direction": request_context.get("messageDirection"), + } + request_time_epoch_ms = int(request_context.get("requestTimeEpoch")) + if is_api_gateway_invocation_async(event): + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") + else: + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync") + args = { + "service": service_name, + "resource": endpoint, + "span_type": "web", + } + tracer.set_tags(_dd_origin) + upstream_authorizer_span = None + finish_time_ns = None + if decode_authorizer_context: + upstream_authorizer_span, finish_time_ns = process_injected_data( + event, request_time_epoch_ms, args, tags + ) + span = tracer.trace("aws.apigateway.websocket", **args) + if span: + span.set_tags(tags) + span.start_ns = int( + finish_time_ns + if finish_time_ns is not None + else request_time_epoch_ms * 1e6 + ) + if upstream_authorizer_span: + span.parent_id = upstream_authorizer_span.span_id + return span + + +def create_inferred_span_from_api_gateway_event( + event, context, decode_authorizer_context: bool = True +): + request_context = event.get("requestContext") + domain = request_context.get("domainName", "") + api_id = request_context.get("apiId") + service_name = determine_service_name( + service_mapping, api_id, "lambda_api_gateway", domain + ) + method = event.get("httpMethod") + path = event.get("path") + http_url = f"https://{domain}{path}/" + resource_path = _get_resource_path(event, request_context) + resource = f"{method} {resource_path}" + tags = { + "operation_name": "aws.apigateway.rest", + "http.url": http_url, + "endpoint": path, + "http.method": method, + "resource_names": resource, + "span.kind": "server", + "apiid": api_id, + "apiname": api_id, + "stage": request_context.get("stage"), + "request_id": context.aws_request_id, + } + request_time_epoch_ms = int(request_context.get("requestTimeEpoch")) + if is_api_gateway_invocation_async(event): + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") + else: + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync") + args = { + "service": service_name, + "resource": resource, + "span_type": "http", + } + tracer.set_tags(_dd_origin) + upstream_authorizer_span = None + finish_time_ns = None + if decode_authorizer_context: + upstream_authorizer_span, finish_time_ns = process_injected_data( + event, request_time_epoch_ms, args, tags + ) + span = tracer.trace("aws.apigateway", **args) + if span: + span.set_tags(tags) + # start time pushed by the inserted authorizer span + span.start_ns = int( + finish_time_ns + if finish_time_ns is not None + else request_time_epoch_ms * 1e6 + ) + if upstream_authorizer_span: + span.parent_id = upstream_authorizer_span.span_id + return span + + +def _get_resource_path(event, request_context): + route_key = request_context.get("routeKey") or "" + if "{" in route_key: + try: + return route_key.split(" ")[1] + except Exception as e: + logger.debug("Error parsing routeKey: %s", e) + return event.get("rawPath") or request_context.get("resourcePath") or route_key + + +def create_inferred_span_from_http_api_event( + event, context, decode_authorizer_context: bool = True +): + request_context = event.get("requestContext") + domain = request_context.get("domainName") + api_id = request_context.get("apiId") + service_name = determine_service_name( + service_mapping, api_id, "lambda_api_gateway", domain + ) + http = request_context.get("http") or {} + method = http.get("method") + path = event.get("rawPath") + http_url = f"https://{domain}{path}/" + resource_path = _get_resource_path(event, request_context) + resource = f"{method} {resource_path}" + tags = { + "operation_name": "aws.httpapi", + "endpoint": path, + "http.url": http_url, + "http.method": http.get("method"), + "http.protocol": http.get("protocol"), + "http.source_ip": http.get("sourceIp"), + "http.user_agent": http.get("userAgent"), + "resource_names": resource, + "request_id": context.aws_request_id, + "apiid": api_id, + "apiname": api_id, + "stage": request_context.get("stage"), + } + request_time_epoch_ms = int(request_context.get("timeEpoch")) + if is_api_gateway_invocation_async(event): + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") + else: + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync") + tracer.set_tags(_dd_origin) + inferred_span_start_ns = request_time_epoch_ms * 1e6 + if decode_authorizer_context: + injected_authorizer_data = get_injected_authorizer_data(event, True) + if injected_authorizer_data: + inferred_span_start_ns = injected_authorizer_data.get( + Headers.Parent_Span_Finish_Time + ) + span = tracer.trace( + "aws.httpapi", service=service_name, resource=resource, span_type="http" + ) + if span: + span.set_tags(tags) + span.start_ns = int(inferred_span_start_ns) + return span + + +def create_inferred_span_from_sqs_event(event, context): + trace_ctx = tracer.current_trace_context() + + event_record = get_first_record(event) + event_source_arn = event_record.get("eventSourceARN") + queue_name = event_source_arn.split(":")[-1] + service_name = determine_service_name( + service_mapping, queue_name, "lambda_sqs", queue_name, "sqs" + ) + attrs = event_record.get("attributes") or {} + tags = { + "operation_name": "aws.sqs", + "resource_names": queue_name, + "span.kind": "server", + "queuename": queue_name, + "event_source_arn": event_source_arn, + "receipt_handle": event_record.get("receiptHandle"), + "sender_id": attrs.get("SenderId"), + } + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") + request_time_epoch = attrs.get("SentTimestamp") + start_time = int(request_time_epoch) / 1000 + + upstream_span = None + if "body" in event_record: + body_str = event_record.get("body", {}) + try: + body = json.loads(body_str) + + # logic to deal with SNS => SQS event + if body.get("Type", "") == "Notification" and "TopicArn" in body: + logger.debug("Found SNS message inside SQS event") + upstream_span = create_inferred_span_from_sns_event( + create_sns_event(body), context + ) + upstream_span.finish(finish_time=start_time) + + # EventBridge => SQS + elif body.get("detail"): + detail = body.get("detail") + if detail.get("_datadog"): + logger.debug("Found an EventBridge message inside SQS event") + upstream_span = create_inferred_span_from_eventbridge_event( + body, context + ) + upstream_span.finish(finish_time=start_time) + + except Exception as e: + logger.debug( + "Unable to create upstream span from SQS message, with error %s", e + ) + pass + + # trace context needs to be set again as it is reset + # when sns_span.finish executes + tracer.context_provider.activate(trace_ctx) + tracer.set_tags(_dd_origin) + span = tracer.trace( + "aws.sqs", service=service_name, resource=queue_name, span_type="web" + ) + if span: + span.set_tags(tags) + span.start = start_time + if upstream_span: + span.parent_id = upstream_span.span_id + + return span + + +def create_inferred_span_from_sns_event(event, context): + event_record = get_first_record(event) + sns_message = event_record.get("Sns") or {} + topic_arn = sns_message.get("TopicArn") + topic_name = topic_arn.split(":")[-1] + service_name = determine_service_name( + service_mapping, topic_name, "lambda_sns", topic_name, "sns" + ) + tags = { + "operation_name": "aws.sns", + "resource_names": topic_name, + "span.kind": "server", + "topicname": topic_name, + "topic_arn": topic_arn, + "message_id": sns_message.get("MessageId"), + "type": sns_message.get("Type"), + } + + # Subject not available in SNS => SQS scenario + subject = sns_message.get("Subject") + if subject: + tags["subject"] = subject + + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") + sns_dt_format = "%Y-%m-%dT%H:%M:%S.%fZ" + timestamp = sns_message.get("Timestamp") + dt = datetime.strptime(timestamp, sns_dt_format) + + tracer.set_tags(_dd_origin) + span = tracer.trace( + "aws.sns", service=service_name, resource=topic_name, span_type="web" + ) + if span: + span.set_tags(tags) + span.start = dt.replace(tzinfo=timezone.utc).timestamp() + return span + + +def create_inferred_span_from_kinesis_event(event, context): + event_record = get_first_record(event) + event_source_arn = event_record.get("eventSourceARN") + event_id = event_record.get("eventID") + stream_name = re.sub(r"^stream/", "", (event_source_arn or "").split(":")[-1]) + shard_id = event_id.split(":")[0] + service_name = determine_service_name( + service_mapping, stream_name, "lambda_kinesis", stream_name, "kinesis" + ) + kinesis = event_record.get("kinesis") or {} + tags = { + "operation_name": "aws.kinesis", + "resource_names": stream_name, + "span.kind": "server", + "streamname": stream_name, + "shardid": shard_id, + "event_source_arn": event_source_arn, + "event_id": event_id, + "event_name": event_record.get("eventName"), + "event_version": event_record.get("eventVersion"), + "partition_key": kinesis.get("partitionKey"), + } + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") + request_time_epoch = kinesis.get("approximateArrivalTimestamp") + + tracer.set_tags(_dd_origin) + span = tracer.trace( + "aws.kinesis", service=service_name, resource=stream_name, span_type="web" + ) + if span: + span.set_tags(tags) + span.start = request_time_epoch + return span + + +def create_inferred_span_from_dynamodb_event(event, context): + event_record = get_first_record(event) + event_source_arn = event_record.get("eventSourceARN") + table_name = event_source_arn.split("/")[1] + service_name = determine_service_name( + service_mapping, table_name, "lambda_dynamodb", table_name, "dynamodb" + ) + dynamodb_message = event_record.get("dynamodb") or {} + tags = { + "operation_name": "aws.dynamodb", + "resource_names": table_name, + "span.kind": "server", + "tablename": table_name, + "event_source_arn": event_source_arn, + "event_id": event_record.get("eventID"), + "event_name": event_record.get("eventName"), + "event_version": event_record.get("eventVersion"), + "stream_view_type": dynamodb_message.get("StreamViewType"), + "size_bytes": str(dynamodb_message.get("SizeBytes")), + } + InferredSpanInfo.set_tags(tags, synchronicity="async", tag_source="self") + request_time_epoch = dynamodb_message.get("ApproximateCreationDateTime") + tracer.set_tags(_dd_origin) + span = tracer.trace( + "aws.dynamodb", service=service_name, resource=table_name, span_type="web" + ) + if span: + span.set_tags(tags) + + span.start = int(request_time_epoch) + return span + + +def create_inferred_span_from_s3_event(event, context): + event_record = get_first_record(event) + s3 = event_record.get("s3") or {} + bucket = s3.get("bucket") or {} + obj = s3.get("object") or {} + bucket_name = bucket.get("name") + service_name = determine_service_name( + service_mapping, bucket_name, "lambda_s3", bucket_name, "s3" + ) + tags = { + "operation_name": "aws.s3", + "resource_names": bucket_name, + "span.kind": "server", + "event_name": event_record.get("eventName"), + "bucketname": bucket_name, + "bucket_arn": bucket.get("arn"), + "object_key": obj.get("key"), + "object_size": str(obj.get("size")), + "object_etag": obj.get("eTag"), + } + InferredSpanInfo.set_tags(tags, synchronicity="async", tag_source="self") + dt_format = "%Y-%m-%dT%H:%M:%S.%fZ" + timestamp = event_record.get("eventTime") + dt = datetime.strptime(timestamp, dt_format) + + tracer.set_tags(_dd_origin) + span = tracer.trace( + "aws.s3", service=service_name, resource=bucket_name, span_type="web" + ) + if span: + span.set_tags(tags) + span.start = dt.replace(tzinfo=timezone.utc).timestamp() + return span + + +def create_inferred_span_from_eventbridge_event(event, context): + source = event.get("source") + service_name = determine_service_name( + service_mapping, source, "lambda_eventbridge", source, "eventbridge" + ) + tags = { + "operation_name": "aws.eventbridge", + "resource_names": source, + "span.kind": "server", + "detail_type": event.get("detail-type"), + } + InferredSpanInfo.set_tags( + tags, + synchronicity="async", + tag_source="self", + ) + + timestamp = event.get("time") + dt_format = "%Y-%m-%dT%H:%M:%SZ" + + # Use more granular timestamp from upstream Step Function if possible + try: + if is_step_function_event(event.get("detail")): + timestamp = event["detail"]["_datadog"]["State"]["EnteredTime"] + dt_format = "%Y-%m-%dT%H:%M:%S.%fZ" + except (TypeError, KeyError, AttributeError): + logger.debug("Error parsing timestamp from Step Functions event") + + dt = datetime.strptime(timestamp, dt_format) + + tracer.set_tags(_dd_origin) + span = tracer.trace( + "aws.eventbridge", service=service_name, resource=source, span_type="web" + ) + if span: + span.set_tags(tags) + span.start = dt.replace(tzinfo=timezone.utc).timestamp() + + # Since inferred span will later parent Lambda, preserve Lambda's current parent + if dd_trace_context.span_id: + span.parent_id = dd_trace_context.span_id + + return span def create_function_execution_span( context, function_name, is_cold_start, + is_proactive_init, trace_context_source, merge_xray_traces, trigger_tags, + parent_span=None, + span_pointers=None, ): - tags = {} + tags = None if context: function_arn = (context.invoked_function_arn or "").lower() tk = function_arn.split(":") @@ -397,22 +1453,130 @@ def create_function_execution_span( "function_version": function_version, "request_id": context.aws_request_id, "resource_names": context.function_name, - "functionname": context.function_name.lower() - if context.function_name - else None, + "functionname": ( + context.function_name.lower() if context.function_name else None + ), "datadog_lambda": datadog_lambda_version, "dd_trace": ddtrace_version, + "span.name": "aws.lambda", } + tags = tags or {} + if is_proactive_init: + tags["proactive_initialization"] = str(is_proactive_init).lower() if trace_context_source == TraceContextSource.XRAY and merge_xray_traces: tags["_dd.parent_source"] = trace_context_source tags.update(trigger_tags) - args = { - "service": "aws.lambda", - "resource": function_name, - "span_type": "serverless", - } - tracer.set_tags({"_dd.origin": "lambda"}) - span = tracer.trace("aws.lambda", **args) + tracer.set_tags(_dd_origin) + # Determine service name based on config and env var + if config.service: + service_name = config.service + else: + aws_service_representation = os.environ.get( + "DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED", "" + ).lower() + if aws_service_representation in ("false", "0"): + service_name = "aws.lambda" + else: + service_name = function_name if function_name else "aws.lambda" + + span = tracer.trace( + "aws.lambda", + service=service_name, + resource=function_name, + span_type="serverless", + ) if span: span.set_tags(tags) + if parent_span: + span.parent_id = parent_span.span_id + if span_pointers: + root_span = parent_span if parent_span else span + for span_pointer_description in span_pointers: + root_span._add_span_pointer( + pointer_kind=span_pointer_description.pointer_kind, + pointer_direction=span_pointer_description.pointer_direction, + pointer_hash=span_pointer_description.pointer_hash, + extra_attributes=span_pointer_description.extra_attributes, + ) return span + + +def mark_trace_as_error_for_5xx_responses(context, status_code, span): + if len(status_code) == 3 and status_code.startswith("5"): + submit_errors_metric(context) + if span: + span.error = 1 + + +class InferredSpanInfo(object): + BASE_NAME = "_inferred_span" + SYNCHRONICITY = f"{BASE_NAME}.synchronicity" + TAG_SOURCE = f"{BASE_NAME}.tag_source" + + @staticmethod + def set_tags( + tags: Dict[str, str], + synchronicity: Optional[Literal["sync", "async"]] = None, + tag_source: Optional[Literal["labmda", "self"]] = None, + ): + if synchronicity is not None: + tags[InferredSpanInfo.SYNCHRONICITY] = str(synchronicity) + if tag_source is not None: + tags[InferredSpanInfo.TAG_SOURCE] = str(tag_source) + + @staticmethod + def set_tags_to_span( + span: Span, + synchronicity: Optional[Literal["sync", "async"]] = None, + tag_source: Optional[Literal["labmda", "self"]] = None, + ): + if synchronicity is not None: + span.set_tags({InferredSpanInfo.SYNCHRONICITY: synchronicity}) + if tag_source is not None: + span.set_tags({InferredSpanInfo.TAG_SOURCE: str(tag_source)}) + + @staticmethod + def is_async(span: Span) -> bool: + if not span: + return False + try: + return span.get_tag(InferredSpanInfo.SYNCHRONICITY) == "async" + except Exception as e: + logger.debug( + "Unabled to read the %s tag, returning False. \ + Reason: %s.", + InferredSpanInfo.SYNCHRONICITY, + e, + ) + return False + + +def emit_telemetry_on_exception_outside_of_handler( + exception, resource_name, handler_load_start_time_ns +): + """ + Emit an enhanced error metric and create a span for exceptions occurring outside the handler + """ + submit_errors_metric(None) + if config.trace_enabled: + span = tracer.trace( + "aws.lambda", + service="aws.lambda", + resource=resource_name, + span_type="serverless", + ) + span.start_ns = handler_load_start_time_ns + + tags = { + "error.status": 500, + "error.type": type(exception).__name__, + "error.message": exception, + "error.stack": traceback.format_exc(), + "resource_names": resource_name, + "resource.name": resource_name, + "operation_name": "aws.lambda", + "status": "error", + } + span.set_tags(tags) + span.error = 1 + span.finish() diff --git a/datadog_lambda/trigger.py b/datadog_lambda/trigger.py index 7271f2395..e60de8f0c 100644 --- a/datadog_lambda/trigger.py +++ b/datadog_lambda/trigger.py @@ -3,19 +3,98 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -import base64 import gzip -import json +import ujson as json from io import BytesIO, BufferedReader +from enum import Enum +from typing import Any -EVENT_SOURCES = [ - "aws:dynamodb", - "aws:kinesis", - "aws:s3", - "aws:sns", - "aws:sqs", -] +class _stringTypedEnum(Enum): + """ + _stringTypedEnum provides a type-hinted convenience function for getting the string value of + an enum. + """ + + def get_string(self) -> str: + return self.value + + +class EventTypes(_stringTypedEnum): + """ + EventTypes is an enum of Lambda event types we care about. + """ + + UNKNOWN = "unknown" + API_GATEWAY = "api-gateway" + APPSYNC = "appsync" + ALB = "application-load-balancer" + CLOUDWATCH_LOGS = "cloudwatch-logs" + CLOUDWATCH_EVENTS = "cloudwatch-events" + CLOUDFRONT = "cloudfront" + DYNAMODB = "dynamodb" + EVENTBRIDGE = "eventbridge" + KINESIS = "kinesis" + LAMBDA_FUNCTION_URL = "lambda-function-url" + S3 = "s3" + SNS = "sns" + SQS = "sqs" + STEPFUNCTIONS = "states" + + +class EventSubtypes(_stringTypedEnum): + """ + EventSubtypes is an enum of Lambda event subtypes. + Currently, API Gateway events subtypes are supported, + e.g. HTTP-API and Websocket events vs vanilla API-Gateway events. + """ + + NONE = "none" + API_GATEWAY = "api-gateway" # regular API Gateway + WEBSOCKET = "websocket" + HTTP_API = "http-api" + + ALB = "alb" # regular alb + # ALB with the multi-value headers option checked on the target group + ALB_MULTI_VALUE_HEADERS = "alb-multi-value-headers" + + +class _EventSource: + """ + _EventSource holds an event's type and subtype. + """ + + def __init__( + self, + event_type: EventTypes, + subtype: EventSubtypes = EventSubtypes.NONE, + ): + self.event_type = event_type + self.subtype = subtype + + def to_string(self) -> str: + """ + to_string returns the string representation of an _EventSource. + Since to_string was added to support trigger tagging, + the event's subtype will never be included in the string. + """ + return self.event_type.get_string() + + def equals( + self, event_type: EventTypes, subtype: EventSubtypes = EventSubtypes.NONE + ) -> bool: + """ + equals provides syntactic sugar to determine whether this _EventSource has a given type + and subtype. + Unknown events will never equal other events. + """ + if self.event_type == EventTypes.UNKNOWN: + return False + if self.event_type != event_type: + return False + if self.subtype != subtype: + return False + return True def get_aws_partition_by_region(region): @@ -32,46 +111,88 @@ def get_first_record(event): return records[0] -def parse_event_source(event): - """Determines the source of the trigger event +def parse_event_source(event: dict) -> _EventSource: + """Determines the source of the trigger event""" + if not isinstance(event, dict): + return _EventSource(EventTypes.UNKNOWN) - Possible Returns: - api-gateway | application-load-balancer | cloudwatch-logs | - cloudwatch-events | cloudfront | dynamodb | kinesis | s3 | sns | sqs - """ - if type(event) is not dict: - return - event_source = event.get("eventSource") or event.get("EventSource") + event_source = None + # Get requestContext safely and ensure it's a dictionary request_context = event.get("requestContext") + if not isinstance(request_context, dict): + request_context = None + if request_context and request_context.get("stage"): - event_source = "api-gateway" + if "domainName" in request_context and detect_lambda_function_url_domain( + request_context.get("domainName", "") + ): + return _EventSource(EventTypes.LAMBDA_FUNCTION_URL) + event_source = _EventSource(EventTypes.API_GATEWAY) + if "httpMethod" in event: + event_source.subtype = EventSubtypes.API_GATEWAY + if "routeKey" in event: + event_source.subtype = EventSubtypes.HTTP_API + if request_context.get("messageDirection"): + event_source.subtype = EventSubtypes.WEBSOCKET if request_context and request_context.get("elb"): - event_source = "application-load-balancer" + if "multiValueHeaders" in event: + event_source = _EventSource( + EventTypes.ALB, EventSubtypes.ALB_MULTI_VALUE_HEADERS + ) + else: + event_source = _EventSource(EventTypes.ALB, EventSubtypes.ALB) if event.get("awslogs"): - event_source = "cloudwatch-logs" + event_source = _EventSource(EventTypes.CLOUDWATCH_LOGS) + + if event.get("detail-type"): + event_source = _EventSource(EventTypes.EVENTBRIDGE) event_detail = event.get("detail") - cw_event_categories = event_detail and event_detail.get("EventCategories") - if event.get("source") == "aws.events" or cw_event_categories: - event_source = "cloudwatch-events" + has_event_categories = ( + isinstance(event_detail, dict) + and event_detail.get("EventCategories") is not None + ) + if event.get("source") == "aws.events" or has_event_categories: + event_source = _EventSource(EventTypes.CLOUDWATCH_EVENTS) + + if is_step_function_event(event): + event_source = _EventSource(EventTypes.STEPFUNCTIONS) event_record = get_first_record(event) - if event_record: - event_source = event_record.get("eventSource") or event_record.get( + if event_record and isinstance(event_record, dict): + aws_event_source = event_record.get("eventSource") or event_record.get( "EventSource" ) + if aws_event_source == "aws:dynamodb": + event_source = _EventSource(EventTypes.DYNAMODB) + if aws_event_source == "aws:kinesis": + event_source = _EventSource(EventTypes.KINESIS) + if aws_event_source == "aws:s3": + event_source = _EventSource(EventTypes.S3) + if aws_event_source == "aws:sns": + event_source = _EventSource(EventTypes.SNS) + if aws_event_source == "aws:sqs": + event_source = _EventSource(EventTypes.SQS) if event_record.get("cf"): - event_source = "cloudfront" + event_source = _EventSource(EventTypes.CLOUDFRONT) + + return event_source or _EventSource(EventTypes.UNKNOWN) - if event_source in EVENT_SOURCES: - event_source = event_source.replace("aws:", "") - return event_source +def detect_lambda_function_url_domain(domain: str) -> bool: + # e.g. "etsn5fibjr.lambda-url.eu-south-1.amazonaws.com" + if not isinstance(domain, str): + return False + domain_parts = domain.split(".") + if len(domain_parts) < 2: + return False + return domain_parts[1] == "lambda-url" -def parse_event_source_arn(source, event, context): + +def parse_event_source_arn(source: _EventSource, event: dict, context: Any) -> str: """ Parses the trigger event for an available ARN. If an ARN field is not provided in the event we stitch it together. @@ -83,50 +204,81 @@ def parse_event_source_arn(source, event, context): event_record = get_first_record(event) # e.g. arn:aws:s3:::lambda-xyz123-abc890 - if source == "s3": - return event_record.get("s3")["bucket"]["arn"] + if source.to_string() == "s3": + s3 = event_record.get("s3") + if s3: + bucket = s3.get("bucket") + if bucket: + return bucket.get("arn") + return None # e.g. arn:aws:sns:us-east-1:123456789012:sns-lambda - if source == "sns": - return event_record.get("Sns")["TopicArn"] + if source.to_string() == "sns": + sns = event_record.get("Sns") + if sns: + return sns.get("TopicArn") + return None # e.g. arn:aws:cloudfront::123456789012:distribution/ABC123XYZ - if source == "cloudfront": - distribution_id = event_record.get("cf")["config"]["distributionId"] - return "arn:{}:cloudfront::{}:distribution/{}".format( - aws_arn, account_id, distribution_id + if source.event_type == EventTypes.CLOUDFRONT: + distribution_id = ( + event_record.get("cf", {}).get("config", {}).get("distributionId") ) + return f"arn:{aws_arn}:cloudfront::{account_id}:distribution/{distribution_id}" + + # e.g. arn:aws:lambda:::url:: + if source.equals(EventTypes.LAMBDA_FUNCTION_URL): + function_name = "" + if len(split_function_arn) >= 7: + function_name = split_function_arn[6] + function_arn = f"arn:aws:lambda:{region}:{account_id}:url:{function_name}" + function_qualifier = "" + if len(split_function_arn) >= 8: + function_qualifier = split_function_arn[7] + function_arn = function_arn + f":{function_qualifier}" + return function_arn # e.g. arn:aws:apigateway:us-east-1::/restapis/xyz123/stages/default - if source == "api-gateway": + if source.event_type == EventTypes.API_GATEWAY: request_context = event.get("requestContext") - return "arn:{}:apigateway:{}::/restapis/{}/stages/{}".format( - aws_arn, region, request_context["apiId"], request_context["stage"] - ) + api_id = request_context.get("apiId") + stage = request_context.get("stage") + return f"arn:{aws_arn}:apigateway:{region}::/restapis/{api_id}/stages/{stage}" # e.g. arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-xyz/123 - if source == "application-load-balancer": + if source.event_type == EventTypes.ALB: request_context = event.get("requestContext") - return request_context.get("elb")["targetGroupArn"] + if request_context: + elb = request_context.get("elb") + if elb: + return elb.get("targetGroupArn") + return None # e.g. arn:aws:logs:us-west-1:123456789012:log-group:/my-log-group-xyz - if source == "cloudwatch-logs": + if source.event_type == EventTypes.CLOUDWATCH_LOGS: + import base64 + with gzip.GzipFile( - fileobj=BytesIO(base64.b64decode(event["awslogs"]["data"])) + fileobj=BytesIO(base64.b64decode(event.get("awslogs", {}).get("data"))) ) as decompress_stream: data = b"".join(BufferedReader(decompress_stream)) logs = json.loads(data) log_group = logs.get("logGroup", "cloudwatch") - return "arn:{}:logs:{}:{}:log-group:{}".format( - aws_arn, region, account_id, log_group - ) + return f"arn:{aws_arn}:logs:{region}:{account_id}:log-group:{log_group}" # e.g. arn:aws:events:us-east-1:123456789012:rule/my-schedule - if source == "cloudwatch-events" and event.get("resources"): + if source.event_type == EventTypes.CLOUDWATCH_EVENTS and event.get("resources"): return event.get("resources")[0] + # Returning state machine arn as event source arn. + if source.event_type == EventTypes.STEPFUNCTIONS: + context = event + if "_datadog" in event: + context = event.get("_datadog") + return context.get("StateMachine").get("Id") + -def get_event_source_arn(source, event, context): +def get_event_source_arn(source: _EventSource, event: dict, context: Any) -> str: event_source_arn = event.get("eventSourceARN") or event.get("eventSourceArn") event_record = get_first_record(event) @@ -145,64 +297,100 @@ def extract_http_tags(event): """ Extracts HTTP facet tags from the triggering event """ - http_tags = {} + http_tags = {"span.kind": "server"} + + # Safely get request_context and ensure it's a dictionary request_context = event.get("requestContext") + if not isinstance(request_context, dict): + request_context = None + path = event.get("path") method = event.get("httpMethod") + if request_context and request_context.get("stage"): - if request_context.get("domainName"): - http_tags["http.url"] = request_context["domainName"] + domain_name = request_context.get("domainName") + if domain_name: + http_tags["http.url"] = f"https://{domain_name}/" path = request_context.get("path") method = request_context.get("httpMethod") + # Version 2.0 HTTP API Gateway - apigateway_v2_http = request_context.get("http") + apigateway_v2_http = request_context.get("http", {}) + if not isinstance(apigateway_v2_http, dict): + apigateway_v2_http = {} + if event.get("version") == "2.0" and apigateway_v2_http: path = apigateway_v2_http.get("path") method = apigateway_v2_http.get("method") if path: - http_tags["http.url_details.path"] = path + if http_tags.get("http.url"): + http_tags["http.url"] += path if method: http_tags["http.method"] = method - headers = event.get("headers") + # Safely get headers + headers = event.get("headers", {}) + if not isinstance(headers, dict): + headers = {} + if headers and headers.get("Referer"): - http_tags["http.referer"] = headers["Referer"] + http_tags["http.referer"] = headers.get("Referer") + + # Try to get `routeKey` from API GW v2; otherwise try to get `resource` from API GW v1 + route = event.get("routeKey") or event.get("resource") + if route and isinstance(route, str): + try: + # "GET /my/endpoint" = > "/my/endpoint" + http_tags["http.route"] = route.split(" ")[-1] + except Exception: + # If splitting fails, use the route as is + http_tags["http.route"] = route return http_tags -def extract_trigger_tags(event, context): +_http_event_types = ( + EventTypes.API_GATEWAY, + EventTypes.ALB, + EventTypes.LAMBDA_FUNCTION_URL, +) + + +def extract_trigger_tags(event: dict, context: Any) -> dict: """ Parses the trigger event object to get tags to be added to the span metadata """ trigger_tags = {} event_source = parse_event_source(event) - if event_source: - trigger_tags["function_trigger.event_source"] = event_source + if event_source.to_string() is not None and event_source.to_string() != "unknown": + trigger_tags["function_trigger.event_source"] = event_source.to_string() event_source_arn = get_event_source_arn(event_source, event, context) if event_source_arn: trigger_tags["function_trigger.event_source_arn"] = event_source_arn - if event_source in ["api-gateway", "application-load-balancer"]: + if event_source.event_type in _http_event_types: trigger_tags.update(extract_http_tags(event)) return trigger_tags +_str_http_triggers = [et.value for et in _http_event_types] + + def extract_http_status_code_tag(trigger_tags, response): """ - If the Lambda was triggered by API Gateway or ALB add the returned status code - as a tag to the function execution span. + If the Lambda was triggered by API Gateway, Lambda Function URL, or ALB, + add the returned status code as a tag to the function execution span. """ - is_http_trigger = trigger_tags and ( - trigger_tags.get("function_trigger.event_source") == "api-gateway" - or trigger_tags.get("function_trigger.event_source") - == "application-load-balancer" - ) - if not is_http_trigger: + if trigger_tags is None: + return + str_event_source = trigger_tags.get("function_trigger.event_source") + # it would be cleaner if each event type was a constant object that + # knew some properties about itself like this. + if str_event_source not in _str_http_triggers: return status_code = "200" @@ -215,3 +403,29 @@ def extract_http_status_code_tag(trigger_tags, response): status_code = response.status_code return str(status_code) + + +def is_step_function_event(event): + """ + Check if the event is a step function that invoked the current lambda. + + The whole event can be wrapped in "Payload" in Legacy Lambda cases. There may also be a + "_datadog" for JSONata style context propagation. + + The actual event must contain "Execution", "StateMachine", and "State" fields. + """ + event = event.get("Payload", event) + + # JSONPath style + if "Execution" in event and "StateMachine" in event and "State" in event: + return True + + # JSONata style + dd_context = event.get("_datadog") + return ( + dd_context + and "Execution" in dd_context + and "StateMachine" in dd_context + and "State" in dd_context + and "serverless-version" in dd_context + ) diff --git a/datadog_lambda/version.py b/datadog_lambda/version.py new file mode 100644 index 000000000..373eef7d0 --- /dev/null +++ b/datadog_lambda/version.py @@ -0,0 +1 @@ +__version__ = "8.117.0.dev0" diff --git a/datadog_lambda/wrapper.py b/datadog_lambda/wrapper.py index 1ba7f1267..8dbd7e359 100644 --- a/datadog_lambda/wrapper.py +++ b/datadog_lambda/wrapper.py @@ -2,39 +2,85 @@ # under the Apache License Version 2.0. # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. - import os import logging import traceback +import ujson as json from importlib import import_module +from time import time_ns +from ddtrace.internal._exceptions import BlockingException from datadog_lambda.extension import should_use_extension, flush_extension -from datadog_lambda.cold_start import set_cold_start, is_cold_start -from datadog_lambda.constants import XraySubsegment, TraceContextSource -from datadog_lambda.metric import ( - flush_stats, - submit_invocations_metric, - submit_errors_metric, +from datadog_lambda.cold_start import ( + set_cold_start, + is_cold_start, + is_proactive_init, + is_new_sandbox, + ColdStartTracer, +) +from datadog_lambda.config import config +from datadog_lambda.constants import ( + TraceContextSource, + XraySubsegment, + Headers, ) from datadog_lambda.module_name import modify_module_name -from datadog_lambda.patch import patch_all +from datadog_lambda.span_pointers import calculate_span_pointers +from datadog_lambda.tag_object import tag_object from datadog_lambda.tracing import ( extract_dd_trace_context, create_dd_dummy_metadata_subsegment, inject_correlation_ids, - dd_tracing_enabled, + mark_trace_as_error_for_5xx_responses, set_correlation_ids, set_dd_trace_py_root, create_function_execution_span, + create_inferred_span, + InferredSpanInfo, + is_authorizer_response, + tracer, + propagator, ) -from datadog_lambda.trigger import extract_trigger_tags, extract_http_status_code_tag -from datadog_lambda.tag_object import tag_object +from datadog_lambda.trigger import ( + extract_trigger_tags, + extract_http_status_code_tag, +) + +# ddtrace imports are also tested in +# dd-trace-py/tests/internal/test_serverless.py please update those tests when +# making changes to any ddtrace import. + +if config.appsec_enabled: + from datadog_lambda.asm import ( + asm_set_context, + asm_start_response, + asm_start_request, + get_asm_blocked_response, + ) + from ddtrace.internal.appsec.product import start + + start() + +if config.profiling_enabled: + from ddtrace.profiling import profiler + +if config.llmobs_enabled: + from ddtrace.llmobs import LLMObs + +if config.exception_replay_enabled: + from ddtrace.debugging._exception.replay import SpanExceptionHandler + + try: + from ddtrace.debugging._uploader import SignalUploader + except ImportError: + from ddtrace.debugging._uploader import LogsIntakeUploaderV1 as SignalUploader logger = logging.getLogger(__name__) -dd_capture_lambda_payload_enabled = ( - os.environ.get("DD_CAPTURE_LAMBDA_PAYLOAD", "false").lower() == "true" -) +DD_REQUESTS_SERVICE_NAME = "DD_REQUESTS_SERVICE_NAME" +DD_SERVICE = "DD_SERVICE" + +init_timestamp_ns = time_ns() """ Usage: @@ -81,29 +127,25 @@ def __new__(cls, func): else: logger.debug("datadog_lambda_wrapper already wrapped") return _NoopDecorator(func) - except Exception: - traceback.print_exc() + except Exception as e: + logger.error(format_err_with_traceback(e)) return func def __init__(self, func): """Executes when the wrapped function gets wrapped""" try: self.func = func - self.flush_to_log = os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true" - self.logs_injection = ( - os.environ.get("DD_LOGS_INJECTION", "true").lower() == "true" - ) - self.merge_xray_traces = ( - os.environ.get("DD_MERGE_XRAY_TRACES", "false").lower() == "true" - ) - self.function_name = os.environ.get("AWS_LAMBDA_FUNCTION_NAME", "function") - self.extractor_env = os.environ.get("DD_TRACE_EXTRACTOR", None) self.trace_extractor = None self.span = None + self.inferred_span = None self.response = None + self.blocking_response = None - if self.extractor_env: - extractor_parts = self.extractor_env.rsplit(".", 1) + if config.profiling_enabled: + self.prof = profiler.Profiler(env=config.env, service=config.service) + + if config.trace_extractor: + extractor_parts = config.trace_extractor.rsplit(".", 1) if len(extractor_parts) == 2: (mod_name, extractor_name) = extractor_parts modified_extractor_name = modify_module_name(mod_name) @@ -111,95 +153,251 @@ def __init__(self, func): self.trace_extractor = getattr(extractor_module, extractor_name) # Inject trace correlation ids to logs - if self.logs_injection: + if config.logs_injection: inject_correlation_ids() # This prevents a breaking change in ddtrace v0.49 regarding the service name # in requests-related spans - os.environ["DD_REQUESTS_SERVICE_NAME"] = os.environ.get( - "DD_SERVICE", "aws.lambda" + os.environ[DD_REQUESTS_SERVICE_NAME] = os.environ.get( + DD_SERVICE, "aws.lambda" ) - # Patch third-party libraries for tracing - patch_all() + + # Enable LLM Observability + if config.llmobs_enabled: + LLMObs.enable() + + # Enable Exception Replay + if config.exception_replay_enabled: + logger.debug("Enabling exception replay") + SpanExceptionHandler.enable() logger.debug("datadog_lambda_wrapper initialized") - except Exception: - traceback.print_exc() + except Exception as e: + logger.error(format_err_with_traceback(e)) def __call__(self, event, context, **kwargs): """Executes when the wrapped function gets called""" self._before(event, context) try: + if self.blocking_response: + return self.blocking_response self.response = self.func(event, context, **kwargs) return self.response + except BlockingException: + self.blocking_response = get_asm_blocked_response(self.event_source) except Exception: + from datadog_lambda.metric import submit_errors_metric + submit_errors_metric(context) + if self.span: self.span.set_traceback() raise finally: self._after(event, context) + if self.blocking_response: + return self.blocking_response + + def _inject_authorizer_span_headers(self, request_id): + reference_span = self.inferred_span if self.inferred_span else self.span + assert reference_span.finished + # the finish_time_ns should be set as the end of the inferred span if it exist + # or the end of the current span + finish_time_ns = ( + reference_span.start_ns + reference_span.duration_ns + if reference_span is not None + and hasattr(reference_span, "start_ns") + and hasattr(reference_span, "duration_ns") + else time_ns() + ) + injected_headers = {} + source_span = self.inferred_span if self.inferred_span else self.span + span_context = source_span.context + propagator.inject(span_context, injected_headers) + injected_headers[Headers.Parent_Span_Finish_Time] = finish_time_ns + if request_id is not None: + injected_headers[Headers.Authorizing_Request_Id] = request_id + + import base64 + + datadog_data = base64.b64encode( + json.dumps(injected_headers, escape_forward_slashes=False).encode() + ).decode() + self.response.setdefault("context", {}) + self.response["context"]["_datadog"] = datadog_data def _before(self, event, context): try: - set_cold_start() - submit_invocations_metric(context) + self.response = None + self.blocking_response = None + set_cold_start(init_timestamp_ns) + + if not should_use_extension: + from datadog_lambda.metric import submit_invocations_metric + + submit_invocations_metric(context) + self.trigger_tags = extract_trigger_tags(event, context) # Extract Datadog trace context and source from incoming requests - dd_context, trace_context_source = extract_dd_trace_context( - event, context, extractor=self.trace_extractor + dd_context, trace_context_source, event_source = extract_dd_trace_context( + event, + context, + extractor=self.trace_extractor, + decode_authorizer_context=config.decode_authorizer_context, ) + self.event_source = event_source # Create a Datadog X-Ray subsegment with the trace context if dd_context and trace_context_source == TraceContextSource.EVENT: create_dd_dummy_metadata_subsegment( - dd_context, XraySubsegment.TRACE_KEY + { + "trace-id": str(dd_context.trace_id), + "parent-id": str(dd_context.span_id), + "sampling-priority": str(dd_context.sampling_priority), + }, + XraySubsegment.TRACE_KEY, ) - if dd_tracing_enabled: - set_dd_trace_py_root(trace_context_source, self.merge_xray_traces) + if config.trace_enabled: + set_dd_trace_py_root(trace_context_source, config.merge_xray_traces) + if config.make_inferred_span: + self.inferred_span = create_inferred_span( + event, context, event_source, config.decode_authorizer_context + ) + + if config.appsec_enabled: + asm_set_context(event_source) + self.span = create_function_execution_span( - context, - self.function_name, - is_cold_start(), - trace_context_source, - self.merge_xray_traces, - self.trigger_tags, + context=context, + function_name=config.function_name, + is_cold_start=is_cold_start(), + is_proactive_init=is_proactive_init(), + trace_context_source=trace_context_source, + merge_xray_traces=config.merge_xray_traces, + trigger_tags=self.trigger_tags, + parent_span=self.inferred_span, + span_pointers=calculate_span_pointers(event_source, event), ) + if config.appsec_enabled: + asm_start_request(self.span, event, event_source, self.trigger_tags) + self.blocking_response = get_asm_blocked_response(self.event_source) else: set_correlation_ids() - + if config.profiling_enabled and is_new_sandbox(): + self.prof.start(stop_on_exit=False, profile_children=True) logger.debug("datadog_lambda_wrapper _before() done") - except Exception: - traceback.print_exc() + except Exception as e: + logger.error(format_err_with_traceback(e)) def _after(self, event, context): try: + from datadog_lambda.metric import submit_batch_item_failures_metric + + submit_batch_item_failures_metric(self.response, context) + status_code = extract_http_status_code_tag(self.trigger_tags, self.response) + + if self.span: + if config.appsec_enabled and not self.blocking_response: + asm_start_response( + self.span, + status_code, + self.event_source, + response=self.response, + ) + self.blocking_response = get_asm_blocked_response(self.event_source) + + if self.blocking_response: + status_code = str(self.blocking_response.get("statusCode")) + if config.capture_payload_enabled and self.response: + tag_object( + self.span, "function.blocked_response", self.response + ) + self.response = self.blocking_response + + if config.capture_payload_enabled: + tag_object(self.span, "function.request", event) + tag_object(self.span, "function.response", self.response) + + if status_code: + self.span.set_tag("http.status_code", status_code) + + self.span.finish() + if status_code: self.trigger_tags["http.status_code"] = status_code + mark_trace_as_error_for_5xx_responses(context, status_code, self.span) + # Create a new dummy Datadog subsegment for function trigger tags so we # can attach them to X-Ray spans when hybrid tracing is used if self.trigger_tags: create_dd_dummy_metadata_subsegment( self.trigger_tags, XraySubsegment.LAMBDA_FUNCTION_TAGS_KEY ) + should_trace_cold_start = config.cold_start_tracing and is_new_sandbox() + if should_trace_cold_start: + trace_ctx = tracer.current_trace_context() + + if self.inferred_span: + if status_code: + self.inferred_span.set_tag("http.status_code", status_code) - if not self.flush_to_log or should_use_extension: - flush_stats() - if should_use_extension: + if self.trigger_tags and (route := self.trigger_tags.get("http.route")): + self.inferred_span.set_tag("http.route", route) + + if config.service: + self.inferred_span.set_tag("peer.service", config.service) + + if InferredSpanInfo.is_async(self.inferred_span) and self.span: + self.inferred_span.finish(finish_time=self.span.start) + else: + self.inferred_span.finish() + + if should_trace_cold_start: + try: + following_span = self.span or self.inferred_span + ColdStartTracer( + tracer, + config.function_name, + following_span.start_ns, + trace_ctx, + config.min_cold_start_trace_duration, + config.cold_start_trace_skip_lib, + ).trace() + except Exception as e: + logger.debug("Failed to create cold start spans. %s", e) + + if not config.flush_to_log or should_use_extension: + from datadog_lambda.metric import flush_stats + + flush_stats(context) + if should_use_extension and config.local_test: + # when testing locally, the extension does not know when an + # invocation completes because it does not have access to the + # logs api flush_extension() - if self.span: - if dd_capture_lambda_payload_enabled: - tag_object(self.span, "function.request", event) - tag_object(self.span, "function.response", self.response) + if config.llmobs_enabled: + LLMObs.flush() - if status_code: - self.span.set_tag("http.status_code", status_code) - self.span.finish() + # Flush exception replay + if config.exception_replay_enabled: + SignalUploader._instance.periodic() + + if config.encode_authorizer_context and is_authorizer_response( + self.response + ): + self._inject_authorizer_span_headers( + event.get("requestContext", {}).get("requestId") + ) logger.debug("datadog_lambda_wrapper _after() done") - except Exception: - traceback.print_exc() + except Exception as e: + logger.error(format_err_with_traceback(e)) + + +def format_err_with_traceback(e): + tb = traceback.format_exc().replace("\n", "\r") + return f"Error {e}. Traceback: {tb}" datadog_lambda_wrapper = _LambdaDecorator diff --git a/datadog_lambda/xray.py b/datadog_lambda/xray.py index d4836fae6..002d13b19 100644 --- a/datadog_lambda/xray.py +++ b/datadog_lambda/xray.py @@ -1,56 +1,70 @@ import os import logging -import json import binascii import time import socket +import ujson as json from datadog_lambda.constants import XrayDaemon, XraySubsegment, TraceContextSource logger = logging.getLogger(__name__) -def get_xray_host_port(adress): - if adress == "": - logger.debug("X-Ray daemon env var not set, not sending sub-segment") - return None - parts = adress.split(":") - if len(parts) <= 1: - logger.debug("X-Ray daemon env var not set, not sending sub-segment") - return None - port = int(parts[1]) - host = parts[0] - return (host, port) - - -def send(host_port_tuple, payload): - sock = None - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setblocking(0) - sock.connect(host_port_tuple) - sock.send(payload.encode("utf-8")) - except Exception as e_send: - logger.error("Error occurred submitting to xray daemon: %s", str(e_send)) - try: - sock.close() - except Exception as e_close: - logger.error("Error while closing the socket: %s", str(e_close)) +class Socket(object): + def __init__(self): + self.sock = None + + @property + def host_port_tuple(self): + if not hasattr(self, "_host_port_tuple"): + self._host_port_tuple = self._get_xray_host_port( + os.environ.get(XrayDaemon.XRAY_DAEMON_ADDRESS, "") + ) + return self._host_port_tuple + + def send(self, payload): + if not self.sock: + self._connect() + try: + self.sock.send(payload.encode("utf-8")) + except Exception as e_send: + logger.error("Error occurred submitting to xray daemon: %s", e_send) + + def _connect(self): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.setblocking(0) + self.sock.connect(self.host_port_tuple) + + def _get_xray_host_port(self, address): + if address == "": + logger.debug("X-Ray daemon env var not set, not sending sub-segment") + return None + parts = address.split(":") + if len(parts) <= 1: + logger.debug("X-Ray daemon env var not set, not sending sub-segment") + return None + port = int(parts[1]) + host = parts[0] + return (host, port) + + +sock = Socket() def build_segment_payload(payload): if payload is None: return None - return '{"format": "json", "version": 1}' + "\n" + payload + return '{"format": "json", "version": 1}\n' + payload def parse_xray_header(raw_trace_id): - # Example: Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1 + # Example: + # Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1;Lineage=c6c5b1b9:0 logger.debug("Reading trace context from env var %s", raw_trace_id) if len(raw_trace_id) == 0: return None parts = raw_trace_id.split(";") - if len(parts) != 3: + if len(parts) < 3: return None root = parts[0].replace("Root=", "") parent = parts[1].replace("Parent=", "") @@ -74,7 +88,6 @@ def generate_random_id(): def build_segment(context, key, metadata): - segment = json.dumps( { "id": generate_random_id(), @@ -89,16 +102,14 @@ def build_segment(context, key, metadata): key: metadata, } }, - } + }, + escape_forward_slashes=False, ) return segment def send_segment(key, metadata): - host_port_tuple = get_xray_host_port( - os.environ.get(XrayDaemon.XRAY_DAEMON_ADDRESS, "") - ) - if host_port_tuple is None: + if sock.host_port_tuple is None: return None context = parse_xray_header( os.environ.get(XrayDaemon.XRAY_TRACE_ID_HEADER_NAME, "") @@ -108,6 +119,11 @@ def send_segment(key, metadata): "Failed to create segment since it was not possible to get trace context from header" ) return None + + # Skip adding segment, if the xray trace is going to be sampled away. + if context["sampled"] == "0": + logger.debug("Skipping sending metadata, x-ray trace was sampled out") + return None segment = build_segment(context, key, metadata) segment_payload = build_segment_payload(segment) - send(host_port_tuple, segment_payload) + sock.send(segment_payload) diff --git a/poetry.lock b/poetry.lock index 8c2626da9..4c37bf871 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,598 +1,949 @@ -[[package]] -name = "attrs" -version = "21.2.0" -description = "Classes Without Boilerplate" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] -name = "boto3" -version = "1.18.57" -description = "The AWS SDK for Python" -category = "main" +name = "botocore" +version = "1.36.8" +description = "Low-level, data-driven core of boto 3." optional = true -python-versions = ">= 3.6" +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "botocore-1.36.8-py3-none-any.whl", hash = "sha256:59d3fdfbae6d916b046e973bebcbeb70a102f9e570ca86d5ba512f1854b78fc2"}, + {file = "botocore-1.36.8.tar.gz", hash = "sha256:81c88e5566cf018e1411a68304dc1fb9e4156ca2b50a3a0f0befc274299e67fa"}, +] [package.dependencies] -botocore = ">=1.21.57,<1.22.0" -jmespath = ">=0.7.1,<1.0.0" -s3transfer = ">=0.5.0,<0.6.0" +jmespath = ">=0.7.1,<2.0.0" +python-dateutil = ">=2.1,<3.0.0" +urllib3 = [ + {version = ">=1.25.4,<1.27", markers = "python_version < \"3.10\""}, + {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""}, +] [package.extras] -crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] +crt = ["awscrt (==0.23.4)"] [[package]] -name = "botocore" -version = "1.21.57" -description = "Low-level, data-driven core of boto 3." -category = "main" -optional = true -python-versions = ">= 3.6" +name = "bytecode" +version = "0.16.1" +description = "Python module to generate and modify bytecode" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "bytecode-0.16.1-py3-none-any.whl", hash = "sha256:1d4b61ed6bade4bff44127c8283bef8131a664ce4dbe09d64a88caf329939f35"}, + {file = "bytecode-0.16.1.tar.gz", hash = "sha256:8fbbb637c880f339e564858bc6c7984ede67ae97bc71343379a535a9a4baf398"}, +] [package.dependencies] -jmespath = ">=0.7.1,<1.0.0" -python-dateutil = ">=2.1,<3.0.0" -urllib3 = ">=1.25.4,<1.27" - -[package.extras] -crt = ["awscrt (==0.11.24)"] +typing_extensions = {version = "*", markers = "python_version < \"3.10\""} [[package]] name = "certifi" -version = "2021.5.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, +] [[package]] name = "charset-normalizer" -version = "2.0.6" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false -python-versions = ">=3.5.0" - -[package.extras] -unicode_backport = ["unicodedata2"] +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, +] [[package]] -name = "coverage" -version = "6.0.1" -description = "Code coverage measurement for Python" -category = "main" +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." optional = true -python-versions = ">=3.6" - -[package.extras] -toml = ["tomli"] +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +markers = "extra == \"dev\" and sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] [[package]] name = "datadog" -version = "0.41.0" +version = "0.51.0" description = "The Datadog Python library" -category = "main" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +files = [ + {file = "datadog-0.51.0-py2.py3-none-any.whl", hash = "sha256:a9764f091c96af4e0996d4400b168fc5fba380f911d6d672c9dcd4773e29ea3f"}, + {file = "datadog-0.51.0.tar.gz", hash = "sha256:3279534f831ae0b4ae2d8ce42ef038b4ab38e667d7ed6ff7437982d7a0cf5250"}, +] [package.dependencies] -decorator = ">=3.3.2" requests = ">=2.6.0" [[package]] name = "ddtrace" -version = "0.50.4" -description = "Datadog tracing code" -category = "main" +version = "2.20.0" +description = "Datadog APM client library" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "ddtrace-2.20.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:e1dee099099b95acf7d0e552179925cfec58a52315cc914d153506367b195bc4"}, + {file = "ddtrace-2.20.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:9d209bef14caafcd53be8c14e04741d86c08f76496c1bf755e2eaa38605ce3e0"}, + {file = "ddtrace-2.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f37966012078151713d61382de2a7ed710a8f375820e0db41930436b813b651"}, + {file = "ddtrace-2.20.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:879b963baf0b97d5ddd26185ab496b79efd25bbfdc2c25dbb1113ec19dc5abf9"}, + {file = "ddtrace-2.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e9b9a87c9df8a029fd3583ac660538dfa9d53207fee82b7f04749148bf8a3b"}, + {file = "ddtrace-2.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:eb76547a4bbf285d03ffc6e065bbad61761954741da2df0e4683d68d46ef2159"}, + {file = "ddtrace-2.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:194973afa1e357c68b6a6eceaabbddcef01130d167775126c2a15b3c1827f683"}, + {file = "ddtrace-2.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a71d2fc753b8fa2c3435b6f4d5f820d8deb51f49df59a4886b4da68b67f923d3"}, + {file = "ddtrace-2.20.0-cp310-cp310-win32.whl", hash = "sha256:567054d0c01dc552a8a24c4c9eeb98d778be720d2c4c9536acf1b86d6969a5e4"}, + {file = "ddtrace-2.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:d39f96e2fdfdf7ab43ee89a20d914f5ab12f8f361c390663eacb0e5da6e6e7fb"}, + {file = "ddtrace-2.20.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:0a1d7eaf6c9a5e0eabb8396f7d19faffc8f76a1ae37f34814c3432a9ca6f31da"}, + {file = "ddtrace-2.20.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:301a7787a34113b56cc9067a593c4717f6e158f2393883c30b59d0a37ebc06fa"}, + {file = "ddtrace-2.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d76ce49eb42588766db6756240d746441a66f03932547bfca9c62a8aecdbb38"}, + {file = "ddtrace-2.20.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a84d2e2411496c1b4ca3ce0cfb407d186cb3d13f1769c321fec30e677d815cd8"}, + {file = "ddtrace-2.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da47746a24242d805a800bca0a10b1354353e18b0bc4b6caf9c9c1724ba286b0"}, + {file = "ddtrace-2.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6f89e6003a738800beeb9948c847366976c73de2e24cc469b644a125f418c0a8"}, + {file = "ddtrace-2.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4fca20220bf668ebcac7051d28648b62aa95d2afeb5036ecad167cb454c7dcf1"}, + {file = "ddtrace-2.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1197e89fcaaca4ce419e3c812d04c73b8d16973202472cf3f674b4698b967697"}, + {file = "ddtrace-2.20.0-cp311-cp311-win32.whl", hash = "sha256:44bcd604a1d9095f4eb6813db6a677a208bd47884aff9ddc5aa46f596765f38e"}, + {file = "ddtrace-2.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:0a5f092df1ee4d0afe96502866ff0fb446a07c6a23d445ed616f1302c883e1d3"}, + {file = "ddtrace-2.20.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:f77103d36e6ab52cb45781766620d3874d0a728565afa7fd57f8ce2d5087e8e7"}, + {file = "ddtrace-2.20.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:d1cec952ce2ca9efbb34c8a9ee522e1cc588fe454b9115120b30fd5d0f821512"}, + {file = "ddtrace-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4a1da150e92b6d43047f2a91a7d3b7133207f94b82613625abf82662359b30e"}, + {file = "ddtrace-2.20.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91ab68c1facc6cf04085fdeea53210ed9928e95116809fd9bfe2dea54e83375d"}, + {file = "ddtrace-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fd7ec6410225e64ca875d1bc9bd6bd8489f52dd8558462fbb52447fb8f66ad3"}, + {file = "ddtrace-2.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:57864590ddb84da4eb99332fe4b521e6fd747992178e3eabcf4f87406e908bb1"}, + {file = "ddtrace-2.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:37693555704a0cbd4a925e4ffe9c6df696146c85557c5f66ce3a7a88406772d9"}, + {file = "ddtrace-2.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ae5e802aaefc0cd3b63e3fd46e051a39e9f960a02e89f44a5bb820f445b736f9"}, + {file = "ddtrace-2.20.0-cp312-cp312-win32.whl", hash = "sha256:14fe4f583bec105c40e233c74fcbaea185658651c626ce1609750d83d93a00ae"}, + {file = "ddtrace-2.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:cfbc926ddfeece0312e82f9e00a68001647666d11ceb050a5bbe66ca8931e3d2"}, + {file = "ddtrace-2.20.0-cp313-cp313-macosx_12_0_universal2.whl", hash = "sha256:eeca6b6bd48794d48de438981dccbc96a06366edde798c12b2b3348ca5e03717"}, + {file = "ddtrace-2.20.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:3f526e75d1b61019db2cd715e8c7298325e21c3584f8677a7decf37aa81e7284"}, + {file = "ddtrace-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96441189ccc772ef4871e23a35cec58a748c16ebfb2293eccaaa719dcbc368fd"}, + {file = "ddtrace-2.20.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d31d769f222c9a5bde1d4a594da1341014bf02db1a7194f5a41ed7e5c4c9fa8"}, + {file = "ddtrace-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54068dbf034e1f607ef5d58a9fa1b26bd78b4f3db0618ce0a3e9c4b04fff7209"}, + {file = "ddtrace-2.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62e86d9b00277fe2b9bdfbc51ca1bc34aa5c1200aa6bc5084c7eaaab28b022de"}, + {file = "ddtrace-2.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c83c2458de1cf1bbac48689c6541a85d54ad94ae6608961e1089cc2959a8c77a"}, + {file = "ddtrace-2.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:569d7a92a88ba9b2a203addea688b0585901534c92c2d148ef9f971b6d7b3805"}, + {file = "ddtrace-2.20.0-cp37-cp37m-macosx_12_0_x86_64.whl", hash = "sha256:df413d646fc14b4be51a15ed8e484bcdf3b21e370e2644a586283bcc7e0b2355"}, + {file = "ddtrace-2.20.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33e4406a436278722df193c93d49e662a8891e8a440fddb273dca9a56fa27947"}, + {file = "ddtrace-2.20.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9d358bc7b4b1daa2d6e6bc697244b39db653ddd5ae139045941d3db28950bfe"}, + {file = "ddtrace-2.20.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a523924382d2f8f87731e4ad86bbf4721fba9eb807ed3b0c862db6d768e1e81c"}, + {file = "ddtrace-2.20.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:0af78a424e9d87250a8648a35b7de5653f27b3f6f6803c1b33780816a07e6d26"}, + {file = "ddtrace-2.20.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:2723378e670d27927f7d1ab878c8668fc392a5656a66453b9808e7c4025431fd"}, + {file = "ddtrace-2.20.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01f76fc9bf1413a188ddd59851eb3b668d3de936afed73a5914a817f36e11005"}, + {file = "ddtrace-2.20.0-cp37-cp37m-win32.whl", hash = "sha256:3a615ae95ef8f889304b2958655ac8cda23cf2f2c8faf5d8ff88bd14bdcf3fb4"}, + {file = "ddtrace-2.20.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b90333661ffd3460bae6dbbd7a5f35d8467cff36bd7a689a47b014edb19c0fe6"}, + {file = "ddtrace-2.20.0-cp38-cp38-macosx_12_0_universal2.whl", hash = "sha256:ab27596e82bdfe9c0c5580f6886ec943ae2fe615a446c22470f6a1f9742dec62"}, + {file = "ddtrace-2.20.0-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:e2de7371291283cba1afdd7e919a577637099da0d6872d33b4008e1cad6e1b8b"}, + {file = "ddtrace-2.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa4f90f472768aef8ce023a924505c9d1d09428fc9d6ab81bc0e3ab183e3ff48"}, + {file = "ddtrace-2.20.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05b68ba6fe4da5317396100669edf91b3d54b95ae979a2a22ca880cfcc6c249d"}, + {file = "ddtrace-2.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1512d07e6c7cde13ae251906d57d31613fe5ee99fab2894e90679053b4256953"}, + {file = "ddtrace-2.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dcadc60aa60e11f2db56065a834aaa5e52a9be02e8edc8d14aa7015fb54092ce"}, + {file = "ddtrace-2.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:698207d88941ea3e4e5f3add6071e6651caa12fcffe079359507391382251759"}, + {file = "ddtrace-2.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9f95a251f84725df055202d933b4a8fb39cefd51341e10cad17d2a8b4d64700e"}, + {file = "ddtrace-2.20.0-cp38-cp38-win32.whl", hash = "sha256:0b121285459693ae9f3c9ce54cc4be981a2e73d4c52b8a5eb038cf41df9974dd"}, + {file = "ddtrace-2.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:4c840dc91c622138a4a6abdbcbee56897d4c55d9e7bf16b1902ee676f20b22f2"}, + {file = "ddtrace-2.20.0-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:c74d69e6a4cbd91f6fe411519d753f34893d6d40a68829b43485690df8a7f30f"}, + {file = "ddtrace-2.20.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:4902b64ba89a8e4008228e7a5007e20b2bb8071c6c7689abd47dddc159e2baf1"}, + {file = "ddtrace-2.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758ba828eddd144a4804af692869e7278376efa740932a7453e8fdc0ed6ef6a7"}, + {file = "ddtrace-2.20.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37995326df811236c9d92d1b5713378a7f11270bf1e21c64914653a3e12d7d01"}, + {file = "ddtrace-2.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab7f1babd7a8e73edf70c957a5b3bbeb4c615b232a078a0fe4da566e1663d1aa"}, + {file = "ddtrace-2.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1cd1b240f465c98e226ab896b1b1c3696752d5eb1051a0aafb8a3db701d2ddc1"}, + {file = "ddtrace-2.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3a300515c3327af4fd5c6c83e6ca63cd0a20e4243381d4b712e3f406d9ddf201"}, + {file = "ddtrace-2.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f1ce886b112e0e8aa66ba8cf3593f00f7f6ae6b48dd09bd8ce90c59adad59d66"}, + {file = "ddtrace-2.20.0-cp39-cp39-win32.whl", hash = "sha256:bb77464849b092f93839d5c257df9eaeb018521ddea2deef97dfc6e3501a2516"}, + {file = "ddtrace-2.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:b95f14f0634fe3f02dcebb7b8a124207b3d44168fd0dfc6bfff1e4db93978089"}, + {file = "ddtrace-2.20.0.tar.gz", hash = "sha256:f185c6dd88cd04884f0ad27b37f14d837274e8fc4dc43407781334d92d41c3bc"}, +] [package.dependencies] -attrs = ">=19.2.0" -packaging = ">=17.1" -pep562 = {version = "*", markers = "python_version < \"3.7\""} +bytecode = [ + {version = ">=0.13.0", markers = "python_version < \"3.11\""}, + {version = ">=0.16.0", markers = "python_version >= \"3.13.0\""}, + {version = ">=0.15.0", markers = "python_version ~= \"3.12.0\""}, + {version = ">=0.14.0", markers = "python_version ~= \"3.11.0\""}, +] +envier = ">=0.5,<1.0" +legacy-cgi = {version = ">=2.0.0", markers = "python_version >= \"3.13.0\""} +opentelemetry-api = ">=1" protobuf = ">=3" -six = ">=1.12.0" -tenacity = ">=5" +typing_extensions = "*" +wrapt = ">=1" +xmltodict = ">=0.12" [package.extras] +openai = ["tiktoken"] opentracing = ["opentracing (>=2.0.0)"] [[package]] -name = "decorator" -version = "5.1.0" -description = "Decorators for Humans" -category = "main" +name = "deprecated" +version = "1.2.18" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=3.5" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["main"] +files = [ + {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, + {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] [[package]] -name = "flake8" -version = "3.9.2" -description = "the modular source code checker: pep8 pyflakes and co" -category = "main" +name = "envier" +version = "0.6.1" +description = "Python application configuration via the environment" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "envier-0.6.1-py3-none-any.whl", hash = "sha256:73609040a76be48bbcb97074d9969666484aa0de706183a6e9ef773156a8a6a9"}, + {file = "envier-0.6.1.tar.gz", hash = "sha256:3309a01bb3d8850c9e7a31a5166d5a836846db2faecb79b9cb32654dd50ca9f9"}, +] + +[package.extras] +mypy = ["mypy"] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" optional = true -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\" and python_version <= \"3.10\"" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.7.0,<2.8.0" -pyflakes = ">=2.3.0,<2.4.0" +[package.extras] +test = ["pytest (>=6)"] [[package]] -name = "httpretty" -version = "0.9.7" -description = "HTTP client mock for Python" -category = "main" +name = "flake8" +version = "5.0.4" +description = "the modular source code checker: pep8 pyflakes and co" optional = true -python-versions = "*" +python-versions = ">=3.6.1" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, + {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, +] [package.dependencies] -six = "*" +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.9.0,<2.10.0" +pyflakes = ">=2.5.0,<2.6.0" [[package]] name = "idna" -version = "3.2" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] [[package]] name = "importlib-metadata" -version = "1.7.0" +version = "8.5.0" description = "Read metadata from Python packages" -category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, + {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, +] [package.dependencies] -zipp = ">=0.5" +zipp = ">=3.20" [package.extras] -docs = ["sphinx", "rst.linker"] -testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = true +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] [[package]] name = "jmespath" -version = "0.10.0" +version = "1.0.1" description = "JSON Matching Expressions" -category = "main" optional = true -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "legacy-cgi" +version = "2.6.2" +description = "Fork of the standard library cgi and cgitb modules, being deprecated in PEP-594" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version >= \"3.13.0\"" +files = [ + {file = "legacy_cgi-2.6.2-py3-none-any.whl", hash = "sha256:a7b83afb1baf6ebeb56522537c5943ef9813cf933f6715e88a803f7edbce0bff"}, + {file = "legacy_cgi-2.6.2.tar.gz", hash = "sha256:9952471ceb304043b104c22d00b4f333cac27a6abe446d8a528fc437cf13c85f"}, +] [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "main" optional = true -python-versions = "*" +python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] [[package]] -name = "nose2" -version = "0.9.2" -description = "unittest2 with plugins, the succesor to nose" -category = "main" -optional = true -python-versions = "*" +name = "opentelemetry-api" +version = "1.29.0" +description = "OpenTelemetry Python API" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "opentelemetry_api-1.29.0-py3-none-any.whl", hash = "sha256:5fcd94c4141cc49c736271f3e1efb777bebe9cc535759c54c936cca4f1b312b8"}, + {file = "opentelemetry_api-1.29.0.tar.gz", hash = "sha256:d04a6cf78aad09614f52964ecb38021e248f5714dc32c2e0d8fd99517b4d69cf"}, +] [package.dependencies] -coverage = ">=4.4.1" -six = ">=1.7" - -[package.extras] -coverage_plugin = ["coverage (>=4.4.1)"] -doc = ["Sphinx (>=1.6.5)", "sphinx-rtd-theme", "mock"] +deprecated = ">=1.2.6" +importlib-metadata = ">=6.0,<=8.5.0" [[package]] name = "packaging" -version = "21.0" +version = "24.2" description = "Core utilities for Python packages" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, +] [[package]] -name = "pep562" -version = "1.1" -description = "Backport of PEP 562." -category = "main" -optional = false -python-versions = "*" +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "protobuf" -version = "3.18.1" -description = "Protocol Buffers" -category = "main" +version = "5.29.5" +description = "" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079"}, + {file = "protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc"}, + {file = "protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671"}, + {file = "protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015"}, + {file = "protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61"}, + {file = "protobuf-5.29.5-cp38-cp38-win32.whl", hash = "sha256:ef91363ad4faba7b25d844ef1ada59ff1604184c0bcd8b39b8a6bef15e1af238"}, + {file = "protobuf-5.29.5-cp38-cp38-win_amd64.whl", hash = "sha256:7318608d56b6402d2ea7704ff1e1e4597bee46d760e7e4dd42a3d45e24b87f2e"}, + {file = "protobuf-5.29.5-cp39-cp39-win32.whl", hash = "sha256:6f642dc9a61782fa72b90878af134c5afe1917c89a568cd3476d758d3c3a0736"}, + {file = "protobuf-5.29.5-cp39-cp39-win_amd64.whl", hash = "sha256:470f3af547ef17847a28e1f47200a1cbf0ba3ff57b7de50d22776607cd2ea353"}, + {file = "protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5"}, + {file = "protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84"}, +] + +[[package]] +name = "py-cpuinfo" +version = "9.0.0" +description = "Get CPU info with pure Python" +optional = true +python-versions = "*" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690"}, + {file = "py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5"}, +] [[package]] name = "pycodestyle" -version = "2.7.0" +version = "2.9.1" description = "Python style guide checker" -category = "main" optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, + {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, +] [[package]] name = "pyflakes" -version = "2.3.1" +version = "2.5.0" description = "passive checker of Python programs" -category = "main" optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, + {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, +] [[package]] -name = "pyparsing" -version = "2.4.7" -description = "Python parsing module" -category = "main" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +name = "pytest" +version = "8.3.4" +description = "pytest: simple powerful testing with Python" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-benchmark" +version = "4.0.0" +description = "A ``pytest`` fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer." +optional = true +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "pytest-benchmark-4.0.0.tar.gz", hash = "sha256:fb0785b83efe599a6a956361c0691ae1dbb5318018561af10f3e915caa0048d1"}, + {file = "pytest_benchmark-4.0.0-py3-none-any.whl", hash = "sha256:fdb7db64e31c8b277dff9850d2a2556d8b60bcb0ea6524e36e28ffd7c87f71d6"}, +] + +[package.dependencies] +py-cpuinfo = "*" +pytest = ">=3.8" + +[package.extras] +aspect = ["aspectlib"] +elasticsearch = ["elasticsearch"] +histogram = ["pygal", "pygaljs"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -category = "main" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] [package.dependencies] six = ">=1.5" [[package]] name = "requests" -version = "2.26.0" +version = "2.32.4" description = "Python HTTP for Humans." -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, + {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, +] [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} -urllib3 = ">=1.21.1,<1.27" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" [package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "s3transfer" -version = "0.5.0" -description = "An Amazon S3 Transfer Manager" -category = "main" +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" optional = true -python-versions = ">= 3.6" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] -[package.dependencies] -botocore = ">=1.12.36,<2.0a.0" +[[package]] +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" and python_version <= \"3.10\"" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] -[package.extras] -crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] [[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -category = "main" +name = "ujson" +version = "5.10.0" +description = "Ultra fast JSON encoder and decoder for Python" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "ujson-5.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2601aa9ecdbee1118a1c2065323bda35e2c5a2cf0797ef4522d485f9d3ef65bd"}, + {file = "ujson-5.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:348898dd702fc1c4f1051bc3aacbf894caa0927fe2c53e68679c073375f732cf"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22cffecf73391e8abd65ef5f4e4dd523162a3399d5e84faa6aebbf9583df86d6"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26b0e2d2366543c1bb4fbd457446f00b0187a2bddf93148ac2da07a53fe51569"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:caf270c6dba1be7a41125cd1e4fc7ba384bf564650beef0df2dd21a00b7f5770"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a245d59f2ffe750446292b0094244df163c3dc96b3ce152a2c837a44e7cda9d1"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:94a87f6e151c5f483d7d54ceef83b45d3a9cca7a9cb453dbdbb3f5a6f64033f5"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:29b443c4c0a113bcbb792c88bea67b675c7ca3ca80c3474784e08bba01c18d51"}, + {file = "ujson-5.10.0-cp310-cp310-win32.whl", hash = "sha256:c18610b9ccd2874950faf474692deee4223a994251bc0a083c114671b64e6518"}, + {file = "ujson-5.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:924f7318c31874d6bb44d9ee1900167ca32aa9b69389b98ecbde34c1698a250f"}, + {file = "ujson-5.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a5b366812c90e69d0f379a53648be10a5db38f9d4ad212b60af00bd4048d0f00"}, + {file = "ujson-5.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:502bf475781e8167f0f9d0e41cd32879d120a524b22358e7f205294224c71126"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b91b5d0d9d283e085e821651184a647699430705b15bf274c7896f23fe9c9d8"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:129e39af3a6d85b9c26d5577169c21d53821d8cf68e079060602e861c6e5da1b"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f77b74475c462cb8b88680471193064d3e715c7c6074b1c8c412cb526466efe9"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ec0ca8c415e81aa4123501fee7f761abf4b7f386aad348501a26940beb1860f"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab13a2a9e0b2865a6c6db9271f4b46af1c7476bfd51af1f64585e919b7c07fd4"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:57aaf98b92d72fc70886b5a0e1a1ca52c2320377360341715dd3933a18e827b1"}, + {file = "ujson-5.10.0-cp311-cp311-win32.whl", hash = "sha256:2987713a490ceb27edff77fb184ed09acdc565db700ee852823c3dc3cffe455f"}, + {file = "ujson-5.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f00ea7e00447918ee0eff2422c4add4c5752b1b60e88fcb3c067d4a21049a720"}, + {file = "ujson-5.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98ba15d8cbc481ce55695beee9f063189dce91a4b08bc1d03e7f0152cd4bbdd5"}, + {file = "ujson-5.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9d2edbf1556e4f56e50fab7d8ff993dbad7f54bac68eacdd27a8f55f433578e"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6627029ae4f52d0e1a2451768c2c37c0c814ffc04f796eb36244cf16b8e57043"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ccb77b3e40b151e20519c6ae6d89bfe3f4c14e8e210d910287f778368bb3d1"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3caf9cd64abfeb11a3b661329085c5e167abbe15256b3b68cb5d914ba7396f3"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6e32abdce572e3a8c3d02c886c704a38a1b015a1fb858004e03d20ca7cecbb21"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a65b6af4d903103ee7b6f4f5b85f1bfd0c90ba4eeac6421aae436c9988aa64a2"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:604a046d966457b6cdcacc5aa2ec5314f0e8c42bae52842c1e6fa02ea4bda42e"}, + {file = "ujson-5.10.0-cp312-cp312-win32.whl", hash = "sha256:6dea1c8b4fc921bf78a8ff00bbd2bfe166345f5536c510671bccececb187c80e"}, + {file = "ujson-5.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:38665e7d8290188b1e0d57d584eb8110951a9591363316dd41cf8686ab1d0abc"}, + {file = "ujson-5.10.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:618efd84dc1acbd6bff8eaa736bb6c074bfa8b8a98f55b61c38d4ca2c1f7f287"}, + {file = "ujson-5.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38d5d36b4aedfe81dfe251f76c0467399d575d1395a1755de391e58985ab1c2e"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67079b1f9fb29ed9a2914acf4ef6c02844b3153913eb735d4bf287ee1db6e557"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7d0e0ceeb8fe2468c70ec0c37b439dd554e2aa539a8a56365fd761edb418988"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59e02cd37bc7c44d587a0ba45347cc815fb7a5fe48de16bf05caa5f7d0d2e816"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a890b706b64e0065f02577bf6d8ca3b66c11a5e81fb75d757233a38c07a1f20"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:621e34b4632c740ecb491efc7f1fcb4f74b48ddb55e65221995e74e2d00bbff0"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9500e61fce0cfc86168b248104e954fead61f9be213087153d272e817ec7b4f"}, + {file = "ujson-5.10.0-cp313-cp313-win32.whl", hash = "sha256:4c4fc16f11ac1612f05b6f5781b384716719547e142cfd67b65d035bd85af165"}, + {file = "ujson-5.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:4573fd1695932d4f619928fd09d5d03d917274381649ade4328091ceca175539"}, + {file = "ujson-5.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a984a3131da7f07563057db1c3020b1350a3e27a8ec46ccbfbf21e5928a43050"}, + {file = "ujson-5.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73814cd1b9db6fc3270e9d8fe3b19f9f89e78ee9d71e8bd6c9a626aeaeaf16bd"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61e1591ed9376e5eddda202ec229eddc56c612b61ac6ad07f96b91460bb6c2fb"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2c75269f8205b2690db4572a4a36fe47cd1338e4368bc73a7a0e48789e2e35a"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7223f41e5bf1f919cd8d073e35b229295aa8e0f7b5de07ed1c8fddac63a6bc5d"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d4dc2fd6b3067c0782e7002ac3b38cf48608ee6366ff176bbd02cf969c9c20fe"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:232cc85f8ee3c454c115455195a205074a56ff42608fd6b942aa4c378ac14dd7"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cc6139531f13148055d691e442e4bc6601f6dba1e6d521b1585d4788ab0bfad4"}, + {file = "ujson-5.10.0-cp38-cp38-win32.whl", hash = "sha256:e7ce306a42b6b93ca47ac4a3b96683ca554f6d35dd8adc5acfcd55096c8dfcb8"}, + {file = "ujson-5.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:e82d4bb2138ab05e18f089a83b6564fee28048771eb63cdecf4b9b549de8a2cc"}, + {file = "ujson-5.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dfef2814c6b3291c3c5f10065f745a1307d86019dbd7ea50e83504950136ed5b"}, + {file = "ujson-5.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4734ee0745d5928d0ba3a213647f1c4a74a2a28edc6d27b2d6d5bd9fa4319e27"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47ebb01bd865fdea43da56254a3930a413f0c5590372a1241514abae8aa7c76"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee5e97c2496874acbf1d3e37b521dd1f307349ed955e62d1d2f05382bc36dd5"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7490655a2272a2d0b072ef16b0b58ee462f4973a8f6bbe64917ce5e0a256f9c0"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba17799fcddaddf5c1f75a4ba3fd6441f6a4f1e9173f8a786b42450851bd74f1"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2aff2985cef314f21d0fecc56027505804bc78802c0121343874741650a4d3d1"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ad88ac75c432674d05b61184178635d44901eb749786c8eb08c102330e6e8996"}, + {file = "ujson-5.10.0-cp39-cp39-win32.whl", hash = "sha256:2544912a71da4ff8c4f7ab5606f947d7299971bdd25a45e008e467ca638d13c9"}, + {file = "ujson-5.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:3ff201d62b1b177a46f113bb43ad300b424b7847f9c5d38b1b4ad8f75d4a282a"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5b6fee72fa77dc172a28f21693f64d93166534c263adb3f96c413ccc85ef6e64"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:61d0af13a9af01d9f26d2331ce49bb5ac1fb9c814964018ac8df605b5422dcb3"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecb24f0bdd899d368b715c9e6664166cf694d1e57be73f17759573a6986dd95a"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbd8fd427f57a03cff3ad6574b5e299131585d9727c8c366da4624a9069ed746"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beeaf1c48e32f07d8820c705ff8e645f8afa690cca1544adba4ebfa067efdc88"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:baed37ea46d756aca2955e99525cc02d9181de67f25515c468856c38d52b5f3b"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7663960f08cd5a2bb152f5ee3992e1af7690a64c0e26d31ba7b3ff5b2ee66337"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:d8640fb4072d36b08e95a3a380ba65779d356b2fee8696afeb7794cf0902d0a1"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78778a3aa7aafb11e7ddca4e29f46bc5139131037ad628cc10936764282d6753"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0111b27f2d5c820e7f2dbad7d48e3338c824e7ac4d2a12da3dc6061cc39c8e6"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:c66962ca7565605b355a9ed478292da628b8f18c0f2793021ca4425abf8b01e5"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ba43cc34cce49cf2d4bc76401a754a81202d8aa926d0e2b79f0ee258cb15d3a4"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac56eb983edce27e7f51d05bc8dd820586c6e6be1c5216a6809b0c668bb312b8"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44bd4b23a0e723bf8b10628288c2c7c335161d6840013d4d5de20e48551773b"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c10f4654e5326ec14a46bcdeb2b685d4ada6911050aa8baaf3501e57024b804"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0de4971a89a762398006e844ae394bd46991f7c385d7a6a3b93ba229e6dac17e"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e1402f0564a97d2a52310ae10a64d25bcef94f8dd643fcf5d310219d915484f7"}, + {file = "ujson-5.10.0.tar.gz", hash = "sha256:b3cd8f3c5d8c7738257f1018880444f7b7d9b66232c64649f562d7ba86ad4bc1"}, +] [[package]] -name = "tenacity" -version = "8.0.1" -description = "Retry code until it succeeds" -category = "main" +name = "urllib3" +version = "1.26.20" +description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.6" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +groups = ["main"] +markers = "python_version < \"3.10\"" +files = [ + {file = "urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e"}, + {file = "urllib3-1.26.20.tar.gz", hash = "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32"}, +] [package.extras] -doc = ["reno", "sphinx", "tornado (>=4.5)"] +brotli = ["brotli (==1.0.9) ; os_name != \"nt\" and python_version < \"3\" and platform_python_implementation == \"CPython\"", "brotli (>=1.0.9) ; python_version >= \"3\" and platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; (os_name != \"nt\" or python_version >= \"3\") and platform_python_implementation != \"CPython\"", "brotlipy (>=0.6.0) ; os_name == \"nt\" and python_version < \"3\""] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress ; python_version == \"2.7\"", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "urllib3" -version = "1.26.7" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, +] [package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wrapt" -version = "1.13.1" +version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." -category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, + {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, + {file = "wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62"}, + {file = "wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563"}, + {file = "wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72"}, + {file = "wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317"}, + {file = "wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9"}, + {file = "wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9"}, + {file = "wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504"}, + {file = "wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a"}, + {file = "wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f"}, + {file = "wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555"}, + {file = "wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f"}, + {file = "wrapt-1.17.2-cp38-cp38-win32.whl", hash = "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7"}, + {file = "wrapt-1.17.2-cp38-cp38-win_amd64.whl", hash = "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9"}, + {file = "wrapt-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb"}, + {file = "wrapt-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb"}, + {file = "wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8"}, + {file = "wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3"}, +] + +[[package]] +name = "xmltodict" +version = "0.14.2" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, +] [[package]] name = "zipp" -version = "3.6.0" +version = "3.20.2" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, + {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, +] [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] [extras] -dev = ["boto3", "requests", "nose2", "flake8", "httpretty"] +dev = ["botocore", "flake8", "pytest", "pytest-benchmark", "requests"] [metadata] -lock-version = "1.1" -python-versions = ">=3.6.0,<4" -content-hash = "1cc5541adcbc8680190d876da57d59a53c9ee3c7628461273305c683594f9425" - -[metadata.files] -attrs = [ - {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, - {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, -] -boto3 = [ - {file = "boto3-1.18.57-py3-none-any.whl", hash = "sha256:3e6176b3ccdd039427f63365bdf25c312ec9e88cc72ba907beea006ccf32116b"}, - {file = "boto3-1.18.57.tar.gz", hash = "sha256:56a4c68a4ee131527e8bd65ab71270b06d985e6687ef27e9dfa992250fcc4c15"}, -] -botocore = [ - {file = "botocore-1.21.57-py3-none-any.whl", hash = "sha256:2a00acb822b148abf6a452c10c5f0b85d245e4bde7a0465ca2a5f8c990c07fc1"}, - {file = "botocore-1.21.57.tar.gz", hash = "sha256:4fd374e2dad91b2375db08e0c8a0bbd03b5e741b7dc4c5e730a544993cc46850"}, -] -certifi = [ - {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, - {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.0.6.tar.gz", hash = "sha256:5ec46d183433dcbd0ab716f2d7f29d8dee50505b3fdb40c6b985c7c4f5a3591f"}, - {file = "charset_normalizer-2.0.6-py3-none-any.whl", hash = "sha256:5d209c0a931f215cee683b6445e2d77677e7e75e159f78def0db09d68fafcaa6"}, -] -coverage = [ - {file = "coverage-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:abe8207dfb8a61ded9cd830d26c1073c8218fc0ae17eb899cfe8ec0fafae6e22"}, - {file = "coverage-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83faa3692e8306b20293889714fdf573d10ef5efc5843bd7c7aea6971487bd6a"}, - {file = "coverage-6.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f82a17f2a77958f3eef40ad385fc82d4c6ba9a77a51a174efe03ce75daebbc16"}, - {file = "coverage-6.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5b06f4f1729e2963281d9cd6e65e6976bf27b44d4c07ac5b47223ce45f822cec"}, - {file = "coverage-6.0.1-cp310-cp310-win32.whl", hash = "sha256:7600fac458f74c68b097379f76f3a6e3a630493fc7fc94b6508fedd9d498c194"}, - {file = "coverage-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c5f39d1556e75fc3c4fb071f9e7cfa618895a999a0de763a541d730775d0d5f"}, - {file = "coverage-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3edbb3ec580c73e5a264f5d04f30245bc98eff1a26765d46c5c65134f0a0e2f7"}, - {file = "coverage-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea452a2d83964d08232ade470091015e7ab9b8f53acbec10f2210fbab4ce7e43"}, - {file = "coverage-6.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1770d24f45f1f2daeae34cfa3b33fcb29702153544cd2ad40d58399dd4ff53b5"}, - {file = "coverage-6.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ad7182a82843f9f85487f44567c8c688f16c906bdb8d0e44ae462aed61cb8f1b"}, - {file = "coverage-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:9d242a2434801ef5125330deddb4cddba8990c9a49b3dec99dca17dd7eefba5a"}, - {file = "coverage-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e66c50f0ab445fec920a9f084914ea1776a809e3016c3738519048195f851bbb"}, - {file = "coverage-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5b1ceacb86e0a9558061dcc6baae865ed25933ea57effea644f21657cdce19bc"}, - {file = "coverage-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e15ab5afbee34abf716fece80ea33ea09a82e7450512f022723b1a82ec9a4e"}, - {file = "coverage-6.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6873f3f954d3e3ab8b1881f4e5307cc19f70c9f931c41048d9f7e6fd946eabe7"}, - {file = "coverage-6.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0898d6948b31df13391cd40568de8f35fa5901bc922c5ae05cf070587cb9c666"}, - {file = "coverage-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9c416ba03844608f45661a5b48dc59c6b5e89956efe388564dd138ca8caf540b"}, - {file = "coverage-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:66fe33e9e0df58675e08e83fe257f89e7f625e7633ea93d0872154e09cce2724"}, - {file = "coverage-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:353a50f123f0185cdb7a1e1e3e2cfb9d1fd7e293cfaf68eedaf5bd8e02e3ec32"}, - {file = "coverage-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b81a4e667c45b13658b84f9b8f1d32ef86d5405fabcbd181b76b9e51d295f397"}, - {file = "coverage-6.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:17426808e8e0824f864876312d41961223bf5e503bf8f1f846735279a60ea345"}, - {file = "coverage-6.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e11cca9eb5c9b3eaad899728ee2ce916138399ee8cbbccaadc1871fecb750827"}, - {file = "coverage-6.0.1-cp38-cp38-win32.whl", hash = "sha256:0a7e55cc9f7efa22d5cc9966276ec7a40a8803676f6ccbfdc06a486fba9aa9ee"}, - {file = "coverage-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:4eb9cd910ca8e243f930243a9940ea1a522e32435d15668445753d087c30ee12"}, - {file = "coverage-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:83682b73785d2e078e0b5f63410b8125b122e1a22422640c57edd4011c950f3e"}, - {file = "coverage-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b45f89a8ef65c29195f8f28dbe215f44ccb29d934f3e862d2a5c12e38698a793"}, - {file = "coverage-6.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:73880a80fad0597eca43e213e5e1711bf6c0fcdb7eb6b01b3b17841ebe5a7f8d"}, - {file = "coverage-6.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f398d38e6ebc2637863db1d7be3d4f9c5174e7d24bb3b0716cdb1f204669cbcf"}, - {file = "coverage-6.0.1-cp39-cp39-win32.whl", hash = "sha256:1864bdf9b2ccb43e724051bc23a1c558daf101ad4488ede1945f2a8be1facdad"}, - {file = "coverage-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:c9c413c4397d4cdc7ca89286158d240ce524f9667b52c9a64dd7e13d16cf8815"}, - {file = "coverage-6.0.1-pp36-none-any.whl", hash = "sha256:65da6e3e8325291f012921bbf71fea0a97824e1c573981871096aac6e2cf0ec5"}, - {file = "coverage-6.0.1-pp37-none-any.whl", hash = "sha256:07efe1fbd72e67df026ad5109bcd216acbbd4a29d5208b3dab61779bae6b7b26"}, - {file = "coverage-6.0.1.tar.gz", hash = "sha256:3490ff6dbf3f7accf0750136ed60ae1f487bccc1f097740e3b21262bc9c89854"}, -] -datadog = [ - {file = "datadog-0.41.0-py2.py3-none-any.whl", hash = "sha256:ab79ed38fb09ff1942c341e32849c4eeaf8b2e4d467b9e6bb1c6071808f454d6"}, - {file = "datadog-0.41.0.tar.gz", hash = "sha256:3de1a43b8a8d5f6b19d162ec1b482dc5ab2636c59cf65e60589702304510a689"}, -] -ddtrace = [ - {file = "ddtrace-0.50.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:823cac9f866a4daa7ae4c2c0d5401a23542dc120f92183d6564bcc6d0db8a019"}, - {file = "ddtrace-0.50.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:4717445ae76adde7de0bf1a463430addc3f81a67b5682e932bab38cd423b416b"}, - {file = "ddtrace-0.50.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:5747096846a995766fe2ef80e23daa36a8a18d56eda09e9131ec64c55a4b9826"}, - {file = "ddtrace-0.50.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:63e916fa3ffc2a7eb068aa7ece3d887544c161577a958bc677d6de379abb3e39"}, - {file = "ddtrace-0.50.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:a99fff0e3ad908acb411a0b03189c360cfead2a97dbd705a162a167923be5265"}, - {file = "ddtrace-0.50.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:78f936f2687e175bf6058e6ea978e0135d32daa45189af82acbda1c760d42eb2"}, - {file = "ddtrace-0.50.4-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:c944c78e57a2eb83564e5524f89e57d451271ff2354cff5b927fb0f47800171d"}, - {file = "ddtrace-0.50.4-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:6afb8b7513c10468feea304ef9ddb1a981abc4aef8b6e0a7592ed9f45f556c14"}, - {file = "ddtrace-0.50.4-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:9332bdb28d7ac252c15fcdf070bddf0bd4945feb2b2386fe5b07c68faebef961"}, - {file = "ddtrace-0.50.4-cp35-cp35m-win32.whl", hash = "sha256:ce7624637bb58aa97d2d91f72a3a72315e5048989a5c68a7dc5b97d7c13cec4b"}, - {file = "ddtrace-0.50.4-cp35-cp35m-win_amd64.whl", hash = "sha256:06c78ef761fa0871430508333dbd0083ec065ca25be2becf9e20e5e6e10ed399"}, - {file = "ddtrace-0.50.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7f8b8f2c639ebbfb0d204d53f299cd168ab3b6945f3e891c8ba77735db8d81ea"}, - {file = "ddtrace-0.50.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:19607fdcfbc962f2a94db8a80acfa4ae0c5193bf01c6ffb18d36b81af4eeb813"}, - {file = "ddtrace-0.50.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ec96ab8a5f50a0f7630348bece8ac93abad5373d1a55e1a3573946d0afaee353"}, - {file = "ddtrace-0.50.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:53aa1dfde89de0512fc82bf88c225881b1b7b3fd07d3016d6f0e372b1c60c979"}, - {file = "ddtrace-0.50.4-cp36-cp36m-win32.whl", hash = "sha256:589a7bb1f22726527aef313c61c1c58d91afc8d8e56945f0c6c0d632df8693b3"}, - {file = "ddtrace-0.50.4-cp36-cp36m-win_amd64.whl", hash = "sha256:970ddc3b407c342a4be665c0cce383309662066c3a66fab5255e8b4facc651b4"}, - {file = "ddtrace-0.50.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6d2838ed0edac122c8c1762dc17d342cfd6514fce1e621f76f86ebc67495b11e"}, - {file = "ddtrace-0.50.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:662b3078000323fbee2b51979992b3301329a6aca6970fb83aa5de9c13919ffa"}, - {file = "ddtrace-0.50.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:969628f9a0cd4860616ccb9bed22d459ab1ccee33df47f814e7f75b49e474305"}, - {file = "ddtrace-0.50.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:8b14b3c3ac5bcf07fba176d9a0cc79e689db0e1cc1e977b93f19185cdd10a3aa"}, - {file = "ddtrace-0.50.4-cp37-cp37m-win32.whl", hash = "sha256:80ea132dd3e0de1b95b60263cf06812cdb5f539c4e5033f07cbad7aceac5ec65"}, - {file = "ddtrace-0.50.4-cp37-cp37m-win_amd64.whl", hash = "sha256:8ebeeadb1d8bc7b0c395ebc85a3acdcb7769e8ee6183fb82236f1c79f7e2f96f"}, - {file = "ddtrace-0.50.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7cb432232d449150037ecf9bcb3f5f42c937159854d8330b4fc9869be94d8801"}, - {file = "ddtrace-0.50.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:db5ebb577f52e8feea5f82fae209ed6faf3d5da274a6e7c77430e49f07f21a93"}, - {file = "ddtrace-0.50.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:bdb44c30057bae7e8f19ccfed3a8889ff7d5af2d0a6fe8f40268dfed03b834e5"}, - {file = "ddtrace-0.50.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:978fd379dbb3752633e85dafdd373d5ede80c09f83bfec884a7ec9d526ce9400"}, - {file = "ddtrace-0.50.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:1a371d82e91ba7c1b1d081195db2013a41da5c33293a6127ffc910e6404b05f3"}, - {file = "ddtrace-0.50.4-cp38-cp38-win32.whl", hash = "sha256:10dd8a02d9a90191aada12e433d2fefad5afff877b9620328f0c33b492914d12"}, - {file = "ddtrace-0.50.4-cp38-cp38-win_amd64.whl", hash = "sha256:51e552eac0deb6e9720eeac00a409ee3443fc72049221c9b580307b4b40dcd4d"}, - {file = "ddtrace-0.50.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c11a2be09fb0080f6b42990e13b1fce8f4a7e5a71b5e3395542c1452c0ebde34"}, - {file = "ddtrace-0.50.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:51ea3d6bee775a9f445d8f0588d5e5e19de4bb6151768d9caf2ea989d7e01e79"}, - {file = "ddtrace-0.50.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:bccb286976fac56abec6b68b38f72cc612eb5a167406e4b6207eaf49cd45d1a8"}, - {file = "ddtrace-0.50.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:b3bb233eeba0f44c7c0777298aaedf59013148e6e4bc3513d4442037c36ec3a7"}, - {file = "ddtrace-0.50.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c2567452b07b902b5a2791dbbd15959f5823ce49e287e1fec3137cb9c1ca7f06"}, - {file = "ddtrace-0.50.4-cp39-cp39-win32.whl", hash = "sha256:1ed6b0572ea6d361c0621b3b520c44cf7bcb172f24453fbb0ea52be2f756eb49"}, - {file = "ddtrace-0.50.4-cp39-cp39-win_amd64.whl", hash = "sha256:86a4fa4ca614603ce4a759d38a9a32f7f440f0fa56162264b15212e18588efef"}, - {file = "ddtrace-0.50.4.tar.gz", hash = "sha256:5b2cc9f6a4515dda715646a9aa75ca39f738105be5adebdbbfade89436c24cec"}, -] -decorator = [ - {file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"}, - {file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"}, -] -flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, -] -httpretty = [ - {file = "httpretty-0.9.7.tar.gz", hash = "sha256:66216f26b9d2c52e81808f3e674a6fb65d4bf719721394a1a9be926177e55fbe"}, -] -idna = [ - {file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"}, - {file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"}, -] -importlib-metadata = [ - {file = "importlib_metadata-1.7.0-py2.py3-none-any.whl", hash = "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"}, - {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, -] -jmespath = [ - {file = "jmespath-0.10.0-py2.py3-none-any.whl", hash = "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"}, - {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"}, -] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] -nose2 = [ - {file = "nose2-0.9.2-py2.py3-none-any.whl", hash = "sha256:fd4b84c65ecea869080a23bdb8916716f5363df3b899933991c861ada8aa3f48"}, - {file = "nose2-0.9.2.tar.gz", hash = "sha256:8762f77925bbafcdf38331e0e2ee718756fb75ff74b1f9097cd08731ad59ab5e"}, -] -packaging = [ - {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, - {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, -] -pep562 = [ - {file = "pep562-1.1-py2.py3-none-any.whl", hash = "sha256:ff2308f21f1fcdf0a539b1af4d5a070c5baf47a07f51ff95f5d311f0c60390a4"}, - {file = "pep562-1.1.tar.gz", hash = "sha256:f8bc94a273dd45bd81a06a57c04bc57fd46f9c054c1354fa056044ceba2f0605"}, -] -protobuf = [ - {file = "protobuf-3.18.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fa6d1049d5315566f55c04d0b50c0033415144f96a9d25c820dc542fe2bb7f45"}, - {file = "protobuf-3.18.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0e2790c580070cff2921b93d562539ae027064340151c50db6aaf94c33048cd"}, - {file = "protobuf-3.18.1-cp36-cp36m-win32.whl", hash = "sha256:7e2f0677d68ecdd1cfda2abea65873f5bc7c3f5aae199404a3f5c1d1198c1a63"}, - {file = "protobuf-3.18.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6f714f5de9d40b3bec90ede4a688cce52f637ccdc5403afcda1f67598f4fdcd7"}, - {file = "protobuf-3.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a7be937c319146cc9f2626f0181e6809062c353e1fe449ecd0df374ba1036b2"}, - {file = "protobuf-3.18.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:10544fc7ace885a882623083c24da5b14148c77563acddc3c58d66f6153c09cd"}, - {file = "protobuf-3.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ee8b11e3eb2ed38f12137c3c132270a0b1dd509e317228ac47b67f21a583f1"}, - {file = "protobuf-3.18.1-cp37-cp37m-win32.whl", hash = "sha256:c492c217d3f69f4d2d5619571e52ab98538edbf53caf67e53ea92bd0a3b5670f"}, - {file = "protobuf-3.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3c1644f8a7f19b45c7a4c32278e2a55ae9e7e2f9e5f02d960a61f04a4890d3e6"}, - {file = "protobuf-3.18.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9ac691f7b24e4371dcd3980e4f5d6c840a2010da37986203053fee995786ec5"}, - {file = "protobuf-3.18.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:93bad12895d8b0ebc66b605c2ef1802311595f881aef032d9f13282b7550e6b2"}, - {file = "protobuf-3.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0851b5b89191e1976d34fa2e8eb8659829dfb45252053224cf9df857fb5f6a45"}, - {file = "protobuf-3.18.1-cp38-cp38-win32.whl", hash = "sha256:09d9268f6f9da81b7657adcf2fb397524c82f20cdf9e0db3ff4e7567977abd67"}, - {file = "protobuf-3.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d6d927774c0ec746fed15a4faff5f44aad0b7a3421fadb6f3ae5ca1f2f8ae26e"}, - {file = "protobuf-3.18.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4d19c9cb805fd2be1d59eee39e152367ee92a30167e77bd06c8819f8f0009a4c"}, - {file = "protobuf-3.18.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:387f621bf7295a331f8c8a6962d097ceddeb85356792888cfa6a5c6bfc6886a4"}, - {file = "protobuf-3.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c1c5d3966c856f60a9d8d62f4455d70c31026422acdd5c228edf22b65b16c38"}, - {file = "protobuf-3.18.1-cp39-cp39-win32.whl", hash = "sha256:f20f803892f2135e8b96dc58c9a0c6a7ad8436794bf8784af229498d939b4c77"}, - {file = "protobuf-3.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:d76201380f41a2d83fb613a4683059d1fcafbe969518b3e409e279a8788fde2f"}, - {file = "protobuf-3.18.1-py2.py3-none-any.whl", hash = "sha256:61ca58e14033ca0dfa484a31d57237c1be3b6013454c7f53876a20fc88dd69b1"}, - {file = "protobuf-3.18.1.tar.gz", hash = "sha256:1c9bb40503751087300dd12ce2e90899d68628977905c76effc48e66d089391e"}, -] -pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, -] -pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, -] -pyparsing = [ - {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, -] -python-dateutil = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] -requests = [ - {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, - {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, -] -s3transfer = [ - {file = "s3transfer-0.5.0-py3-none-any.whl", hash = "sha256:9c1dc369814391a6bda20ebbf4b70a0f34630592c9aa520856bf384916af2803"}, - {file = "s3transfer-0.5.0.tar.gz", hash = "sha256:50ed823e1dc5868ad40c8dc92072f757aa0e653a192845c94a3b676f4a62da4c"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -tenacity = [ - {file = "tenacity-8.0.1-py3-none-any.whl", hash = "sha256:f78f4ea81b0fabc06728c11dc2a8c01277bfc5181b321a4770471902e3eb844a"}, - {file = "tenacity-8.0.1.tar.gz", hash = "sha256:43242a20e3e73291a28bcbcacfd6e000b02d3857a9a9fff56b297a27afdc932f"}, -] -urllib3 = [ - {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, - {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, -] -wrapt = [ - {file = "wrapt-1.13.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:97f016514ceac524832e7d1bd41cf928b992ebe0324d59736f84ad5f4bbe0632"}, - {file = "wrapt-1.13.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:0b2cbe418beeff3aadb3afc39a67d3f5f6a3eb020ceb5f2bcf56bef14b33629a"}, - {file = "wrapt-1.13.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:95c9fcfc326fdd3e2fd264e808f6474ca7ffd253feb3a505ee5ceb4d78216ef7"}, - {file = "wrapt-1.13.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:db0daf2afca9f3b3a76e96ecb5f55ba82615ec584471d7aa27c1bdeb9e3888bb"}, - {file = "wrapt-1.13.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:1b46e4fe0f9efbfaf1ee82fc79f9cb044c69b67b181c58370440d396fe40736e"}, - {file = "wrapt-1.13.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:b0eed9b295039a619f64667f27cffbffcfc0559073d562700912ca6266bc8b28"}, - {file = "wrapt-1.13.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8a6ba1b00d07f5a90a2d2eb1804a42e2067a6145b7745a8297664a75a8a232ba"}, - {file = "wrapt-1.13.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:947a8d9d7829364e11eca88af18394713c8f98571cbc672b12545977d837f054"}, - {file = "wrapt-1.13.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6aa687da5565674c9696fafd2b8d44a04fb697ec2431af21c3def9cbedc4082a"}, - {file = "wrapt-1.13.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:7929ce97be2f7c49f454a6f8e014225e53cc3767fe48cce94b188de2225232ac"}, - {file = "wrapt-1.13.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2d18618440df6bc072762625e9c843d32a7328347c321b89f8df3a7c4a72ce6c"}, - {file = "wrapt-1.13.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:cb0b12b365b054bee2a53078a67df81781be0686cc3f3ab8bbdd16b2e188570a"}, - {file = "wrapt-1.13.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:3816922f0941f1637869a04e25d1e5261dfa55cc6b39c73872cbf192ea562443"}, - {file = "wrapt-1.13.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:b41ce8ee3825634e67883dd4dab336f95d0cc9d223fb7e224dcd36d66af93694"}, - {file = "wrapt-1.13.1-cp35-cp35m-win32.whl", hash = "sha256:d0ae90fd60c7473e437b0dd48ae323c11f631fe47c243056f9e7505d26e8e2f6"}, - {file = "wrapt-1.13.1-cp35-cp35m-win_amd64.whl", hash = "sha256:f4377eda306b488255ea4336662cd9015a902d6dc2ed77a3e4c1e3b42387453a"}, - {file = "wrapt-1.13.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:bc42803987eb46b5fc67ec9a072df15a72ee9db61e3b7dd955d82581bf141f60"}, - {file = "wrapt-1.13.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:04a00cef5d1b9e0e8db997816437b436e859106283c4771a40c4de4759344765"}, - {file = "wrapt-1.13.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:836c73f53a0cefc7ba10c6f4a0d78894cb4876f56035fe500b029e0a1ae0ffe9"}, - {file = "wrapt-1.13.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:6c241b4ef0744590ae0ee89305743977e478200cff961bdcc6b3d0530aea3377"}, - {file = "wrapt-1.13.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:19b2c992668c9ca764899bae52987a04041ebc21859d2646db0b27e089c2fd6b"}, - {file = "wrapt-1.13.1-cp36-cp36m-win32.whl", hash = "sha256:9d200716eb4bb1d73f47f3ccc4f98fdf979dcc82d752183828f1be2e332b6874"}, - {file = "wrapt-1.13.1-cp36-cp36m-win_amd64.whl", hash = "sha256:77fef0bfdc612f5f30e43392a9f67dddaf4f48f299421bf25f910d0f47173f3d"}, - {file = "wrapt-1.13.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1137e6aef3ac267c2af7d3af0266ef3f8dd1e5cde67b8eac9fa3b94e7fa0ada"}, - {file = "wrapt-1.13.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:972099fa9cf4e43c255701c78ec5098c2fec4d6ea669a110b3414a158e772b0a"}, - {file = "wrapt-1.13.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5dc6c8cfaf4ff2a4632f8f97d29f555d6951eb0f905d3d47b3fd69bddb653214"}, - {file = "wrapt-1.13.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:f1e2cea943192e24070b65bda862901c02bdf7c6abcd66ef5381ad6511921067"}, - {file = "wrapt-1.13.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:8a184c655bb41295a9b0c28745a1b762c0c86025e43808b7e814f9cedc6c563d"}, - {file = "wrapt-1.13.1-cp37-cp37m-win32.whl", hash = "sha256:6b81913fdba96e286f0c6007eb61f0158e64a1941bfc72fee61b34a4f8f9877f"}, - {file = "wrapt-1.13.1-cp37-cp37m-win_amd64.whl", hash = "sha256:aa637733f1d599077522f6a1f0c6c40389aa90a44cba37afcefef26f8e53d28f"}, - {file = "wrapt-1.13.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec803c9d6e4ce037201132d903ff8b0dd26c9688be50ce4c77c420c076e78ff7"}, - {file = "wrapt-1.13.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:8055f8cc9a80dc1db01f31af6399b83f597ec164f07b7251d2a1bf1c6c025190"}, - {file = "wrapt-1.13.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:3658ae9c704906cab5865a00c1aa9e1fd3555074d1a4462fa1742d7fea8260ae"}, - {file = "wrapt-1.13.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:9f839c47698052ef5c2c094e21f8a06d0828aebe52d20cdb505faa318c62e886"}, - {file = "wrapt-1.13.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:fd5320bf61a2e8d3b46d9e183323293c9a695df8f38c98d17c45e1846758f9a9"}, - {file = "wrapt-1.13.1-cp38-cp38-win32.whl", hash = "sha256:e2eb4f38441b56698b4d40d48fd331e4e8a0477264785d08cbced63813d4bd29"}, - {file = "wrapt-1.13.1-cp38-cp38-win_amd64.whl", hash = "sha256:2f6fbea8936ba862425664fc689182a8ef50a6d88cd49f3cd073eccd3e78c930"}, - {file = "wrapt-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4f3f99bb8eed5d394bbb898c5191ed91ebf21187d52b2c45895733ae2798f373"}, - {file = "wrapt-1.13.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:21c1710f61aa95b4be83a32b6d6facbb0efdfac22dee65e1caa72a83deed7cda"}, - {file = "wrapt-1.13.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:40fd2cebad4010787de4221ec27a650635eed3e49e4bbfa8244fc34836cc2457"}, - {file = "wrapt-1.13.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:c803526c0d3fa426e06de379b4eb56102234f2dc3c3a24a500d7962a83ca6166"}, - {file = "wrapt-1.13.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:e5a0727ea56de6e9a17693589bcf913d6bf1ec49f12d4671993321f3325fda4f"}, - {file = "wrapt-1.13.1-cp39-cp39-win32.whl", hash = "sha256:04312fbf51e9dd15261228e6b4bed0c0ed5723ccf986645d2c7308511dccba35"}, - {file = "wrapt-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:bd705e341baccc3d1ef20e790b1f6383bd4ae92a77ba87a86ece8189fab8793c"}, - {file = "wrapt-1.13.1.tar.gz", hash = "sha256:909a80ce028821c7ad01bdcaa588126825931d177cdccd00b3545818d4a195ce"}, -] -zipp = [ - {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, - {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, -] +lock-version = "2.1" +python-versions = ">=3.8.0,<4" +content-hash = "f6a2f7355200da107aa5b027d6fe4fb6bdb5a898ce8298a56e6ac39fe8d8e34d" diff --git a/pyproject.toml b/pyproject.toml index b8a94134b..d135e085b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,11 @@ [tool.poetry] name = "datadog_lambda" -version = "3.49.0" +version = "8.117.0.dev0" description = "The Datadog AWS Lambda Library" authors = ["Datadog, Inc. "] license = "Apache-2.0" readme = "README.md" -repository = "https://github.com/DataDog/datadog-lambda-pyhon" +repository = "https://github.com/DataDog/datadog-lambda-python" keywords = [ "datadog", "aws", @@ -16,34 +16,38 @@ packages = [ { include = "datadog_lambda" } ] classifiers = [ - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] [tool.poetry.dependencies] -python = ">=3.6.0,<4" -datadog = "^0.41.0" +python = ">=3.8.0,<4" +datadog = ">=0.51.0,<1.0.0" wrapt = "^1.11.2" -ddtrace = "^0.50.0" -importlib_metadata = {version = "^1.0", python = "<3.8"} -boto3 = { version = "^1.10.33", optional = true } +ddtrace = ">=3.16.2,<4" +ujson = ">=5.9.0" +botocore = { version = "^1.34.0", optional = true } requests = { version ="^2.22.0", optional = true } -nose2 = { version= "^0.9.1", optional = true } -flake8 = { version = "^3.7.9", optional = true } -httpretty = {version = "^0.9.7", optional = true } - +pytest = { version= "^8.0.0", optional = true } +pytest-benchmark = { version = "^4.0", optional = true } +flake8 = { version = "^5.0.4", optional = true } [tool.poetry.extras] dev = [ - "boto3", - "requests", - "nose2", + "botocore", "flake8", - "httpretty", + "pytest", + "pytest-benchmark", + "requests", ] [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" + +[tool.pytest.ini_options] +addopts = "--benchmark-disable --benchmark-autosave" diff --git a/scripts/add_new_region.sh b/scripts/add_new_region.sh index 6384319f9..576d13e7f 100755 --- a/scripts/add_new_region.sh +++ b/scripts/add_new_region.sh @@ -8,12 +8,38 @@ # Copy layers from us-east-1 to new region # args: [new-region] -set -e +set -e OLD_REGION='us-east-1' -PYTHON_VERSIONS_FOR_AWS_CLI=("python3.6" "python3.7" "python3.8" "python3.9") -LAYER_NAMES=("Datadog-Python36" "Datadog-Python37" "Datadog-Python38" "Datadog-Python39") +LAYER_NAMES=( + "Datadog-Python38" + "Datadog-Python38-ARM" + "Datadog-Python39" + "Datadog-Python39-ARM" + "Datadog-Python310" + "Datadog-Python310-ARM" + "Datadog-Python311" + "Datadog-Python311-ARM" + "Datadog-Python312" + "Datadog-Python312-ARM" + "Datadog-Python313" + "Datadog-Python313-ARM" +) +PYTHON_VERSIONS_FOR_AWS_CLI=( + "python3.8" + "python3.8" + "python3.9" + "python3.9" + "python3.10" + "python3.10" + "python3.11" + "python3.11" + "python3.12" + "python3.12" + "python3.13" + "python3.13" +) NEW_REGION=$1 publish_layer() { @@ -68,11 +94,11 @@ for layer_name in "${LAYER_NAMES[@]}"; do fi # run for each version of layer - for i in $(seq 1 $last_layer_version); do + for i in $(seq 1 $last_layer_version); do layer_path=$layer_name"_"$i.zip aws_version_key="${PYTHON_VERSIONS_FOR_AWS_CLI[$j]}" - # download layer versions + # download layer versions URL=$(AWS_REGION=$OLD_REGION aws lambda get-layer-version --layer-name $layer_name --version-number $i --query Content.Location --output text) curl $URL -o $layer_path @@ -82,4 +108,4 @@ for layer_name in "${LAYER_NAMES[@]}"; do done j=$(expr $j + 1) -done \ No newline at end of file +done diff --git a/scripts/build_layers.sh b/scripts/build_layers.sh index f2c70ff90..23941b7a0 100755 --- a/scripts/build_layers.sh +++ b/scripts/build_layers.sh @@ -7,14 +7,29 @@ # Builds datadog-lambda-python layers for Lambda functions -# Usage: PYTHON_VERSION=3.7 ./build_layers.sh +# Usage: PYTHON_VERSION=3.11 ./build_layers.sh # If PYTHON_VERSION is not specified, all versions will be built. set -e LAYER_DIR=".layers" LAYER_FILES_PREFIX="datadog_lambda_py" -AVAILABLE_PYTHON_VERSIONS=("3.6" "3.7" "3.8" "3.9") +AVAILABLE_PYTHON_VERSIONS=("3.8" "3.9" "3.10" "3.11" "3.12" "3.13") +AVAILABLE_ARCHS=("arm64" "amd64") + +if [ -z "$ARCH" ]; then + echo "No architectures specified, building layers for all architectures." + ARCHS=("${AVAILABLE_ARCHS[@]}") +else + echo "Architecture specified: $ARCH" + if [[ ! " ${AVAILABLE_ARCHS[@]} " =~ " ${ARCH} " ]]; then + echo "Architecture $ARCH is not a valid option. Choose from: ${AVAILABLE_ARCHS[@]}" + echo "" + echo "EXITING SCRIPT." + exit 1 + fi + ARCHS=$ARCH +fi # Determine which Python versions to build layers for if [ -z "$PYTHON_VERSION" ]; then @@ -46,15 +61,11 @@ function docker_build_zip { # between different python runtimes. temp_dir=$(mktemp -d) docker buildx build -t datadog-lambda-python-${arch}:$1 . --no-cache \ - --build-arg image=python:$1 \ + --build-arg image=public.ecr.aws/sam/build-python$1:1 \ --build-arg runtime=python$1 \ --platform linux/${arch} \ - --load - - # Run the image by runtime tag, tar its generatd `python` directory to sdout, - # then extract it to a temp directory. - docker run datadog-lambda-python-${arch}:$1 tar cf - python | tar -xf - -C $temp_dir - + --progress=plain \ + -o $temp_dir/python # Zip to destination, and keep directory structure as based in $temp_dir (cd $temp_dir && zip -q -r $destination ./) @@ -68,12 +79,11 @@ mkdir $LAYER_DIR for python_version in "${PYTHON_VERSIONS[@]}" do - if [ "$python_version" == "3.8" ] || [ "$python_version" == "3.9" ]; then - echo "Building layer for Python ${python_version} arch=arm64" - docker_build_zip ${python_version} $LAYER_DIR/${LAYER_FILES_PREFIX}-arm64-${python_version}.zip arm64 - fi - echo "Building layer for Python ${python_version} arch=amd64" - docker_build_zip ${python_version} $LAYER_DIR/${LAYER_FILES_PREFIX}-amd64-${python_version}.zip amd64 + for architecture in "${ARCHS[@]}" + do + echo "Building layer for Python ${python_version} arch=${architecture}" + docker_build_zip ${python_version} $LAYER_DIR/${LAYER_FILES_PREFIX}-${architecture}-${python_version}.zip ${architecture} + done done echo "Done creating layers:" diff --git a/scripts/check_format.sh b/scripts/check_format.sh index 984b588fe..df5a67187 100755 --- a/scripts/check_format.sh +++ b/scripts/check_format.sh @@ -2,7 +2,7 @@ set -e PYTHON_VERSION=$(python -c 'import sys; print(sys.version_info.major)') -pip install -Iv black==21.5b2 +pip install -Iv black==22.3.0 python -m black --check datadog_lambda/ --diff python -m black --check tests --diff diff --git a/scripts/check_layer_size.sh b/scripts/check_layer_size.sh index c213d4969..ce67d92d9 100755 --- a/scripts/check_layer_size.sh +++ b/scripts/check_layer_size.sh @@ -7,33 +7,29 @@ # Compares layer size to threshold, and fails if below that threshold -# 5 mb size limit -MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 5 \* 1024) -MAX_LAYER_UNCOMPRESSED_SIZE_KB=$(expr 16 \* 1024) +set -e +MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 9 \* 1024) # 9216 KB +MAX_LAYER_UNCOMPRESSED_SIZE_KB=$(expr 25 \* 1024) # 25600 KB LAYER_FILES_PREFIX="datadog_lambda_py" LAYER_DIR=".layers" -VERSIONS=("3.6" "3.7" "3.8" "3.9") -for version in "${VERSIONS[@]}" -do - FILE=$LAYER_DIR/${LAYER_FILES_PREFIX}-amd64-${version}.zip - FILE_SIZE=$(stat --printf="%s" $FILE) - FILE_SIZE_KB="$(( ${FILE_SIZE%% *} / 1024))" - echo "Layer file ${FILE} has zipped size ${FILE_SIZE_KB} kb" - if [ "$FILE_SIZE_KB" -gt "$MAX_LAYER_COMPRESSED_SIZE_KB" ]; then - echo "Zipped size exceeded limit $MAX_LAYER_COMPRESSED_SIZE_KB kb" - exit 1 - fi - mkdir tmp - unzip -q $FILE -d tmp - UNZIPPED_FILE_SIZE=$(du -shb tmp/ | cut -f1) - UNZIPPED_FILE_SIZE_KB="$(( ${UNZIPPED_FILE_SIZE%% *} / 1024))" - rm -rf tmp - echo "Layer file ${FILE} has unzipped size ${UNZIPPED_FILE_SIZE_KB} kb" - if [ "$UNZIPPED_FILE_SIZE_KB" -gt "$MAX_LAYER_UNCOMPRESSED_SIZE_KB" ]; then - echo "Unzipped size exceeded limit $MAX_LAYER_UNCOMPRESSED_SIZE_KB kb" - exit 1 - fi -done \ No newline at end of file +FILE=$LAYER_DIR/${LAYER_FILES_PREFIX}-${ARCH}-${PYTHON_VERSION}.zip +FILE_SIZE=$(stat --printf="%s" $FILE) +FILE_SIZE_KB="$(( ${FILE_SIZE%% *} / 1024))" +echo "Layer file ${FILE} has zipped size ${FILE_SIZE_KB} kb" +if [ "$FILE_SIZE_KB" -gt "$MAX_LAYER_COMPRESSED_SIZE_KB" ]; then + echo "Zipped size exceeded limit $MAX_LAYER_COMPRESSED_SIZE_KB kb" + exit 1 +fi +mkdir tmp +unzip -q $FILE -d tmp +UNZIPPED_FILE_SIZE=$(du -shb tmp/ | cut -f1) +UNZIPPED_FILE_SIZE_KB="$(( ${UNZIPPED_FILE_SIZE%% *} / 1024))" +rm -rf tmp +echo "Layer file ${FILE} has unzipped size ${UNZIPPED_FILE_SIZE_KB} kb" +if [ "$UNZIPPED_FILE_SIZE_KB" -gt "$MAX_LAYER_UNCOMPRESSED_SIZE_KB" ]; then + echo "Unzipped size exceeded limit $MAX_LAYER_UNCOMPRESSED_SIZE_KB kb" + exit 1 +fi diff --git a/scripts/list_layers.sh b/scripts/list_layers.sh index 8a845edd8..6449e5115 100755 --- a/scripts/list_layers.sh +++ b/scripts/list_layers.sh @@ -10,7 +10,20 @@ set -e -LAYER_NAMES=("Datadog-Python36" "Datadog-Python37" "Datadog-Python38" "Datadog-Python38-ARM" "Datadog-Python39" "Datadog-Python39-ARM") +LAYER_NAMES=( + "Datadog-Python38" + "Datadog-Python38-ARM" + "Datadog-Python39" + "Datadog-Python39-ARM" + "Datadog-Python310" + "Datadog-Python310-ARM" + "Datadog-Python311" + "Datadog-Python311-ARM" + "Datadog-Python312" + "Datadog-Python312-ARM" + "Datadog-Python313" + "Datadog-Python313-ARM" +) AVAILABLE_REGIONS=$(aws ec2 describe-regions | jq -r '.[] | .[] | .RegionName') LAYERS_MISSING_REGIONS=() @@ -63,6 +76,6 @@ done if [ ${#LAYERS_MISSING_REGIONS[@]} -gt 0 ]; then echo "WARNING: Following regions missing layers: ${LAYERS_MISSING_REGIONS[@]}" - echo "Please run ./add_new_region.sh to add layers to the missing regions" + echo "Please run ./add_new_region.sh to add layers to the missing regions" exit 1 -fi \ No newline at end of file +fi diff --git a/scripts/publish_govcloud.sh b/scripts/publish_govcloud.sh new file mode 100755 index 000000000..5fd107b0e --- /dev/null +++ b/scripts/publish_govcloud.sh @@ -0,0 +1,105 @@ +#! /usr/bin/env bash + +# Unless explicitly stated otherwise all files in this repository are licensed +# under the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2025 Datadog, Inc. +# +# USAGE: download the layer bundle from the build pipeline in gitlab. Use the +# Download button on the `layer bundle` job. This will be a zip file containing +# all of the required layers. Run this script as follows: +# +# ENVIRONMENT=[us1-staging-fed or us1-fed] [LAYER_NAME_SUFFIX=optional-layer-suffix] [REGIONS=us-gov-west-1] ./scripts/publish_govcloud.sh +# +# protip: you can drag the zip file from finder into your terminal to insert +# its path. + +set -e + +LAYER_PACKAGE=$1 + +if [ -z "$LAYER_PACKAGE" ]; then + printf "[ERROR]: layer package not provided\n" + exit 1 +fi + +PACKAGE_NAME=$(basename "$LAYER_PACKAGE" .zip) + +if [ -z "$ENVIRONMENT" ]; then + printf "[ERROR]: ENVIRONMENT not specified\n" + exit 1 +fi + +if [ "$ENVIRONMENT" = "us1-staging-fed" ]; then + AWS_VAULT_ROLE=sso-govcloud-us1-staging-fed-power-user + + export STAGE=gov-staging + + if [[ ! "$PACKAGE_NAME" =~ ^datadog_lambda_py-(signed-)?bundle-[0-9]+$ ]]; then + echo "[ERROR]: Unexpected package name: $PACKAGE_NAME" + exit 1 + fi + +elif [ $ENVIRONMENT = "us1-fed" ]; then + AWS_VAULT_ROLE=sso-govcloud-us1-fed-engineering + + export STAGE=gov-prod + + if [[ ! "$PACKAGE_NAME" =~ ^datadog_lambda_py-signed-bundle-[0-9]+$ ]]; then + echo "[ERROR]: Unexpected package name: $PACKAGE_NAME" + exit 1 + fi + +else + printf "[ERROR]: ENVIRONMENT not supported, must be us1-staging-fed or us1-fed.\n" + exit 1 +fi + +TEMP_DIR=$(mktemp -d) +unzip $LAYER_PACKAGE -d $TEMP_DIR +cp -v $TEMP_DIR/$PACKAGE_NAME/*.zip .layers/ + + +AWS_VAULT_PREFIX="aws-vault exec $AWS_VAULT_ROLE --" + +echo "Checking that you have access to the GovCloud AWS account" +$AWS_VAULT_PREFIX aws sts get-caller-identity + + +AVAILABLE_REGIONS=$($AWS_VAULT_PREFIX aws ec2 describe-regions | jq -r '.[] | .[] | .RegionName') + +# Determine the target regions +if [ -z "$REGIONS" ]; then + echo "Region not specified, running for all available regions." + REGIONS=$AVAILABLE_REGIONS +else + echo "Region specified: $REGIONS" + if [[ ! "$AVAILABLE_REGIONS" == *"$REGIONS"* ]]; then + echo "Could not find $REGIONS in available regions: $AVAILABLE_REGIONS" + echo "" + echo "EXITING SCRIPT." + exit 1 + fi +fi + +for region in $REGIONS +do + echo "Starting publishing layers for region $region..." + + export REGION=$region + + for python_version in "3.8" "3.9" "3.10" "3.11" "3.12" "3.13"; do + for arch in "amd64" "arm64"; do + export PYTHON_VERSION=$python_version + export ARCH=$arch + + export SKIP_PIP_INSTALL=true + + echo "Publishing layer for $PYTHON_VERSION and $ARCH" + + $AWS_VAULT_PREFIX ./ci/publish_layers.sh + done + done +done + +echo "Done !" diff --git a/scripts/publish_layers.sh b/scripts/publish_layers.sh index f3c790d71..8c78093f8 100755 --- a/scripts/publish_layers.sh +++ b/scripts/publish_layers.sh @@ -13,12 +13,56 @@ set -e # Makes sure any subprocesses will be terminated with this process trap "pkill -P $$; exit 1;" INT -PYTHON_VERSIONS_FOR_AWS_CLI=("python3.6" "python3.7" "python3.8" "python3.8" "python3.9" "python3.9") -LAYER_PATHS=(".layers/datadog_lambda_py-amd64-3.6.zip" ".layers/datadog_lambda_py-amd64-3.7.zip" ".layers/datadog_lambda_py-amd64-3.8.zip" ".layers/datadog_lambda_py-arm64-3.8.zip" ".layers/datadog_lambda_py-amd64-3.9.zip" ".layers/datadog_lambda_py-arm64-3.9.zip") -AVAILABLE_LAYERS=("Datadog-Python36" "Datadog-Python37" "Datadog-Python38" "Datadog-Python38-ARM" "Datadog-Python39" "Datadog-Python39-ARM") -ARCHS=("amd64" "amd64" "amd64""amd64" "amd64" "arm64") +PYTHON_VERSIONS_FOR_AWS_CLI=( + "python3.8" + "python3.8" + "python3.9" + "python3.9" + "python3.10" + "python3.10" + "python3.11" + "python3.11" + "python3.12" + "python3.12" + "python3.13" + "python3.13" +) +LAYER_PATHS=( + ".layers/datadog_lambda_py-amd64-3.8.zip" + ".layers/datadog_lambda_py-arm64-3.8.zip" + ".layers/datadog_lambda_py-amd64-3.9.zip" + ".layers/datadog_lambda_py-arm64-3.9.zip" + ".layers/datadog_lambda_py-amd64-3.10.zip" + ".layers/datadog_lambda_py-arm64-3.10.zip" + ".layers/datadog_lambda_py-amd64-3.11.zip" + ".layers/datadog_lambda_py-arm64-3.11.zip" + ".layers/datadog_lambda_py-amd64-3.12.zip" + ".layers/datadog_lambda_py-arm64-3.12.zip" + ".layers/datadog_lambda_py-amd64-3.13.zip" + ".layers/datadog_lambda_py-arm64-3.13.zip" +) +AVAILABLE_LAYERS=( + "Datadog-Python38" + "Datadog-Python38-ARM" + "Datadog-Python39" + "Datadog-Python39-ARM" + "Datadog-Python310" + "Datadog-Python310-ARM" + "Datadog-Python311" + "Datadog-Python311-ARM" + "Datadog-Python312" + "Datadog-Python312-ARM" + "Datadog-Python313" + "Datadog-Python313-ARM" +) AVAILABLE_REGIONS=$(aws ec2 describe-regions | jq -r '.[] | .[] | .RegionName') +BATCH_SIZE=60 +PIDS=() + +# Makes sure any subprocesses will be terminated with this process +trap "pkill -P $$; exit 1;" INT + # Check that the layer files exist for layer_file in "${LAYER_PATHS[@]}" do @@ -102,6 +146,35 @@ publish_layer() { echo $version_nbr } +wait_for_processes() { + for pid in "${PIDS[@]}"; do + wait $pid + done + PIDS=() +} + +backfill_layers() { + latest_version=$1 + region=$2 + layer_name=$3 + aws_version_key=$4 + layer_path=$5 + + while [ $latest_version -lt $VERSION ]; do + latest_version=$(publish_layer $region $layer_name $aws_version_key $layer_path) + echo "Published version $latest_version for layer $layer_name in region $region" + + # This shouldn't happen unless someone manually deleted the latest version, say 28, and + # then tries to republish 28 again. The published version would actually be 29, because + # Lambda layers are immutable and AWS will skip deleted version and use the next number. + if [ $latest_version -gt $VERSION ]; then + echo "ERROR: Published version $latest_version is greater than the desired version $VERSION!" + echo "Exiting" + exit 1 + fi + done +} + for region in $REGIONS do echo "Starting publishing layer for region $region..." @@ -112,31 +185,20 @@ do echo "Layer $layer_name version $VERSION already exists in region $region, skipping..." continue elif [ $latest_version -lt $((VERSION-1)) ]; then - read -p "WARNING: The latest version of layer $layer_name in region $region is $latest_version, publish all the missing versions including $VERSION or EXIT the script (y/n)?" CONT - if [ "$CONT" != "y" ]; then - echo "Exiting" - exit 1 - fi + echo "WARNING: The latest version of layer $layer_name in region $region is $latest_version, this will publish all the missing versions including $VERSION" fi index=$(index_of_layer $layer_name) aws_version_key="${PYTHON_VERSIONS_FOR_AWS_CLI[$index]}" layer_path="${LAYER_PATHS[$index]}" - while [ $latest_version -lt $VERSION ]; do - latest_version=$(publish_layer $region $layer_name $aws_version_key $layer_path) - echo "Published version $latest_version for layer $layer_name in region $region" - - # This shouldn't happen unless someone manually deleted the latest version, say 28 - # and then try to republish it again. The published version is actually be 29, because - # Lambda layers are immutable and AWS will skip deleted version and use the next number. - if [ $latest_version -gt $VERSION ]; then - echo "ERROR: Published version $latest_version is greater than the desired version $VERSION!" - echo "Exiting" - exit 1 - fi - done + backfill_layers $latest_version $region $layer_name $aws_version_key $layer_path & + PIDS+=($!) + if [ ${#PIDS[@]} -ge $BATCH_SIZE ]; then + wait_for_processes + fi done done +wait_for_processes echo "Done !" diff --git a/scripts/publish_prod.sh b/scripts/publish_prod.sh index b1d787596..d2918c544 100755 --- a/scripts/publish_prod.sh +++ b/scripts/publish_prod.sh @@ -4,6 +4,13 @@ set -e +read -p "Are we only doing the simplified GovCloud release? ONLY IF THE NORMAL RELEASE IS DONE AND YOU HAVE DOWNLOADED THE LAYERS (y/n)? " GOVCLOUD_ONLY + +if [ $GOVCLOUD_ONLY != "n" ]; then + echo "GovCloud publishing is now supported only in publich_govcloud.sh" + exit 1 +fi + # Ensure on main, and pull the latest BRANCH=$(git rev-parse --abbrev-ref HEAD) if [ $BRANCH != "main" ]; then @@ -31,13 +38,8 @@ else NEW_VERSION=$1 fi -# Ensure AWS access before proceeding -saml2aws login -a govcloud-us1-fed-human-engineering -AWS_PROFILE=govcloud-us1-fed-human-engineering aws sts get-caller-identity -aws-vault exec prod-engineering -- aws sts get-caller-identity - # Ensure pypi registry access -read -p "Do you have the PyPi login credentials for datadog account (y/n)?" CONT +read -p "Do you have access to PyPI (y/n)?" CONT if [ "$CONT" != "y" ]; then echo "Exiting" exit 1 @@ -52,11 +54,18 @@ if [ "$CONT" != "y" ]; then exit 1 fi -echo -echo "Replacing version in pyproject.toml" -echo +echo "Answer 'n' if already done in a PR" +read -p "Update pyproject.toml version? (y/n)?" CONT +if [ "$CONT" != "y" ]; then + echo "Skipping updating package.json version" +else + echo + echo "Replacing version in pyproject.toml and datadog_lambda/version.py" + echo -poetry version ${NEW_VERSION} + poetry version ${NEW_VERSION} + echo "__version__ = \"${NEW_VERSION}\"" > datadog_lambda/version.py +fi echo echo "Building layers..." @@ -64,35 +73,48 @@ echo "Building layers..." echo echo "Signing layers for commercial AWS regions" -aws-vault exec prod-engineering -- ./scripts/sign_layers.sh prod +aws-vault exec sso-prod-engineering -- ./scripts/sign_layers.sh prod -echo -echo "Publishing layers to commercial AWS regions" -VERSION=$LAYER_VERSION aws-vault exec prod-engineering -- ./scripts/publish_layers.sh +echo "Answer 'n' if GitLab already did this" +read -p "Deploy layers to commercial AWS (y/n)?" CONT +if [ "$CONT" != "y" ]; then + echo "Skipping deployment to commercial AWS" +else + echo "Ensuring you have access to the production AWS account" + aws-vault exec sso-prod-engineering -- aws sts get-caller-identity -echo "Publishing layers to GovCloud AWS regions" -saml2aws login -a govcloud-us1-fed-human-engineering -VERSION=$LAYER_VERSION AWS_PROFILE=govcloud-us1-fed-human-engineering ./scripts/publish_layers.sh + echo + echo "Publishing layers to commercial AWS regions" + VERSION=$LAYER_VERSION aws-vault exec sso-prod-engineering --no-session -- ./scripts/publish_layers.sh +fi +echo "Answer 'n' if GitLab already did this" read -p "Ready to publish $NEW_VERSION to PyPI (y/n)?" CONT if [ "$CONT" != "y" ]; then - echo "Exiting" - exit 1 + echo "Skipping publishing to PyPI" +else + echo + echo "Publishing to https://pypi.org/project/datadog-lambda/" + ./scripts/pypi.sh fi -echo -echo "Publishing to https://pypi.org/project/datadog-lambda/" -./scripts/pypi.sh -echo -echo 'Publishing updates to github' -git commit ./datadog_lambda/__init__.py -m "Update module version to ${NEW_VERSION}" -git push origin main -git tag "v$LAYER_VERSION" -git push origin "refs/tags/v$LAYER_VERSION" +echo "Answer 'n' if you already released in GitHub" +read -p "Do you want to bump the version in GitHub? (y/n)" CONT +if [ "$CONT" != "y" ]; then + echo "Skipping publishing updates to GitHub" +else + echo + echo 'Publishing updates to github' + git commit pyproject.toml datadog_lambda/version.py -m "Bump version to ${NEW_VERSION}" + git push origin main + git tag "v$LAYER_VERSION" + git push origin "refs/tags/v$LAYER_VERSION" +fi echo -echo "Now create a new release with the tag v${LAYER_VERSION} created" +echo "Now create a new release with the tag v${LAYER_VERSION} created unless you have done this already" echo "https://github.com/DataDog/datadog-lambda-python/releases/new?tag=v$LAYER_VERSION&title=v$LAYER_VERSION" + # Open a PR to the documentation repo to automatically bump layer version VERSION=$LAYER_VERSION LAYER=datadog-lambda-python ./scripts/create_documentation_pr.sh diff --git a/scripts/publish_sandbox.sh b/scripts/publish_sandbox.sh index 0517c65a7..8f7d1de54 100755 --- a/scripts/publish_sandbox.sh +++ b/scripts/publish_sandbox.sh @@ -4,8 +4,8 @@ set -e ./scripts/build_layers.sh -aws-vault exec sandbox-account-admin -- ./scripts/sign_layers.sh sandbox -aws-vault exec sandbox-account-admin -- ./scripts/publish_layers.sh +aws-vault exec sso-serverless-sandbox-account-admin -- ./scripts/sign_layers.sh sandbox +aws-vault exec sso-serverless-sandbox-account-admin -- ./scripts/publish_layers.sh # Automatically create PR against github.com/DataDog/documentation # If you'd like to test, please uncomment the below line diff --git a/scripts/pypi.sh b/scripts/pypi.sh index 9d8592c0e..6abe685fc 100755 --- a/scripts/pypi.sh +++ b/scripts/pypi.sh @@ -14,6 +14,9 @@ if [ -d "dist" ]; then rm -rf dist; fi -# Publish to pypi -poetry publish --build +echo "Please enter the PyPI token (password) for datadog-lambda-python" +echo "This can be found in 1password under the shared-serverless vault" +read -p "Token name: " TOKEN +# Publish to pypi +poetry publish --build --username __token__ --password $TOKEN diff --git a/scripts/run_integration_tests.sh b/scripts/run_integration_tests.sh index 332089039..f6e4f537c 100755 --- a/scripts/run_integration_tests.sh +++ b/scripts/run_integration_tests.sh @@ -2,16 +2,15 @@ # Usage - run commands from repo root: # To check if new changes to the layer cause changes to any snapshots: -# BUILD_LAYERS=true DD_API_KEY=XXXX aws-vault exec sandbox-account-admin -- ./scripts/run_integration_tests +# BUILD_LAYERS=true DD_API_KEY=XXXX aws-vault exec sso-serverless-sandbox-account-admin -- ./scripts/run_integration_tests.sh # To regenerate snapshots: -# UPDATE_SNAPSHOTS=true DD_API_KEY=XXXX aws-vault exec sandbox-account-admin -- ./scripts/run_integration_tests +# UPDATE_SNAPSHOTS=true DD_API_KEY=XXXX aws-vault exec sso-serverless-sandbox-account-admin -- ./scripts/run_integration_tests.sh 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") -RUNTIMES=("python36" "python37" "python38" "python39") LOGS_WAIT_SECONDS=20 @@ -28,12 +27,14 @@ mismatch_found=false # [0]: serverless runtime name # [1]: python version # [2]: random 8-character ID to avoid collisions with other runs -python36=("python3.6" "3.6" $(xxd -l 4 -c 4 -p < /dev/random)) -python37=("python3.7" "3.7" $(xxd -l 4 -c 4 -p < /dev/random)) python38=("python3.8" "3.8" $(xxd -l 4 -c 4 -p < /dev/random)) python39=("python3.9" "3.9" $(xxd -l 4 -c 4 -p < /dev/random)) +python310=("python3.10" "3.10" $(xxd -l 4 -c 4 -p < /dev/random)) +python311=("python3.11" "3.11" $(xxd -l 4 -c 4 -p < /dev/random)) +python312=("python3.12" "3.12" $(xxd -l 4 -c 4 -p < /dev/random)) +python313=("python3.13" "3.13" $(xxd -l 4 -c 4 -p < /dev/random)) -PARAMETERS_SETS=("python36" "python37" "python38" "python39") +PARAMETERS_SETS=("python38" "python39" "python310" "python311" "python312" "python313") if [ -z "$RUNTIME_PARAM" ]; then echo "Python version not specified, running for all python versions." @@ -56,17 +57,32 @@ if [ -z "$DD_API_KEY" ]; then exit 1 fi +if [ -z "$ARCH" ]; then + echo "No ARCH env var set, exiting" + exit 1 +fi + if [ -n "$UPDATE_SNAPSHOTS" ]; then echo "Overwriting snapshots in this execution" fi if [ -n "$BUILD_LAYERS" ]; then echo "Building layers that will be deployed with our test functions" - PYTHON_VERSION=${!BUILD_LAYER_VERSION} source $scripts_dir/build_layers.sh + if [ -n "$BUILD_LAYER_VERSION" ]; then + PYTHON_VERSION=${!BUILD_LAYER_VERSION} source $scripts_dir/build_layers.sh + else + source $scripts_dir/build_layers.sh + fi else echo "Not building layers, ensure they've already been built or re-run with 'BUILD_LAYERS=true DD_API_KEY=XXXX ./scripts/run_integration_tests.sh'" fi +SERVERLESS_FRAMEWORK_ARCH="" +if [ "$ARCH" = "amd64" ]; then + SERVERLESS_FRAMEWORK_ARCH="x86_64" +else + SERVERLESS_FRAMEWORK_ARCH="arm64" +fi cd $integration_tests_dir input_event_files=$(ls ./input_events) @@ -80,17 +96,13 @@ function remove_stack() { python_version=$parameters_set[1] run_id=$parameters_set[2] echo "Removing stack for stage : ${!run_id}" - PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \ + PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} SLS_ARCH=${SERVERLESS_FRAMEWORK_ARCH} \ serverless remove --stage ${!run_id} done } - - trap remove_stack EXIT - for parameters_set in "${PARAMETERS_SETS[@]}"; do - serverless_runtime=$parameters_set[0] python_version=$parameters_set[1] run_id=$parameters_set[2] @@ -98,22 +110,21 @@ for parameters_set in "${PARAMETERS_SETS[@]}"; do echo "Deploying functions for runtime : $parameters_set, serverless runtime : ${!serverless_runtime}, \ python version : ${!python_version} and run id : ${!run_id}" - PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \ + PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} ARCH=${ARCH} SLS_ARCH=${SERVERLESS_FRAMEWORK_ARCH} \ serverless deploy --stage ${!run_id} echo "Invoking functions for runtime $parameters_set" set +e # Don't exit this script if an invocation fails or there's a diff for handler_name in "${LAMBDA_HANDLERS[@]}"; do - function_name="${handler_name}_python" echo "$function_name" # Invoke function once for each input event for input_event_file in "${input_event_files[@]}"; do # Get event name without trailing ".json" so we can build the snapshot file name input_event_name=$(echo "$input_event_file" | sed "s/.json//") - snapshot_path="./snapshots/return_values/${handler_name}_${parameters_set}_${input_event_name}.json" + snapshot_path="./snapshots/return_values/${handler_name}_${input_event_name}.json" - return_value=$(PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \ + return_value=$(PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} SLS_ARCH=${SERVERLESS_FRAMEWORK_ARCH} \ serverless invoke --stage ${!run_id} -f "$function_name" --path "./input_events/$input_event_file") if [ ! -f $snapshot_path ]; then @@ -155,7 +166,7 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do # Fetch logs with serverless cli, retrying to avoid AWS account-wide rate limit error retry_counter=0 while [ $retry_counter -lt 10 ]; do - raw_logs=$(PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \ + raw_logs=$(PYTHON_VERSION=${!python_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} ARCH=${ARCH} SLS_ARCH=${SERVERLESS_FRAMEWORK_ARCH} \ serverless logs --stage ${!run_id} -f $function_name --startTime $script_utc_start_time) fetch_logs_exit_code=$? if [ $fetch_logs_exit_code -eq 1 ]; then @@ -178,6 +189,7 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do # Replace invocation-specific data like timestamps and IDs with XXXX to normalize logs across executions logs=$( echo "$raw_logs" | + node parse-json.js | # Filter serverless cli errors sed '/Serverless: Recoverable error occurred/d' | # Remove RequestsDependencyWarning from botocore/vendored/requests/__init__.py @@ -185,7 +197,8 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do # Remove blank lines sed '/^$/d' | # Normalize Lambda runtime REPORT logs - sed -E 's/(RequestId|TraceId|SegmentId|Duration|Memory Used|"e"): [a-z0-9\.\-]+/\1: XXXX/g' | + sed -E 's/(RequestId|TraceId|SegmentId|Duration|init|Memory Used|"e"): [a-z0-9\.\-]+/\1: XXXX/g' | + sed -E 's/(python:3.[0-9]+\.v)[0-9]+/\1X/g' | # Normalize HTTP headers sed -E "s/(x-datadog-parent-id:|x-datadog-trace-id:|Content-Length:)[0-9]+/\1XXXX/g" | # Remove Account ID @@ -193,43 +206,74 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do # Normalize timestamps in datapoints POSTed to DD sed -E 's/"points": \[\[[0-9\.]+,/"points": \[\[XXXX,/g' | # Strip API key from logged requests - sed -E "s/(api_key=|'api_key': ')[a-z0-9\.\-]+/\1XXXX/g" | + sed -E "s/(api_key=|'api_key': '|DD-API-KEY:)[a-z0-9\.\-]+/\1XXXX/g" | # Normalize package version so that these snapshots aren't broken on version bumps sed -E "s/(dd_lambda_layer:datadog-python[0-9]+_)[0-9]+\.[0-9]+\.[0-9]+/\1X\.X\.X/g" | - sed -E "s/(datadog_lambda:v)([0-9]+\.[0-9]+\.[0-9])/\1XX/g" | + sed -E "s/(datadog_lambda:v)([0-9]+\.[0-9]+\.[0-9]+)/\1XX/g" | + sed -E "s/(datadogpy\/)([0-9]+\.[0-9]+\.[0-9]+)/\1XX/g" | sed -E "s/(python )([0-9]\.[0-9]+\.[0-9]+)/\1XX/g" | + # Remove .devN versioning from logs + sed -E "s/\.dev[0-9]+//g" | # Strip out run ID (from function name, resource, etc.) sed -E "s/${!run_id}/XXXX/g" | # Normalize python-requests version sed -E "s/(User-Agent:python-requests\/)[0-9]+\.[0-9]+\.[0-9]+/\1X\.X\.X/g" | + sed -E "s/(\"http.useragent\"\: \"python-requests\/)[0-9]+\.[0-9]+\.[0-9]+/\1X\.X\.X/g" | # Strip out trace/span/parent/timestamps sed -E "s/(\"trace_id\"\: \")[A-Z0-9\.\-]+/\1XXXX/g" | sed -E "s/(\"span_id\"\: \")[A-Z0-9\.\-]+/\1XXXX/g" | sed -E "s/(\"parent_id\"\: \")[A-Z0-9\.\-]+/\1XXXX/g" | sed -E "s/(\"request_id\"\: \")[a-z0-9\.\-]+/\1XXXX/g" | - sed -E "s/(\"duration\"\: )[0-9\.\-]+/\1XXXX/g" | - sed -E "s/(\"start\"\: )[0-9\.\-]+/\1XXXX/g" | - sed -E "s/(\"system\.pid\"\: )[0-9\.\-]+/\1XXXX/g" | + sed -E "s/(\"http.source_ip\"\: \")[a-z0-9\.\-]+/\1XXXX/g" | + sed -E "s/(\"http.user_agent\"\: \")[a-z0-9\.\-]+/\1XXXX/g" | + sed -E "s/(\"function_trigger.event_source_arn\"\: \")[A-Za-z0-9\/\.\:\-]+/\1XXXX/g" | + sed -E "s/(\"duration\"\: )[0-9\.\-]+/\1\"XXXX\"/g" | + sed -E "s/(\"start\"\: )[0-9\.\-]+/\1\"XXXX\"/g" | + sed -E "s/(\"system\.pid\"\: )[0-9\.\-]+/\1\"XXXX\"/g" | + sed -E "s/(\"process_id\"\: )[0-9\.\-]+/\1XXXX/g" | sed -E "s/(\"runtime-id\"\: \")[a-z0-9\.\-]+/\1XXXX/g" | - sed -E "s/(\"datadog_lambda\"\: \")([0-9]+\.[0-9]+\.[0-9])/\1X.X.X/g" | - sed -E "s/(\"dd_trace\"\: \")([0-9]+\.[0-9]+\.[0-9])/\1X.X.X/g" + sed -E "s/([a-zA-Z0-9]+)(\.execute-api\.[a-z0-9\-]+\.amazonaws\.com)/XXXX\2/g" | + sed -E "s/(\"apiid\"\: \")[a-z0-9\.\-]+/\1XXXX/g" | + sed -E "s/(\"apiname\"\: \")[a-z0-9\.\-]+/\1XXXX/g" | + sed -E "s/(\"function_trigger.event_source_arn\"\: \")[a-z0-9\.\-\:]+/\1XXXX/g" | + sed -E "s/(\"event_id\"\: \")[a-zA-Z0-9\:\-]+/\1XXXX/g" | + sed -E "s/(\"message_id\"\: \")[a-zA-Z0-9\:\-]+/\1XXXX/g" | + sed -E "s/(\"request_id\"\:\ \")[a-zA-Z0-9\-\=]+/\1XXXX/g" | + sed -E "s/(\"connection_id\"\:\ \")[a-zA-Z0-9\-]+/\1XXXX/g" | + sed -E "s/(\"shardId\-)([0-9]+)\:([a-zA-Z0-9]+)[a-zA-Z0-9]/\1XXXX:XXXX/g" | + sed -E "s/(\"shardId\-)[0-9a-zA-Z]+/\1XXXX/g" | + sed -E "s/(\"datadog_lambda\"\: \")([0-9]+\.[0-9]+\.[0-9]+)/\1X.X.X/g" | + sed -E "s/(\"partition_key\"\:\ \")[a-zA-Z0-9\-]+/\1XXXX/g" | + sed -E "s/(\"object_etag\"\:\ \")[a-zA-Z0-9\-]+/\1XXXX/g" | + sed -E "s/(\"dd_trace\"\: \")([0-9]+\.[0-9]+\.[0-9]+)/\1X.X.X/g" | + sed -E "s/(traceparent\:)([A-Za-z0-9\-]+)/\1XXX/g" | + sed -E "s/(tracestate\:)([A-Za-z0-9\-\=\:\;].+)/\1XXX/g" | + sed -E "s/(\"_dd.p.tid\"\: \")[a-z0-9\.\-]+/\1XXXX/g" | + sed -E "s/(_dd.p.tid=)[a-z0-9\.\-]+/\1XXXX/g" | + sed -E 's/arch (aarch64|x86_64)/arch XXXX/g' | + # Parse out account ID in ARN + sed -E "s/([a-zA-Z0-9]+):([a-zA-Z0-9]+):([a-zA-Z0-9]+):([a-zA-Z0-9\-]+):([a-zA-Z0-9\-\:]+)/\1:\2:\3:\4:XXXX:\4/g" | + sed -E "/init complete at epoch/d" | + sed -E "/main started at epoch/d" ) if [ ! -f $function_snapshot_path ]; then # If no snapshot file exists yet, we create one echo "Writing logs to $function_snapshot_path because no snapshot exists yet" echo "$logs" >$function_snapshot_path - elif [ -n "$UPDATE_SNAPSHOTS" ]; then - # If $UPDATE_SNAPSHOTS is set to true write the new logs over the current snapshot - echo "Overwriting log snapshot for $function_snapshot_path" - echo "$logs" >$function_snapshot_path else # Compare new logs to snapshots - diff_output=$(echo "$logs" | diff - $function_snapshot_path) + diff_output=$(echo "$logs" | sort | diff -w - <(sort $function_snapshot_path)) if [ $? -eq 1 ]; then - echo "Failed: Mismatch found between new $function_name logs (first) and snapshot (second):" - echo "$diff_output" - mismatch_found=true + if [ -n "$UPDATE_SNAPSHOTS" ]; then + # If $UPDATE_SNAPSHOTS is set to true write the new logs over the current snapshot + echo "Overwriting log snapshot for $function_snapshot_path" + echo "$logs" >$function_snapshot_path + else + echo "Failed: Mismatch found between new $function_name logs (first) and snapshot (second):" + echo "$diff_output" + mismatch_found=true + fi else echo "Ok: New logs for $function_name match snapshot" fi @@ -241,7 +285,7 @@ set -e if [ "$mismatch_found" = true ]; then echo "FAILURE: A mismatch between new data and a snapshot was found and printed above." echo "If the change is expected, generate new snapshots by running 'UPDATE_SNAPSHOTS=true DD_API_KEY=XXXX ./scripts/run_integration_tests.sh'" - echo "Make sure https://httpstat.us/400/ is UP for `http_error` test case" + echo "Make sure https://httpstat.us/400/ is UP for 'http_error' test case" exit 1 fi diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh index ca4864c81..26f4e2156 100755 --- a/scripts/run_tests.sh +++ b/scripts/run_tests.sh @@ -8,7 +8,7 @@ # Run unit tests in Docker set -e -PYTHON_VERSIONS=("3.6" "3.7" "3.8" "3.9") +PYTHON_VERSIONS=("3.8" "3.9" "3.10" "3.11" "3.12" "3.13") for python_version in "${PYTHON_VERSIONS[@]}" do @@ -16,12 +16,10 @@ do docker build -t datadog-lambda-python-test:$python_version \ -f tests/Dockerfile . \ --build-arg python_version=$python_version - docker run -v `pwd`:/datadog-lambda-python \ - -w /datadog-lambda-python \ + docker run -w /test \ datadog-lambda-python-test:$python_version \ - nose2 -v - docker run -v `pwd`:/datadog-lambda-python \ - -w /datadog-lambda-python \ + pytest -vv + docker run -w /test \ datadog-lambda-python-test:$python_version \ flake8 datadog_lambda/ done diff --git a/scripts/sign_layers.sh b/scripts/sign_layers.sh index 679f3f27e..eb40062f0 100755 --- a/scripts/sign_layers.sh +++ b/scripts/sign_layers.sh @@ -9,12 +9,18 @@ set -e LAYER_DIR=".layers" LAYER_FILES=( - "datadog_lambda_py-amd64-3.6.zip" - "datadog_lambda_py-amd64-3.7.zip" "datadog_lambda_py-amd64-3.8.zip" "datadog_lambda_py-arm64-3.8.zip" "datadog_lambda_py-amd64-3.9.zip" "datadog_lambda_py-arm64-3.9.zip" + "datadog_lambda_py-amd64-3.10.zip" + "datadog_lambda_py-arm64-3.10.zip" + "datadog_lambda_py-amd64-3.11.zip" + "datadog_lambda_py-arm64-3.11.zip" + "datadog_lambda_py-amd64-3.12.zip" + "datadog_lambda_py-arm64-3.12.zip" + "datadog_lambda_py-amd64-3.13.zip" + "datadog_lambda_py-arm64-3.13.zip" ) SIGNING_PROFILE_NAME="DatadogLambdaSigningProfile" @@ -30,16 +36,28 @@ if [[ ! "${VALID_ACCOUNTS[@]}" =~ $1 ]]; then fi if [ "$1" = "sandbox" ]; then REGION="sa-east-1" - S3_BUCKET_NAME="dd-lambda-signing-bucket-sandbox" + S3_BUCKET_NAME="dd-lambda-signing-bucket-serverless-sandbox" fi if [ "$1" = "prod" ]; then REGION="us-east-1" S3_BUCKET_NAME="dd-lambda-signing-bucket" fi +if [ -z "$LAYER_FILE" ]; then + echo "Layer file not specified, running for all layer files." +else + echo "Layer file is specified: $LAYER_FILE" + if (printf '%s\n' "${LAYER_FILES[@]}" | grep -xq $LAYER_FILE); then + LAYER_FILES=($LAYER_FILE) + else + echo "Unsupported layer found, valid options are : ${LAYER_FILES[@]}" + exit 1 + fi +fi + for LAYER_FILE in "${LAYER_FILES[@]}" do - echo + echo echo "${LAYER_FILE}" echo "-------------------------" @@ -69,7 +87,7 @@ do do sleep 3 SECONDS_WAITED_SO_FAR=$((SECONDS_WAITED_SO_FAR + 3)) - + SIGNING_JOB_DESCRIPTION=$(aws signer describe-signing-job \ --job-id $SIGNING_JOB_ID \ --region $REGION\ diff --git a/tests/Dockerfile b/tests/Dockerfile index 86bafa0b7..585c0fbe0 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -1,13 +1,19 @@ ARG python_version -FROM python:$python_version +FROM public.ecr.aws/docker/library/python:$python_version ENV PYTHONDONTWRITEBYTECODE True +# Add Rust compiler which is needed to build dd-trace-py from source +RUN curl https://sh.rustup.rs -sSf | \ + sh -s -- --default-toolchain stable -y +ENV PATH=/root/.cargo/bin:$PATH + RUN mkdir -p /test/datadog_lambda WORKDIR /test # Copy minimal subset of files to make pip install succeed and be cached (next docker builds will be way faster) -COPY setup.py . +COPY pyproject.toml . +COPY poetry.lock . COPY README.md . COPY datadog_lambda/__init__.py datadog_lambda/__init__.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..338698025 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,8 @@ +import pytest + +from datadog_lambda.config import config + + +@pytest.fixture(autouse=True) +def reset_config(): + config._reset() diff --git a/tests/event_samples/api-gateway-no-apiid.json b/tests/event_samples/api-gateway-no-apiid.json new file mode 100644 index 000000000..0b8f91f19 --- /dev/null +++ b/tests/event_samples/api-gateway-no-apiid.json @@ -0,0 +1,126 @@ +{ + "body": "eyJ0ZXN0IjoiYm9keSJ9", + "resource": "/{proxy+}", + "path": "/path/to/resource", + "httpMethod": "POST", + "isBase64Encoded": true, + "queryStringParameters": { + "foo": "bar" + }, + "multiValueQueryStringParameters": { + "foo": [ + "bar" + ] + }, + "pathParameters": { + "proxy": "/path/to/resource" + }, + "stageVariables": { + "baz": "qux" + }, + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Encoding": "gzip, deflate, sdch", + "Accept-Language": "en-US,en;q=0.8", + "Cache-Control": "max-age=0", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https", + "X-Datadog-Trace-Id": "12345", + "X-Datadog-Parent-Id": "67890", + "x-datadog-sampling-priority": "2" + }, + "multiValueHeaders": { + "Accept": [ + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" + ], + "Accept-Encoding": [ + "gzip, deflate, sdch" + ], + "Accept-Language": [ + "en-US,en;q=0.8" + ], + "Cache-Control": [ + "max-age=0" + ], + "CloudFront-Forwarded-Proto": [ + "https" + ], + "CloudFront-Is-Desktop-Viewer": [ + "true" + ], + "CloudFront-Is-Mobile-Viewer": [ + "false" + ], + "CloudFront-Is-SmartTV-Viewer": [ + "false" + ], + "CloudFront-Is-Tablet-Viewer": [ + "false" + ], + "CloudFront-Viewer-Country": [ + "US" + ], + "Host": [ + "0123456789.execute-api.us-east-1.amazonaws.com" + ], + "Upgrade-Insecure-Requests": [ + "1" + ], + "User-Agent": [ + "Custom User Agent String" + ], + "Via": [ + "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)" + ], + "X-Amz-Cf-Id": [ + "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==" + ], + "X-Forwarded-For": [ + "127.0.0.1, 127.0.0.2" + ], + "X-Forwarded-Port": [ + "443" + ], + "X-Forwarded-Proto": [ + "https" + ] + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "123456", + "stage": "prod", + "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", + "requestTime": "09/Apr/2015:12:34:56 +0000", + "requestTimeEpoch": 1428582896000, + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "accessKey": null, + "sourceIp": "127.0.0.1", + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "Custom User Agent String", + "user": null + }, + "domainName": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + "path": "/prod/path/to/resource", + "resourcePath": "/{proxy+}", + "httpMethod": "POST", + "protocol": "HTTP/1.1" + } +} diff --git a/tests/event_samples/api-gateway-non-proxy-async.json b/tests/event_samples/api-gateway-non-proxy-async.json new file mode 100644 index 000000000..09d388d22 --- /dev/null +++ b/tests/event_samples/api-gateway-non-proxy-async.json @@ -0,0 +1,109 @@ +{ + "resource": "/http/get", + "path": "/http/get", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com", + "User-Agent": "curl/7.64.1", + "Via": "2.0 a1882a601559755135741e91a9f86c28.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "dHMNSBrMT0Xjg3rtMrI0Ie9BDg3D_OIPoj7m0mTuIOpTujrU0Ob8_A==", + "X-Amzn-Trace-Id": "Root=1-613a4da3-5012576973e2e5670d4c549a", + "X-Forwarded-For": "38.122.226.210, 70.132.52.143", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https", + "X-Amz-Invocation-Type": "Event", + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" + }, + "multiValueHeaders": { + "Accept": [ + "*/*" + ], + "CloudFront-Forwarded-Proto": [ + "https" + ], + "CloudFront-Is-Desktop-Viewer": [ + "true" + ], + "CloudFront-Is-Mobile-Viewer": [ + "false" + ], + "CloudFront-Is-SmartTV-Viewer": [ + "false" + ], + "CloudFront-Is-Tablet-Viewer": [ + "false" + ], + "CloudFront-Viewer-Country": [ + "US" + ], + "Host": [ + "lgxbo6a518.execute-api.eu-west-1.amazonaws.com" + ], + "User-Agent": [ + "curl/7.64.1" + ], + "Via": [ + "2.0 a1882a601559755135741e91a9f86c28.cloudfront.net (CloudFront)" + ], + "X-Amz-Cf-Id": [ + "dHMNSBrMT0Xjg3rtMrI0Ie9BDg3D_OIPoj7m0mTuIOpTujrU0Ob8_A==" + ], + "X-Amzn-Trace-Id": [ + "Root=1-613a4da3-5012576973e2e5670d4c549a" + ], + "X-Forwarded-For": [ + "38.122.226.210, 70.132.52.143" + ], + "X-Forwarded-Port": [ + "443" + ], + "X-Forwarded-Proto": [ + "https" + ] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": null, + "stageVariables": null, + "requestContext": { + "resourceId": "8ajqil", + "resourcePath": "/http/get", + "httpMethod": "GET", + "extendedRequestId": "FaERiG1RGjQFb6g=", + "requestTime": "09/Sep/2021:18:08:35 +0000", + "path": "/dev/http/get", + "accountId": "601427279990", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "lgxbo6a518", + "requestTimeEpoch": 1631210915251, + "requestId": "7bf3b161-f698-432c-a639-6fef8b445137", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "38.122.226.210", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "curl/7.64.1", + "user": null + }, + "domainName": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com", + "apiId": "lgxbo6a518" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway-non-proxy.json b/tests/event_samples/api-gateway-non-proxy.json new file mode 100644 index 000000000..978492b57 --- /dev/null +++ b/tests/event_samples/api-gateway-non-proxy.json @@ -0,0 +1,108 @@ +{ + "resource": "/http/get", + "path": "/http/get", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com", + "User-Agent": "curl/7.64.1", + "Via": "2.0 a1882a601559755135741e91a9f86c28.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "dHMNSBrMT0Xjg3rtMrI0Ie9BDg3D_OIPoj7m0mTuIOpTujrU0Ob8_A==", + "X-Amzn-Trace-Id": "Root=1-613a4da3-5012576973e2e5670d4c549a", + "X-Forwarded-For": "38.122.226.210, 70.132.52.143", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https", + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" + }, + "multiValueHeaders": { + "Accept": [ + "*/*" + ], + "CloudFront-Forwarded-Proto": [ + "https" + ], + "CloudFront-Is-Desktop-Viewer": [ + "true" + ], + "CloudFront-Is-Mobile-Viewer": [ + "false" + ], + "CloudFront-Is-SmartTV-Viewer": [ + "false" + ], + "CloudFront-Is-Tablet-Viewer": [ + "false" + ], + "CloudFront-Viewer-Country": [ + "US" + ], + "Host": [ + "lgxbo6a518.execute-api.eu-west-1.amazonaws.com" + ], + "User-Agent": [ + "curl/7.64.1" + ], + "Via": [ + "2.0 a1882a601559755135741e91a9f86c28.cloudfront.net (CloudFront)" + ], + "X-Amz-Cf-Id": [ + "dHMNSBrMT0Xjg3rtMrI0Ie9BDg3D_OIPoj7m0mTuIOpTujrU0Ob8_A==" + ], + "X-Amzn-Trace-Id": [ + "Root=1-613a4da3-5012576973e2e5670d4c549a" + ], + "X-Forwarded-For": [ + "38.122.226.210, 70.132.52.143" + ], + "X-Forwarded-Port": [ + "443" + ], + "X-Forwarded-Proto": [ + "https" + ] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": null, + "stageVariables": null, + "requestContext": { + "resourceId": "8ajqil", + "resourcePath": "/http/get", + "httpMethod": "GET", + "extendedRequestId": "FaERiG1RGjQFb6g=", + "requestTime": "09/Sep/2021:18:08:35 +0000", + "path": "/dev/http/get", + "accountId": "601427279990", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "lgxbo6a518", + "requestTimeEpoch": 1631210915251, + "requestId": "7bf3b161-f698-432c-a639-6fef8b445137", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "38.122.226.210", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "curl/7.64.1", + "user": null + }, + "domainName": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com", + "apiId": "lgxbo6a518" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway-v1-parametrized.json b/tests/event_samples/api-gateway-v1-parametrized.json new file mode 100644 index 000000000..65527ccb6 --- /dev/null +++ b/tests/event_samples/api-gateway-v1-parametrized.json @@ -0,0 +1,111 @@ +{ + "resource": "/user/{id}", + "path": "/user/42", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-ASN": "7922", + "CloudFront-Viewer-Country": "US", + "Host": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com", + "User-Agent": "curl/8.1.2", + "Via": "2.0 xxx.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "Tz3yUVcJkwOhQGqZgKTzrEHqAoOd8ZprYAHpg2S6BNxdd-Ym79pb6g==", + "X-Amzn-Trace-Id": "Root=1-65f49d20-7ba106216238dd0078a5db31", + "X-Forwarded-For": "76.115.124.192, 15.158.54.119", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Accept": [ + "*/*" + ], + "CloudFront-Forwarded-Proto": [ + "https" + ], + "CloudFront-Is-Desktop-Viewer": [ + "true" + ], + "CloudFront-Is-Mobile-Viewer": [ + "false" + ], + "CloudFront-Is-SmartTV-Viewer": [ + "false" + ], + "CloudFront-Is-Tablet-Viewer": [ + "false" + ], + "CloudFront-Viewer-ASN": [ + "7922" + ], + "CloudFront-Viewer-Country": [ + "US" + ], + "Host": [ + "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com" + ], + "User-Agent": [ + "curl/8.1.2" + ], + "Via": [ + "2.0 xxx.cloudfront.net (CloudFront)" + ], + "X-Amz-Cf-Id": [ + "Tz3yUVcJkwOhQGqZgKTzrEHqAoOd8ZprYAHpg2S6BNxdd-Ym79pb6g==" + ], + "X-Amzn-Trace-Id": [ + "Root=1-65f49d20-7ba106216238dd0078a5db31" + ], + "X-Forwarded-For": [ + "76.115.124.192, 15.158.54.119" + ], + "X-Forwarded-Port": [ + "443" + ], + "X-Forwarded-Proto": [ + "https" + ] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": { + "id": "42" + }, + "stageVariables": null, + "requestContext": { + "resourceId": "ojg3nk", + "resourcePath": "/user/{id}", + "httpMethod": "GET", + "extendedRequestId": "Ur19IHYDmjQEU5A=", + "requestTime": "15/Mar/2024:19:10:24 +0000", + "path": "/dev/user/42", + "accountId": "425362996713", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "mcwkra0ya4", + "requestTimeEpoch": 1710529824520, + "requestId": "e16399f7-e984-463a-9931-745ba021a27f", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "76.115.124.192", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "curl/8.1.2", + "user": null + }, + "domainName": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com", + "apiId": "mcwkra0ya4" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway-v2-parametrized.json b/tests/event_samples/api-gateway-v2-parametrized.json new file mode 100644 index 000000000..89ff72b9c --- /dev/null +++ b/tests/event_samples/api-gateway-v2-parametrized.json @@ -0,0 +1,38 @@ +{ + "version": "2.0", + "routeKey": "GET /user/{id}", + "rawPath": "/user/42", + "rawQueryString": "", + "headers": { + "accept": "*/*", + "content-length": "0", + "host": "9vj54we5ih.execute-api.sa-east-1.amazonaws.com", + "user-agent": "curl/8.1.2", + "x-amzn-trace-id": "Root=1-65f49d71-505edb3b69b8abd513cfa08b", + "x-forwarded-for": "76.115.124.192", + "x-forwarded-port": "443", + "x-forwarded-proto": "https" + }, + "requestContext": { + "accountId": "425362996713", + "apiId": "9vj54we5ih", + "domainName": "9vj54we5ih.execute-api.sa-east-1.amazonaws.com", + "domainPrefix": "9vj54we5ih", + "http": { + "method": "GET", + "path": "/user/42", + "protocol": "HTTP/1.1", + "sourceIp": "76.115.124.192", + "userAgent": "curl/8.1.2" + }, + "requestId": "Ur2JtjEfGjQEPOg=", + "routeKey": "GET /user/{id}", + "stage": "$default", + "time": "15/Mar/2024:19:11:45 +0000", + "timeEpoch": 1710529905066 + }, + "pathParameters": { + "id": "42" + }, + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway-websocket-connect.json b/tests/event_samples/api-gateway-websocket-connect.json new file mode 100644 index 000000000..c54600fae --- /dev/null +++ b/tests/event_samples/api-gateway-websocket-connect.json @@ -0,0 +1,59 @@ +{ + "headers": { + "Host": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits", + "Sec-WebSocket-Key": "cdxrfyi/jZ7kKMSRkIgBjg==", + "Sec-WebSocket-Version": "13", + "X-Amzn-Trace-Id": "Root=1-613b6b23-34ae0ce37f8d09ae19095835", + "X-Forwarded-For": "38.122.226.210", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https", + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" + }, + "multiValueHeaders": { + "Host": [ + "p62c47itsb.execute-api.eu-west-1.amazonaws.com" + ], + "Sec-WebSocket-Extensions": [ + "permessage-deflate; client_max_window_bits" + ], + "Sec-WebSocket-Key": [ + "cdxrfyi/jZ7kKMSRkIgBjg==" + ], + "Sec-WebSocket-Version": [ + "13" + ], + "X-Amzn-Trace-Id": [ + "Root=1-613b6b23-34ae0ce37f8d09ae19095835" + ], + "X-Forwarded-For": [ + "38.122.226.210" + ], + "X-Forwarded-Port": [ + "443" + ], + "X-Forwarded-Proto": [ + "https" + ] + }, + "requestContext": { + "routeKey": "$connect", + "eventType": "CONNECT", + "extendedRequestId": "Fc2tgH1RmjQFnOg=", + "requestTime": "10/Sep/2021:14:26:43 +0000", + "messageDirection": "IN", + "stage": "dev", + "connectedAt": 1631284003070, + "requestTimeEpoch": 1631284003071, + "identity": { + "sourceIp": "38.122.226.210" + }, + "requestId": "Fc2tgH1RmjQFnOg=", + "domainName": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "connectionId": "Fc2tgfl3mjQCJfA=", + "apiId": "p62c47itsb" + }, + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway-websocket-default.json b/tests/event_samples/api-gateway-websocket-default.json new file mode 100644 index 000000000..8ec748ea4 --- /dev/null +++ b/tests/event_samples/api-gateway-websocket-default.json @@ -0,0 +1,45 @@ +{ + "headers": { + "Host": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "x-api-key": "", + "X-Forwarded-For": "", + "x-restapi": "", + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" + }, + "multiValueHeaders": { + "Host": [ + "p62c47itsb.execute-api.eu-west-1.amazonaws.com" + ], + "x-api-key": [ + "" + ], + "X-Forwarded-For": [ + "" + ], + "x-restapi": [ + "" + ] + }, + "requestContext": { + "routeKey": "$default", + "messageId": "Fc5S3coemjQCJlg=", + "eventType": "MESSAGE", + "extendedRequestId": "Fc5S3EvdGjQFtsQ=", + "requestTime": "10/Sep/2021:14:44:21 +0000", + "messageDirection": "IN", + "stage": "dev", + "connectedAt": 1631285060967, + "requestTimeEpoch": 1631285061365, + "identity": { + "sourceIp": "38.122.226.210" + }, + "requestId": "Fc5S3EvdGjQFtsQ=", + "domainName": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "connectionId": "Fc5SzcoYGjQCJlg=", + "apiId": "p62c47itsb" + }, + "body": "\"What's good in the hood?\"", + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway-websocket-disconnect.json b/tests/event_samples/api-gateway-websocket-disconnect.json new file mode 100644 index 000000000..416aec13d --- /dev/null +++ b/tests/event_samples/api-gateway-websocket-disconnect.json @@ -0,0 +1,45 @@ +{ + "headers": { + "Host": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "x-api-key": "", + "X-Forwarded-For": "", + "x-restapi": "", + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" + }, + "multiValueHeaders": { + "Host": [ + "p62c47itsb.execute-api.eu-west-1.amazonaws.com" + ], + "x-api-key": [ + "" + ], + "X-Forwarded-For": [ + "" + ], + "x-restapi": [ + "" + ] + }, + "requestContext": { + "routeKey": "$disconnect", + "disconnectStatusCode": 1000, + "eventType": "DISCONNECT", + "extendedRequestId": "Fc2ydE4LmjQFhdg=", + "requestTime": "10/Sep/2021:14:27:14 +0000", + "messageDirection": "IN", + "disconnectReason": "", + "stage": "dev", + "connectedAt": 1631284003070, + "requestTimeEpoch": 1631284034737, + "identity": { + "sourceIp": "38.122.226.210" + }, + "requestId": "Fc2ydE4LmjQFhdg=", + "domainName": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "connectionId": "Fc2tgfl3mjQCJfA=", + "apiId": "p62c47itsb" + }, + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway.json b/tests/event_samples/api-gateway.json index 5e13b6e3d..b2c7f96eb 100644 --- a/tests/event_samples/api-gateway.json +++ b/tests/event_samples/api-gateway.json @@ -36,7 +36,10 @@ "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", "X-Forwarded-For": "127.0.0.1, 127.0.0.2", "X-Forwarded-Port": "443", - "X-Forwarded-Proto": "https" + "X-Forwarded-Proto": "https", + "X-Datadog-Trace-Id": "12345", + "X-Datadog-Parent-Id": "67890", + "x-datadog-sampling-priority": "2" }, "multiValueHeaders": { "Accept": [ diff --git a/tests/event_samples/application-load-balancer-multivalue-headers.json b/tests/event_samples/application-load-balancer-multivalue-headers.json new file mode 100644 index 000000000..a35ca5023 --- /dev/null +++ b/tests/event_samples/application-load-balancer-multivalue-headers.json @@ -0,0 +1,31 @@ +{ + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-xyz/123abc" + } + }, + "httpMethod": "GET", + "path": "/lambda", + "multiValueQueryStringParameters": { + "query": "1234ABCD" + }, + "multiValueHeaders": { + "accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"], + "accept-encoding": ["gzip"], + "accept-language": ["en-US,en;q=0.9"], + "connection": ["keep-alive"], + "host": ["lambda-alb-123578498.us-east-2.elb.amazonaws.com"], + "upgrade-insecure-requests": ["1"], + "user-agent": ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"], + "x-amzn-trace-id": ["Root=1-5c536348-3d683b8b04734faae651f476"], + "x-forwarded-for": ["72.12.164.125"], + "x-forwarded-port": ["80"], + "x-forwarded-proto": ["http"], + "x-imforwards": ["20"], + "x-datadog-trace-id": ["12345"], + "x-datadog-parent-id": ["67890"], + "x-datadog-sampling-priority": ["2"] + }, + "body": "", + "isBase64Encoded": false +} diff --git a/tests/event_samples/application-load-balancer.json b/tests/event_samples/application-load-balancer.json index fa8ed48a8..bf1779520 100644 --- a/tests/event_samples/application-load-balancer.json +++ b/tests/event_samples/application-load-balancer.json @@ -21,7 +21,10 @@ "x-forwarded-for": "72.12.164.125", "x-forwarded-port": "80", "x-forwarded-proto": "http", - "x-imforwards": "20" + "x-imforwards": "20", + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" }, "body": "", "isBase64Encoded": false diff --git a/tests/event_samples/authorizer-request-api-gateway-v1-cached.json b/tests/event_samples/authorizer-request-api-gateway-v1-cached.json new file mode 100644 index 000000000..6bcfe19b5 --- /dev/null +++ b/tests/event_samples/authorizer-request-api-gateway-v1-cached.json @@ -0,0 +1,93 @@ +{ + "resource": "/hello", + "path": "/hello", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Authorization": "secretT0k3n", + "authorizationToken": "secretT0k3n", + "Cache-Control": "no-cache", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-ASN": "12271", + "CloudFront-Viewer-Country": "US", + "Host": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "Postman-Token": "5ddd364a-4191-4dbc-9831-09f1bf46bca8", + "User-Agent": "PostmanRuntime/7.29.2", + "Via": "1.1 x.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "ToqncSIka6Ae1pZlyxEOtyqqcns8cwL3hVxwo0ZZqMC60zTSSXW7yA==", + "X-Amzn-Trace-Id": "Root=1-63580c1d-12aa2dcf30cd2d3476a6f18f", + "X-Forwarded-For": "24.193.182.233, 15.158.35.232", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Accept": ["*/*"], + "Accept-Encoding": ["gzip, deflate, br"], + "Authorization": ["secretT0k3n"], + "authorizationToken": ["secretT0k3n"], + "Cache-Control": ["no-cache"], + "CloudFront-Forwarded-Proto": ["https"], + "CloudFront-Is-Desktop-Viewer": ["true"], + "CloudFront-Is-Mobile-Viewer": ["false"], + "CloudFront-Is-SmartTV-Viewer": ["false"], + "CloudFront-Is-Tablet-Viewer": ["false"], + "CloudFront-Viewer-ASN": ["12271"], + "CloudFront-Viewer-Country": ["US"], + "Host": ["amddr1rix9.execute-api.eu-west-1.amazonaws.com"], + "Postman-Token": ["5ddd364a-4191-4dbc-9831-09f1bf46bca8"], + "User-Agent": ["PostmanRuntime/7.29.2"], + "Via": ["1.1 x.cloudfront.net (CloudFront)"], + "X-Amz-Cf-Id": ["ToqncSIka6Ae1pZlyxEOtyqqcns8cwL3hVxwo0ZZqMC60zTSSXW7yA=="], + "X-Amzn-Trace-Id": ["Root=1-63580c1d-12aa2dcf30cd2d3476a6f18f"], + "X-Forwarded-For": ["24.193.182.233, 15.158.35.232"], + "X-Forwarded-Port": ["443"], + "X-Forwarded-Proto": ["https"] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": null, + "stageVariables": null, + "requestContext": { + "resourceId": "var16m", + "authorizer": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMzQyMDA1NDg3OTQxNzk5OTg3NyIsICJ4LWRhdGFkb2ctcGFyZW50LWlkIjogIjE1NDY2ODY0ODU4OTY3MTY5NjM2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjY3MTQ2NDg1OTAuMTA5NCwgIngtZGF0YWRvZy1hdXRob3JpemluZy1yZXF1ZXN0aWQiOiAiMjRkNjk4OTItNjcwMi00OTYxLThlNDgtMDg1NWNjNTU0MjQwIn0=", + "scope": "this is just a string", + "principalId": "foo", + "integrationLatency": 0 + }, + "resourcePath": "/hello", + "httpMethod": "GET", + "extendedRequestId": "akbUqFBZmjQFbJg=", + "requestTime": "25/Oct/2022:16:17:33 +0000", + "path": "/dev/hello", + "accountId": "425362996713", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "amddr1rix9", + "requestTimeEpoch": 1666714653636, + "requestId": "abc123", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "24.193.182.233", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "PostmanRuntime/7.29.2", + "user": null + }, + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "apiId": "amddr1rix9" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/authorizer-request-api-gateway-v1.json b/tests/event_samples/authorizer-request-api-gateway-v1.json new file mode 100644 index 000000000..d14b7aa01 --- /dev/null +++ b/tests/event_samples/authorizer-request-api-gateway-v1.json @@ -0,0 +1,93 @@ +{ + "resource": "/hello", + "path": "/hello", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Authorization": "secretT0k3n", + "authorizationToken": "secretT0k3n", + "Cache-Control": "no-cache", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-ASN": "12271", + "CloudFront-Viewer-Country": "US", + "Host": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "Postman-Token": "75a5e2b0-d8e8-4370-ad2c-7209761c3f43", + "User-Agent": "PostmanRuntime/7.29.2", + "Via": "1.1 ed4584f7c263c11cf4adf75ba3a25764.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "wbruuv68N6jFldH7oUaE9kWABzHsvPi3zzByABVGXCVsnGYOhcRjow==", + "X-Amzn-Trace-Id": "Root=1-6323de2b-0155211e49422a532809a10e", + "X-Forwarded-For": "24.193.182.233, 15.158.35.8", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Accept": ["*/*"], + "Accept-Encoding": ["gzip, deflate, br"], + "Authorization": ["secretT0k3n"], + "authorizationToken": ["secretT0k3n"], + "Cache-Control": ["no-cache"], + "CloudFront-Forwarded-Proto": ["https"], + "CloudFront-Is-Desktop-Viewer": ["true"], + "CloudFront-Is-Mobile-Viewer": ["false"], + "CloudFront-Is-SmartTV-Viewer": ["false"], + "CloudFront-Is-Tablet-Viewer": ["false"], + "CloudFront-Viewer-ASN": ["12271"], + "CloudFront-Viewer-Country": ["US"], + "Host": ["amddr1rix9.execute-api.eu-west-1.amazonaws.com"], + "Postman-Token": ["75a5e2b0-d8e8-4370-ad2c-7209761c3f43"], + "User-Agent": ["PostmanRuntime/7.29.2"], + "Via": ["1.1 ed4584f7c263c11cf4adf75ba3a25764.cloudfront.net (CloudFront)"], + "X-Amz-Cf-Id": ["wbruuv68N6jFldH7oUaE9kWABzHsvPi3zzByABVGXCVsnGYOhcRjow=="], + "X-Amzn-Trace-Id": ["Root=1-6323de2b-0155211e49422a532809a10e"], + "X-Forwarded-For": ["24.193.182.233, 15.158.35.8"], + "X-Forwarded-Port": ["443"], + "X-Forwarded-Proto": ["https"] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": null, + "stageVariables": null, + "requestContext": { + "resourceId": "0et54l", + "authorizer": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM0Nzg3MDU5OTU3OTcyMjEyMDkiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI4NDcxMjg4MjYzMzg0MjE2ODk2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjMyOTUwMjE4MjcuNTIxLCAieC1kYXRhZG9nLWF1dGhvcml6aW5nLXJlcXVlc3RpZCI6ICJhYmMxMjMifQ==", + "scope": "this is just a string", + "principalId": "foo", + "integrationLatency": 1897 + }, + "resourcePath": "/hello", + "httpMethod": "GET", + "extendedRequestId": "Yh-m5G_wGjQFftQ=", + "requestTime": "16/Sep/2022:02:23:39 +0000", + "path": "/dev/hello", + "accountId": "601427279990", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "amddr1rix9", + "requestTimeEpoch": 1663295019935, + "requestId": "abc123", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "24.193.182.233", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "PostmanRuntime/7.29.2", + "user": null + }, + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "apiId": "amddr1rix9" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/authorizer-request-api-gateway-v2-cached.json b/tests/event_samples/authorizer-request-api-gateway-v2-cached.json new file mode 100644 index 000000000..f9ac874cb --- /dev/null +++ b/tests/event_samples/authorizer-request-api-gateway-v2-cached.json @@ -0,0 +1,47 @@ +{ + "version": "2.0", + "routeKey": "GET /hello", + "rawPath": "/hello", + "rawQueryString": "", + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "authorization": "secretT0k3n", + "authorizationtoken": "secretT0k3n", + "cache-control": "no-cache", + "content-length": "0", + "host": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "postman-token": "f901530c-cc2f-475f-8634-d9156e9cd9d7", + "user-agent": "PostmanRuntime/7.29.2", + "userid": "1236", + "x-amzn-trace-id": "Root=1-63580f25-5f01511071135d5966c8c63d", + "x-forwarded-for": "24.193.182.233", + "x-forwarded-port": "443", + "x-forwarded-proto": "https" + }, + "requestContext": { + "accountId": "425362996713", + "apiId": "amddr1rix9", + "authorizer": { + "lambda": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTc4MDIxMTQ1NTc4ODI1OTY0MTYiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICIxMjg3ODYzNTg0NTE5MTY5NDQ5NCIsICJ4LWRhdGFkb2ctc2FtcGxpbmctcHJpb3JpdHkiOiAiMSIsICJ4LWRhdGFkb2ctcGFyZW50LXNwYW4tZmluaXNoLXRpbWUiOiAxNjY2NzE1NDI5Mzk1Ljc3ODgsICJ4LWRhdGFkb2ctYXV0aG9yaXppbmctcmVxdWVzdGlkIjogImFrZE4zaEdER2pRRU1Ddz0ifQ==", + "scope": "this is just a string" + } + }, + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "domainPrefix": "amddr1rix9", + "http": { + "method": "GET", + "path": "/hello", + "protocol": "HTTP/1.1", + "sourceIp": "24.193.182.233", + "userAgent": "PostmanRuntime/7.29.2" + }, + "requestId": "abc123", + "routeKey": "GET /hello", + "stage": "dev", + "time": "25/Oct/2022:16:30:29 +0000", + "timeEpoch": 1666715429349 + }, + "isBase64Encoded": false +} diff --git a/tests/event_samples/authorizer-request-api-gateway-v2.json b/tests/event_samples/authorizer-request-api-gateway-v2.json new file mode 100644 index 000000000..2984e14ec --- /dev/null +++ b/tests/event_samples/authorizer-request-api-gateway-v2.json @@ -0,0 +1,47 @@ +{ + "version": "2.0", + "routeKey": "GET /hello", + "rawPath": "/hello", + "rawQueryString": "", + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "authorization": "secretT0k3n", + "authorizationtoken": "secretT0k3n", + "cache-control": "no-cache", + "content-length": "0", + "host": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "postman-token": "5e0efdb2-d93f-4d44-8792-45404d40dae2", + "user": "12345", + "user-agent": "curl/7.64.1", + "x-amzn-trace-id": "Root=1-63321d1e-6b80ef0d2c2cf49600b9c28e", + "x-forwarded-for": "38.122.226.210", + "x-forwarded-port": "443", + "x-forwarded-proto": "https" + }, + "requestContext": { + "accountId": "601427279990", + "apiId": "amddr1rix9", + "authorizer": { + "lambda": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTQzNTY5ODM2MTk4NTI5MzMzNTQiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICIxMjY1ODYyMTA4MzUwNTQxMzgwOSIsICJ4LWRhdGFkb2ctc2FtcGxpbmctcHJpb3JpdHkiOiAiMSIsICJ4LWRhdGFkb2ctcGFyZW50LXNwYW4tZmluaXNoLXRpbWUiOiAxNjY0MjI4NjM5NTMzNzc1NDAwLCAieC1kYXRhZG9nLWF1dGhvcml6aW5nLXJlcXVlc3RpZCI6ICJhYmMxMjMifQ==", + "scope": "this is just a string" + } + }, + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "domainPrefix": "amddr1rix9", + "http": { + "method": "GET", + "path": "/hello", + "protocol": "HTTP/1.1", + "sourceIp": "38.122.226.210", + "userAgent": "curl/7.64.1" + }, + "requestId": "abc123", + "routeKey": "GET /hello", + "stage": "dev", + "time": "26/Sep/2022:21:43:58 +0000", + "timeEpoch": 1664228638084 + }, + "isBase64Encoded": false +} diff --git a/tests/event_samples/authorizer-request-api-gateway-websocket-connect.json b/tests/event_samples/authorizer-request-api-gateway-websocket-connect.json new file mode 100644 index 000000000..ab4fb1045 --- /dev/null +++ b/tests/event_samples/authorizer-request-api-gateway-websocket-connect.json @@ -0,0 +1,48 @@ +{ + "headers": { + "Auth": "secretT0k3n", + "Host": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits", + "Sec-WebSocket-Key": "j9g8xXvniFqyyA+34vQ/Lg==", + "Sec-WebSocket-Version": "13", + "X-Amzn-Trace-Id": "Root=1-63348d21-727f66307696916d50f93f1b", + "X-Forwarded-For": "38.122.226.210", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Auth": ["secretT0k3n"], + "Host": ["amddr1rix9.execute-api.eu-west-1.amazonaws.com"], + "Sec-WebSocket-Extensions": ["permessage-deflate; client_max_window_bits"], + "Sec-WebSocket-Key": ["j9g8xXvniFqyyA+34vQ/Lg=="], + "Sec-WebSocket-Version": ["13"], + "X-Amzn-Trace-Id": ["Root=1-63348d21-727f66307696916d50f93f1b"], + "X-Forwarded-For": ["38.122.226.210"], + "X-Forwarded-Port": ["443"], + "X-Forwarded-Proto": ["https"] + }, + "requestContext": { + "routeKey": "$connect", + "authorizer": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiNTM1MTA0NzQwNDgzNDcyMzE4OSIsICJ4LWRhdGFkb2ctcGFyZW50LWlkIjogIjE4MjMwNDYwNjMxMTU2MTYxODM3IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjQzODgzODY4OTAsICJ4LWRhdGFkb2ctYXV0aG9yaXppbmctcmVxdWVzdGlkIjogImFiYzEyMyJ9", + "scope": "this is just a string", + "principalId": "foo", + "integrationLatency": 1440 + }, + "eventType": "CONNECT", + "extendedRequestId": "abc123", + "requestTime": "28/Sep/2022:18:06:25 +0000", + "messageDirection": "IN", + "stage": "dev", + "connectedAt": 1664388385450, + "requestTimeEpoch": 1664388385452, + "identity": { + "sourceIp": "38.122.226.210" + }, + "requestId": "abc123", + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "connectionId": "ZLr9QeNLmjQCIZA=", + "apiId": "amddr1rix9" + }, + "isBase64Encoded": false +} diff --git a/tests/event_samples/authorizer-request-api-gateway-websocket-message.json b/tests/event_samples/authorizer-request-api-gateway-websocket-message.json new file mode 100644 index 000000000..576b1625a --- /dev/null +++ b/tests/event_samples/authorizer-request-api-gateway-websocket-message.json @@ -0,0 +1,27 @@ +{ + "requestContext": { + "routeKey": "main", + "authorizer": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTczNzQwNjkwNjUwMjU0MzQ5MjAiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI3OTE1MTg2NzUxOTE0MTc2MTA2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjQzOTAzMzM1MjYuNTA2OCwgIngtZGF0YWRvZy1hdXRob3JpemluZy1yZXF1ZXN0aWQiOiAiYWJjMzIxIn0=", + "scope": "this is just a string", + "principalId": "foo" + }, + "messageId": "ZLw3leP1GjQCI8Q=", + "eventType": "MESSAGE", + "extendedRequestId": "ZLw3lFowmjQFvSA=", + "requestTime": "28/Sep/2022:18:39:57 +0000", + "messageDirection": "IN", + "stage": "dev", + "connectedAt": 1664390332261, + "requestTimeEpoch": 1664390397117, + "identity": { + "sourceIp": "38.122.226.210" + }, + "requestId": "abc123", + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "connectionId": "ZLwtceO1mjQCI8Q=", + "apiId": "amddr1rix9" + }, + "body": "{\n \"action\":\"main\",\n \"message\":\"hi\"\n}", + "isBase64Encoded": false +} diff --git a/tests/event_samples/authorizer-token-api-gateway-v1-cached.json b/tests/event_samples/authorizer-token-api-gateway-v1-cached.json new file mode 100644 index 000000000..f7b30faad --- /dev/null +++ b/tests/event_samples/authorizer-token-api-gateway-v1-cached.json @@ -0,0 +1,93 @@ +{ + "resource": "/hello", + "path": "/hello", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Authorization": "secretT0k3n", + "authorizationToken": "secretT0k3n", + "Cache-Control": "no-cache", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-ASN": "174", + "CloudFront-Viewer-Country": "US", + "Host": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "Postman-Token": "bb30e418-d4ee-45b6-a659-89f4dbd41c84", + "User-Agent": "PostmanRuntime/7.29.2", + "Via": "1.1 x.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "iFM3jhMRNr0jJn8b4A7lgYVLUhUb6pOxFQm1YA4JDTDylUHJOOl-Jw==", + "X-Amzn-Trace-Id": "Root=1-635967a6-2b0999ba248345b32a8ff5ce", + "X-Forwarded-For": "38.122.226.210, 130.176.179.111", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Accept": ["*/*"], + "Accept-Encoding": ["gzip, deflate, br"], + "Authorization": ["secretT0k3n"], + "authorizationToken": ["secretT0k3n"], + "Cache-Control": ["no-cache"], + "CloudFront-Forwarded-Proto": ["https"], + "CloudFront-Is-Desktop-Viewer": ["true"], + "CloudFront-Is-Mobile-Viewer": ["false"], + "CloudFront-Is-SmartTV-Viewer": ["false"], + "CloudFront-Is-Tablet-Viewer": ["false"], + "CloudFront-Viewer-ASN": ["174"], + "CloudFront-Viewer-Country": ["US"], + "Host": ["amddr1rix9.execute-api.eu-west-1.amazonaws.com"], + "Postman-Token": ["bb30e418-d4ee-45b6-a659-89f4dbd41c84"], + "User-Agent": ["PostmanRuntime/7.29.2"], + "Via": ["1.1 x.cloudfront.net (CloudFront)"], + "X-Amz-Cf-Id": ["iFM3jhMRNr0jJn8b4A7lgYVLUhUb6pOxFQm1YA4JDTDylUHJOOl-Jw=="], + "X-Amzn-Trace-Id": ["Root=1-635967a6-2b0999ba248345b32a8ff5ce"], + "X-Forwarded-For": ["38.122.226.210, 130.176.179.111"], + "X-Forwarded-Port": ["443"], + "X-Forwarded-Proto": ["https"] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": null, + "stageVariables": null, + "requestContext": { + "resourceId": "mi7nzd", + "authorizer": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM3NTkyNDk3NDA5MDA1OTMyNjEiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICIxNTkzNTAyMzY1NTYxMjM0MTgxOSIsICJ4LWRhdGFkb2ctc2FtcGxpbmctcHJpb3JpdHkiOiAiMSIsICJ4LWRhdGFkb2ctcGFyZW50LXNwYW4tZmluaXNoLXRpbWUiOiAxNjY2ODAzNjE2OTMzLjIwNzh9", + "scope": "this is just a string", + "principalId": "foo", + "integrationLatency": 0 + }, + "resourcePath": "/hello", + "httpMethod": "GET", + "extendedRequestId": "an0iHGmHmjQFjLw=", + "requestTime": "26/Oct/2022:17:00:22 +0000", + "path": "/dev/hello", + "accountId": "425362996713", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "amddr1rix9", + "requestTimeEpoch": 1666803622990, + "requestId": "abc123", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "38.122.226.210", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "PostmanRuntime/7.29.2", + "user": null + }, + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "apiId": "amddr1rix9" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/authorizer-token-api-gateway-v1.json b/tests/event_samples/authorizer-token-api-gateway-v1.json new file mode 100644 index 000000000..c31da2785 --- /dev/null +++ b/tests/event_samples/authorizer-token-api-gateway-v1.json @@ -0,0 +1,93 @@ +{ + "resource": "/hello", + "path": "/hello", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Authorization": "secretT0k3n", + "authorizationToken": "secretT0k3n", + "Cache-Control": "no-cache", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-ASN": "174", + "CloudFront-Viewer-Country": "US", + "Host": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "Postman-Token": "791b2f79-1732-4877-abc1-5c538daf4642", + "User-Agent": "PostmanRuntime/7.29.2", + "Via": "1.1 d58463d219ef6ca0331e7200a6667c18.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "tqU0SVyX_dKKI0XIN4-kwzCHrROBFECLXtAKCtjKr1uRQ-uijj99sQ==", + "X-Amzn-Trace-Id": "Root=1-632b4732-3e69c6a34f21f00d7f9b5599", + "X-Forwarded-For": "38.122.226.210, 64.252.135.71", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Accept": ["*/*"], + "Accept-Encoding": ["gzip, deflate, br"], + "Authorization": ["secretT0k3n"], + "authorizationToken": ["secretT0k3n"], + "Cache-Control": ["no-cache"], + "CloudFront-Forwarded-Proto": ["https"], + "CloudFront-Is-Desktop-Viewer": ["true"], + "CloudFront-Is-Mobile-Viewer": ["false"], + "CloudFront-Is-SmartTV-Viewer": ["false"], + "CloudFront-Is-Tablet-Viewer": ["false"], + "CloudFront-Viewer-ASN": ["174"], + "CloudFront-Viewer-Country": ["US"], + "Host": ["amddr1rix9.execute-api.eu-west-1.amazonaws.com"], + "Postman-Token": ["791b2f79-1732-4877-abc1-5c538daf4642"], + "User-Agent": ["PostmanRuntime/7.29.2"], + "Via": ["1.1 d58463d219ef6ca0331e7200a6667c18.cloudfront.net (CloudFront)"], + "X-Amz-Cf-Id": ["tqU0SVyX_dKKI0XIN4-kwzCHrROBFECLXtAKCtjKr1uRQ-uijj99sQ=="], + "X-Amzn-Trace-Id": ["Root=1-632b4732-3e69c6a34f21f00d7f9b5599"], + "X-Forwarded-For": ["38.122.226.210, 64.252.135.71"], + "X-Forwarded-Port": ["443"], + "X-Forwarded-Proto": ["https"] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": null, + "stageVariables": null, + "requestContext": { + "resourceId": "elem3u", + "authorizer": { + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTc4NzQ3OTgyNjgxNDQ5MDI3MTIiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICIxNjE4NDY2NzM5OTMxNTM3MjEwMSIsICJ4LWRhdGFkb2ctc2FtcGxpbmctcHJpb3JpdHkiOiAiMSIsICJ4LWRhdGFkb2ctcGFyZW50LXNwYW4tZmluaXNoLXRpbWUiOiAxNjYzNzIxNjAyNDQwLjgyODZ9", + "scope": "this is just a string", + "principalId": "foo", + "integrationLatency": 1897 + }, + "resourcePath": "/hello", + "httpMethod": "GET", + "extendedRequestId": "Y0gP8FG9mjQFZTQ=", + "requestTime": "21/Sep/2022:17:17:38 +0000", + "path": "/dev/hello", + "accountId": "601427279990", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "amddr1rix9", + "requestTimeEpoch": 1663295019935, + "requestId": "abc123", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "38.122.226.210", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "PostmanRuntime/7.29.2", + "user": null + }, + "domainName": "amddr1rix9.execute-api.eu-west-1.amazonaws.com", + "apiId": "amddr1rix9" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/eventbridge-custom.json b/tests/event_samples/eventbridge-custom.json new file mode 100644 index 000000000..c24d21cae --- /dev/null +++ b/tests/event_samples/eventbridge-custom.json @@ -0,0 +1,18 @@ +{ + "version": "0", + "id": "fd03f394-e769-eff5-08a8-53c228933591", + "detail-type": "testdetail", + "source": "eventbridge.custom.event.sender", + "account": "601427279990", + "time": "2021-11-04T01:37:45Z", + "region": "eu-west-1", + "resources": [], + "detail": { + "foo": "bar", + "_datadog": { + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" + } + } +} diff --git a/tests/event_samples/eventbridge-sqs.json b/tests/event_samples/eventbridge-sqs.json new file mode 100644 index 000000000..606abc094 --- /dev/null +++ b/tests/event_samples/eventbridge-sqs.json @@ -0,0 +1,21 @@ +{ + "Records": [ + { + "messageId": "e995e54f-1724-41fa-82c0-8b81821f854e", + "receiptHandle": "AQEB4mIfRcyqtzn1X5Ss+ConhTejVGc+qnAcmu3/Z9ZvbNkaPcpuDLX/bzvPD/ZkAXJUXZcemGSJmd7L3snZHKMP2Ck8runZiyl4mubiLb444pZvdiNPuGRJ6a3FvgS/GQPzho/9nNMyOi66m8Viwh70v4EUCPGO4JmD3TTDAUrrcAnqU4WSObjfC/NAp9bI6wH2CEyAYEfex6Nxplbl/jBf9ZUG0I3m3vQd0Q4l4gd4jIR4oxQUglU2Tldl4Kx5fMUAhTRLAENri6HsY81avBkKd9FAuxONlsITB5uj02kOkvLlRGEcalqsKyPJ7AFaDLrOLaL3U+yReroPEJ5R5nwhLOEbeN5HROlZRXeaAwZOIN8BjqdeooYTIOrtvMEVb7a6OPLMdH1XB+ddevtKAH8K9Tm2ZjpaA7dtBGh1zFVHzBk=", + "body": "{\"version\":\"0\",\"id\":\"af718b2a-b987-e8c0-7a2b-a188fad2661a\",\"detail-type\":\"my.Detail\",\"source\":\"my.Source\",\"account\":\"425362996713\",\"time\":\"2023-08-03T22:49:03Z\",\"region\":\"us-east-1\",\"resources\":[],\"detail\":{\"text\":\"Hello, world!\",\"_datadog\":{\"x-datadog-trace-id\":\"7379586022458917877\",\"x-datadog-parent-id\":\"2644033662113726488\",\"x-datadog-sampling-priority\":\"1\",\"x-datadog-tags\":\"_dd.p.dm=-0\",\"traceparent\":\"00-000000000000000066698e63821a03f5-24b17e9b6476c018-01\",\"tracestate\":\"dd=t.dm:-0;s:1\"}}}", + "attributes": { + "ApproximateReceiveCount": "1", + "AWSTraceHeader": "Root=1-64cc2edd-112fbf1701d1355973a11d57;Parent=7d5a9776024b2d42;Sampled=0", + "SentTimestamp": "1691102943638", + "SenderId": "AIDAJXNJGGKNS7OSV23OI", + "ApproximateFirstReceiveTimestamp": "1691102943647" + }, + "messageAttributes": {}, + "md5OfBody": "93d9f0cd8886d1e000a1a0b7007bffc4", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:425362996713:eventbridge-sqs-queue", + "awsRegion": "us-east-1" + } + ] +} diff --git a/tests/event_samples/http-api.json b/tests/event_samples/http-api.json new file mode 100644 index 000000000..2968c1b5d --- /dev/null +++ b/tests/event_samples/http-api.json @@ -0,0 +1,38 @@ +{ + "version": "2.0", + "routeKey": "GET /httpapi/get", + "rawPath": "/httpapi/get", + "rawQueryString": "", + "headers": { + "accept": "*/*", + "content-length": "0", + "host": "x02yirxc7a.execute-api.eu-west-1.amazonaws.com", + "user-agent": "curl/7.64.1", + "x-amzn-trace-id": "Root=1-613a52fb-4c43cfc95e0241c1471bfa05", + "x-forwarded-for": "38.122.226.210", + "x-forwarded-port": "443", + "x-forwarded-proto": "https", + "x-datadog-trace-id": "12345", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "2" + }, + "requestContext": { + "accountId": "601427279990", + "apiId": "x02yirxc7a", + "domainName": "x02yirxc7a.execute-api.eu-west-1.amazonaws.com", + "domainPrefix": "x02yirxc7a", + "http": { + "method": "GET", + "path": "/httpapi/get", + "protocol": "HTTP/1.1", + "sourceIp": "38.122.226.210", + "userAgent": "curl/7.64.1" + }, + "requestId": "FaHnXjKCGjQEJ7A=", + "routeKey": "GET /httpapi/get", + "stage": "$default", + "time": "09/Sep/2021:18:31:23 +0000", + "timeEpoch": 1631212283738 + }, + "isBase64Encoded": false +} diff --git a/tests/event_samples/kinesis-batch.json b/tests/event_samples/kinesis-batch.json new file mode 100644 index 000000000..9c645a464 --- /dev/null +++ b/tests/event_samples/kinesis-batch.json @@ -0,0 +1,36 @@ +{ + "Records": [ + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "partitionkey", + "sequenceNumber": "49624230154685806402418173680709770494154422022871973922", + "data": "eyJmb28iOiAiYmFyIiwgIl9kYXRhZG9nIjogeyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiNDk0ODM3NzMxNjM1NzI5MTQyMSIsICJ4LWRhdGFkb2ctcGFyZW50LWlkIjogIjI4NzYyNTMzODAwMTg2ODEwMjYiLCAieC1kYXRhZG9nLXNhbXBsaW5nLXByaW9yaXR5IjogIjEifX0=", + "approximateArrivalTimestamp": 1643638425.163 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000002:49624230154685806402418173680709770494154422022871973922", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::601427279990:role/inferred-spans-python-dev-eu-west-1-lambdaRole", + "awsRegion": "eu-west-1", + "eventSourceARN": "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream" + }, + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "partitionkey", + "sequenceNumber": "49624230154685806402418173680709770494154422022871973922", + "data": "eyJmb28iOiAiYmFyIiwgIl9kYXRhZG9nIjogeyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiNDk0ODM3NzMxNjM1NzI5MTQyMSIsICJ4LWRhdGFkb2ctcGFyZW50LWlkIjogIjI4NzYyNTMzODAwMTg2ODEwMjYiLCAieC1kYXRhZG9nLXNhbXBsaW5nLXByaW9yaXR5IjogIjEifX0=", + "approximateArrivalTimestamp": 1643638425.163 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000002:49624230154685806402418173680709770494154422022871973922", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::601427279990:role/inferred-spans-python-dev-eu-west-1-lambdaRole", + "awsRegion": "eu-west-1", + "eventSourceARN": "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream" + } + ] +} diff --git a/tests/event_samples/kinesis.json b/tests/event_samples/kinesis.json index 2d7f8887a..a320fc44f 100644 --- a/tests/event_samples/kinesis.json +++ b/tests/event_samples/kinesis.json @@ -2,19 +2,19 @@ "Records": [ { "kinesis": { - "partitionKey": "partitionKey-03", "kinesisSchemaVersion": "1.0", - "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=", - "sequenceNumber": "49545115243490985018280067714973144582180062593244200961", - "approximateArrivalTimestamp": 1428537600 + "partitionKey": "partitionkey", + "sequenceNumber": "49624230154685806402418173680709770494154422022871973922", + "data": "eyJmb28iOiAiYmFyIiwgIl9kYXRhZG9nIjogeyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiNDk0ODM3NzMxNjM1NzI5MTQyMSIsICJ4LWRhdGFkb2ctcGFyZW50LWlkIjogIjI4NzYyNTMzODAwMTg2ODEwMjYiLCAieC1kYXRhZG9nLXNhbXBsaW5nLXByaW9yaXR5IjogIjEifX0=", + "approximateArrivalTimestamp": 1643638425.163 }, "eventSource": "aws:kinesis", - "eventID": "shardId-000000000000:49545115243490985018280067714973144582180062593244200961", - "invokeIdentityArn": "arn:aws:iam::EXAMPLE", "eventVersion": "1.0", + "eventID": "shardId-000000000002:49624230154685806402418173680709770494154422022871973922", "eventName": "aws:kinesis:record", - "eventSourceARN": "arn:aws:kinesis:EXAMPLE", - "awsRegion": "us-east-1" + "invokeIdentityArn": "arn:aws:iam::601427279990:role/inferred-spans-python-dev-eu-west-1-lambdaRole", + "awsRegion": "eu-west-1", + "eventSourceARN": "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream" } ] } diff --git a/tests/event_samples/kinesisStream.json b/tests/event_samples/kinesisStream.json new file mode 100644 index 000000000..a320fc44f --- /dev/null +++ b/tests/event_samples/kinesisStream.json @@ -0,0 +1,20 @@ +{ + "Records": [ + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "partitionkey", + "sequenceNumber": "49624230154685806402418173680709770494154422022871973922", + "data": "eyJmb28iOiAiYmFyIiwgIl9kYXRhZG9nIjogeyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiNDk0ODM3NzMxNjM1NzI5MTQyMSIsICJ4LWRhdGFkb2ctcGFyZW50LWlkIjogIjI4NzYyNTMzODAwMTg2ODEwMjYiLCAieC1kYXRhZG9nLXNhbXBsaW5nLXByaW9yaXR5IjogIjEifX0=", + "approximateArrivalTimestamp": 1643638425.163 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000002:49624230154685806402418173680709770494154422022871973922", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::601427279990:role/inferred-spans-python-dev-eu-west-1-lambdaRole", + "awsRegion": "eu-west-1", + "eventSourceARN": "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream" + } + ] +} diff --git a/tests/event_samples/lambda-url.json b/tests/event_samples/lambda-url.json new file mode 100644 index 000000000..8e78650a8 --- /dev/null +++ b/tests/event_samples/lambda-url.json @@ -0,0 +1,47 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/", + "rawQueryString": "", + "headers": { + "sec-fetch-mode": "navigate", + "sec-fetch-site": "none", + "accept-language": "en-US,en;q=0.9", + "x-forwarded-proto": "https", + "x-forwarded-port": "443", + "x-forwarded-for": "71.195.30.42", + "sec-fetch-user": "?1", + "pragma": "no-cache", + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", + "sec-ch-ua": "\"Google Chrome\";v=\"95\", \"Chromium\";v=\"95\", \";Not A Brand\";v=\"99\"", + "sec-ch-ua-mobile": "?0", + "x-amzn-trace-id": "Root=1-61953929-1ec00c3011062a48477b169e", + "sec-ch-ua-platform": "\"macOS\"", + "host": "a8hyhsshac.lambda-url.eu-south-1.amazonaws.com", + "upgrade-insecure-requests": "1", + "cache-control": "no-cache", + "accept-encoding": "gzip, deflate, br", + "sec-fetch-dest": "document", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" + }, + "requestContext": { + "accountId": "601427279990", + "apiId": "a8hyhsshac", + "domainName": "a8hyhsshac.lambda-url.eu-south-1.amazonaws.com", + "domainPrefix": "a8hyhsshac", + "http": { + "method": "GET", + "path": "/", + "protocol": "HTTP/1.1", + "sourceIp": "71.195.30.42", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" + }, + "requestId": "ec4d58f8-2b8b-4ceb-a1d5-2be7bff58505", + "routeKey": "$default", + "stage": "$default", + "time": "17/Nov/2021:17:17:29 +0000", + "timeEpoch": 1637169449721 + }, + "isBase64Encoded": false + } + \ No newline at end of file diff --git a/tests/event_samples/rum-appsync-no-headers.json b/tests/event_samples/rum-appsync-no-headers.json new file mode 100644 index 000000000..ce42c9722 --- /dev/null +++ b/tests/event_samples/rum-appsync-no-headers.json @@ -0,0 +1,14 @@ +{ + "identity": "None", + "info": { + "fieldName": "getItems", + "parentTypeName": "Query", + "selectionSetGraphQL": "{\n id\n}", + "selectionSetList":["id"] + }, + "prev": "None", + "request": { + "domainName": "None" + }, + "source": "None" +} \ No newline at end of file diff --git a/tests/event_samples/rum-appsync-request-not-dict.json b/tests/event_samples/rum-appsync-request-not-dict.json new file mode 100644 index 000000000..1ab6dba82 --- /dev/null +++ b/tests/event_samples/rum-appsync-request-not-dict.json @@ -0,0 +1,12 @@ +{ + "identity": "None", + "info": { + "fieldName": "getItems", + "parentTypeName": "Query", + "selectionSetGraphQL": "{\n id\n}", + "selectionSetList":["id"] + }, + "prev": "None", + "request": "hello", + "source": "None" +} \ No newline at end of file diff --git a/tests/event_samples/rum-appsync.json b/tests/event_samples/rum-appsync.json new file mode 100644 index 000000000..ae085359f --- /dev/null +++ b/tests/event_samples/rum-appsync.json @@ -0,0 +1,53 @@ +{ + "identity": "None", + "info": { + "fieldName": "getItems", + "parentTypeName": "Query", + "selectionSetGraphQL": "{\n id\n}", + "selectionSetList":["id"] + }, + "prev": "None", + "request": { + "domainName": "None", + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "accept-language": "en-US,en;q=0.9", + "cloudfront-forwarded-proto": "https", + "cloudfront-is-desktop-viewer": "True", + "cloudfront-is-mobile-viewer": "False", + "cloudfront-is-smarttv-viewer":"False", + "cloudfront-is-tablet-viewer":" False", + "cloudfront-viewer-asn": "6461", + "cloudfront-viewer-country": "US", + "content-length": "47", + "content-type": "application/graphql", + "host": "4aowrg2uhvbw5mn7osu6searqi.appsync-api.us-east-1.amazonaws.com", + "origin": "http://localhost:5173/", + "priority": "u=1, i", + "referer": "http://localhost:5173/", + "sec-ch-ua": "\"Chromium\";v=\"140\", \"Not=A?Brand\";v=\"24\", \"Google Chrome\";v=\"140\"", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "macOS", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "cross-site", + "traceparent": "00-0000000000000000d9f454c80b9a529a-73ac6ca3427073a3-01", + "tracestate": "dd=s:1;o:rum", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36","via":"2.0 62f9f3967e93a923f21c8acb20cf10b6.cloudfront.net (CloudFront)", + "x-amz-cf-id": "Femhicb_Vbva-J8qWjdI4hKMmqusCeQSp207UGyY3u8VOUrdE8BBvg==", + "x-amzn-appsync-is-vpce-request": "False", + "x-amzn-remote-ip": "64.124.12.19", + "x-amzn-requestid": "1ee1669a-eda3-4d4f-911c-35f74ebef31d", + "x-amzn-trace-id": "Root=1-68cdb7e9-438bf88259d7ce3535723bdd", + "x-datadog-origin": "rum", + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "1", + "x-datadog-trace-id": "12345", + "x-forwarded-for": "64.124.12.19,15.158.225.229", + "x-forwarded-port": "443", + "x-forwarded-proto": "https" + } + }, + "source": "None" +} \ No newline at end of file diff --git a/tests/event_samples/sns-b64-msg-attribute.json b/tests/event_samples/sns-b64-msg-attribute.json new file mode 100644 index 000000000..ce67e19b8 --- /dev/null +++ b/tests/event_samples/sns-b64-msg-attribute.json @@ -0,0 +1,27 @@ +{ + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "Sns": { + "Type": "Notification", + "MessageId": "87056a47-f506-5d77-908b-303605d3b197", + "TopicArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", + "Subject": null, + "Message": "Asynchronously invoking a Lambda function with SNS.", + "Timestamp": "2022-01-31T14:13:41.637Z", + "SignatureVersion": "1", + "Signature": "BmwnJb0Ku2KgQef9QOgaSSTwLyUsbkRq90lzD5Vn4mAcRUOq2ForfMOYbxMB6idljWIWy9t/jK4AIMxPGk/eOGiRcENx3BvAcGcoDayBRFY13+xUGaPn5Lfoht/ZJ7/hmCgFWKRa8ooATZL+AwGAw6Id8qzf0R3M3k2asy5Vxa4ODKiFW9OzWY/zFgsYJhddR3JrQl9YOMRyIobNNHT96o1TwjGsSUTEemrxA6jQtb3QbardEKO+2SuataLEZki7gE2D2sA300WqZecumI339q7la+OIj6VDGDwFoppE2sh8hzJYXAH7oo11giwltE0V3/eLFCVhsE8Y1KD/yDPPsA==", + "SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-7ff5318490ec183fbaddaa2a969abfda.pem", + "UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "MessageAttributes": { + "_datadog": { + "Type": "Binary", + "Value": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiI0OTQ4Mzc3MzE2MzU3MjkxNDIxIiwieC1kYXRhZG9nLXBhcmVudC1pZCI6IjY3NDY5OTgwMTUwMzc0Mjk1MTIiLCJ4LWRhdGFkb2ctc2FtcGxpbmctcHJpb3JpdHkiOiIxIn0=" + } + } + } + } + ] +} diff --git a/tests/event_samples/sns-batch.json b/tests/event_samples/sns-batch.json new file mode 100644 index 000000000..4b5fdb344 --- /dev/null +++ b/tests/event_samples/sns-batch.json @@ -0,0 +1,50 @@ +{ + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "Sns": { + "Type": "Notification", + "MessageId": "87056a47-f506-5d77-908b-303605d3b197", + "TopicArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", + "Subject": null, + "Message": "Asynchronously invoking a Lambda function with SNS.", + "Timestamp": "2022-01-31T14:13:41.637Z", + "SignatureVersion": "1", + "Signature": "BmwnJb0Ku2KgQef9QOgaSSTwLyUsbkRq90lzD5Vn4mAcRUOq2ForfMOYbxMB6idljWIWy9t/jK4AIMxPGk/eOGiRcENx3BvAcGcoDayBRFY13+xUGaPn5Lfoht/ZJ7/hmCgFWKRa8ooATZL+AwGAw6Id8qzf0R3M3k2asy5Vxa4ODKiFW9OzWY/zFgsYJhddR3JrQl9YOMRyIobNNHT96o1TwjGsSUTEemrxA6jQtb3QbardEKO+2SuataLEZki7gE2D2sA300WqZecumI339q7la+OIj6VDGDwFoppE2sh8hzJYXAH7oo11giwltE0V3/eLFCVhsE8Y1KD/yDPPsA==", + "SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-7ff5318490ec183fbaddaa2a969abfda.pem", + "UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "MessageAttributes": { + "_datadog": { + "Type": "String", + "Value": "{\"x-datadog-trace-id\": \"4948377316357291421\", \"x-datadog-parent-id\": \"6746998015037429512\", \"x-datadog-sampling-priority\": \"1\"}" + } + } + } + }, + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "Sns": { + "Type": "Notification", + "MessageId": "87056a47-f506-5d77-908b-303605d3b197", + "TopicArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", + "Subject": null, + "Message": "Asynchronously invoking a Lambda function with SNS.", + "Timestamp": "2022-01-31T14:13:41.637Z", + "SignatureVersion": "1", + "Signature": "BmwnJb0Ku2KgQef9QOgaSSTwLyUsbkRq90lzD5Vn4mAcRUOq2ForfMOYbxMB6idljWIWy9t/jK4AIMxPGk/eOGiRcENx3BvAcGcoDayBRFY13+xUGaPn5Lfoht/ZJ7/hmCgFWKRa8ooATZL+AwGAw6Id8qzf0R3M3k2asy5Vxa4ODKiFW9OzWY/zFgsYJhddR3JrQl9YOMRyIobNNHT96o1TwjGsSUTEemrxA6jQtb3QbardEKO+2SuataLEZki7gE2D2sA300WqZecumI339q7la+OIj6VDGDwFoppE2sh8hzJYXAH7oo11giwltE0V3/eLFCVhsE8Y1KD/yDPPsA==", + "SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-7ff5318490ec183fbaddaa2a969abfda.pem", + "UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "MessageAttributes": { + "_datadog": { + "Type": "String", + "Value": "{\"x-datadog-trace-id\": \"4948377316357291421\", \"x-datadog-parent-id\": \"6746998015037429512\", \"x-datadog-sampling-priority\": \"1\"}" + } + } + } + } + ] +} diff --git a/tests/event_samples/sns-sqs-java-upstream.json b/tests/event_samples/sns-sqs-java-upstream.json new file mode 100644 index 000000000..bef072c3c --- /dev/null +++ b/tests/event_samples/sns-sqs-java-upstream.json @@ -0,0 +1,32 @@ +{ + "Records": [ + { + "messageId": "892f0033-3a4e-4d61-9e26-70d6f7901cd5", + "receiptHandle": "AQEBa1vYusKmlcrFsXDOh8/il3nFWZt+cGeLSU7cjEEpF+N4dPfHzkFpVXKEZebtXbUGyJ18lpBpRtXMpbL7gNukCv3z3Uj61NQbwTTabhsX0Y0iAbh2TSTNgaC/egNVbl3mwDjtXhmIvQIA8Zzzl4AqIlS7a76QiTeTVAjLb1c2FtJYq+znDb52GNPzZ62fSJtDpjfhFEkHwL+w23NQo/Yx4rCmaygR/F7/5hOFtsOwERpTFBei7fDM0z87HVT0nLkqvtg9wyM1kKSsMX8ltjdI3cwFSMs9aTMGFA3uAee6JKswkMp0HCXxNZZ8lp3T9wdQTBUwS8y01vMxl9e0qtYwUpakBYfdlmGHDIbZGEsf59ZpLYlUek0iFl0pdW+5LquNvlA2hA/J9ENpxJYHN4eguTNwRxxpEyzSwmfNXgukgRqDmcZT84UY9GkeaGJ2f2jfyCE525sqB2CAPcK7zx9MZ2Jt/UxsbX5APdX4skXDgck=", + "body": { + "Type": "Notification", + "MessageId": "6dacdb4e-f8dd-5752-9f49-858ee02bcd55", + "TopicArn": "arn:aws:sns:us-west-2:425362996713:DdTraceXLambda-snssqschecksNestedStacksnssqschecksNestedStackResource58F786C6-11NORKTA1JFML-snsProducerJavaForPythonNonRawsnssqsproducerjavaforpythonnonrawtopicDDBAB6EA-ZBb8uCZzkS0S", + "Message": "hello from DdTraceXLambda-snssqschec-snssqsproducerjavaforpyt-z0t7yDk3zWt1", + "Timestamp": "2024-05-16T14:22:46.902Z", + "SignatureVersion": "1", + "Signature": "HBf+KLJg/1Crvg3T5a8jJwVwIjmiNe1jEZ1QXOw11x8At/nqXUrevdm/j8KR33w4gmW/MG6WPpafH8K5k+M+tmn8Mr4sWfJhzsfV4in8s6qbbesBCVL5TsGkfauBfSeOkvrH+2/MAnexUx1m28m+qLJyeTzozelT9IdEhm1ATg5bASeVQS3mFTWYvnO4DoJdMSS9O15ZUQSitjhB8Lv5/DRLKGIYYwhAqOVBVKBfbEbz/BbaI47dqu+uarxL4+m5wAUQIACncg/mxCIsB+oGdBVvFCd0YS7NahSpIKkL08tC78mvKZGiITPOzXw0VlmryWruNYyIXPPnTDhE31Pw6Q==", + "SigningCertURL": "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem", + "UnsubscribeURL": "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:425362996713:DdTraceXLambda-snssqschecksNestedStacksnssqschecksNestedStackResource58F786C6-11NORKTA1JFML-snsProducerJavaForPythonNonRawsnssqsproducerjavaforpythonnonrawtopicDDBAB6EA-ZBb8uCZzkS0S:d44c53e8-538c-472f-89e1-89c131d9cd26", + "MessageAttributes": {} + }, + "attributes": { + "ApproximateReceiveCount": "1", + "AWSTraceHeader": "Root=1-664616b6-00000000425c5f4f8367f57e;Parent=6b971d513e9f9847;Sampled=1", + "SentTimestamp": "1715869366931", + "SenderId": "AIDAIYLAVTDLUXBIEIX46", + "ApproximateFirstReceiveTimestamp": "1715869366945" + }, + "messageAttributes": {}, + "md5OfBody": "e4f9d1cfee42abb22f764d004e88e7f2", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-west-2:425362996713:DdTraceXLambda-snssqschecksNested-snsProducerJavaForPythonNonRawsns-1vws7QPqW8e6", + "awsRegion": "us-west-2" + } + ] +} diff --git a/tests/event_samples/sns-string-msg-attribute.json b/tests/event_samples/sns-string-msg-attribute.json new file mode 100644 index 000000000..8bdacaeaf --- /dev/null +++ b/tests/event_samples/sns-string-msg-attribute.json @@ -0,0 +1,27 @@ +{ + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "Sns": { + "Type": "Notification", + "MessageId": "87056a47-f506-5d77-908b-303605d3b197", + "TopicArn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", + "Subject": null, + "Message": "Asynchronously invoking a Lambda function with SNS.", + "Timestamp": "2022-01-31T14:13:41.637Z", + "SignatureVersion": "1", + "Signature": "BmwnJb0Ku2KgQef9QOgaSSTwLyUsbkRq90lzD5Vn4mAcRUOq2ForfMOYbxMB6idljWIWy9t/jK4AIMxPGk/eOGiRcENx3BvAcGcoDayBRFY13+xUGaPn5Lfoht/ZJ7/hmCgFWKRa8ooATZL+AwGAw6Id8qzf0R3M3k2asy5Vxa4ODKiFW9OzWY/zFgsYJhddR3JrQl9YOMRyIobNNHT96o1TwjGsSUTEemrxA6jQtb3QbardEKO+2SuataLEZki7gE2D2sA300WqZecumI339q7la+OIj6VDGDwFoppE2sh8hzJYXAH7oo11giwltE0V3/eLFCVhsE8Y1KD/yDPPsA==", + "SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-7ff5318490ec183fbaddaa2a969abfda.pem", + "UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy:224b60ba-befc-4830-ad96-f1f0ac94eb04", + "MessageAttributes": { + "_datadog": { + "Type": "String", + "Value": "{\"x-datadog-trace-id\": \"4948377316357291421\", \"x-datadog-parent-id\": \"6746998015037429512\", \"x-datadog-sampling-priority\": \"1\"}" + } + } + } + } + ] +} diff --git a/tests/event_samples/sns.json b/tests/event_samples/sns.json deleted file mode 100644 index 06c6062d6..000000000 --- a/tests/event_samples/sns.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "Records": [ - { - "EventSource": "aws:sns", - "EventVersion": "1.0", - "EventSubscriptionArn": "arn:aws:sns:us-east-1:{{{accountId}}}:ExampleTopic", - "Sns": { - "Type": "Notification", - "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", - "TopicArn": "arn:aws:sns:us-east-1:123456789012:ExampleTopic", - "Subject": "example subject", - "Message": "example message", - "Timestamp": "1970-01-01T00:00:00.000Z", - "SignatureVersion": "1", - "Signature": "EXAMPLE", - "SigningCertUrl": "EXAMPLE", - "UnsubscribeUrl": "EXAMPLE", - "MessageAttributes": { - "Test": { - "Type": "String", - "Value": "TestString" - }, - "TestBinary": { - "Type": "Binary", - "Value": "TestBinary" - } - } - } - } - ] -} diff --git a/tests/event_samples/sqs-batch.json b/tests/event_samples/sqs-batch.json new file mode 100644 index 000000000..9ec6cba17 --- /dev/null +++ b/tests/event_samples/sqs-batch.json @@ -0,0 +1,52 @@ +{ + "Records": [ + { + "messageId": "2fcbad66-372a-4b1c-87da-26b2cea13936", + "receiptHandle": "AQEBnxFcyzQZhkrLV/TrSpn0VBszuq4a5/u66uyGRdUKuvXMurd6RRV952L+arORbE4MlGqWLUxurzYH9mKvc/A3MYjmGwQvvhp6uK5c7gXxg6tvHVAlsEFmTB0p35dxfGCmtrJbzdPjVtmcucPEpRx7z51tQokgGWuJbqx3Z9MVRD+6dyO3o6Zu6G3oWUgiUZ0dxhNoIIeT6xr/tEsoWhGK9ZUPRJ7e0BM/UZKfkecX1CVgVZ8J/t8fHRklJd34S6pN99SPNBKx+1lOZCelm2MihbQR6zax8bkhwL3glxYP83MxexvfOELA3G/6jx96oQ4mQdJASsKFUzvcs2NUxX+0bBVX9toS7MW/Udv+3CiQwSjjkc18A385QHtNrJDRbH33OUxFCqN5CcUMiGvEFed5EQ==", + "body": "Asynchronously invoking a Lambda function with SQS.", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1634662094538", + "SenderId": "AROAYYB64AB3LSVUYFP5T:harv-inferred-spans-dev-initSender", + "ApproximateFirstReceiveTimestamp": "1634662094544" + }, + "messageAttributes": { + "_datadog": { + "stringValue": "{\"x-datadog-trace-id\":\"2684756524522091840\",\"x-datadog-parent-id\":\"7431398482019833808\",\"x-datadog-sampled\":\"1\",\"x-datadog-sampling-priority\":\"1\"}", + "stringListValues": [], + "binaryListValues": [], + "dataType": "String" + } + }, + "md5OfMessageAttributes": "14b3b4a81d5ddeb96af62963d703c528", + "md5OfBody": "24933a8beabe72088d7576cab1a59142", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-west-1:601427279990:InferredSpansQueueNode", + "awsRegion": "eu-west-1" + }, + { + "messageId": "2fcbad66-372a-4b1c-87da-26b2cea13937", + "receiptHandle": "AQEBnxFcyzQZhkrLV/TrSpn0VBszuq4a5/u66uyGRdUKuvXMurd6RRV952L+arORbE4MlGqWLUxurzYH9mKvc/A3MYjmGwQvvhp6uK5c7gXxg6tvHVAlsEFmTB0p35dxfGCmtrJbzdPjVtmcucPEpRx7z51tQokgGWuJbqx3Z9MVRD+6dyO3o6Zu6G3oWUgiUZ0dxhNoIIeT6xr/tEsoWhGK9ZUPRJ7e0BM/UZKfkecX1CVgVZ8J/t8fHRklJd34S6pN99SPNBKx+1lOZCelm2MihbQR6zax8bkhwL3glxYP83MxexvfOELA3G/6jx96oQ4mQdJASsKFUzvcs2NUxX+0bBVX9toS7MW/Udv+3CiQwSjjkc18A385QHtNrJDRbH33OUxFCqN5CcUMiGvEFed5EQ==", + "body": "Asynchronously invoking a Lambda function with SQS.", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1634662094538", + "SenderId": "AROAYYB64AB3LSVUYFP5T:harv-inferred-spans-dev-initSender", + "ApproximateFirstReceiveTimestamp": "1634662094544" + }, + "messageAttributes": { + "_datadog": { + "stringValue": "{\"x-datadog-trace-id\":\"2684756524522091840\",\"x-datadog-parent-id\":\"7431398482019833808\",\"x-datadog-sampled\":\"1\",\"x-datadog-sampling-priority\":\"1\"}", + "stringListValues": [], + "binaryListValues": [], + "dataType": "String" + } + }, + "md5OfMessageAttributes": "14b3b4a81d5ddeb96af62963d703c528", + "md5OfBody": "24933a8beabe72088d7576cab1a59142", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-west-1:601427279990:InferredSpansQueueNode", + "awsRegion": "eu-west-1" + } + ] +} diff --git a/tests/event_samples/sqs-java-upstream.json b/tests/event_samples/sqs-java-upstream.json new file mode 100644 index 000000000..23ab68811 --- /dev/null +++ b/tests/event_samples/sqs-java-upstream.json @@ -0,0 +1,22 @@ +{ + "Records": [ + { + "messageId": "f7e888aa-1368-484c-8e15-fc3f0f7c6fea", + "receiptHandle": "AQEBN1aYTQ1c5huZh9bkhBYqcMMnqTUMRh8MfUPyGXkEolcn23rvM9saGEg3wTK/7JnJ1s3Uk107uLjaP6yV6+zS3oQRU0vMG2LfyTgHovWhYQ8TnrpC7XpYL+Uf+oc9KoILQopiYi4wsFnOWQqy82yQmlOA3W+CZ3Rvq8N6rNcmyaZEXVdozHG+FyMCMQ8QdTcCHhzR9YKnkZ87Y40+LhysUR57VNPVtRwENI8H1uMEfmxaCkW+CAkdCGoXeX+KioT7pHJDZaEutXM3VRmGXDDzCXvfUJQ9JQIlP5xe66JO8/cpCyl5sDoHsCjLy6X/XCmfG2+XclPObGHBzcMSjG1RQtHsEGTOAJrLREucqf/oj0Ab4svpxz6lR4UXrICygZ2x0NZcNFXcZx3GV2QL9nHmJxzrO2lnNTEOMuYB4SnqtIhsaDTcmkYHumaAJdRHl5BksFcU5qpS7BQrnRvXn5Sz3hYdR2KuYKN5Oq6W1vuT16o=", + "body": "{\"hello\":\"world\"}", + "attributes": { + "ApproximateReceiveCount": "1", + "AWSTraceHeader": "Root=1-65eb7350-000000006dfd06bf489aa4e5;Parent=48cc02b6aafae897;Sampled=1", + "SentTimestamp": "1709929297382", + "SenderId": "AROAWGCM4HXUTHYJKOM7M:DdTraceXLambda-sqsjavache-sqsjavaproducerforPython-moi7s7Hu7Ppy", + "ApproximateFirstReceiveTimestamp": "1709929297387" + }, + "messageAttributes": {}, + "md5OfMessageAttributes": "", + "md5OfBody": "fbc24bcc7a1794758fc1327fcfebdaf6", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-west-2:444442222111:DdTraceXLambda-sqsjavachecksNeste-sqsJavaProducer2sqsjavaproducerfo-dwpHQF6fcZT4", + "awsRegion": "us-west-2" + } + ] +} diff --git a/tests/event_samples/sqs-string-msg-attribute.json b/tests/event_samples/sqs-string-msg-attribute.json new file mode 100644 index 000000000..2bde2ce5c --- /dev/null +++ b/tests/event_samples/sqs-string-msg-attribute.json @@ -0,0 +1,28 @@ +{ + "Records": [ + { + "messageId": "2fcbad66-372a-4b1c-87da-26b2cea13936", + "receiptHandle": "AQEBnxFcyzQZhkrLV/TrSpn0VBszuq4a5/u66uyGRdUKuvXMurd6RRV952L+arORbE4MlGqWLUxurzYH9mKvc/A3MYjmGwQvvhp6uK5c7gXxg6tvHVAlsEFmTB0p35dxfGCmtrJbzdPjVtmcucPEpRx7z51tQokgGWuJbqx3Z9MVRD+6dyO3o6Zu6G3oWUgiUZ0dxhNoIIeT6xr/tEsoWhGK9ZUPRJ7e0BM/UZKfkecX1CVgVZ8J/t8fHRklJd34S6pN99SPNBKx+1lOZCelm2MihbQR6zax8bkhwL3glxYP83MxexvfOELA3G/6jx96oQ4mQdJASsKFUzvcs2NUxX+0bBVX9toS7MW/Udv+3CiQwSjjkc18A385QHtNrJDRbH33OUxFCqN5CcUMiGvEFed5EQ==", + "body": "Asynchronously invoking a Lambda function with SQS.", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1634662094538", + "SenderId": "AROAYYB64AB3LSVUYFP5T:harv-inferred-spans-dev-initSender", + "ApproximateFirstReceiveTimestamp": "1634662094544" + }, + "messageAttributes": { + "_datadog": { + "stringValue": "{\"x-datadog-trace-id\":\"2684756524522091840\",\"x-datadog-parent-id\":\"7431398482019833808\",\"x-datadog-sampled\":\"1\",\"x-datadog-sampling-priority\":\"1\"}", + "stringListValues": [], + "binaryListValues": [], + "dataType": "String" + } + }, + "md5OfMessageAttributes": "14b3b4a81d5ddeb96af62963d703c528", + "md5OfBody": "24933a8beabe72088d7576cab1a59142", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-west-1:601427279990:InferredSpansQueueNode", + "awsRegion": "eu-west-1" + } + ] +} diff --git a/tests/event_samples/sqs.json b/tests/event_samples/sqs.json deleted file mode 100644 index e7e5eb73b..000000000 --- a/tests/event_samples/sqs.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Records": [ - { - "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", - "receiptHandle": "MessageReceiptHandle", - "body": "Hello from SQS!", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1523232000000", - "SenderId": "123456789012", - "ApproximateFirstReceiveTimestamp": "1523232000001" - }, - "messageAttributes": {}, - "md5OfBody": "{{{md5_of_body}}}", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", - "awsRegion": "us-east-1" - } - ] -} diff --git a/tests/event_samples/states.json b/tests/event_samples/states.json new file mode 100644 index 000000000..778fe4376 --- /dev/null +++ b/tests/event_samples/states.json @@ -0,0 +1,22 @@ +{ + "_datadog": { + "Execution": { + "Id": "arn:aws:states:ca-central-1:425362996713:execution:MyStateMachine-wsx8chv4d:1356a963-42a5-48b0-ba3f-73bde559a50c", + "StartTime": "2024-11-13T16:46:47.715Z", + "Name": "1356a963-42a5-48b0-ba3f-73bde559a50c", + "RoleArn": "arn:aws:iam::425362996713:role/service-role/StepFunctions-MyStateMachine-wsx8chv4d-role-1su0fkfd3", + "RedriveCount": 0 + }, + "StateMachine": { + "Id": "arn:aws:states:ca-central-1:425362996713:stateMachine:MyStateMachine-wsx8chv4d", + "Name": "MyStateMachine-wsx8chv4d" + }, + "State": { + "Name": "Lambda Invoke", + "EnteredTime": "2024-11-13T16:46:47.740Z", + "RetryCount": 0 + }, + "RootExecutionId": "arn:aws:states:ca-central-1:425362996713:execution:MyStateMachine-wsx8chv4d:1356a963-42a5-48b0-ba3f-73bde559a50c", + "serverless-version": "v1" + } +} diff --git a/tests/integration/handle.py b/tests/integration/handle.py index df9f80190..3590cb18c 100644 --- a/tests/integration/handle.py +++ b/tests/integration/handle.py @@ -26,8 +26,7 @@ def handle(event, context): ) # Make HTTP calls to test ddtrace instrumentation - requests.get("https://httpstat.us/200/") - requests.get("https://httpstat.us/400/") + requests.get("https://datadoghq.com/") return { "statusCode": 200, diff --git a/tests/integration/input_events/api-gateway-get.json b/tests/integration/input_events/api-gateway-get.json index 496553dee..e309177a7 100644 --- a/tests/integration/input_events/api-gateway-get.json +++ b/tests/integration/input_events/api-gateway-get.json @@ -1,55 +1,101 @@ { - "path": "/test/hello", - "headers": { - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", - "Accept-Encoding": "gzip, deflate, lzma, sdch, br", - "Accept-Language": "en-US,en;q=0.8", - "CloudFront-Forwarded-Proto": "https", - "CloudFront-Is-Desktop-Viewer": "true", - "CloudFront-Is-Mobile-Viewer": "false", - "CloudFront-Is-SmartTV-Viewer": "false", - "CloudFront-Is-Tablet-Viewer": "false", - "CloudFront-Viewer-Country": "US", - "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", - "Upgrade-Insecure-Requests": "1", - "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", - "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", - "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", - "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": { - "cognitoIdentityPoolId": "", - "accountId": "", - "cognitoIdentityId": "", - "caller": "", - "apiKey": "", - "sourceIp": "192.168.100.1", - "cognitoAuthenticationType": "", - "cognitoAuthenticationProvider": "", - "userArn": "", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", - "user": "" + "resource":"/", + "path":"/", + "httpMethod":"GET", + "headers":{ + "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", + "accept-encoding":"gzip, deflate, br", + "accept-language":"en-US,en;q=0.9", + "cookie":"s_fid=7AAB6XMPLAFD9BBF-0643XMPL09956DE2; regStatus=pre-register", + "Host":"70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + "sec-fetch-dest":"document", + "sec-fetch-mode":"navigate", + "sec-fetch-site":"none", + "upgrade-insecure-requests":"1", + "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "X-Amzn-Trace-Id":"Root=1-5e66d96f-7491f09xmpl79d18acf3d050", + "X-Forwarded-For":"52.255.255.12", + "X-Forwarded-Port":"443", + "X-Forwarded-Proto":"https" }, - "resourcePath": "/{proxy+}", - "httpMethod": "GET", - "apiId": "wt6mne2s9k" - }, - "resource": "/{proxy+}", - "httpMethod": "GET", - "queryStringParameters": { - "name": "me" - }, - "stageVariables": { - "stageVarName": "stageVarValue" - } -} + "multiValueHeaders":{ + "accept":[ + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + ], + "accept-encoding":[ + "gzip, deflate, br" + ], + "accept-language":[ + "en-US,en;q=0.9" + ], + "cookie":[ + "s_fid=7AABXMPL1AFD9BBF-0643XMPL09956DE2; regStatus=pre-register;" + ], + "Host":[ + "70ixmpl4fl.execute-api.ca-central-1.amazonaws.com" + ], + "sec-fetch-dest":[ + "document" + ], + "sec-fetch-mode":[ + "navigate" + ], + "sec-fetch-site":[ + "none" + ], + "upgrade-insecure-requests":[ + "1" + ], + "User-Agent":[ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36" + ], + "X-Amzn-Trace-Id":[ + "Root=1-5e66d96f-7491f09xmpl79d18acf3d050" + ], + "X-Forwarded-For":[ + "52.255.255.12" + ], + "X-Forwarded-Port":[ + "443" + ], + "X-Forwarded-Proto":[ + "https" + ] + }, + "queryStringParameters":null, + "multiValueQueryStringParameters":null, + "pathParameters":null, + "stageVariables":null, + "requestContext":{ + "resourceId":"2gxmpl", + "resourcePath":"/", + "httpMethod":"GET", + "extendedRequestId":"JJbxmplHYosFVYQ=", + "requestTime":"10/Mar/2020:00:03:59 +0000", + "path":"/Prod/", + "accountId":"123456789012", + "protocol":"HTTP/1.1", + "stage":"Prod", + "domainPrefix":"70ixmpl4fl", + "requestTimeEpoch":1583798639428, + "requestId":"77375676-xmpl-4b79-853a-f982474efe18", + "identity":{ + "cognitoIdentityPoolId":null, + "accountId":null, + "cognitoIdentityId":null, + "caller":null, + "sourceIp":"52.255.255.12", + "principalOrgId":null, + "accessKey":null, + "cognitoAuthenticationType":null, + "cognitoAuthenticationProvider":null, + "userArn":null, + "userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "user":null + }, + "domainName":"70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + "apiId":"70ixmpl4fl" + }, + "body":null, + "isBase64Encoded":false + } diff --git a/tests/integration/input_events/appsync.json b/tests/integration/input_events/appsync.json new file mode 100644 index 000000000..dacf24e7e --- /dev/null +++ b/tests/integration/input_events/appsync.json @@ -0,0 +1,49 @@ +{ + "identity": "None", + "info": { + "fieldName": "getItems", + "parentTypeName": "Query", + "selectionSetGraphQL": "{\n id\n}", + "selectionSetList":["id"] + }, + "prev": "None", + "request": { + "domainName": "None", + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "accept-language": "en-US,en;q=0.9", + "cloudfront-forwarded-proto": "https", + "cloudfront-is-desktop-viewer": "True", + "cloudfront-is-mobile-viewer": "False", + "cloudfront-is-smarttv-viewer":"False", + "cloudfront-is-tablet-viewer":" False", + "cloudfront-viewer-asn": "6461", + "cloudfront-viewer-country": "US", + "content-length": "47", + "content-type": "application/graphql", + "host": "4aowrg2uhvbw5mn7osu6searqi.appsync-api.us-east-1.amazonaws.com", + "origin": "http://localhost:5173/", + "priority": "u=1, i", + "referer": "http://localhost:5173/", + "sec-ch-ua": "\"Chromium\";v=\"140\", \"Not=A?Brand\";v=\"24\", \"Google Chrome\";v=\"140\"", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "macOS", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "cross-site", + "traceparent": "00-0000000000000000d9f454c80b9a529a-73ac6ca3427073a3-01", + "tracestate": "dd=s:1;o:rum", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36","via":"2.0 62f9f3967e93a923f21c8acb20cf10b6.cloudfront.net (CloudFront)", + "x-amz-cf-id": "Femhicb_Vbva-J8qWjdI4hKMmqusCeQSp207UGyY3u8VOUrdE8BBvg==", + "x-amzn-appsync-is-vpce-request": "False", + "x-amzn-remote-ip": "64.124.12.19", + "x-amzn-requestid": "1ee1669a-eda3-4d4f-911c-35f74ebef31d", + "x-amzn-trace-id": "Root=1-68cdb7e9-438bf88259d7ce3535723bdd", + "x-forwarded-for": "64.124.12.19,15.158.225.229", + "x-forwarded-port": "443", + "x-forwarded-proto": "https" + } + }, + "source": "None" +} \ No newline at end of file diff --git a/tests/integration/input_events/dynamodb.json b/tests/integration/input_events/dynamodb.json new file mode 100644 index 000000000..b39228a51 --- /dev/null +++ b/tests/integration/input_events/dynamodb.json @@ -0,0 +1,93 @@ +{ + "Records": [ + { + "eventID": "c4ca4238a0b923820dcc509a6f75849b", + "eventName": "INSERT", + "eventVersion": "1.1", + "eventSource": "aws:dynamodb", + "awsRegion": "us-east-1", + "dynamodb": { + "Keys": { + "Id": { + "N": "101" + } + }, + "NewImage": { + "Message": { + "S": "New item!" + }, + "Id": { + "N": "101" + } + }, + "ApproximateCreationDateTime": 1428537600, + "SequenceNumber": "4421584500000000017450439091", + "SizeBytes": 26, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" + }, + { + "eventID": "c81e728d9d4c2f636f067f89cc14862c", + "eventName": "MODIFY", + "eventVersion": "1.1", + "eventSource": "aws:dynamodb", + "awsRegion": "us-east-1", + "dynamodb": { + "Keys": { + "Id": { + "N": "101" + } + }, + "NewImage": { + "Message": { + "S": "This item has changed" + }, + "Id": { + "N": "101" + } + }, + "OldImage": { + "Message": { + "S": "New item!" + }, + "Id": { + "N": "101" + } + }, + "ApproximateCreationDateTime": 1428537600, + "SequenceNumber": "4421584500000000017450439092", + "SizeBytes": 59, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" + }, + { + "eventID": "eccbc87e4b5ce2fe28308fd9f2a7baf3", + "eventName": "REMOVE", + "eventVersion": "1.1", + "eventSource": "aws:dynamodb", + "awsRegion": "us-east-1", + "dynamodb": { + "Keys": { + "Id": { + "N": "101" + } + }, + "OldImage": { + "Message": { + "S": "This item has changed" + }, + "Id": { + "N": "101" + } + }, + "ApproximateCreationDateTime": 1428537600, + "SequenceNumber": "4421584500000000017450439093", + "SizeBytes": 38, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" + } + ] +} diff --git a/tests/integration/input_events/eventbridge-custom.json b/tests/integration/input_events/eventbridge-custom.json new file mode 100644 index 000000000..04184feff --- /dev/null +++ b/tests/integration/input_events/eventbridge-custom.json @@ -0,0 +1,13 @@ +{ + "version": "0", + "id": "fd03f394-e769-eff5-08a8-53c228933591", + "detail-type": "testdetail", + "source": "eventbridge.custom.event.sender", + "account": "601427279990", + "time": "2021-11-04T01:37:45Z", + "region": "eu-west-1", + "resources": [], + "detail": { + "foo": "bar" + } +} diff --git a/tests/integration/input_events/http-api.json b/tests/integration/input_events/http-api.json new file mode 100644 index 000000000..83de330ff --- /dev/null +++ b/tests/integration/input_events/http-api.json @@ -0,0 +1,35 @@ +{ + "version": "2.0", + "routeKey": "GET /httpapi/get", + "rawPath": "/httpapi/get", + "rawQueryString": "", + "headers": { + "accept": "*/*", + "content-length": "0", + "host": "x02yirxc7a.execute-api.eu-west-1.amazonaws.com", + "user-agent": "curl/7.64.1", + "x-amzn-trace-id": "Root=1-613a52fb-4c43cfc95e0241c1471bfa05", + "x-forwarded-for": "38.122.226.210", + "x-forwarded-port": "443", + "x-forwarded-proto": "https" + }, + "requestContext": { + "accountId": "601427279990", + "apiId": "x02yirxc7a", + "domainName": "x02yirxc7a.execute-api.eu-west-1.amazonaws.com", + "domainPrefix": "x02yirxc7a", + "http": { + "method": "GET", + "path": "/httpapi/get", + "protocol": "HTTP/1.1", + "sourceIp": "38.122.226.210", + "userAgent": "curl/7.64.1" + }, + "requestId": "FaHnXjKCGjQEJ7A=", + "routeKey": "GET /httpapi/get", + "stage": "$default", + "time": "09/Sep/2021:18:31:23 +0000", + "timeEpoch": 1631212283738 + }, + "isBase64Encoded": false +} diff --git a/tests/integration/input_events/kinesis.json b/tests/integration/input_events/kinesis.json new file mode 100644 index 000000000..2d7f8887a --- /dev/null +++ b/tests/integration/input_events/kinesis.json @@ -0,0 +1,20 @@ +{ + "Records": [ + { + "kinesis": { + "partitionKey": "partitionKey-03", + "kinesisSchemaVersion": "1.0", + "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=", + "sequenceNumber": "49545115243490985018280067714973144582180062593244200961", + "approximateArrivalTimestamp": 1428537600 + }, + "eventSource": "aws:kinesis", + "eventID": "shardId-000000000000:49545115243490985018280067714973144582180062593244200961", + "invokeIdentityArn": "arn:aws:iam::EXAMPLE", + "eventVersion": "1.0", + "eventName": "aws:kinesis:record", + "eventSourceARN": "arn:aws:kinesis:EXAMPLE", + "awsRegion": "us-east-1" + } + ] +} diff --git a/tests/integration/input_events/s3.json b/tests/integration/input_events/s3.json new file mode 100644 index 000000000..3ad4466f0 --- /dev/null +++ b/tests/integration/input_events/s3.json @@ -0,0 +1,38 @@ +{ + "Records": [ + { + "eventVersion": "2.0", + "eventSource": "aws:s3", + "awsRegion": "us-east-1", + "eventTime": "1970-01-01T00:00:00.000Z", + "eventName": "ObjectCreated:Put", + "userIdentity": { + "principalId": "EXAMPLE" + }, + "requestParameters": { + "sourceIPAddress": "127.0.0.1" + }, + "responseElements": { + "x-amz-request-id": "EXAMPLE123456789", + "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH" + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "testConfigRule", + "bucket": { + "name": "example-bucket", + "ownerIdentity": { + "principalId": "EXAMPLE" + }, + "arn": "arn:aws:s3:::example-bucket" + }, + "object": { + "key": "test/key", + "size": 1024, + "eTag": "0123456789abcdef0123456789abcdef", + "sequencer": "0A1B2C3D4E5F678901" + } + } + } + ] +} diff --git a/tests/integration/input_events/websocket.json b/tests/integration/input_events/websocket.json new file mode 100644 index 000000000..24215c633 --- /dev/null +++ b/tests/integration/input_events/websocket.json @@ -0,0 +1,22 @@ +{ + "requestContext": { + "routeKey": "$default", + "messageId": "Fc5S3coemjQCJlg=", + "eventType": "MESSAGE", + "extendedRequestId": "Fc5S3EvdGjQFtsQ=", + "requestTime": "10/Sep/2021:14:44:21 +0000", + "messageDirection": "IN", + "stage": "dev", + "connectedAt": 1631285060967, + "requestTimeEpoch": 1631285061365, + "identity": { + "sourceIp": "38.122.226.210" + }, + "requestId": "Fc5S3EvdGjQFtsQ=", + "domainName": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "connectionId": "Fc5SzcoYGjQCJlg=", + "apiId": "p62c47itsb" + }, + "body": "\"What's good in the hood?\"", + "isBase64Encoded": false +} diff --git a/tests/integration/package-lock.json b/tests/integration/package-lock.json new file mode 100644 index 000000000..5990cc8db --- /dev/null +++ b/tests/integration/package-lock.json @@ -0,0 +1,1119 @@ +{ + "name": "integration", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "serverless-plugin-datadog": "^2.18.0", + "serverless-python-requirements": "^6.1.2" + } + }, + "node_modules/@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true, + "license": "ISC" + }, + "node_modules/2-thenable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/2-thenable/-/2-thenable-1.0.0.tgz", + "integrity": "sha512-HqiDzaLDFCXkcCO/SwoyhRwqYtINFHF7t9BDRq4x90TOKNAJpiqUt9X5lQ08bwxYzc067HUywDjGySpebHcUpw==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.47" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/appdirectory": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/appdirectory/-/appdirectory-0.1.0.tgz", + "integrity": "sha512-DJ5DV8vZXBbusyiyPlH28xppwS8eAMRuuyMo88xeEcf4bV64lbLtbxRxqixZuJBXsZzLtXFmA13GwVjJc7vdQw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/child-process-ext": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/child-process-ext/-/child-process-ext-2.1.1.tgz", + "integrity": "sha512-0UQ55f51JBkOFa+fvR76ywRzxiPwQS3Xe8oe5bZRphpv+dIMeerW5Zn5e4cUy4COJwVtJyU0R79RMnw+aCqmGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^6.0.5", + "es5-ext": "^0.10.53", + "log": "^6.0.0", + "split2": "^3.1.1", + "stream-promise": "^3.2.0" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.46" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-all": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/glob-all/-/glob-all-3.3.1.tgz", + "integrity": "sha512-Y+ESjdI7ZgMwfzanHZYQ87C59jOO0i+Hd+QYtVt9PhLi6d8wlOpzQnfBxWUlaTuAoR3TkybLqqbIoWveU4Ji7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "yargs": "^15.3.1" + }, + "bin": { + "glob-all": "bin/glob-all" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-primitive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", + "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.values": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz", + "integrity": "sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/log": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/log/-/log-6.3.2.tgz", + "integrity": "sha512-ek8NRg/OPvS9ISOJNWNAz5vZcpYacWNFDWNJjj5OXsc6YuKacfey6wF04cXz/tOJIVrZ2nGSkHpAY5qKtF6ISg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "duration": "^0.2.2", + "es5-ext": "^0.10.64", + "event-emitter": "^0.3.5", + "sprintf-kit": "^2.0.2", + "type": "^2.7.3", + "uni-global": "^1.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serverless-plugin-datadog": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/serverless-plugin-datadog/-/serverless-plugin-datadog-2.18.0.tgz", + "integrity": "sha512-RUdCNjUk+uUKQYgQBjK0WNeYJ7lM2/RScqg/LjVSfv5EACeJ3iIUPz1c4bS2jtiH05al8qXudNb6QDkv9zxG7w==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/serverless-python-requirements": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/serverless-python-requirements/-/serverless-python-requirements-6.1.2.tgz", + "integrity": "sha512-pas27CBxxaLTU5XMYnCVPJc+LVdm65Ys5olNvRWRqfUaZwTfD/7KSSt2XPSRme8BeJubroslaiOtWPP+IrxTVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@iarna/toml": "^2.2.5", + "appdirectory": "^0.1.0", + "bluebird": "^3.7.2", + "child-process-ext": "^2.1.1", + "fs-extra": "^10.1.0", + "glob-all": "^3.3.1", + "is-wsl": "^2.2.0", + "jszip": "^3.10.1", + "lodash.get": "^4.4.2", + "lodash.uniqby": "^4.7.0", + "lodash.values": "^4.3.0", + "rimraf": "^3.0.2", + "semver": "^7.6.0", + "set-value": "^4.1.0", + "sha256-file": "1.0.0", + "shell-quote": "^1.8.1" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-value": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", + "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==", + "dev": true, + "funding": [ + "https://github.com/sponsors/jonschlinkert", + "https://paypal.me/jonathanschlinkert", + "https://jonschlinkert.dev/sponsor" + ], + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "is-primitive": "^3.0.1" + }, + "engines": { + "node": ">=11.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/sha256-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sha256-file/-/sha256-file-1.0.0.tgz", + "integrity": "sha512-nqf+g0veqgQAkDx0U2y2Tn2KWyADuuludZTw9A7J3D+61rKlIIl9V5TS4mfnwKuXZOH9B7fQyjYJ9pKRHIsAyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "license": "ISC", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sprintf-kit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sprintf-kit/-/sprintf-kit-2.0.2.tgz", + "integrity": "sha512-lnapdj6W4LflHZGKvl9eVkz5YF0xaTrqpRWVA4cNVOTedwqifIP8ooGImldzT/4IAN5KXFQAyXTdLidYVQdyag==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/stream-promise": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-promise/-/stream-promise-3.2.0.tgz", + "integrity": "sha512-P+7muTGs2C8yRcgJw/PPt61q7O517tDHiwYEzMWo1GSBCcZedUMT/clz7vUNsSxFphIlJ6QUL4GexQKlfJoVtA==", + "dev": true, + "license": "ISC", + "dependencies": { + "2-thenable": "^1.0.0", + "es5-ext": "^0.10.49", + "is-stream": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/uni-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uni-global/-/uni-global-1.0.0.tgz", + "integrity": "sha512-WWM3HP+siTxzIWPNUg7hZ4XO8clKi6NoCAJJWnuRL+BAqyFXF8gC03WNyTefGoUXYc47uYgXxpKLIEvo65PEHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/tests/integration/package.json b/tests/integration/package.json index 9dcad1b4c..8dae6acaa 100644 --- a/tests/integration/package.json +++ b/tests/integration/package.json @@ -1,5 +1,6 @@ { "devDependencies": { - "serverless-plugin-datadog": "^2.18.0" + "serverless-plugin-datadog": "^2.18.0", + "serverless-python-requirements": "^6.1.2" } } diff --git a/tests/integration/parse-json.js b/tests/integration/parse-json.js new file mode 100644 index 000000000..0e54e0dc2 --- /dev/null +++ b/tests/integration/parse-json.js @@ -0,0 +1,17 @@ +'use strict' + +var readline = require('readline'); +var rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false +}); + +rl.on('line', function(line){ + try { + const obj = JSON.parse(line) + console.log(JSON.stringify(obj, null, 2)) + } catch (e) { + console.log(line) + } +}) diff --git a/tests/integration/requirements.txt b/tests/integration/requirements.txt new file mode 100644 index 000000000..343ea0257 --- /dev/null +++ b/tests/integration/requirements.txt @@ -0,0 +1,4 @@ +certifi==2024.12.14 +charset-normalizer==3.4.1 +idna==3.10 +requests==2.32.4 diff --git a/tests/integration/serverless.yml b/tests/integration/serverless.yml index 9f10622de..8c7e62f08 100644 --- a/tests/integration/serverless.yml +++ b/tests/integration/serverless.yml @@ -1,34 +1,45 @@ # IAM permissions require service name to begin with 'integration-tests' service: integration-tests-python -# As of mid-August 2021, the Serverless framework does not support Python 3.9 -# and complains about an invalid configuration when we deploy Python 3.9 functions. -# This option suppresses the warning. -# Remove this when the Serverless framework supports Python 3.9. -configValidationMode: off - provider: name: aws - region: sa-east-1 + region: eu-west-1 tracing: lambda: "PassThrough" + architecture: ${env:SLS_ARCH} environment: DD_INTEGRATION_TEST: true DD_TRACE_ENABLED: true DD_API_KEY: ${env:DD_API_KEY} - DD_CAPTURE_LAMBDA_PAYLOAD: true - lambdaHashingVersion: 20201221 + DD_TRACE_MANAGED_SERVICES: true + DD_COLD_START_TRACING: false + DD_SERVICE: ${self:service} timeout: 15 deploymentBucket: - name: integration-tests-deployment-bucket + name: integration-tests-serververless-deployment-bucket iam: # IAM permissions require that all functions are deployed with this role - role: "arn:aws:iam::601427279990:role/serverless-integration-test-lambda-role" + role: "arn:aws:iam::425362996713:role/serverless-integration-test-lambda-role" + layers: + - { Ref: PythonLambdaLayer } + - { Ref: PythonRequirementsLambdaLayer } + +plugins: + - serverless-python-requirements + +custom: + pythonRequirements: + pythonBin: python3 + pipCmdExtraArgs: + - --no-deps # install just requests + layer: + compatibleRuntimes: + - ${env:SERVERLESS_RUNTIME} layers: python: package: - artifact: ../../.layers/datadog_lambda_py-amd64-${env:PYTHON_VERSION}.zip + artifact: ../../.layers/datadog_lambda_py-${env:ARCH}-${env:PYTHON_VERSION}.zip functions: # async-metrics (flushed to logs) @@ -36,8 +47,6 @@ functions: name: integration-tests-python-${sls:stage}-async-metrics_${env:RUNTIME} handler: handle.handle runtime: ${env:SERVERLESS_RUNTIME} - layers: - - { Ref: PythonLambdaLayer } environment: DD_FLUSH_TO_LOG: true @@ -46,5 +55,3 @@ functions: name: integration-tests-python-${sls:stage}-sync-metrics_${env:RUNTIME} handler: handle.handle runtime: ${env:SERVERLESS_RUNTIME} - layers: - - { Ref: PythonLambdaLayer } diff --git a/tests/integration/snapshots/logs/async-metrics_python310.log b/tests/integration/snapshots/logs/async-metrics_python310.log new file mode 100644 index 000000000..6779d7ddb --- /dev/null +++ b/tests/integration/snapshots/logs/async-metrics_python310.log @@ -0,0 +1,1674 @@ +INIT_START Runtime Version: python:3.10.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:true", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python310", + "resource:integration-tests-python-XXXX-async-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python311.log b/tests/integration/snapshots/logs/async-metrics_python311.log new file mode 100644 index 000000000..9f14ff15c --- /dev/null +++ b/tests/integration/snapshots/logs/async-metrics_python311.log @@ -0,0 +1,1674 @@ +INIT_START Runtime Version: python:3.11.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:true", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python311", + "resource:integration-tests-python-XXXX-async-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python312.log b/tests/integration/snapshots/logs/async-metrics_python312.log new file mode 100644 index 000000000..789a39551 --- /dev/null +++ b/tests/integration/snapshots/logs/async-metrics_python312.log @@ -0,0 +1,1674 @@ +INIT_START Runtime Version: python:3.12.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:true", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python312", + "resource:integration-tests-python-XXXX-async-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python313.log b/tests/integration/snapshots/logs/async-metrics_python313.log new file mode 100644 index 000000000..78ade6a7a --- /dev/null +++ b/tests/integration/snapshots/logs/async-metrics_python313.log @@ -0,0 +1,1674 @@ +INIT_START Runtime Version: python:3.13.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:true", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python36.log b/tests/integration/snapshots/logs/async-metrics_python36.log deleted file mode 100644 index 423dfe9c3..000000000 --- a/tests/integration/snapshots/logs/async-metrics_python36.log +++ /dev/null @@ -1,27 +0,0 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python36", "resource:integration-tests-python-XXXX-async-metrics_python36", "cold_start:true", "memorysize:1024", "runtime:python3.6", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python36_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python36", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python36", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python36", "functionname": "integration-tests-python-XXXX-async-metrics_python36", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python36", "resource:integration-tests-python-XXXX-async-metrics_python36", "cold_start:false", "memorysize:1024", "runtime:python3.6", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python36_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python36", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python36", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python36", "functionname": "integration-tests-python-XXXX-async-metrics_python36", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python36", "resource:integration-tests-python-XXXX-async-metrics_python36", "cold_start:false", "memorysize:1024", "runtime:python3.6", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python36_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python36", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python36", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python36", "functionname": "integration-tests-python-XXXX-async-metrics_python36", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python37.log b/tests/integration/snapshots/logs/async-metrics_python37.log deleted file mode 100644 index 80880511c..000000000 --- a/tests/integration/snapshots/logs/async-metrics_python37.log +++ /dev/null @@ -1,27 +0,0 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python37", "resource:integration-tests-python-XXXX-async-metrics_python37", "cold_start:true", "memorysize:1024", "runtime:python3.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python37_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python37", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python37", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python37", "functionname": "integration-tests-python-XXXX-async-metrics_python37", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python37", "resource:integration-tests-python-XXXX-async-metrics_python37", "cold_start:false", "memorysize:1024", "runtime:python3.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python37_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python37", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python37", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python37", "functionname": "integration-tests-python-XXXX-async-metrics_python37", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python37", "resource:integration-tests-python-XXXX-async-metrics_python37", "cold_start:false", "memorysize:1024", "runtime:python3.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python37_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python37", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python37", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python37", "functionname": "integration-tests-python-XXXX-async-metrics_python37", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python38.log b/tests/integration/snapshots/logs/async-metrics_python38.log index 2359182d3..5375fafec 100644 --- a/tests/integration/snapshots/logs/async-metrics_python38.log +++ b/tests/integration/snapshots/logs/async-metrics_python38.log @@ -1,27 +1,1674 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python38", "resource:integration-tests-python-XXXX-async-metrics_python38", "cold_start:true", "memorysize:1024", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python38", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python38", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python38", "functionname": "integration-tests-python-XXXX-async-metrics_python38", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python38", "resource:integration-tests-python-XXXX-async-metrics_python38", "cold_start:false", "memorysize:1024", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python38", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python38", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python38", "functionname": "integration-tests-python-XXXX-async-metrics_python38", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python38", "resource:integration-tests-python-XXXX-async-metrics_python38", "cold_start:false", "memorysize:1024", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python38", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python38", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python38", "functionname": "integration-tests-python-XXXX-async-metrics_python38", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB +INIT_START Runtime Version: python:3.8.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:true", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python38", + "resource:integration-tests-python-XXXX-async-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python39.log b/tests/integration/snapshots/logs/async-metrics_python39.log index 9478cdcee..f16e9e2d5 100644 --- a/tests/integration/snapshots/logs/async-metrics_python39.log +++ b/tests/integration/snapshots/logs/async-metrics_python39.log @@ -1,27 +1,1674 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python39", "resource:integration-tests-python-XXXX-async-metrics_python39", "cold_start:true", "memorysize:1024", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python39", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python39", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python39", "functionname": "integration-tests-python-XXXX-async-metrics_python39", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python39", "resource:integration-tests-python-XXXX-async-metrics_python39", "cold_start:false", "memorysize:1024", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python39", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python39", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python39", "functionname": "integration-tests-python-XXXX-async-metrics_python39", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python39", "resource:integration-tests-python-XXXX-async-metrics_python39", "cold_start:false", "memorysize:1024", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X"]} -{"m": "hello.dog", "v": 1, "e": XXXX, "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"]} -{"m": "tests.integration.count", "v": 21, "e": XXXX, "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-async-metrics_python39", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python39", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-async-metrics_python39", "functionname": "integration-tests-python-XXXX-async-metrics_python39", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB +INIT_START Runtime Version: python:3.9.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:true", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python39", + "resource:integration-tests-python-XXXX-async-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "hello.dog", + "v": 1, + "e": XXXX, + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "tests.integration.count", + "v": 21, + "e": XXXX, + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python310.log b/tests/integration/snapshots/logs/sync-metrics_python310.log new file mode 100644 index 000000000..1cbd91dd8 --- /dev/null +++ b/tests/integration/snapshots/logs/sync-metrics_python310.log @@ -0,0 +1,1864 @@ +INIT_START Runtime Version: python:3.10.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:true", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python310", + "resource:integration-tests-python-XXXX-sync-metrics_python310", + "memorysize:1024", + "cold_start:false", + "runtime:python3.10", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python310_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python311.log b/tests/integration/snapshots/logs/sync-metrics_python311.log new file mode 100644 index 000000000..b043a8f47 --- /dev/null +++ b/tests/integration/snapshots/logs/sync-metrics_python311.log @@ -0,0 +1,1864 @@ +INIT_START Runtime Version: python:3.11.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:true", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python311", + "resource:integration-tests-python-XXXX-sync-metrics_python311", + "memorysize:1024", + "cold_start:false", + "runtime:python3.11", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python311_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python312.log b/tests/integration/snapshots/logs/sync-metrics_python312.log new file mode 100644 index 000000000..ff9bbdb75 --- /dev/null +++ b/tests/integration/snapshots/logs/sync-metrics_python312.log @@ -0,0 +1,1864 @@ +INIT_START Runtime Version: python:3.12.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:true", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", + "memorysize:1024", + "cold_start:false", + "runtime:python3.12", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python312_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python313.log b/tests/integration/snapshots/logs/sync-metrics_python313.log new file mode 100644 index 000000000..87352f25e --- /dev/null +++ b/tests/integration/snapshots/logs/sync-metrics_python313.log @@ -0,0 +1,1864 @@ +INIT_START Runtime Version: python:3.13.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:true", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python313", + "resource:integration-tests-python-XXXX-sync-metrics_python313", + "memorysize:1024", + "cold_start:false", + "runtime:python3.13", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python313_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python36.log b/tests/integration/snapshots/logs/sync-metrics_python36.log deleted file mode 100644 index 6ce824ee6..000000000 --- a/tests/integration/snapshots/logs/sync-metrics_python36.log +++ /dev/null @@ -1,24 +0,0 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python36", "resource:integration-tests-python-XXXX-sync-metrics_python36", "cold_start:true", "memorysize:1024", "runtime:python3.6", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python36_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python36", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python36", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python36", "functionname": "integration-tests-python-XXXX-sync-metrics_python36", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python36", "resource:integration-tests-python-XXXX-sync-metrics_python36", "cold_start:false", "memorysize:1024", "runtime:python3.6", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python36_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python36", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python36", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python36", "functionname": "integration-tests-python-XXXX-sync-metrics_python36", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python36", "resource:integration-tests-python-XXXX-sync-metrics_python36", "cold_start:false", "memorysize:1024", "runtime:python3.6", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python36_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python36_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python36", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python36", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python36", "functionname": "integration-tests-python-XXXX-sync-metrics_python36", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python37.log b/tests/integration/snapshots/logs/sync-metrics_python37.log deleted file mode 100644 index 39906139d..000000000 --- a/tests/integration/snapshots/logs/sync-metrics_python37.log +++ /dev/null @@ -1,24 +0,0 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python37", "resource:integration-tests-python-XXXX-sync-metrics_python37", "cold_start:true", "memorysize:1024", "runtime:python3.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python37_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python37", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python37", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python37", "functionname": "integration-tests-python-XXXX-sync-metrics_python37", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python37", "resource:integration-tests-python-XXXX-sync-metrics_python37", "cold_start:false", "memorysize:1024", "runtime:python3.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python37_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python37", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python37", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python37", "functionname": "integration-tests-python-XXXX-sync-metrics_python37", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python37", "resource:integration-tests-python-XXXX-sync-metrics_python37", "cold_start:false", "memorysize:1024", "runtime:python3.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python37_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python37_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python37", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python37", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python37", "functionname": "integration-tests-python-XXXX-sync-metrics_python37", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python38.log b/tests/integration/snapshots/logs/sync-metrics_python38.log index 83bce86ed..ae41bc18d 100644 --- a/tests/integration/snapshots/logs/sync-metrics_python38.log +++ b/tests/integration/snapshots/logs/sync-metrics_python38.log @@ -1,24 +1,1864 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python38", "resource:integration-tests-python-XXXX-sync-metrics_python38", "cold_start:true", "memorysize:1024", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python38", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python38", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python38", "resource:integration-tests-python-XXXX-sync-metrics_python38", "cold_start:false", "memorysize:1024", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python38", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python38", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python38", "resource:integration-tests-python-XXXX-sync-metrics_python38", "cold_start:false", "memorysize:1024", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python38", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python38", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB +INIT_START Runtime Version: python:3.8.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:true", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python38", + "resource:integration-tests-python-XXXX-sync-metrics_python38", + "memorysize:1024", + "cold_start:false", + "runtime:python3.8", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python38_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python39.log b/tests/integration/snapshots/logs/sync-metrics_python39.log index 4f186d3b8..1acb7f0da 100644 --- a/tests/integration/snapshots/logs/sync-metrics_python39.log +++ b/tests/integration/snapshots/logs/sync-metrics_python39.log @@ -1,24 +1,1864 @@ -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python39", "resource:integration-tests-python-XXXX-sync-metrics_python39", "cold_start:true", "memorysize:1024", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python39", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "true", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python39", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "http.method": "GET", "function.request.path": "/test/hello", "function.request.headers.Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "function.request.headers.Accept-Encoding": "gzip, deflate, lzma, sdch, br", "function.request.headers.Accept-Language": "en-US,en;q=0.8", "function.request.headers.CloudFront-Forwarded-Proto": "https", "function.request.headers.CloudFront-Is-Desktop-Viewer": "True", "function.request.headers.CloudFront-Is-Mobile-Viewer": "False", "function.request.headers.CloudFront-Is-SmartTV-Viewer": "False", "function.request.headers.CloudFront-Is-Tablet-Viewer": "False", "function.request.headers.CloudFront-Viewer-Country": "US", "function.request.headers.Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "function.request.headers.User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.headers.Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "function.request.headers.X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "function.request.headers.X-Forwarded-For": "192.168.100.1, 192.168.1.1", "function.request.headers.X-Forwarded-Proto": "https", "function.request.pathParameters.proxy": "hello", "function.request.requestContext.resourceId": "us4z18", "function.request.requestContext.stage": "test", "function.request.requestContext.requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "function.request.requestContext.identity.cognitoIdentityPoolId": "", "function.request.requestContext.identity.accountId": "", "function.request.requestContext.identity.cognitoIdentityId": "", "function.request.requestContext.identity.caller": "", "function.request.requestContext.identity.apiKey": "", "function.request.requestContext.identity.sourceIp": "192.168.100.1", "function.request.requestContext.identity.cognitoAuthenticationType": "", "function.request.requestContext.identity.cognitoAuthenticationProvider": "", "function.request.requestContext.identity.userArn": "", "function.request.requestContext.identity.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "function.request.requestContext.identity.user": "", "function.request.requestContext.resourcePath": "/{proxy+}", "function.request.requestContext.httpMethod": "GET", "function.request.requestContext.apiId": "wt6mne2s9k", "function.request.resource": "/{proxy+}", "function.request.httpMethod": "GET", "function.request.queryStringParameters.name": "me", "function.request.stageVariables.stageVarName": "stageVarValue", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "http.status_code": "200"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.headers.Upgrade-Insecure-Requests": 1, "function.request.headers.X-Forwarded-Port": 443, "function.request.requestContext.accountId": 123456789012, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python39", "resource:integration-tests-python-XXXX-sync-metrics_python39", "cold_start:false", "memorysize:1024", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python39", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python39", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sns", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.EventSource": "aws:sns", "function.request.Records.0.Sns.Timestamp": "2019-01-02T12:45:07.000Z", "function.request.Records.0.Sns.Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "function.request.Records.0.Sns.SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "function.request.Records.0.Sns.MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "function.request.Records.0.Sns.Message": "Hello from SNS!", "function.request.Records.0.Sns.MessageAttributes.Test.Type": "String", "function.request.Records.0.Sns.MessageAttributes.Test.Value": "TestString", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Type": "Binary", "function.request.Records.0.Sns.MessageAttributes.TestBinary.Value": "TestBinary", "function.request.Records.0.Sns.Type": "Notification", "function.request.Records.0.Sns.UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "function.request.Records.0.Sns.TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function.request.Records.0.Sns.Subject": "TestInvoke", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}, "metrics": {"_dd.agent_psr": 1.0, "system.pid": XXXX, "function.request.Records.0.EventVersion": 1.0, "function.request.Records.0.Sns.SignatureVersion": 1, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB -START RequestId: XXXX Version: $LATEST -{"m": "aws.lambda.enhanced.invocations", "v": 1, "e": XXXX, "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python39", "resource:integration-tests-python-XXXX-sync-metrics_python39", "cold_start:false", "memorysize:1024", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X"]} -HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {} -HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Encoding:deflate", "Content-Length:XXXX", "Content-Type:application/json", "User-Agent:datadogpy/0.41.0 (python XX; os linux; arch x86_64)", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"metric": "hello.dog", "points": [[XXXX, [1.0]]], "type": "distribution", "host": null, "device": null, "tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"], "interval": 10}, {"metric": "tests.integration.count", "points": [[XXXX, [21.0]]], "type": "distribution", "host": null, "device": null, "tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X"], "interval": 10}]} -{"traces": [[{"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "integration-tests-python-XXXX-sync-metrics_python39", "name": "aws.lambda", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"runtime-id": "XXXX", "_dd.origin": "lambda", "cold_start": "false", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-sync-metrics_python39", "function_version": "$LATEST", "request_id": "XXXX", "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "function_trigger.event_source": "sqs", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.request.Records.0.receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "function.request.Records.0.body": "Test message.", "function.request.Records.0.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.0.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.0.eventSource": "aws:sqs", "function.request.Records.0.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.0.awsRegion": "us-east-2", "function.request.Records.1.messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "function.request.Records.1.receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "function.request.Records.1.body": "Test message.", "function.request.Records.1.attributes.SenderId": "AIDAIENQZJOLO23YVJ4VO", "function.request.Records.1.md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "function.request.Records.1.eventSource": "aws:sqs", "function.request.Records.1.eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function.request.Records.1.awsRegion": "us-east-2", "function.response.body.message": "hello, dog!", "function.response.body.request_id": "None", "function.response.body.event_record_ids.0": "059f36b4-87a3-44ab-83d2-661975830a7d", "function.response.body.event_record_ids.1": "2e1424d4-f796-459a-8184-9c92662be6da"}, "metrics": {"system.pid": XXXX, "function.request.Records.0.attributes.ApproximateReceiveCount": 1, "function.request.Records.0.attributes.SentTimestamp": 1545082649183, "function.request.Records.0.attributes.ApproximateFirstReceiveTimestamp": 1545082649185, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-trace-id": 666, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-parent-id": 777, "function.request.Records.0.messageAttributes._datadog.stringValue.x-datadog-sampling-priority": 1, "function.request.Records.1.attributes.ApproximateReceiveCount": 1, "function.request.Records.1.attributes.SentTimestamp": 1545082650636, "function.request.Records.1.attributes.ApproximateFirstReceiveTimestamp": 1545082650649, "function.response.statusCode": 200, "_sampling_priority_v1": 1}, "type": "serverless"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/200/", "http.status_code": "200"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "GET", "http.url": "https://httpstat.us/400/", "http.status_code": "400"}, "metrics": {"_dd.measured": 1}, "type": "http"}, {"trace_id": "XXXX", "parent_id": "XXXX", "span_id": "XXXX", "service": "aws.lambda", "resource": "requests.request", "name": "requests.request", "error": 0, "start": XXXX, "duration": XXXX, "meta": {"_dd.origin": "lambda", "http.method": "POST", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202"}, "metrics": {"_dd.measured": 1}, "type": "http"}]]} -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB +INIT_START Runtime Version: python:3.9.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:true", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "resource": "GET /", + "name": "aws.apigateway", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.rest", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/", + "endpoint": "/", + "http.method": "GET", + "resource_names": "GET /", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "Prod", + "request_id": "XXXX", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "true", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.us-east-2.amazonaws.com/Prod/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +{ + "m": "datadog.serverless.dynamodb.stream.type", + "v": 1, + "e": XXXX, + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "ExampleTableWithStream", + "resource": "ExampleTableWithStream", + "name": "aws.dynamodb", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.dynamodb", + "resource_names": "ExampleTableWithStream", + "span.kind": "server", + "tablename": "ExampleTableWithStream", + "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_id": "XXXX", + "event_name": "INSERT", + "event_version": "1.1", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "size_bytes": "26", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + }, + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.dynamodb.item", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "eventbridge.custom.event.sender", + "resource": "eventbridge.custom.event.sender", + "name": "aws.eventbridge", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.eventbridge", + "resource_names": "eventbridge.custom.event.sender", + "span.kind": "server", + "detail_type": "testdetail", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "eventbridge" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "GET /httpapi/get", + "name": "aws.httpapi", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.httpapi", + "endpoint": "/httpapi/get", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "XXXX", + "http.user_agent": "XXXX/7.64.1", + "resource_names": "GET /httpapi/get", + "request_id": "XXXX", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "$default", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "http.route": "/httpapi/get", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "EXAMPLE", + "resource": "EXAMPLE", + "name": "aws.kinesis", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.kinesis", + "resource_names": "EXAMPLE", + "span.kind": "server", + "streamname": "EXAMPLE", + "shardid": "shardId-XXXX", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_version": "1.0", + "partition_key": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "example-bucket", + "resource": "example-bucket", + "name": "aws.s3", + "error": 0, + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.s3", + "resource_names": "example-bucket", + "span.kind": "server", + "event_name": "ObjectCreated:Put", + "bucketname": "example-bucket", + "bucket_arn": "arn:aws:s3:::example-bucket", + "object_key": "test/key", + "object_size": "1024", + "object_etag": "XXXX", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web", + "span_links": [ + { + "trace_id": "XXXX", + "span_id": "XXXX", + "attributes": { + "ptr.kind": "aws.s3.object", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "link.kind": "span-pointer" + } + } + ] + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "sns-lambda", + "resource": "sns-lambda", + "name": "aws.sns", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sns", + "resource_names": "sns-lambda", + "span.kind": "server", + "topicname": "sns-lambda", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "message_id": "XXXX", + "type": "Notification", + "subject": "TestInvoke", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "my-queue", + "resource": "my-queue", + "name": "aws.sqs", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.sqs", + "resource_names": "my-queue", + "span.kind": "server", + "queuename": "my-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "m": "aws.lambda.enhanced.invocations", + "v": 1, + "e": XXXX, + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python39", + "resource:integration-tests-python-XXXX-sync-metrics_python39", + "memorysize:1024", + "cold_start:false", + "runtime:python3.9", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python39_X.X.X" + ] +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "resource": "$default", + "name": "aws.apigateway.websocket", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "operation_name": "aws.apigateway.websocket", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com$default/", + "endpoint": "$default", + "resource_names": "$default", + "span.kind": "server", + "apiid": "XXXX", + "apiname": "XXXX", + "stage": "dev", + "request_id": "XXXX", + "connection_id": "XXXX=", + "event_type": "MESSAGE", + "message_direction": "IN", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "http.status_code": "200", + "peer.service": "integration-tests-python", + "_dd.peer.service.source": "peer.service", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "web" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "integration-tests-python", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "name": "aws.lambda", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "span.name": "aws.lambda", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "span.kind": "server", + "http.url": "https://xxxx.execute-api.eu-west-1.amazonaws.com/", + "http.status_code": "200" + }, + "metrics": { + "_dd.top_level": 1 + }, + "type": "serverless" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://datadoghq.com/", + "out.host": "datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "type": "http" + }, + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "GET /", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "_dd.p.tid": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "GET", + "http.url": "https://www.datadoghq.com/", + "out.host": "www.datadoghq.com", + "http.status_code": "200", + "http.useragent": "python-requests/X.X.X" + }, + "metrics": { + "_dd.measured": 1 + }, + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "trace_id": "XXXX", + "parent_id": "XXXX", + "span_id": "XXXX", + "service": "requests", + "resource": "POST /api/v1/distribution_points", + "name": "requests.request", + "error": 0, + "start": "XXXX", + "duration": "XXXX", + "meta": { + "runtime-id": "XXXX", + "_dd.origin": "lambda", + "component": "requests", + "span.kind": "client", + "http.method": "POST", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "out.host": "api.datadoghq.com", + "http.status_code": "202", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "language": "python" + }, + "metrics": { + "process_id": XXXX, + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1 + }, + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/return_values/async-metrics_python39_api-gateway-get.json b/tests/integration/snapshots/return_values/async-metrics_api-gateway-get.json similarity index 64% rename from tests/integration/snapshots/return_values/async-metrics_python39_api-gateway-get.json rename to tests/integration/snapshots/return_values/async-metrics_api-gateway-get.json index 220380935..64b724471 100644 --- a/tests/integration/snapshots/return_values/async-metrics_python39_api-gateway-get.json +++ b/tests/integration/snapshots/return_values/async-metrics_api-gateway-get.json @@ -2,7 +2,7 @@ "statusCode": 200, "body": { "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", + "request_id": "77375676-xmpl-4b79-853a-f982474efe18", "event_record_ids": [] } } diff --git a/tests/integration/snapshots/return_values/async-metrics_python38_api-gateway-get.json b/tests/integration/snapshots/return_values/async-metrics_appsync.json similarity index 64% rename from tests/integration/snapshots/return_values/async-metrics_python38_api-gateway-get.json rename to tests/integration/snapshots/return_values/async-metrics_appsync.json index 220380935..1ad668ecc 100644 --- a/tests/integration/snapshots/return_values/async-metrics_python38_api-gateway-get.json +++ b/tests/integration/snapshots/return_values/async-metrics_appsync.json @@ -2,7 +2,7 @@ "statusCode": 200, "body": { "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", + "request_id": null, "event_record_ids": [] } } diff --git a/tests/integration/snapshots/return_values/async-metrics_python37_api-gateway-get.json b/tests/integration/snapshots/return_values/async-metrics_dynamodb.json similarity index 64% rename from tests/integration/snapshots/return_values/async-metrics_python37_api-gateway-get.json rename to tests/integration/snapshots/return_values/async-metrics_dynamodb.json index 220380935..1ad668ecc 100644 --- a/tests/integration/snapshots/return_values/async-metrics_python37_api-gateway-get.json +++ b/tests/integration/snapshots/return_values/async-metrics_dynamodb.json @@ -2,7 +2,7 @@ "statusCode": 200, "body": { "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", + "request_id": null, "event_record_ids": [] } } diff --git a/tests/integration/snapshots/return_values/async-metrics_python36_api-gateway-get.json b/tests/integration/snapshots/return_values/async-metrics_eventbridge-custom.json similarity index 64% rename from tests/integration/snapshots/return_values/async-metrics_python36_api-gateway-get.json rename to tests/integration/snapshots/return_values/async-metrics_eventbridge-custom.json index 220380935..1ad668ecc 100644 --- a/tests/integration/snapshots/return_values/async-metrics_python36_api-gateway-get.json +++ b/tests/integration/snapshots/return_values/async-metrics_eventbridge-custom.json @@ -2,7 +2,7 @@ "statusCode": 200, "body": { "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", + "request_id": null, "event_record_ids": [] } } diff --git a/tests/integration/snapshots/return_values/async-metrics_http-api copy.json b/tests/integration/snapshots/return_values/async-metrics_http-api copy.json new file mode 100644 index 000000000..d279e5e29 --- /dev/null +++ b/tests/integration/snapshots/return_values/async-metrics_http-api copy.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": "FaHnXjKCGjQEJ7A=", + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/async-metrics_http-api.json b/tests/integration/snapshots/return_values/async-metrics_http-api.json new file mode 100644 index 000000000..d279e5e29 --- /dev/null +++ b/tests/integration/snapshots/return_values/async-metrics_http-api.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": "FaHnXjKCGjQEJ7A=", + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/async-metrics_kinesis.json b/tests/integration/snapshots/return_values/async-metrics_kinesis.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/async-metrics_kinesis.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": null, + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/async-metrics_python27_api-gateway-get.json b/tests/integration/snapshots/return_values/async-metrics_python27_api-gateway-get.json deleted file mode 100644 index d8e93bb00..000000000 --- a/tests/integration/snapshots/return_values/async-metrics_python27_api-gateway-get.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "body": { - "message": "hello, dog!", - "event_record_ids": [], - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9" - }, - "statusCode": 200 -} diff --git a/tests/integration/snapshots/return_values/async-metrics_python27_sns.json b/tests/integration/snapshots/return_values/async-metrics_python27_sns.json deleted file mode 100644 index 08cbae602..000000000 --- a/tests/integration/snapshots/return_values/async-metrics_python27_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "body": { - "message": "hello, dog!", - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ], - "request_id": null - }, - "statusCode": 200 -} diff --git a/tests/integration/snapshots/return_values/async-metrics_python27_sqs.json b/tests/integration/snapshots/return_values/async-metrics_python27_sqs.json deleted file mode 100644 index 03f2a6cdf..000000000 --- a/tests/integration/snapshots/return_values/async-metrics_python27_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "body": { - "message": "hello, dog!", - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ], - "request_id": null - }, - "statusCode": 200 -} diff --git a/tests/integration/snapshots/return_values/async-metrics_python38_sns.json b/tests/integration/snapshots/return_values/async-metrics_python38_sns.json deleted file mode 100644 index e1f007e65..000000000 --- a/tests/integration/snapshots/return_values/async-metrics_python38_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ] - } -} diff --git a/tests/integration/snapshots/return_values/async-metrics_python38_sqs.json b/tests/integration/snapshots/return_values/async-metrics_python38_sqs.json deleted file mode 100644 index 970f7dff2..000000000 --- a/tests/integration/snapshots/return_values/async-metrics_python38_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ] - } -} diff --git a/tests/integration/snapshots/return_values/async-metrics_python39_sns.json b/tests/integration/snapshots/return_values/async-metrics_python39_sns.json deleted file mode 100644 index e1f007e65..000000000 --- a/tests/integration/snapshots/return_values/async-metrics_python39_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ] - } -} diff --git a/tests/integration/snapshots/return_values/async-metrics_python39_sqs.json b/tests/integration/snapshots/return_values/async-metrics_python39_sqs.json deleted file mode 100644 index 970f7dff2..000000000 --- a/tests/integration/snapshots/return_values/async-metrics_python39_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ] - } -} diff --git a/tests/integration/snapshots/return_values/async-metrics_s3.json b/tests/integration/snapshots/return_values/async-metrics_s3.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/async-metrics_s3.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": null, + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/async-metrics_python36_sns.json b/tests/integration/snapshots/return_values/async-metrics_sns.json similarity index 100% rename from tests/integration/snapshots/return_values/async-metrics_python36_sns.json rename to tests/integration/snapshots/return_values/async-metrics_sns.json diff --git a/tests/integration/snapshots/return_values/async-metrics_python36_sqs.json b/tests/integration/snapshots/return_values/async-metrics_sqs.json similarity index 100% rename from tests/integration/snapshots/return_values/async-metrics_python36_sqs.json rename to tests/integration/snapshots/return_values/async-metrics_sqs.json diff --git a/tests/integration/snapshots/return_values/async-metrics_websocket.json b/tests/integration/snapshots/return_values/async-metrics_websocket.json new file mode 100644 index 000000000..d888139d2 --- /dev/null +++ b/tests/integration/snapshots/return_values/async-metrics_websocket.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": "Fc5S3EvdGjQFtsQ=", + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/sync-metrics_api-gateway-get.json b/tests/integration/snapshots/return_values/sync-metrics_api-gateway-get.json new file mode 100644 index 000000000..64b724471 --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_api-gateway-get.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": "77375676-xmpl-4b79-853a-f982474efe18", + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/sync-metrics_appsync.json b/tests/integration/snapshots/return_values/sync-metrics_appsync.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_appsync.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": null, + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/sync-metrics_dynamodb.json b/tests/integration/snapshots/return_values/sync-metrics_dynamodb.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_dynamodb.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": null, + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/sync-metrics_eventbridge-custom.json b/tests/integration/snapshots/return_values/sync-metrics_eventbridge-custom.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_eventbridge-custom.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": null, + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/sync-metrics_http-api.json b/tests/integration/snapshots/return_values/sync-metrics_http-api.json new file mode 100644 index 000000000..d279e5e29 --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_http-api.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": "FaHnXjKCGjQEJ7A=", + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/sync-metrics_kinesis.json b/tests/integration/snapshots/return_values/sync-metrics_kinesis.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_kinesis.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": null, + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python27_api-gateway-get.json b/tests/integration/snapshots/return_values/sync-metrics_python27_api-gateway-get.json deleted file mode 100644 index d8e93bb00..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python27_api-gateway-get.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "body": { - "message": "hello, dog!", - "event_record_ids": [], - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9" - }, - "statusCode": 200 -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python27_sns.json b/tests/integration/snapshots/return_values/sync-metrics_python27_sns.json deleted file mode 100644 index 08cbae602..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python27_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "body": { - "message": "hello, dog!", - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ], - "request_id": null - }, - "statusCode": 200 -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python27_sqs.json b/tests/integration/snapshots/return_values/sync-metrics_python27_sqs.json deleted file mode 100644 index 03f2a6cdf..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python27_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "body": { - "message": "hello, dog!", - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ], - "request_id": null - }, - "statusCode": 200 -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python36_api-gateway-get.json b/tests/integration/snapshots/return_values/sync-metrics_python36_api-gateway-get.json deleted file mode 100644 index 220380935..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python36_api-gateway-get.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", - "event_record_ids": [] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python36_sns.json b/tests/integration/snapshots/return_values/sync-metrics_python36_sns.json deleted file mode 100644 index e1f007e65..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python36_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python36_sqs.json b/tests/integration/snapshots/return_values/sync-metrics_python36_sqs.json deleted file mode 100644 index 970f7dff2..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python36_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python37_api-gateway-get.json b/tests/integration/snapshots/return_values/sync-metrics_python37_api-gateway-get.json deleted file mode 100644 index 220380935..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python37_api-gateway-get.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", - "event_record_ids": [] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python37_sns.json b/tests/integration/snapshots/return_values/sync-metrics_python37_sns.json deleted file mode 100644 index e1f007e65..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python37_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python37_sqs.json b/tests/integration/snapshots/return_values/sync-metrics_python37_sqs.json deleted file mode 100644 index 970f7dff2..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python37_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python38_api-gateway-get.json b/tests/integration/snapshots/return_values/sync-metrics_python38_api-gateway-get.json deleted file mode 100644 index 220380935..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python38_api-gateway-get.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", - "event_record_ids": [] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python38_sns.json b/tests/integration/snapshots/return_values/sync-metrics_python38_sns.json deleted file mode 100644 index e1f007e65..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python38_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python38_sqs.json b/tests/integration/snapshots/return_values/sync-metrics_python38_sqs.json deleted file mode 100644 index 970f7dff2..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python38_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python39_api-gateway-get.json b/tests/integration/snapshots/return_values/sync-metrics_python39_api-gateway-get.json deleted file mode 100644 index 220380935..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python39_api-gateway-get.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", - "event_record_ids": [] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python39_sns.json b/tests/integration/snapshots/return_values/sync-metrics_python39_sns.json deleted file mode 100644 index e1f007e65..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python39_sns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "95df01b4-ee98-5cb9-9903-4c221d41eb5e" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_python39_sqs.json b/tests/integration/snapshots/return_values/sync-metrics_python39_sqs.json deleted file mode 100644 index 970f7dff2..000000000 --- a/tests/integration/snapshots/return_values/sync-metrics_python39_sqs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "statusCode": 200, - "body": { - "message": "hello, dog!", - "request_id": null, - "event_record_ids": [ - "059f36b4-87a3-44ab-83d2-661975830a7d", - "2e1424d4-f796-459a-8184-9c92662be6da" - ] - } -} diff --git a/tests/integration/snapshots/return_values/sync-metrics_s3.json b/tests/integration/snapshots/return_values/sync-metrics_s3.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_s3.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": null, + "event_record_ids": [] + } +} diff --git a/tests/integration/snapshots/return_values/async-metrics_python37_sns.json b/tests/integration/snapshots/return_values/sync-metrics_sns.json similarity index 100% rename from tests/integration/snapshots/return_values/async-metrics_python37_sns.json rename to tests/integration/snapshots/return_values/sync-metrics_sns.json diff --git a/tests/integration/snapshots/return_values/async-metrics_python37_sqs.json b/tests/integration/snapshots/return_values/sync-metrics_sqs.json similarity index 100% rename from tests/integration/snapshots/return_values/async-metrics_python37_sqs.json rename to tests/integration/snapshots/return_values/sync-metrics_sqs.json diff --git a/tests/integration/snapshots/return_values/sync-metrics_websocket.json b/tests/integration/snapshots/return_values/sync-metrics_websocket.json new file mode 100644 index 000000000..d888139d2 --- /dev/null +++ b/tests/integration/snapshots/return_values/sync-metrics_websocket.json @@ -0,0 +1,8 @@ +{ + "statusCode": 200, + "body": { + "message": "hello, dog!", + "request_id": "Fc5S3EvdGjQFtsQ=", + "event_record_ids": [] + } +} diff --git a/tests/integration/yarn.lock b/tests/integration/yarn.lock index 867a90abe..7477e8dae 100644 --- a/tests/integration/yarn.lock +++ b/tests/integration/yarn.lock @@ -2,7 +2,679 @@ # yarn lockfile v1 +"@iarna/toml@^2.2.5": + version "2.2.5" + resolved "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz" + integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== + +"2-thenable@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/2-thenable/-/2-thenable-1.0.0.tgz" + integrity sha512-HqiDzaLDFCXkcCO/SwoyhRwqYtINFHF7t9BDRq4x90TOKNAJpiqUt9X5lQ08bwxYzc067HUywDjGySpebHcUpw== + dependencies: + d "1" + es5-ext "^0.10.47" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +appdirectory@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/appdirectory/-/appdirectory-0.1.0.tgz" + integrity sha512-DJ5DV8vZXBbusyiyPlH28xppwS8eAMRuuyMo88xeEcf4bV64lbLtbxRxqixZuJBXsZzLtXFmA13GwVjJc7vdQw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +brace-expansion@^1.1.7: + version "1.1.12" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +child-process-ext@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/child-process-ext/-/child-process-ext-2.1.1.tgz" + integrity sha512-0UQ55f51JBkOFa+fvR76ywRzxiPwQS3Xe8oe5bZRphpv+dIMeerW5Zn5e4cUy4COJwVtJyU0R79RMnw+aCqmGA== + dependencies: + cross-spawn "^6.0.5" + es5-ext "^0.10.53" + log "^6.0.0" + split2 "^3.1.1" + stream-promise "^3.2.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-spawn@^6.0.5: + version "6.0.6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz" + integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +d@^1.0.1, d@^1.0.2, d@1: + version "1.0.2" + resolved "https://registry.npmjs.org/d/-/d-1.0.2.tgz" + integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw== + dependencies: + es5-ext "^0.10.64" + type "^2.7.2" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +duration@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz" + integrity sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg== + dependencies: + d "1" + es5-ext "~0.10.46" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +es5-ext@^0.10.35, es5-ext@^0.10.47, es5-ext@^0.10.49, es5-ext@^0.10.53, es5-ext@^0.10.62, es5-ext@^0.10.64, es5-ext@~0.10.14, es5-ext@~0.10.46: + version "0.10.64" + resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + esniff "^2.0.1" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.4" + resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz" + integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== + dependencies: + d "^1.0.2" + ext "^1.7.0" + +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + +ext@^1.7.0: + version "1.7.0" + resolved "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob-all@^3.3.1: + version "3.3.1" + resolved "https://registry.npmjs.org/glob-all/-/glob-all-3.3.1.tgz" + integrity sha512-Y+ESjdI7ZgMwfzanHZYQ87C59jOO0i+Hd+QYtVt9PhLi6d8wlOpzQnfBxWUlaTuAoR3TkybLqqbIoWveU4Ji7Q== + dependencies: + glob "^7.2.3" + yargs "^15.3.1" + +glob@^7.1.3, glob@^7.2.3: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@^2.0.3, inherits@~2.0.3, inherits@2: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-primitive@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz" + integrity sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jszip@^3.10.1: + version "3.10.1" + resolved "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + +lodash.uniqby@^4.7.0: + version "4.7.0" + resolved "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz" + integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww== + +lodash.values@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz" + integrity sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q== + +log@^6.0.0: + version "6.3.2" + resolved "https://registry.npmjs.org/log/-/log-6.3.2.tgz" + integrity sha512-ek8NRg/OPvS9ISOJNWNAz5vZcpYacWNFDWNJjj5OXsc6YuKacfey6wF04cXz/tOJIVrZ2nGSkHpAY5qKtF6ISg== + dependencies: + d "^1.0.2" + duration "^0.2.2" + es5-ext "^0.10.64" + event-emitter "^0.3.5" + sprintf-kit "^2.0.2" + type "^2.7.3" + uni-global "^1.0.0" + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +readable-stream@^3.0.0: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +semver@^5.5.0: + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^7.6.0: + version "7.6.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + serverless-plugin-datadog@^2.18.0: version "2.18.0" - resolved "https://registry.yarnpkg.com/serverless-plugin-datadog/-/serverless-plugin-datadog-2.18.0.tgz#8af9903f0867eaac4789c3908e100f4c0e11c578" + resolved "https://registry.npmjs.org/serverless-plugin-datadog/-/serverless-plugin-datadog-2.18.0.tgz" integrity sha512-RUdCNjUk+uUKQYgQBjK0WNeYJ7lM2/RScqg/LjVSfv5EACeJ3iIUPz1c4bS2jtiH05al8qXudNb6QDkv9zxG7w== + +serverless-python-requirements@^6.1.2: + version "6.1.2" + resolved "https://registry.npmjs.org/serverless-python-requirements/-/serverless-python-requirements-6.1.2.tgz" + integrity sha512-pas27CBxxaLTU5XMYnCVPJc+LVdm65Ys5olNvRWRqfUaZwTfD/7KSSt2XPSRme8BeJubroslaiOtWPP+IrxTVA== + dependencies: + "@iarna/toml" "^2.2.5" + appdirectory "^0.1.0" + bluebird "^3.7.2" + child-process-ext "^2.1.1" + fs-extra "^10.1.0" + glob-all "^3.3.1" + is-wsl "^2.2.0" + jszip "^3.10.1" + lodash.get "^4.4.2" + lodash.uniqby "^4.7.0" + lodash.values "^4.3.0" + rimraf "^3.0.2" + semver "^7.6.0" + set-value "^4.1.0" + sha256-file "1.0.0" + shell-quote "^1.8.1" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-value@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz" + integrity sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw== + dependencies: + is-plain-object "^2.0.4" + is-primitive "^3.0.1" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +sha256-file@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/sha256-file/-/sha256-file-1.0.0.tgz" + integrity sha512-nqf+g0veqgQAkDx0U2y2Tn2KWyADuuludZTw9A7J3D+61rKlIIl9V5TS4mfnwKuXZOH9B7fQyjYJ9pKRHIsAyg== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +shell-quote@^1.8.1: + version "1.8.2" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz" + integrity sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA== + +split2@^3.1.1: + version "3.2.2" + resolved "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz" + integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== + dependencies: + readable-stream "^3.0.0" + +sprintf-kit@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/sprintf-kit/-/sprintf-kit-2.0.2.tgz" + integrity sha512-lnapdj6W4LflHZGKvl9eVkz5YF0xaTrqpRWVA4cNVOTedwqifIP8ooGImldzT/4IAN5KXFQAyXTdLidYVQdyag== + dependencies: + es5-ext "^0.10.64" + +stream-promise@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/stream-promise/-/stream-promise-3.2.0.tgz" + integrity sha512-P+7muTGs2C8yRcgJw/PPt61q7O517tDHiwYEzMWo1GSBCcZedUMT/clz7vUNsSxFphIlJ6QUL4GexQKlfJoVtA== + dependencies: + "2-thenable" "^1.0.0" + es5-ext "^0.10.49" + is-stream "^1.1.0" + +string_decoder@^1.1.1, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +type@^2.5.0, type@^2.7.2, type@^2.7.3: + version "2.7.3" + resolved "https://registry.npmjs.org/type/-/type-2.7.3.tgz" + integrity sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ== + +uni-global@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/uni-global/-/uni-global-1.0.0.tgz" + integrity sha512-WWM3HP+siTxzIWPNUg7hZ4XO8clKi6NoCAJJWnuRL+BAqyFXF8gC03WNyTefGoUXYc47uYgXxpKLIEvo65PEHw== + dependencies: + type "^2.5.0" + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +which-module@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" diff --git a/tests/test_api.py b/tests/test_api.py new file mode 100644 index 000000000..7fcc3c221 --- /dev/null +++ b/tests/test_api.py @@ -0,0 +1,143 @@ +import os +import unittest +from unittest.mock import MagicMock, patch + +import datadog_lambda.api as api + + +class TestDatadogLambdaAPI(unittest.TestCase): + def setUp(self): + api.api_key = None + self.env_patcher = patch.dict( + os.environ, + { + "DD_API_KEY_SECRET_ARN": "", + "DD_API_KEY_SSM_NAME": "", + "DD_KMS_API_KEY": "", + "DD_API_KEY": "", + "DATADOG_API_KEY": "", + "AWS_REGION": "", + }, + clear=True, + ) + self.env_patcher.start() + + def tearDown(self): + del os.environ["AWS_REGION"] + + @patch("datadog_lambda.config.Config.fips_mode_enabled", True) + @patch("botocore.session.Session.create_client") + def test_secrets_manager_fips_endpoint(self, mock_boto3_client): + mock_client = MagicMock() + mock_client.get_secret_value.return_value = {"SecretString": "test-api-key"} + mock_boto3_client.return_value = mock_client + + os.environ["AWS_REGION"] = "us-gov-east-1" + os.environ[ + "DD_API_KEY_SECRET_ARN" + ] = "arn:aws:secretsmanager:us-gov-east-1:1234567890:secret:key-name-123ABC" + + api_key = api.get_api_key() + + mock_boto3_client.assert_called_with( + "secretsmanager", + endpoint_url="https://secretsmanager-fips.us-gov-east-1.amazonaws.com/", + region_name="us-gov-east-1", + ) + self.assertEqual(api_key, "test-api-key") + + @patch("botocore.session.Session.create_client") + def test_secrets_manager_different_region(self, mock_boto3_client): + mock_client = MagicMock() + mock_client.get_secret_value.return_value = {"SecretString": "test-api-key"} + mock_boto3_client.return_value = mock_client + + os.environ["AWS_REGION"] = "us-east-1" + os.environ[ + "DD_API_KEY_SECRET_ARN" + ] = "arn:aws:secretsmanager:us-west-1:1234567890:secret:key-name-123ABC" + + api_key = api.get_api_key() + + mock_boto3_client.assert_called_with( + "secretsmanager", + endpoint_url=None, + region_name="us-west-1", + ) + self.assertEqual(api_key, "test-api-key") + + @patch("datadog_lambda.config.Config.fips_mode_enabled", True) + @patch("botocore.session.Session.create_client") + def test_secrets_manager_different_region_but_still_fips(self, mock_boto3_client): + mock_client = MagicMock() + mock_client.get_secret_value.return_value = {"SecretString": "test-api-key"} + mock_boto3_client.return_value = mock_client + + os.environ["AWS_REGION"] = "us-east-1" + os.environ[ + "DD_API_KEY_SECRET_ARN" + ] = "arn:aws:secretsmanager:us-west-1:1234567890:secret:key-name-123ABC" + + api_key = api.get_api_key() + + mock_boto3_client.assert_called_with( + "secretsmanager", + endpoint_url="https://secretsmanager-fips.us-west-1.amazonaws.com/", + region_name="us-west-1", + ) + self.assertEqual(api_key, "test-api-key") + + @patch("datadog_lambda.config.Config.fips_mode_enabled", True) + @patch("botocore.session.Session.create_client") + def test_ssm_fips_endpoint(self, mock_boto3_client): + mock_client = MagicMock() + mock_client.get_parameter.return_value = { + "Parameter": {"Value": "test-api-key"} + } + mock_boto3_client.return_value = mock_client + + os.environ["AWS_REGION"] = "us-gov-west-1" + os.environ["DD_API_KEY_SSM_NAME"] = "test-ssm-param" + + api_key = api.get_api_key() + + mock_boto3_client.assert_called_with( + "ssm", endpoint_url="https://ssm-fips.us-gov-west-1.amazonaws.com/" + ) + self.assertEqual(api_key, "test-api-key") + + @patch("datadog_lambda.config.Config.fips_mode_enabled", True) + @patch("botocore.session.Session.create_client") + @patch("datadog_lambda.api.decrypt_kms_api_key") + def test_kms_fips_endpoint(self, mock_decrypt_kms, mock_boto3_client): + mock_client = MagicMock() + mock_boto3_client.return_value = mock_client + mock_decrypt_kms.return_value = "test-api-key" + + os.environ["AWS_REGION"] = "us-gov-west-1" + os.environ["DD_KMS_API_KEY"] = "encrypted-api-key" + + api_key = api.get_api_key() + + mock_boto3_client.assert_called_with( + "kms", endpoint_url="https://kms-fips.us-gov-west-1.amazonaws.com/" + ) + self.assertEqual(api_key, "test-api-key") + + @patch("botocore.session.Session.create_client") + def test_no_fips_for_standard_regions(self, mock_boto3_client): + mock_client = MagicMock() + mock_client.get_secret_value.return_value = {"SecretString": "test-api-key"} + mock_boto3_client.return_value = mock_client + + os.environ.clear() + os.environ["AWS_REGION"] = "us-west-2" + os.environ[ + "DD_API_KEY_SECRET_ARN" + ] = "arn:aws:secretsmanager:us-west-2:1234567890:secret:key-name-123ABC" + + api.get_api_key() + + mock_boto3_client.assert_called_with( + "secretsmanager", endpoint_url=None, region_name="us-west-2" + ) diff --git a/tests/test_asm.py b/tests/test_asm.py new file mode 100644 index 000000000..3aab8dd73 --- /dev/null +++ b/tests/test_asm.py @@ -0,0 +1,429 @@ +import json +import pytest +from unittest.mock import MagicMock, patch + +from datadog_lambda.asm import ( + asm_start_request, + asm_start_response, + get_asm_blocked_response, +) +from datadog_lambda.trigger import ( + EventSubtypes, + EventTypes, + _EventSource, + extract_trigger_tags, + parse_event_source, +) +from tests.utils import get_mock_context + +event_samples = "tests/event_samples/" + + +# Test cases for ASM start request +ASM_START_REQUEST_TEST_CASES = [ + ( + "application_load_balancer", + "application-load-balancer.json", + "72.12.164.125", + "/lambda?query=1234ABCD", + "GET", + "", + False, + {"query": "1234ABCD"}, + None, + None, + ), + ( + "application_load_balancer_multivalue_headers", + "application-load-balancer-multivalue-headers.json", + "72.12.164.125", + "/lambda?query=1234ABCD", + "GET", + "", + False, + {"query": "1234ABCD"}, + None, + None, + ), + ( + "lambda_function_url", + "lambda-url.json", + "71.195.30.42", + "/", + "GET", + None, + False, + None, + None, + None, + ), + ( + "api_gateway", + "api-gateway.json", + "127.0.0.1", + "/path/to/resource?foo=bar", + "POST", + "eyJ0ZXN0IjoiYm9keSJ9", + True, + {"foo": ["bar"]}, + {"proxy": "/path/to/resource"}, + "/{proxy+}", + ), + ( + "api_gateway_v2_parametrized", + "api-gateway-v2-parametrized.json", + "76.115.124.192", + "/user/42", + "GET", + None, + False, + None, + {"id": "42"}, + "/user/{id}", + ), + ( + "api_gateway_websocket", + "api-gateway-websocket-default.json", + "38.122.226.210", + None, + None, + '"What\'s good in the hood?"', + False, + None, + None, + None, + ), +] + + +# Test cases for ASM start response +ASM_START_RESPONSE_TEST_CASES = [ + ( + "application_load_balancer", + "application-load-balancer.json", + { + "statusCode": 200, + "headers": {"Content-Type": "text/html"}, + }, + "200", + {"Content-Type": "text/html"}, + None, + True, + ), + ( + "application_load_balancer_multivalue_headers", + "application-load-balancer-multivalue-headers.json", + { + "statusCode": 404, + "multiValueHeaders": { + "Content-Type": ["text/plain"], + "X-Error": ["Not Found"], + }, + }, + "404", + { + "Content-Type": "text/plain", + "X-Error": "Not Found", + }, + None, + True, + ), + ( + "lambda_function_url", + "lambda-url.json", + { + "statusCode": 201, + "headers": { + "Location": "/user/123", + "Content-Type": "application/json", + }, + }, + "201", + { + "Location": "/user/123", + "Content-Type": "application/json", + }, + None, + True, + ), + ( + "api_gateway", + "api-gateway.json", + { + "statusCode": 200, + "headers": { + "Content-Type": "application/json", + "X-Custom-Header": "test-value", + }, + "body": '{"message": "success"}', + }, + "200", + { + "Content-Type": "application/json", + "X-Custom-Header": "test-value", + }, + '{"message": "success"}', + True, + ), + ( + "api_gateway_v2_parametrized", + "api-gateway-v2-parametrized.json", + { + "statusCode": 200, + "headers": {"Content-Type": "application/json"}, + }, + "200", + {"Content-Type": "application/json"}, + None, + True, + ), + ( + "api_gateway_websocket", + "api-gateway-websocket-default.json", + { + "statusCode": 200, + "headers": {"Content-Type": "text/plain"}, + }, + "200", + {"Content-Type": "text/plain"}, + None, + True, + ), + ( + "non_http_event_s3", + "s3.json", + {"statusCode": 200}, + "200", + {}, + None, + False, # Should not dispatch for non-HTTP events + ), + ( + "api_gateway_v2_string_response", + "api-gateway-v2-parametrized.json", + "Hello, World!", + "200", + {"content-type": "application/json"}, + "Hello, World!", + True, + ), + ( + "api_gateway_v2_dict_response", + "api-gateway-v2-parametrized.json", + {"message": "Hello, World!"}, + "200", + {"content-type": "application/json"}, + {"message": "Hello, World!"}, + True, + ), +] + +ASM_BLOCKED_RESPONSE_TEST_CASES = [ + # JSON blocking response + ( + {"status_code": 403, "type": "auto", "content-type": "application/json"}, + 403, + {"content-type": "application/json"}, + ), + # HTML blocking response + ( + { + "status_code": 401, + "type": "html", + "content-type": "text/html", + }, + 401, + {"content-type": "text/html"}, + ), + # Plain text redirect response + ( + {"status_code": 301, "type": "none", "location": "https://example.com/blocked"}, + 301, + { + "content-type": "text/plain; charset=utf-8", + "location": "https://example.com/blocked", + }, + ), + # Default to content-type application/json and status code 403 when not provided + ( + {"type": "auto"}, + 403, + {"content-type": "application/json"}, + ), +] + + +@pytest.mark.parametrize( + "name,file,expected_ip,expected_uri,expected_method,expected_body,expected_base64,expected_query,expected_path_params,expected_route", + ASM_START_REQUEST_TEST_CASES, +) +@patch("datadog_lambda.asm.core") +def test_asm_start_request_parametrized( + mock_core, + name, + file, + expected_ip, + expected_uri, + expected_method, + expected_body, + expected_base64, + expected_query, + expected_path_params, + expected_route, +): + """Test ASM start request for various HTTP event types using parametrization""" + mock_span = MagicMock() + ctx = get_mock_context() + + # Reset mock for each test + mock_core.reset_mock() + mock_span.reset_mock() + + test_file = event_samples + file + with open(test_file, "r") as f: + event = json.load(f) + + event_source = parse_event_source(event) + trigger_tags = extract_trigger_tags(event, ctx) + + asm_start_request(mock_span, event, event_source, trigger_tags) + + # Verify core.dispatch was called + mock_core.dispatch.assert_called_once() + call_args = mock_core.dispatch.call_args + dispatch_args = call_args[0][1] + ( + span, + request_headers, + request_ip, + body, + is_base64_encoded, + raw_uri, + http_route, + http_method, + parsed_query, + request_path_parameters, + ) = dispatch_args + + # Common assertions + assert span == mock_span + assert isinstance(request_headers, dict) + + # Specific assertions based on test case + assert request_ip == expected_ip + assert raw_uri == expected_uri + assert http_method == expected_method + assert body == expected_body + assert is_base64_encoded == expected_base64 + + if expected_query is not None: + assert parsed_query == expected_query + else: + assert parsed_query is None + + if expected_path_params is not None: + assert request_path_parameters == expected_path_params + else: + assert request_path_parameters is None + + # Check route is correctly extracted and passed + assert http_route == expected_route + + # Check IP tags were set if IP is present + if expected_ip: + mock_span.set_tag.assert_any_call("http.client_ip", expected_ip) + mock_span.set_tag.assert_any_call("network.client.ip", expected_ip) + + +@pytest.mark.parametrize( + "name,event_file,response,status_code,expected_headers,expected_body,should_dispatch", + ASM_START_RESPONSE_TEST_CASES, +) +@patch("datadog_lambda.asm.core") +def test_asm_start_response_parametrized( + mock_core, + name, + event_file, + response, + status_code, + expected_headers, + expected_body, + should_dispatch, +): + """Test ASM start response for various HTTP event types using parametrization""" + mock_span = MagicMock() + + # Reset mock for each test + mock_core.reset_mock() + mock_span.reset_mock() + + test_file = event_samples + event_file + with open(test_file, "r") as f: + event = json.load(f) + + event_source = parse_event_source(event) + + asm_start_response(mock_span, status_code, event_source, response) + + if should_dispatch: + assert mock_core.dispatch.call_count == 2 + + assert mock_core.dispatch.call_args_list[0].args == ( + "aws_lambda.start_response", + (mock_span, status_code, expected_headers), + ) + + assert mock_core.dispatch.call_args_list[1].args == ( + "aws_lambda.parse_body", + (expected_body,), + ) + else: + # Verify core.dispatch was not called for non-HTTP events + mock_core.dispatch.assert_not_called() + + +@pytest.mark.parametrize( + "blocked_config, expected_status, expected_headers", + ASM_BLOCKED_RESPONSE_TEST_CASES, +) +@patch("datadog_lambda.asm.get_blocked") +def test_get_asm_blocked_response_blocked( + mock_get_blocked, + blocked_config, + expected_status, + expected_headers, +): + mock_get_blocked.return_value = blocked_config + event_source = _EventSource(event_type=EventTypes.API_GATEWAY) + response = get_asm_blocked_response(event_source) + assert response["statusCode"] == expected_status + assert response["headers"] == expected_headers + assert "multiValueHeaders" not in response + + +@patch("datadog_lambda.asm.get_blocked") +def test_get_asm_blocked_response_blocked_multi_value_headers( + mock_get_blocked, +): + # HTML blocking response + mock_get_blocked.return_value = { + "status_code": 401, + "type": "html", + "content-type": "text/html", + } + + event_source = _EventSource(EventTypes.ALB, EventSubtypes.ALB_MULTI_VALUE_HEADERS) + response = get_asm_blocked_response(event_source) + assert response["statusCode"] == 401 + assert response["multiValueHeaders"] == {"content-type": ["text/html"]} + assert "headers" not in response + + +@patch("datadog_lambda.asm.get_blocked") +def test_get_asm_blocked_response_not_blocked( + mock_get_blocked, +): + mock_get_blocked.return_value = None + event_source = _EventSource(event_type=EventTypes.API_GATEWAY) + response = get_asm_blocked_response(event_source) + assert response is None diff --git a/tests/test_benchmarks.py b/tests/test_benchmarks.py new file mode 100644 index 000000000..48598cb37 --- /dev/null +++ b/tests/test_benchmarks.py @@ -0,0 +1,97 @@ +import builtins +import json +import os +import pytest + +import ddtrace + +from datadog_lambda import metric +from datadog_lambda import tag_object +from datadog_lambda import tracing +from datadog_lambda import trigger +from datadog_lambda import xray + +from datadog_lambda.constants import XrayDaemon, XraySubsegment + +from tests.utils import get_mock_context, reset_xray_connection + + +event_samples_dir = "tests/event_samples" +event_samples = [f[:-5] for f in os.listdir(event_samples_dir) if f.endswith(".json")] + + +def test_metric_write_metric_point_to_stdout(benchmark, monkeypatch): + monkeypatch.setattr(builtins, "print", lambda *a, **k: None) + benchmark( + metric.write_metric_point_to_stdout, + "metric_name", + 1, + tags=[ + "tag1:value1", + "tag2:value2", + "tag3:value3", + ], + ) + + +@pytest.mark.parametrize("event", event_samples) +def test_tag_object_tag_object(event, benchmark): + with open(f"{event_samples_dir}/{event}.json") as f: + event = json.load(f) + span = ddtrace.trace.tracer.start_span("test") + benchmark(tag_object.tag_object, span, "function.request", event) + + +@pytest.mark.parametrize("event", event_samples) +def test_tracing_create_inferred_span(event, benchmark): + with open(f"{event_samples_dir}/{event}.json") as f: + event = json.load(f) + context = get_mock_context() + benchmark(tracing.create_inferred_span, event, context) + + +@pytest.mark.parametrize("event", event_samples) +def test_tracing_extract_dd_trace_context(event, benchmark): + with open(f"{event_samples_dir}/{event}.json") as f: + event = json.load(f) + context = get_mock_context() + benchmark(tracing.extract_dd_trace_context, event, context) + + +@pytest.mark.parametrize("event", event_samples) +def test_trigger_parse_event_source(event, benchmark): + with open(f"{event_samples_dir}/{event}.json") as f: + event = json.load(f) + benchmark(trigger.parse_event_source, event) + + +@pytest.mark.parametrize("event", event_samples) +def test_trigger_extract_trigger_tags(event, benchmark): + with open(f"{event_samples_dir}/{event}.json") as f: + event = json.load(f) + context = get_mock_context() + benchmark(trigger.extract_trigger_tags, event, context) + + +def test_xray_send_segment(benchmark, monkeypatch): + reset_xray_connection() + + monkeypatch.setenv(XrayDaemon.XRAY_DAEMON_ADDRESS, "localhost:9000") + monkeypatch.setenv( + XrayDaemon.XRAY_TRACE_ID_HEADER_NAME, + "Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1;Lineage=c6c5b1b9:0", + ) + + def socket_send(*a, **k): + sends.append(True) + + sends = [] + monkeypatch.setattr("socket.socket.send", socket_send) + + key = { + "trace-id": "12345678901234567890123456789012", + "parent-id": "1234567890123456", + "sampling-priority": "1", + } + benchmark(xray.send_segment, XraySubsegment.TRACE_KEY, key) + assert sends diff --git a/tests/test_cold_start.py b/tests/test_cold_start.py new file mode 100644 index 000000000..d75b5f43a --- /dev/null +++ b/tests/test_cold_start.py @@ -0,0 +1,276 @@ +import os +import time +import unittest + +from sys import modules, meta_path +from unittest.mock import MagicMock + +import datadog_lambda.cold_start as cold_start +import datadog_lambda.wrapper as wrapper + +from tests.utils import get_mock_context + + +class TestColdStartTracingSetup(unittest.TestCase): + def test_proactive_init(self): + cold_start._cold_start = True + cold_start._proactive_initialization = False + cold_start._lambda_container_initialized = False + fifteen_seconds_ago = time.time_ns() - 15_000_000_000 + cold_start.set_cold_start(fifteen_seconds_ago) + self.assertTrue(cold_start.is_proactive_init()) + self.assertTrue(cold_start.is_new_sandbox()) + self.assertFalse(cold_start.is_cold_start()) + self.assertEqual( + cold_start.get_proactive_init_tag(), "proactive_initialization:true" + ) + self.assertEqual(cold_start.get_cold_start_tag(), "cold_start:false") + + def test_cold_start(self): + cold_start._cold_start = True + cold_start._proactive_initialization = False + cold_start._lambda_container_initialized = False + one_second_ago = time.time_ns() - 1_000_000_000 + cold_start.set_cold_start(one_second_ago) + self.assertFalse(cold_start.is_proactive_init()) + self.assertTrue(cold_start.is_new_sandbox()) + self.assertTrue(cold_start.is_cold_start()) + self.assertEqual( + cold_start.get_proactive_init_tag(), "proactive_initialization:false" + ) + self.assertEqual(cold_start.get_cold_start_tag(), "cold_start:true") + + def test_initialize_cold_start_tracing(self): + cold_start._cold_start = True + cold_start.initialize_cold_start_tracing() # testing double wrapping + cold_start._cold_start = True + cold_start.initialize_cold_start_tracing() + cold_start.reset_node_stacks() + for module_name in ["ast", "dis", "inspect"]: + if module_name in modules: + del modules[module_name] + import inspect # import some package + + self.assertTrue(inspect.ismodule(inspect)) + self.assertEqual(len(cold_start.root_nodes), 1) + self.assertEqual(cold_start.root_nodes[0].module_name, "inspect") + + def test_bad_importer_find_spec_attribute_error(self): + mock_importer = object() # AttributeError when accessing find_spec + meta_path.append(mock_importer) + cold_start._cold_start = True + cold_start.initialize_cold_start_tracing() # safe to call + meta_path.pop() + + def test_not_wrapping_case(self): + os.environ["DD_COLD_START_TRACING"] = "false" + mock_importer = MagicMock() + mock_module_spec = MagicMock() + mock_module_spec.name = "test_name" + mock_loader = object() + mock_module_spec.loader = mock_loader + + def find_spec(*args, **kwargs): + return mock_module_spec + + mock_importer.find_spec = find_spec + meta_path.append(mock_importer) + cold_start._cold_start = True + cold_start.initialize_cold_start_tracing() + self.assertFalse(mock_loader in cold_start.already_wrapped_loaders) + meta_path.pop() + os.environ["DD_COLD_START_TRACING"] = "true" + + def test_exec_module_failure_case(self): + mock_importer = MagicMock() + mock_module_spec = MagicMock() + mock_module_spec.name = "test_name" + mock_loader = MagicMock() + + def bad_exec_module(*args, **kwargs): + raise Exception("Module failed to load") + + mock_loader.exec_module = bad_exec_module + mock_module_spec.loader = mock_loader + + def find_spec(*args, **kwargs): + return mock_module_spec + + mock_importer.find_spec = find_spec + meta_path.insert(0, mock_importer) + cold_start._cold_start = True + cold_start.initialize_cold_start_tracing() + cold_start.reset_node_stacks() + try: + import dummy_module + except Exception as e: + self.assertEqual(str(e), "Module failed to load") + meta_path.pop(0) # clean up first before checking test results + self.assertEqual( + len(cold_start.root_nodes), 1 + ) # push_node should have pushed the node + self.assertEqual(cold_start.root_nodes[0].module_name, mock_module_spec.name) + + +class TestColdStartTracer(unittest.TestCase): + def setUp(self) -> None: + mock_tracer = MagicMock() + self.output_spans = [] + self.shared_mock_span = MagicMock() + self.shared_mock_span.current_spans = [] + self.finish_call_count = 0 + + def _finish(finish_time_s): + module_name = self.shared_mock_span.current_spans.pop() + self.output_spans.append(module_name) + self.finish_call_count += 1 + + self.shared_mock_span.finish = _finish + + def _trace(*args, **kwargs): + module_name = kwargs["resource"] + self.shared_mock_span.current_spans.append(module_name) + return self.shared_mock_span + + mock_tracer.trace = _trace + self.mock_activate = MagicMock() + mock_tracer.context_provider.activate = self.mock_activate + self.mock_trace_ctx = MagicMock() + self.first_node_start_time_ns = 1676217209680116000 + self.cold_start_tracer = cold_start.ColdStartTracer( + mock_tracer, + "unittest_cold_start", + self.first_node_start_time_ns + 2e9, + self.mock_trace_ctx, + 3, + ["ignored_module_a", "ignored_module_b"], + ) + self.test_time_unit = (self.cold_start_tracer.min_duration_ms + 1) * 1e6 + + def test_trace_empty_root_nodes(self): + self.cold_start_tracer.trace([]) + self.assertEqual(len(self.output_spans), 0) + + def test_trace_one_root_node_no_children(self): + node_0 = cold_start.ImportNode("node_0", None, self.first_node_start_time_ns) + node_0.end_time_ns = self.first_node_start_time_ns + 4e6 + self.cold_start_tracer.trace([node_0]) + self.mock_activate.assert_called_once_with(self.mock_trace_ctx) + self.assertEqual(self.output_spans, ["node_0", "unittest_cold_start"]) + + def test_trace_one_root_node_with_children(self): + node_0 = cold_start.ImportNode("node_0", None, self.first_node_start_time_ns) + node_0.end_time_ns = self.first_node_start_time_ns + self.test_time_unit * 2 + node_1 = cold_start.ImportNode("node_1", None, self.first_node_start_time_ns) + node_1.end_time_ns = self.first_node_start_time_ns + self.test_time_unit + node_2 = cold_start.ImportNode( + "node_2", None, self.first_node_start_time_ns + self.test_time_unit + ) + node_2.end_time_ns = self.first_node_start_time_ns + self.test_time_unit * 2 + node_3 = cold_start.ImportNode("node_3", None, self.first_node_start_time_ns) + node_3.end_time_ns = self.first_node_start_time_ns + self.test_time_unit + nodes = [node_0] + node_0.children = [node_1, node_2] + node_1.children = [node_3] + self.cold_start_tracer.trace(nodes) + self.mock_activate.assert_called_with(self.mock_trace_ctx) + self.assertEqual(self.finish_call_count, 5) + self.assertEqual(self.mock_activate.call_count, 2) + self.assertEqual( + self.output_spans, + ["node_3", "node_1", "node_2", "node_0", "unittest_cold_start"], + ) + + def test_trace_multiple_root_nodes(self): + node_0 = cold_start.ImportNode("node_0", None, self.first_node_start_time_ns) + node_0.end_time_ns = self.first_node_start_time_ns + self.test_time_unit * 2 + node_1 = cold_start.ImportNode( + "node_1", None, self.first_node_start_time_ns + self.test_time_unit * 2 + ) + node_1.end_time_ns = self.first_node_start_time_ns + self.test_time_unit * 3 + node_2 = cold_start.ImportNode("node_2", None, self.first_node_start_time_ns) + node_2.end_time_ns = self.first_node_start_time_ns + self.test_time_unit + node_3 = cold_start.ImportNode( + "node_3", None, self.first_node_start_time_ns + self.test_time_unit + ) + node_3.end_time_ns = self.first_node_start_time_ns + self.test_time_unit * 2 + node_4 = cold_start.ImportNode( + "node_4", None, self.first_node_start_time_ns + self.test_time_unit * 2 + ) + node_4.end_time_ns = self.first_node_start_time_ns + self.test_time_unit * 3 + nodes = [node_0, node_1] + node_0.children = [node_2, node_3] + node_1.children = [node_4] + self.cold_start_tracer.trace(nodes) + self.mock_activate.assert_called_with(self.mock_trace_ctx) + self.assertEqual(self.finish_call_count, 6) + self.assertEqual(self.mock_activate.call_count, 3) + self.assertEqual( + self.output_spans, + ["node_4", "node_1", "node_2", "node_3", "node_0", "unittest_cold_start"], + ) + + def test_trace_min_duration(self): + node_0 = cold_start.ImportNode("node_0", None, self.first_node_start_time_ns) + node_0.end_time_ns = ( + self.first_node_start_time_ns + + self.cold_start_tracer.min_duration_ms * 1e6 + - 1e5 + ) + self.cold_start_tracer.trace([node_0]) + self.mock_activate.assert_called_once_with(self.mock_trace_ctx) + self.assertEqual(self.output_spans, ["unittest_cold_start"]) + + def test_trace_ignore_libs(self): + node_0 = cold_start.ImportNode("node_0", None, self.first_node_start_time_ns) + node_0.end_time_ns = self.first_node_start_time_ns + self.test_time_unit + node_1 = cold_start.ImportNode( + "ignored_module_a", + None, + self.first_node_start_time_ns + self.test_time_unit, + ) + node_1.end_time_ns = self.first_node_start_time_ns + self.test_time_unit * 2 + node_2 = cold_start.ImportNode( + "ignored_module_b", None, self.first_node_start_time_ns + ) + node_2.end_time_ns = self.first_node_start_time_ns + self.test_time_unit + nodes = [node_0, node_1] + node_0.children = [node_2] + self.cold_start_tracer.trace(nodes) + self.mock_activate.assert_called_once_with(self.mock_trace_ctx) + self.assertEqual(self.output_spans, ["node_0", "unittest_cold_start"]) + + +def test_lazy_loaded_package_imports(monkeypatch): + spans = [] + + def finish(span): + spans.append(span) + + monkeypatch.setattr(wrapper.tracer, "_on_span_finish", finish) + monkeypatch.setattr(wrapper, "is_new_sandbox", lambda: True) + monkeypatch.setattr("datadog_lambda.config.Config.trace_enabled", True) + monkeypatch.setenv( + "DD_COLD_START_TRACE_SKIP_LIB", "ddtrace.contrib.logging,datadog_lambda.wrapper" + ) + monkeypatch.setenv("DD_MIN_COLD_START_DURATION", "0") + + @wrapper.datadog_lambda_wrapper + def handler(event, context): + import tabnanny + + lambda_context = get_mock_context() + + handler.cold_start_tracing = True + handler({}, lambda_context) + + function_span = import_span = None + for span in spans: + if span.resource == "tabnanny": + import_span = span + elif span.name == "aws.lambda": + function_span = span + + assert function_span is not None + assert import_span is not None + assert import_span.parent_id == function_span.span_id diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 000000000..9c5da63a2 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,262 @@ +import importlib +import sys + +import pytest + +from datadog_lambda.config import config, _get_env, Config + + +@pytest.fixture +def setenv(monkeypatch): + def set_env(key, value): + if value is None: + monkeypatch.delenv(key, raising=False) + else: + monkeypatch.setenv(key, value) + + return set_env + + +def test_config_import_does_not_import_ddtrace(monkeypatch): + import datadog_lambda + + with monkeypatch.context() as mp: + for name in list(sys.modules): + if name == "ddtrace" or name.startswith("ddtrace."): + mp.delitem(sys.modules, name, raising=False) + + class _BlockDdtrace(importlib.abc.MetaPathFinder): + def find_spec(self, fullname, path=None, target=None): + if fullname == "ddtrace" or fullname.startswith("ddtrace."): + raise ImportError("ddtrace must not be imported during this test") + return None + + blocker = _BlockDdtrace() + mp.setattr(sys, "meta_path", [blocker] + sys.meta_path, raising=False) + + mp.delattr(datadog_lambda, "config", raising=False) + mp.delitem(sys.modules, "datadog_lambda.config", raising=False) + importlib.invalidate_caches() + importlib.import_module("datadog_lambda.config") + + +def _test_as_bool(env_key, conf_key, default): + return ( + (env_key, conf_key, None, default), + (env_key, conf_key, "", False), + (env_key, conf_key, "true", True), + (env_key, conf_key, "TRUE", True), + (env_key, conf_key, "false", False), + (env_key, conf_key, "FALSE", False), + (env_key, conf_key, "1", True), + (env_key, conf_key, "0", False), + (env_key, conf_key, "purple", False), + ) + + +def _test_int(env_key, conf_key, default): + return ( + (env_key, conf_key, None, default), + (env_key, conf_key, "", default), + (env_key, conf_key, "5", 5), + (env_key, conf_key, "0", 0), + (env_key, conf_key, "2.5", default), + (env_key, conf_key, "-1", -1), + (env_key, conf_key, "purple", default), + ) + + +def _test_as_list(env_key, conf_key, default): + return ( + (env_key, conf_key, None, default.split(",")), + (env_key, conf_key, "", []), + (env_key, conf_key, " ", []), + (env_key, conf_key, ",", []), + (env_key, conf_key, " , ", []), + (env_key, conf_key, "a", ["a"]), + (env_key, conf_key, "a,", ["a"]), + (env_key, conf_key, "a, ", ["a"]), + (env_key, conf_key, "a,b", ["a", "b"]), + (env_key, conf_key, "a, b", ["a", "b"]), + ) + + +_test_config_from_environ = ( + *_test_as_bool("DD_FLUSH_TO_LOG", "flush_to_log", default=False), + *_test_as_bool("DD_LOGS_INJECTION", "logs_injection", default=True), + *_test_as_bool("DD_TRACE_ENABLED", "trace_enabled", default=True), + *_test_as_bool("DD_COLD_START_TRACING", "cold_start_tracing", default=True), + *_test_as_bool("DD_TRACE_MANAGED_SERVICES", "make_inferred_span", default=True), + *_test_as_bool( + "DD_ENCODE_AUTHORIZER_CONTEXT", "encode_authorizer_context", default=True + ), + *_test_as_bool( + "DD_DECODE_AUTHORIZER_CONTEXT", "decode_authorizer_context", default=True + ), + *_test_as_bool("DD_FLUSH_IN_THREAD", "flush_in_thread", default=False), + *_test_as_bool("DD_ENHANCED_METRICS", "enhanced_metrics_enabled", default=True), + *_test_as_bool("DD_INTEGRATION_TEST", "integration_test", default=False), + *_test_as_bool("DD_BOTOCORE_ADD_SPAN_POINTERS", "add_span_pointers", default=True), + *_test_as_bool("DD_TRACE_OTEL_ENABLED", "otel_enabled", default=False), + *_test_as_bool("DD_MERGE_XRAY_TRACES", "merge_xray_traces", default=False), + *_test_as_bool("DD_PROFILING_ENABLED", "profiling_enabled", default=False), + *_test_as_bool("DD_LLMOBS_ENABLED", "llmobs_enabled", default=False), + *_test_as_bool( + "DD_EXCEPTION_REPLAY_ENABLED", "exception_replay_enabled", default=False + ), + *_test_as_bool( + "DD_CAPTURE_LAMBDA_PAYLOAD", "capture_payload_enabled", default=False + ), + *_test_as_bool("DD_LOCAL_TEST", "local_test", default=False), + *_test_as_bool("DD_DATA_STREAMS_ENABLED", "data_streams_enabled", default=False), + *_test_as_bool("DD_APPSEC_ENABLED", "appsec_enabled", default=False), + *_test_as_bool("DD_APPSEC_SCA_ENABLED", "sca_enabled", default=False), + *_test_int( + "DD_CAPTURE_LAMBDA_PAYLOAD_MAX_DEPTH", "capture_payload_max_depth", default=10 + ), + *_test_int( + "DD_MIN_COLD_START_DURATION", "min_cold_start_trace_duration", default=3 + ), + *_test_as_list( + "DD_COLD_START_TRACE_SKIP_LIB", + "cold_start_trace_skip_lib", + default="ddtrace.internal.compat,ddtrace.filters", + ), + ("DD_SERVICE", "service", None, None), + ("DD_SERVICE", "service", "", ""), + ("DD_SERVICE", "service", "my_service", "my_service"), + ("AWS_LAMBDA_FUNCTION_NAME", "aws_lambda_function_name", None, None), + ("AWS_LAMBDA_FUNCTION_NAME", "aws_lambda_function_name", "", ""), + ( + "AWS_LAMBDA_FUNCTION_NAME", + "aws_lambda_function_name", + "my_function", + "my_function", + ), + ("AWS_LAMBDA_FUNCTION_NAME", "function_name", None, "function"), + ("AWS_LAMBDA_FUNCTION_NAME", "function_name", "", ""), + ("AWS_LAMBDA_FUNCTION_NAME", "function_name", "my_function", "my_function"), + ("AWS_LAMBDA_FUNCTION_NAME", "is_lambda_context", None, False), + ("AWS_LAMBDA_FUNCTION_NAME", "is_lambda_context", "", False), + ("AWS_LAMBDA_FUNCTION_NAME", "is_lambda_context", "my_function", True), + ("AWS_REGION", "is_gov_region", None, False), + ("AWS_REGION", "is_gov_region", "", False), + ("AWS_REGION", "is_gov_region", "us-gov-1", True), + ("AWS_REGION", "is_gov_region", "us-est-1", False), + ("DD_TRACE_EXTRACTOR", "trace_extractor", None, None), + ("DD_TRACE_EXTRACTOR", "trace_extractor", "", ""), + ("DD_TRACE_EXTRACTOR", "trace_extractor", "my_extractor", "my_extractor"), + ("DD_ENV", "env", None, None), + ("DD_ENV", "env", "", ""), + ("DD_ENV", "env", "my_env", "my_env"), +) + + +@pytest.mark.parametrize("env_key,conf_key,env_val,conf_val", _test_config_from_environ) +def test_config_from_environ(env_key, conf_key, env_val, conf_val, setenv): + setenv(env_key, env_val) + assert getattr(config, conf_key) == conf_val + + +_test_config_from_environ_depends_on_tracing = ( + *_test_as_bool("DD_COLD_START_TRACING", "cold_start_tracing", default=True), + *_test_as_bool("DD_TRACE_MANAGED_SERVICES", "make_inferred_span", default=True), + *_test_as_bool( + "DD_ENCODE_AUTHORIZER_CONTEXT", "encode_authorizer_context", default=True + ), + *_test_as_bool( + "DD_DECODE_AUTHORIZER_CONTEXT", "decode_authorizer_context", default=True + ), + *_test_as_bool("DD_DATA_STREAMS_ENABLED", "data_streams_enabled", default=False), +) + + +@pytest.mark.parametrize( + "env_key,conf_key,env_val,conf_val", _test_config_from_environ_depends_on_tracing +) +def test_config_from_environ_depends_on_tracing( + env_key, conf_key, env_val, conf_val, setenv +): + setenv(env_key, env_val) + setenv("DD_TRACE_ENABLED", "false") + assert getattr(config, conf_key) is False + + +def test_config_aws_lambda_function_name(setenv): + # these config values all access the same environment variable, test to + # ensure the wrong value is not cached + setenv("AWS_LAMBDA_FUNCTION_NAME", "my_function") + assert config.aws_lambda_function_name == "my_function" + assert config.function_name == "my_function" + assert config.is_lambda_context is True + + +_test_fips_mode_from_environ = ( + (None, None, False), + (None, "", False), + (None, "us-gov-1", True), + (None, "us-east-1", False), + ("", None, False), + ("", "", False), + ("", "us-gov-1", False), + ("", "us-east-1", False), + ("true", None, True), + ("true", "", True), + ("true", "us-gov-1", True), + ("true", "us-east-1", True), + ("TRUE", None, True), + ("TRUE", "", True), + ("TRUE", "us-gov-1", True), + ("TRUE", "us-east-1", True), + ("false", None, False), + ("false", "", False), + ("false", "us-gov-1", False), + ("false", "us-east-1", False), + ("FALSE", None, False), + ("FALSE", "", False), + ("FALSE", "us-gov-1", False), + ("FALSE", "us-east-1", False), + ("1", None, False), + ("1", "", False), + ("1", "us-gov-1", False), + ("1", "us-east-1", False), + ("0", None, False), + ("0", "", False), + ("0", "us-gov-1", False), + ("0", "us-east-1", False), +) + + +@pytest.mark.parametrize("fips_mode,region,conf_val", _test_fips_mode_from_environ) +def test_fips_mode_from_environ(fips_mode, region, conf_val, setenv): + setenv("DD_LAMBDA_FIPS_MODE", fips_mode) + setenv("AWS_REGION", region) + assert config.fips_mode_enabled == conf_val + + +def test__get_env_does_not_log_when_env_not_set(setenv, monkeypatch): + setenv("TEST_1", None) + setenv("TEST_2", None) + setenv("TEST_3", None) + setenv("TEST_4", None) + + class Testing(Config): + test_1 = _get_env("TEST_1") + test_2 = _get_env("TEST_2", "purple") + test_3 = _get_env("TEST_3", "true", bool) + test_4 = _get_env("TEST_4", "true", bool, depends_on_tracing=True) + + logs = [] + + def cap_warn(*args, **kwargs): + logs.append(args) + + monkeypatch.setattr("datadog_lambda.config.logger.warning", cap_warn) + + testing = Testing() + testing.test_1 + testing.test_2 + testing.test_3 + testing.test_4 + + assert not logs diff --git a/tests/test_dogstatsd.py b/tests/test_dogstatsd.py index 149e1a707..6fe79372d 100644 --- a/tests/test_dogstatsd.py +++ b/tests/test_dogstatsd.py @@ -1,5 +1,5 @@ -from collections import deque import unittest +from collections import deque from datadog_lambda.dogstatsd import statsd @@ -36,16 +36,24 @@ def test_init(self): self.assertEqual(statsd.port, 8125) self.assertEqual(statsd.encoding, "utf-8") - def test_distribution_no_tags(self): - statsd.distribution("my.test.metric", 3) + def _checkOnlyOneMetric(self, value): payload = self.recv() metrics = payload.split("\n") self.assertEqual(len(metrics), 1) - self.assertEqual("my.test.metric:3|d", metrics[0]) + self.assertEqual(value, metrics[0]) + + def test_distribution_no_tags(self): + statsd.distribution("my.test.metric", 3) + self._checkOnlyOneMetric("my.test.metric:3|d") def test_distribution_with_tags(self): statsd.distribution("my.test.tags.metric", 3, tags=["taga:valuea,tagb:valueb"]) - payload = self.recv() - metrics = payload.split("\n") - self.assertEqual(len(metrics), 1) - self.assertEqual("my.test.tags.metric:3|d|#taga:valuea_tagb:valueb", metrics[0]) + self._checkOnlyOneMetric("my.test.tags.metric:3|d|#taga:valuea_tagb:valueb") + + def test_distribution_with_timestamp(self): + statsd.distribution("my.test.timestamp.metric", 9, timestamp=123456789) + self._checkOnlyOneMetric("my.test.timestamp.metric:9|d|T123456789") + + def test_distribution_with_float_timestamp(self): + statsd.distribution("my.test.timestamp.metric", 9, timestamp=123456789.123) + self._checkOnlyOneMetric("my.test.timestamp.metric:9|d|T123456789") diff --git a/tests/test_extension.py b/tests/test_extension.py index 8882fa8f2..92142a9e3 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -1,71 +1,66 @@ +import http.server import os +import threading import unittest -import httpretty from unittest.mock import patch from datadog_lambda.extension import ( - is_extension_running, + is_extension_present, flush_extension, should_use_extension, ) -def exceptionCallback(request, uri, headers): - raise Exception("oopsy!") +class MockServer(threading.Thread): + def __init__(self): + super().__init__() + self.daemon = True + self.raises = False + self.called = False + + class handler(http.server.BaseHTTPRequestHandler): + def do_POST(sf): + self.called = True + sf.send_response(500 if self.raises else 200) + sf.end_headers() + + do_GET = do_POST + + self.server = http.server.HTTPServer(("127.0.0.1", 8124), handler) + + def run(self): + self.server.serve_forever() + + def stop(self): + self.server.shutdown() + self.server.server_close() + self.join(timeout=0) class TestLambdaExtension(unittest.TestCase): + def setUp(self): + self.server = MockServer() + self.server.start() + + def tearDown(self): + self.server.stop() + @patch("datadog_lambda.extension.EXTENSION_PATH", os.path.abspath(__file__)) def test_is_extension_running_true(self): - httpretty.enable() - last_request = httpretty.last_request() - httpretty.register_uri(httpretty.GET, "http://127.0.0.1:8124/lambda/hello") - assert is_extension_running() == True - assert httpretty.last_request() != last_request - httpretty.disable() + assert is_extension_present() def test_is_extension_running_file_not_found(self): - httpretty.enable() - last_request = httpretty.last_request() - httpretty.register_uri(httpretty.GET, "http://127.0.0.1:8124/lambda/hello") - assert is_extension_running() == False - assert httpretty.last_request() == last_request - httpretty.disable() - - @patch("datadog_lambda.extension.EXTENSION_PATH", os.path.abspath(__file__)) - def test_is_extension_running_http_failure(self): - httpretty.enable() - last_request = httpretty.last_request() - httpretty.register_uri( - httpretty.GET, - "http://127.0.0.1:8124/lambda/hello", - status=503, - body=exceptionCallback, - ) - assert is_extension_running() == False - assert httpretty.last_request() != last_request - httpretty.disable() + assert not is_extension_present() + assert not self.server.called @patch("datadog_lambda.extension.EXTENSION_PATH", os.path.abspath(__file__)) def test_flush_ok(self): - httpretty.enable() - last_request = httpretty.last_request() - httpretty.register_uri(httpretty.POST, "http://127.0.0.1:8124/lambda/flush") - assert flush_extension() == True - assert httpretty.last_request() != last_request - httpretty.disable() + assert flush_extension() + assert self.server.called @patch("datadog_lambda.extension.EXTENSION_PATH", os.path.abspath(__file__)) def test_flush_not_ok(self): - httpretty.enable() - last_request = httpretty.last_request() - httpretty.register_uri( - httpretty.POST, - "http://127.0.0.1:8124/lambda/flush", - status=503, - body=exceptionCallback, - ) - assert flush_extension() == False - assert httpretty.last_request() != last_request - httpretty.disable() + self.server.raises = True + assert not flush_extension() + assert self.server.called diff --git a/tests/test_handler.py b/tests/test_handler.py new file mode 100644 index 000000000..50f426dc9 --- /dev/null +++ b/tests/test_handler.py @@ -0,0 +1,72 @@ +import os +import sys +import unittest +from unittest.mock import patch + +from tests.utils import get_mock_context + + +class TestHandler(unittest.TestCase): + def tearDown(self): + for mod in sys.modules.copy(): + if mod.startswith("datadog_lambda.handler"): + del sys.modules[mod] + + def test_dd_lambda_handler_env_var_none(self): + with self.assertRaises(Exception) as context: + import datadog_lambda.handler as handler + + assert context.exception == handler.HandlerError( + "DD_LAMBDA_HANDLER is not defined. Can't use prebuilt datadog handler" + ) + + @patch.dict(os.environ, {"DD_LAMBDA_HANDLER": "malformed"}, clear=True) + def test_dd_lambda_handler_env_var_malformed(self): + with self.assertRaises(Exception) as context: + import datadog_lambda.handler as handler + + assert context.exception == handler.HandlerError( + "Value malformed for DD_LAMBDA_HANDLER has invalid format." + ) + + @patch.dict(os.environ, {"DD_LAMBDA_HANDLER": "nonsense.nonsense"}, clear=True) + @patch("datadog_lambda.tracing.emit_telemetry_on_exception_outside_of_handler") + @patch("time.time_ns", return_value=42) + def test_exception_importing_module(self, mock_time, mock_emit_telemetry): + with self.assertRaises(ModuleNotFoundError) as test_context: + import datadog_lambda.handler + + mock_emit_telemetry.assert_called_once_with( + test_context.exception, "nonsense", 42 + ) + + @patch.dict(os.environ, {"DD_LAMBDA_HANDLER": "nonsense.nonsense"}, clear=True) + @patch("importlib.import_module", return_value=None) + @patch("datadog_lambda.tracing.emit_telemetry_on_exception_outside_of_handler") + @patch("time.time_ns", return_value=42) + def test_exception_getting_handler_func( + self, mock_time, mock_emit_telemetry, mock_import + ): + with self.assertRaises(AttributeError) as test_context: + import datadog_lambda.handler + + mock_emit_telemetry.assert_called_once_with( + test_context.exception, "nonsense", 42 + ) + + @patch.dict(os.environ, {"DD_LAMBDA_HANDLER": "nonsense.nonsense"}, clear=True) + @patch("importlib.import_module") + @patch("datadog_lambda.tracing.emit_telemetry_on_exception_outside_of_handler") + @patch("datadog_lambda.wrapper.datadog_lambda_wrapper") + def test_handler_success( + self, mock_lambda_wrapper, mock_emit_telemetry, mock_import + ): + def nonsense(): + pass + + mock_import.nonsense.return_value = nonsense + + import datadog_lambda.handler + + mock_emit_telemetry.assert_not_called() + mock_lambda_wrapper.assert_called_once_with(mock_import().nonsense) diff --git a/tests/test_logger.py b/tests/test_logger.py new file mode 100644 index 000000000..eb2822f2f --- /dev/null +++ b/tests/test_logger.py @@ -0,0 +1,43 @@ +import io +import logging +import pytest + +from datadog_lambda.logger import initialize_logging + +_test_initialize_logging = ( + ("TRACE", (10, 20, 30, 40, 50)), + ("DEBUG", (10, 20, 30, 40, 50)), + ("debug", (10, 20, 30, 40, 50)), + ("INFO", (20, 30, 40, 50)), + ("WARNING", (30, 40, 50)), + ("WARN", (30, 40, 50)), + ("ERROR", (40, 50)), + ("CRITICAL", (50,)), + ("OFF", ()), + ("", (20, 30, 40, 50)), + (None, (20, 30, 40, 50)), + ("PURPLE", (30, 20, 30, 40, 50)), # log warning then default to INFO +) + + +@pytest.mark.parametrize("level,logged_levels", _test_initialize_logging) +def test_initialize_logging(level, logged_levels, monkeypatch): + if level is not None: + monkeypatch.setenv("DD_LOG_LEVEL", level) + + stream = io.StringIO() + handler = logging.StreamHandler(stream) + handler.setFormatter(logging.Formatter("%(levelno)s")) + logger = logging.getLogger(__name__) + logger.addHandler(handler) + + initialize_logging(__name__) + + logger.debug("debug") + logger.info("info") + logger.warning("warning") + logger.error("error") + logger.critical("critical") + + logged = tuple(map(int, stream.getvalue().strip().split())) + assert logged == logged_levels diff --git a/tests/test_metric.py b/tests/test_metric.py index 24c9a56da..fe3df247d 100644 --- a/tests/test_metric.py +++ b/tests/test_metric.py @@ -1,55 +1,190 @@ import os import unittest - -from unittest.mock import patch, call +from datetime import datetime, timedelta +from unittest.mock import call, patch from botocore.exceptions import ClientError as BotocoreClientError from datadog.api.exceptions import ClientError - -from datadog_lambda.metric import lambda_metric -from datadog_lambda.api import decrypt_kms_api_key, KMS_ENCRYPTION_CONTEXT_KEY +from datadog_lambda.api import KMS_ENCRYPTION_CONTEXT_KEY, decrypt_kms_api_key +from datadog_lambda.metric import ( + MetricsHandler, + _select_metrics_handler, + flush_stats, + lambda_metric, + submit_batch_item_failures_metric, +) +from datadog_lambda.tags import dd_lambda_layer_tag from datadog_lambda.thread_stats_writer import ThreadStatsWriter -from datadog_lambda.tags import _format_dd_lambda_layer_tag class TestLambdaMetric(unittest.TestCase): def setUp(self): - patcher = patch("datadog_lambda.metric.lambda_stats") - self.mock_metric_lambda_stats = patcher.start() - self.addCleanup(patcher.stop) + lambda_stats_patcher = patch("datadog_lambda.metric.lambda_stats") + self.mock_metric_lambda_stats = lambda_stats_patcher.start() + self.addCleanup(lambda_stats_patcher.stop) + + stdout_metric_patcher = patch( + "datadog_lambda.metric.write_metric_point_to_stdout" + ) + self.mock_write_metric_point_to_stdout = stdout_metric_patcher.start() + self.addCleanup(stdout_metric_patcher.stop) def test_lambda_metric_tagged_with_dd_lambda_layer(self): lambda_metric("test", 1) lambda_metric("test", 1, 123, []) lambda_metric("test", 1, tags=["tag1:test"]) - expected_tag = _format_dd_lambda_layer_tag() self.mock_metric_lambda_stats.distribution.assert_has_calls( [ - call("test", 1, timestamp=None, tags=[expected_tag]), - call("test", 1, timestamp=123, tags=[expected_tag]), - call("test", 1, timestamp=None, tags=["tag1:test", expected_tag]), + call("test", 1, timestamp=None, tags=[dd_lambda_layer_tag]), + call("test", 1, timestamp=123, tags=[dd_lambda_layer_tag]), + call( + "test", 1, timestamp=None, tags=["tag1:test", dd_lambda_layer_tag] + ), ] ) # let's fake that the extension is present, this should override DD_FLUSH_TO_LOG @patch("datadog_lambda.metric.should_use_extension", True) - def test_lambda_metric_flush_to_log_with_extension(self): + def test_select_metrics_handler_extension_despite_flush_to_logs(self): os.environ["DD_FLUSH_TO_LOG"] = "True" + self.assertEqual(MetricsHandler.EXTENSION, _select_metrics_handler()) + del os.environ["DD_FLUSH_TO_LOG"] + + @patch("datadog_lambda.metric.should_use_extension", False) + def test_select_metrics_handler_forwarder_when_flush_to_logs(self): + os.environ["DD_FLUSH_TO_LOG"] = "True" + self.assertEqual(MetricsHandler.FORWARDER, _select_metrics_handler()) + del os.environ["DD_FLUSH_TO_LOG"] + + @patch("datadog_lambda.metric.should_use_extension", False) + def test_select_metrics_handler_dd_api_fallback(self): + os.environ["DD_FLUSH_TO_LOG"] = "False" + self.assertEqual(MetricsHandler.DATADOG_API, _select_metrics_handler()) + del os.environ["DD_FLUSH_TO_LOG"] + + @patch("datadog_lambda.config.Config.fips_mode_enabled", True) + @patch("datadog_lambda.metric.should_use_extension", False) + def test_select_metrics_handler_has_no_fallback_in_fips_mode(self): + os.environ["DD_FLUSH_TO_LOG"] = "False" + self.assertEqual(MetricsHandler.NO_METRICS, _select_metrics_handler()) + del os.environ["DD_FLUSH_TO_LOG"] + + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION) + def test_lambda_metric_goes_to_extension_with_extension_handler(self): lambda_metric("test", 1) - expected_tag = _format_dd_lambda_layer_tag() self.mock_metric_lambda_stats.distribution.assert_has_calls( - [call("test", 1, timestamp=None, tags=[expected_tag])] + [call("test", 1, timestamp=None, tags=[dd_lambda_layer_tag])] ) - del os.environ["DD_FLUSH_TO_LOG"] - def test_lambda_metric_flush_to_log(self): - os.environ["DD_FLUSH_TO_LOG"] = "True" + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.NO_METRICS) + def test_lambda_metric_has_nowhere_to_go_with_no_metrics_handler(self): + lambda_metric("test", 1) + self.mock_metric_lambda_stats.distribution.assert_not_called() + self.mock_write_metric_point_to_stdout.assert_not_called() + + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION) + def test_lambda_metric_timestamp_with_extension(self): + delta = timedelta(minutes=1) + timestamp = int((datetime.now() - delta).timestamp()) + + lambda_metric("test_timestamp", 1, timestamp) + self.mock_metric_lambda_stats.distribution.assert_has_calls( + [call("test_timestamp", 1, timestamp=timestamp, tags=[dd_lambda_layer_tag])] + ) + self.mock_write_metric_point_to_stdout.assert_not_called() + + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION) + def test_lambda_metric_datetime_with_extension(self): + delta = timedelta(minutes=1) + timestamp = datetime.now() - delta + + lambda_metric("test_datetime_timestamp", 0, timestamp) + self.mock_metric_lambda_stats.distribution.assert_has_calls( + [ + call( + "test_datetime_timestamp", + 0, + timestamp=int(timestamp.timestamp()), + tags=[dd_lambda_layer_tag], + ) + ] + ) + self.mock_write_metric_point_to_stdout.assert_not_called() + + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION) + def test_lambda_metric_float_with_extension(self): + delta = timedelta(minutes=1) + timestamp_float = (datetime.now() - delta).timestamp() + timestamp_int = int(timestamp_float) + + lambda_metric("test_timestamp", 1, timestamp_float) + self.mock_metric_lambda_stats.distribution.assert_has_calls( + [ + call( + "test_timestamp", + 1, + timestamp=timestamp_int, + tags=[dd_lambda_layer_tag], + ) + ] + ) + self.mock_write_metric_point_to_stdout.assert_not_called() + + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION) + def test_lambda_metric_timestamp_junk_with_extension(self): + delta = timedelta(minutes=1) + timestamp = (datetime.now() - delta).isoformat() + + lambda_metric("test_timestamp", 1, timestamp) + self.mock_metric_lambda_stats.distribution.assert_not_called() + self.mock_write_metric_point_to_stdout.assert_not_called() + + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION) + def test_lambda_metric_invalid_timestamp_with_extension(self): + delta = timedelta(hours=5) + timestamp = int((datetime.now() - delta).timestamp()) + + lambda_metric("test_timestamp", 1, timestamp) + self.mock_metric_lambda_stats.distribution.assert_not_called() + self.mock_write_metric_point_to_stdout.assert_not_called() + @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.FORWARDER) + def test_lambda_metric_flush_to_log(self): lambda_metric("test", 1) self.mock_metric_lambda_stats.distribution.assert_not_called() + self.mock_write_metric_point_to_stdout.assert_has_calls( + [call("test", 1, timestamp=None, tags=[dd_lambda_layer_tag])] + ) - del os.environ["DD_FLUSH_TO_LOG"] + @patch("datadog_lambda.metric.logger.warning") + def test_lambda_metric_invalid_metric_name_none(self, mock_logger_warning): + lambda_metric(None, 1) + self.mock_metric_lambda_stats.distribution.assert_not_called() + self.mock_write_metric_point_to_stdout.assert_not_called() + mock_logger_warning.assert_called_once_with( + "Ignoring metric submission. Invalid metric name: %s", None + ) + + @patch("datadog_lambda.metric.logger.warning") + def test_lambda_metric_invalid_metric_name_not_string(self, mock_logger_warning): + lambda_metric(123, 1) + self.mock_metric_lambda_stats.distribution.assert_not_called() + self.mock_write_metric_point_to_stdout.assert_not_called() + mock_logger_warning.assert_called_once_with( + "Ignoring metric submission. Invalid metric name: %s", 123 + ) + + @patch("datadog_lambda.metric.logger.warning") + def test_lambda_metric_non_numeric_value(self, mock_logger_warning): + lambda_metric("test.non_numeric", "oops") + self.mock_metric_lambda_stats.distribution.assert_not_called() + self.mock_write_metric_point_to_stdout.assert_not_called() + mock_logger_warning.assert_called_once_with( + "Ignoring metric submission for metric '%s' because the value is not numeric: %r", + "test.non_numeric", + "oops", + ) class TestFlushThreadStats(unittest.TestCase): @@ -72,6 +207,72 @@ def test_retry_on_remote_disconnected(self): lambda_stats.flush() self.assertEqual(self.mock_threadstats_flush_distributions.call_count, 2) + def test_flush_stats_with_tags(self): + lambda_stats = ThreadStatsWriter(True) + original_constant_tags = lambda_stats.thread_stats.constant_tags.copy() + tags = ["tag1:value1", "tag2:value2"] + + # Add a metric to be flushed + lambda_stats.distribution("test.metric", 1, tags=["metric:tag"]) + + with patch.object( + lambda_stats.thread_stats.reporter, "flush_distributions" + ) as mock_flush_distributions: + lambda_stats.flush(tags) + mock_flush_distributions.assert_called_once() + # Verify that after flush, constant_tags is reset to original + self.assertEqual( + lambda_stats.thread_stats.constant_tags, original_constant_tags + ) + + def test_flush_temp_constant_tags(self): + lambda_stats = ThreadStatsWriter(flush_in_thread=True) + lambda_stats.thread_stats.constant_tags = ["initial:tag"] + original_constant_tags = lambda_stats.thread_stats.constant_tags.copy() + + lambda_stats.distribution("test.metric", 1, tags=["metric:tag"]) + flush_tags = ["flush:tag1", "flush:tag2"] + + with patch.object( + lambda_stats.thread_stats.reporter, "flush_distributions" + ) as mock_flush_distributions: + lambda_stats.flush(tags=flush_tags) + mock_flush_distributions.assert_called_once() + flushed_dists = mock_flush_distributions.call_args[0][0] + + # Expected tags: original constant_tags + flush_tags + metric tags + expected_tags = original_constant_tags + flush_tags + ["metric:tag"] + + # Verify the tags on the metric + self.assertEqual(len(flushed_dists), 1) + metric = flushed_dists[0] + self.assertEqual(sorted(metric["tags"]), sorted(expected_tags)) + + # Verify that constant_tags is reset after flush + self.assertEqual( + lambda_stats.thread_stats.constant_tags, original_constant_tags + ) + + # Repeat to ensure tags do not accumulate over multiple flushes + new_flush_tags = ["flush:tag3"] + lambda_stats.distribution("test.metric2", 2, tags=["metric2:tag"]) + + with patch.object( + lambda_stats.thread_stats.reporter, "flush_distributions" + ) as mock_flush_distributions: + lambda_stats.flush(tags=new_flush_tags) + mock_flush_distributions.assert_called_once() + flushed_dists = mock_flush_distributions.call_args[0][0] + # Expected tags for the new metric + expected_tags = original_constant_tags + new_flush_tags + ["metric2:tag"] + + self.assertEqual(len(flushed_dists), 1) + metric = flushed_dists[0] + self.assertEqual(sorted(metric["tags"]), sorted(expected_tags)) + self.assertEqual( + lambda_stats.thread_stats.constant_tags, original_constant_tags + ) + MOCK_FUNCTION_NAME = "myFunction" @@ -124,3 +325,80 @@ def decrypt(self, CiphertextBlob=None, EncryptionContext={}): mock_kms_client, MOCK_ENCRYPTED_API_KEY_BASE64 ) self.assertEqual(decrypted_key, EXPECTED_DECRYPTED_API_KEY) + + +class TestBatchItemFailuresMetric(unittest.TestCase): + def setUp(self): + patcher = patch("datadog_lambda.metric.lambda_metric") + self.mock_lambda_metric = patcher.start() + self.addCleanup(patcher.stop) + + patcher = patch("datadog_lambda.config.Config.enhanced_metrics_enabled", True) + self.mock_enhanced_metrics_enabled = patcher.start() + self.addCleanup(patcher.stop) + + def test_submit_batch_item_failures_with_failures(self): + response = { + "batchItemFailures": [ + {"itemIdentifier": "msg-1"}, + {"itemIdentifier": "msg-2"}, + {"itemIdentifier": "msg-3"}, + ] + } + context = unittest.mock.Mock() + + with patch("datadog_lambda.metric.get_enhanced_metrics_tags") as mock_get_tags: + mock_get_tags.return_value = ["tag1:value1"] + submit_batch_item_failures_metric(response, context) + + self.mock_lambda_metric.assert_called_once_with( + "aws.lambda.enhanced.batch_item_failures", + 3, + timestamp=None, + tags=["tag1:value1"], + force_async=True, + ) + + def test_submit_batch_item_failures_with_no_failures(self): + response = {"batchItemFailures": []} + context = unittest.mock.Mock() + + with patch("datadog_lambda.metric.get_enhanced_metrics_tags") as mock_get_tags: + mock_get_tags.return_value = ["tag1:value1"] + submit_batch_item_failures_metric(response, context) + self.mock_lambda_metric.assert_called_once_with( + "aws.lambda.enhanced.batch_item_failures", + 0, + timestamp=None, + tags=["tag1:value1"], + force_async=True, + ) + + def test_submit_batch_item_failures_with_no_field(self): + response = {"statusCode": 200} + context = unittest.mock.Mock() + submit_batch_item_failures_metric(response, context) + self.mock_lambda_metric.assert_not_called() + + def test_submit_batch_item_failures_with_none_response(self): + response = None + context = unittest.mock.Mock() + submit_batch_item_failures_metric(response, context) + self.mock_lambda_metric.assert_not_called() + + def test_submit_batch_item_failures_with_non_list_value(self): + response = {"batchItemFailures": "invalid"} + context = unittest.mock.Mock() + submit_batch_item_failures_metric(response, context) + self.mock_lambda_metric.assert_not_called() + + @patch("datadog_lambda.config.Config.enhanced_metrics_enabled", False) + def test_submit_batch_item_failures_enhanced_metrics_disabled(self): + response = { + "batchItemFailures": [ + {"itemIdentifier": "msg-1"}, + ] + } + context = unittest.mock.Mock() + submit_batch_item_failures_metric(response, context) + self.mock_lambda_metric.assert_not_called() diff --git a/tests/test_module_name.py b/tests/test_module_name.py index 213964656..a6faf8298 100644 --- a/tests/test_module_name.py +++ b/tests/test_module_name.py @@ -1,7 +1,5 @@ import unittest -from unittest.mock import patch, call, MagicMock - from datadog_lambda.module_name import modify_module_name diff --git a/tests/test_patch.py b/tests/test_patch.py index bf9248756..b03d2e23e 100644 --- a/tests/test_patch.py +++ b/tests/test_patch.py @@ -1,3 +1,4 @@ +import pytest import unittest from unittest.mock import patch, MagicMock @@ -5,6 +6,13 @@ from datadog_lambda.patch import _patch_http, _ensure_patch_requests from datadog_lambda.constants import TraceHeader +from ddtrace.contrib.internal.requests.patch import unpatch as unpatch_requests + + +@pytest.fixture(scope="module", autouse=True) +def reset_patches(): + unpatch_requests() + class TestPatchHTTPClients(unittest.TestCase): def setUp(self): diff --git a/tests/test_span_pointers.py b/tests/test_span_pointers.py new file mode 100644 index 000000000..f4cd1b268 --- /dev/null +++ b/tests/test_span_pointers.py @@ -0,0 +1,185 @@ +from typing import List +from typing import NamedTuple + +from ddtrace._trace._span_pointer import _SpanPointerDirection +from ddtrace._trace._span_pointer import _SpanPointerDescription +from datadog_lambda.trigger import _EventSource +from datadog_lambda.trigger import EventTypes +from datadog_lambda.span_pointers import calculate_span_pointers +import pytest + + +class TestCalculateSpanPointers: + class SpanPointersCase(NamedTuple): + name: str + event_source: _EventSource + event: dict + dd_botocore_span_pointers: bool + span_pointers: List[_SpanPointerDescription] + + @pytest.mark.parametrize( + "test_case", + [ + SpanPointersCase( + name="some unsupported event", + event_source=_EventSource(EventTypes.UNKNOWN), + event={}, + dd_botocore_span_pointers=True, + span_pointers=[], + ), + SpanPointersCase( + name="empty s3 event", + event_source=_EventSource(EventTypes.S3), + event={}, + dd_botocore_span_pointers=True, + span_pointers=[], + ), + SpanPointersCase( + name="sensible s3 event", + event_source=_EventSource(EventTypes.S3), + event={ + "Records": [ + { + "eventName": "ObjectCreated:Put", + "s3": { + "bucket": { + "name": "mybucket", + }, + "object": { + "key": "mykey", + "eTag": "123abc", + }, + }, + }, + ], + }, + dd_botocore_span_pointers=True, + span_pointers=[ + _SpanPointerDescription( + pointer_kind="aws.s3.object", + pointer_direction=_SpanPointerDirection.UPSTREAM, + pointer_hash="8d49f5b0b742484159d4cd572bae1ce5", + extra_attributes={}, + ), + ], + ), + SpanPointersCase( + name="sensible s3 event with dd_botocore_span_pointers disabled", + event_source=_EventSource(EventTypes.S3), + event={ + "Records": [ + { + "eventName": "ObjectCreated:Put", + "s3": { + "bucket": { + "name": "mybucket", + }, + "object": { + "key": "mykey", + "eTag": "123abc", + }, + }, + }, + ], + }, + dd_botocore_span_pointers=False, + span_pointers=[], + ), + SpanPointersCase( + name="malformed s3 event", + event_source=_EventSource(EventTypes.S3), + event={ + "Records": [ + { + "eventName": "ObjectCreated:Put", + "s3": { + "bucket": { + "name": "mybucket", + }, + "object": { + "key": "mykey", + # missing eTag + }, + }, + }, + ], + }, + dd_botocore_span_pointers=True, + span_pointers=[], + ), + SpanPointersCase( + name="empty dynamodb event", + event_source=_EventSource(EventTypes.DYNAMODB), + event={}, + dd_botocore_span_pointers=True, + span_pointers=[], + ), + SpanPointersCase( + name="sensible dynamodb event", + event_source=_EventSource(EventTypes.DYNAMODB), + event={ + "Records": [ + { + "eventSourceARN": "arn:aws:dynamodb:us-west-2:123456789012:table/some-table/stream/2015-06-27T00:48:05.899", + "dynamodb": { + "Keys": { + "some-key": {"S": "some-value"}, + }, + }, + }, + { + "eventSourceARN": "arn:aws:dynamodb:us-west-2:123456789012:table/some-table/stream/2015-06-27T00:48:05.899", + "dynamodb": { + "Keys": { + "some-key": {"S": "some-other-value"}, + }, + }, + }, + ], + }, + dd_botocore_span_pointers=True, + span_pointers=[ + _SpanPointerDescription( + pointer_kind="aws.dynamodb.item", + pointer_direction=_SpanPointerDirection.UPSTREAM, + pointer_hash="7f1aee721472bcb48701d45c7c7f7821", + extra_attributes={}, + ), + _SpanPointerDescription( + pointer_kind="aws.dynamodb.item", + pointer_direction=_SpanPointerDirection.UPSTREAM, + pointer_hash="36b820424312a6069bd3f2185f1af584", + extra_attributes={}, + ), + ], + ), + SpanPointersCase( + name="malformed dynamodb event", + event_source=_EventSource(EventTypes.DYNAMODB), + event={ + "Records": [ + { + "eventSourceARN": "arn:aws:dynamodb:us-west-2:123456789012:table/some-table", # missing stream info + "dynamodb": { + "Keys": { + "some-key": {"S": "some-value"}, + }, + }, + }, + ], + }, + dd_botocore_span_pointers=True, + span_pointers=[], + ), + ], + ids=lambda test_case: test_case.name, + ) + def test_calculate_span_pointers(self, test_case: SpanPointersCase) -> None: + assert ( + calculate_span_pointers( + test_case.event_source, + test_case.event, + botocore_add_span_pointers=test_case.dd_botocore_span_pointers, + ) + == test_case.span_pointers + ) diff --git a/tests/test_tag_object.py b/tests/test_tag_object.py index 0936f0c5c..574bb331a 100644 --- a/tests/test_tag_object.py +++ b/tests/test_tag_object.py @@ -1,4 +1,5 @@ import unittest +from decimal import Decimal try: from unittest.mock import MagicMock, patch, call @@ -18,16 +19,71 @@ def test_tag_object(self): tag_object(spanMock, "function.request", payload) spanMock.set_tag.assert_has_calls( [ - call("function.request.vals.0.thingOne", 1), - call("function.request.vals.1.thingTwo", 2), + call("function.request.vals.0.thingOne", "1"), + call("function.request.vals.1.thingTwo", "2"), call("function.request.hello", "world"), call("function.request.anotherThing.blah", None), call("function.request.anotherThing.foo", "bar"), - call("function.request.anotherThing.nice", True), + call("function.request.anotherThing.nice", "True"), + ], + True, + ) + + @patch("datadog_lambda.config.Config.capture_payload_max_depth", 2) + def test_tag_object_max_depth(self): + payload = { + "hello": "world", + "level1": { + "level2_dict": {"level3": 3}, + "level2_list": [None, True, "nice", {"l3": "v3"}], + "level2_bool": True, + "level2_int": 2, + }, + "vals": [{"thingOne": 1}, {"thingTwo": 2}], + } + spanMock = MagicMock() + + tag_object(spanMock, "function.request", payload) + spanMock.set_tag.assert_has_calls( + [ + call("function.request.vals.0", "{'thingOne': 1}"), + call("function.request.vals.1", "{'thingTwo': 2}"), + call("function.request.hello", "world"), + call("function.request.level1.level2_dict", "{'level3': 3}"), + call( + "function.request.level1.level2_list", + "[None, True, 'nice', {'l3': 'v3'}]", + ), + call("function.request.level1.level2_bool", "True"), + call("function.request.level1.level2_int", "2"), + ], + True, + ) + + @patch("datadog_lambda.config.Config.capture_payload_max_depth", 0) + def test_tag_object_max_depth_0(self): + payload = { + "hello": "world", + "level1": { + "level2_dict": {"level3": 3}, + "level2_list": [None, True, "nice", {"l3": "v3"}], + "level2_bool": True, + "level2_int": 2, + }, + "vals": [{"thingOne": 1}, {"thingTwo": 2}], + } + spanMock = MagicMock() + + tag_object(spanMock, "function.request", payload) + spanMock.set_tag.assert_has_calls( + [ + call( + "function.request", + "{'hello': 'world', 'level1': {'level2_dict': {'level3': 3}, 'level2_list': [None, True, 'nice', {'l3': 'v3'}], 'level2_bool': True, 'level2_int': 2}, 'vals': [{'thingOne': 1}, {'thingTwo': 2}]}", + ), ], True, ) - self.assertEqual(1, 1) def test_redacted_tag_object(self): payload = { @@ -39,12 +95,12 @@ def test_redacted_tag_object(self): tag_object(spanMock, "function.request", payload) spanMock.set_tag.assert_has_calls( [ - call("function.request.vals.0.thingOne", 1), - call("function.request.vals.1.thingTwo", 2), + call("function.request.vals.0.thingOne", "1"), + call("function.request.vals.1.thingTwo", "2"), call("function.request.authorization", "redacted"), call("function.request.anotherThing.blah", None), call("function.request.anotherThing.password", "redacted"), - call("function.request.anotherThing.nice", True), + call("function.request.anotherThing.nice", "True"), ], True, ) @@ -61,7 +117,7 @@ def test_json_tag_object(self): call("function.request.token", "redacted"), call("function.request.jsonString.stringifyThisJson.0.here", "is"), call("function.request.jsonString.stringifyThisJson.0.an", "object"), - call("function.request.jsonString.stringifyThisJson.0.number", 1), + call("function.request.jsonString.stringifyThisJson.0.number", "1"), ], True, ) @@ -69,7 +125,7 @@ def test_json_tag_object(self): def test_unicode_tag_object(self): payload = { "token": "world", - u"jsonString": u'{"stringifyThisJson":[{"here":"is","an":"object","number":1}]}', + "jsonString": '{"stringifyThisJson":[{"here":"is","an":"object","number":1}]}', } spanMock = MagicMock() tag_object(spanMock, "function.request", payload) @@ -78,7 +134,59 @@ def test_unicode_tag_object(self): call("function.request.token", "redacted"), call("function.request.jsonString.stringifyThisJson.0.here", "is"), call("function.request.jsonString.stringifyThisJson.0.an", "object"), - call("function.request.jsonString.stringifyThisJson.0.number", 1), + call("function.request.jsonString.stringifyThisJson.0.number", "1"), + ], + True, + ) + + def test_decimal_tag_object(self): + payload = {"myValue": Decimal(500.5)} + spanMock = MagicMock() + tag_object(spanMock, "function.request", payload) + spanMock.set_tag.assert_has_calls( + [ + call("function.request.myValue", "500.5"), + ], + True, + ) + + class CustomResponse(object): + """ + For example, chalice.app.Response class + """ + + def __init__(self, body, headers=None, status_code: int = 200): + self.body = body + if headers is None: + headers = {} + self.headers = headers + self.status_code = status_code + + def __str__(self): + return str(self.body) + + class ResponseHasToDict(CustomResponse): + def to_dict(self): + return self.headers + + def test_custom_response(self): + payload = self.CustomResponse({"hello": "world"}, {"key1": "val1"}, 200) + spanMock = MagicMock() + tag_object(spanMock, "function.response", payload) + spanMock.set_tag.assert_has_calls( + [ + call("function.response", "{'hello': 'world'}"), + ], + True, + ) + + def test_custom_response_to_dict(self): + payload = self.ResponseHasToDict({"hello": "world"}, {"key1": "val1"}, 200) + spanMock = MagicMock() + tag_object(spanMock, "function.response", payload) + spanMock.set_tag.assert_has_calls( + [ + call("function.response.key1", "val1"), ], True, ) diff --git a/tests/test_tags.py b/tests/test_tags.py index 80b5f86db..07daa8e03 100644 --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -1,30 +1,25 @@ import unittest -from unittest.mock import patch, MagicMock +from unittest.mock import patch +from datadog_lambda.tags import parse_lambda_tags_from_arn -from datadog_lambda.tags import parse_lambda_tags_from_arn, get_runtime_tag - - -def get_mock_context( - invoked_function_arn="arn:aws:lambda:us-east-1:1234597598159:function:swf-hello-test:$Latest", - function_version="1", -): - lambda_context = MagicMock() - lambda_context.invoked_function_arn = invoked_function_arn - lambda_context.function_version = function_version - return lambda_context +from tests.utils import get_mock_context class TestMetricTags(unittest.TestCase): def setUp(self): - patcher = patch("datadog_lambda.tags.python_version_tuple") + patcher = patch("sys.version_info", (3, 12, 0)) self.mock_python_version_tuple = patcher.start() self.addCleanup(patcher.stop) def test_parse_lambda_tags_from_arn_latest(self): + lambda_context = get_mock_context() + lambda_context.invoked_function_arn = ( + "arn:aws:lambda:us-east-1:1234597598159:function:swf-hello-test:$Latest" + ) self.assertListEqual( - parse_lambda_tags_from_arn(get_mock_context()), + parse_lambda_tags_from_arn(lambda_context), [ "region:us-east-1", "account_id:1234597598159", @@ -63,7 +58,3 @@ def test_parse_lambda_tags_from_arn_alias(self): "resource:swf-hello-test:my_alias-1", ], ) - - def test_get_runtime_tag(self): - self.mock_python_version_tuple.return_value = ("3", "7", "2") - self.assertEqual(get_runtime_tag(), "runtime:python3.7") diff --git a/tests/test_tracing.py b/tests/test_tracing.py index cf2e9f96f..0fddd52ba 100644 --- a/tests/test_tracing.py +++ b/tests/test_tracing.py @@ -1,25 +1,56 @@ -import unittest +import base64 +import copy +import functools import json +import traceback +import pytest import os +import unittest -from unittest.mock import MagicMock, patch, call +from unittest.mock import Mock, patch, call, ANY -from ddtrace.helpers import get_correlation_ids -from ddtrace.context import Context +import ddtrace -from datadog_lambda.constants import SamplingPriority, TraceHeader, XraySubsegment +from ddtrace.trace import Context, tracer +from ddtrace._trace._span_pointer import _SpanPointer +from ddtrace._trace._span_pointer import _SpanPointerDirection +from ddtrace._trace._span_pointer import _SpanPointerDescription + +from datadog_lambda.constants import ( + SamplingPriority, + TraceHeader, + TraceContextSource, + XraySubsegment, +) from datadog_lambda.tracing import ( + HIGHER_64_BITS, + LOWER_64_BITS, + _deterministic_sha256_hash, + create_inferred_span, extract_dd_trace_context, create_dd_dummy_metadata_subsegment, create_function_execution_span, get_dd_trace_context, + mark_trace_as_error_for_5xx_responses, set_correlation_ids, set_dd_trace_py_root, _convert_xray_trace_id, _convert_xray_entity_id, _convert_xray_sampling, + create_service_mapping, + determine_service_name, + service_mapping as global_service_mapping, + propagator, + emit_telemetry_on_exception_outside_of_handler, + _dsm_set_checkpoint, + extract_context_from_kinesis_event, + extract_context_from_sqs_or_sns_event_or_context, ) +from datadog_lambda.trigger import parse_event_source +from tests.utils import get_mock_context, ClientContext + + function_arn = "arn:aws:lambda:us-west-1:123457598159:function:python-layer-test" fake_xray_header_value = ( @@ -28,59 +59,237 @@ fake_xray_header_value_parent_decimal = "10713633173203262661" fake_xray_header_value_root_decimal = "3995693151288333088" +event_samples = "tests/event_samples/" + + +def with_trace_propagation_style(style): + style_list = list(style.split(",")) -class ClientContext(object): - def __init__(self, custom=None): - self.custom = custom + def _wrapper(fn): + @functools.wraps(fn) + def _wrap(*args, **kwargs): + from ddtrace.propagation.http import config + orig_extract = config._propagation_style_extract + orig_inject = config._propagation_style_inject + config._propagation_style_extract = style_list + config._propagation_style_inject = style_list + try: + return fn(*args, **kwargs) + finally: + config._propagation_style_extract = orig_extract + config._propagation_style_inject = orig_inject -def get_mock_context( - aws_request_id="request-id-1", - memory_limit_in_mb="256", - invoked_function_arn=function_arn, - function_version="1", - function_name="Function", - custom=None, -): - lambda_context = MagicMock() - lambda_context.aws_request_id = aws_request_id - lambda_context.memory_limit_in_mb = memory_limit_in_mb - lambda_context.invoked_function_arn = invoked_function_arn - lambda_context.function_version = function_version - lambda_context.function_name = function_name - lambda_context.client_context = ClientContext(custom) - return lambda_context + return _wrap + + return _wrapper + + +_test_extract_dd_trace_context = ( + ("api-gateway", Context(trace_id=12345, span_id=67890, sampling_priority=2)), + ( + "api-gateway-no-apiid", + Context(trace_id=12345, span_id=67890, sampling_priority=2), + ), + ( + "api-gateway-non-proxy", + Context(trace_id=12345, span_id=67890, sampling_priority=2), + ), + ( + "api-gateway-non-proxy-async", + Context(trace_id=12345, span_id=67890, sampling_priority=2), + ), + ( + "api-gateway-websocket-connect", + Context(trace_id=12345, span_id=67890, sampling_priority=2), + ), + ( + "api-gateway-websocket-default", + Context(trace_id=12345, span_id=67890, sampling_priority=2), + ), + ( + "api-gateway-websocket-disconnect", + Context(trace_id=12345, span_id=67890, sampling_priority=2), + ), + ( + "authorizer-request-api-gateway-v1", + Context( + trace_id=13478705995797221209, + span_id=8471288263384216896, + sampling_priority=1, + ), + ), + ("authorizer-request-api-gateway-v1-cached", None), + ( + "authorizer-request-api-gateway-v2", + Context( + trace_id=14356983619852933354, + span_id=12658621083505413809, + sampling_priority=1, + ), + ), + ("authorizer-request-api-gateway-v2-cached", None), + ( + "authorizer-request-api-gateway-websocket-connect", + Context( + trace_id=5351047404834723189, + span_id=18230460631156161837, + sampling_priority=1, + ), + ), + ("authorizer-request-api-gateway-websocket-message", None), + ( + "authorizer-token-api-gateway-v1", + Context( + trace_id=17874798268144902712, + span_id=16184667399315372101, + sampling_priority=1, + ), + ), + ("authorizer-token-api-gateway-v1-cached", None), + ("cloudfront", None), + ("cloudwatch-events", None), + ("cloudwatch-logs", None), + ("custom", None), + ("dynamodb", None), + ("eventbridge-custom", Context(trace_id=12345, span_id=67890, sampling_priority=2)), + ( + "eventbridge-sqs", + Context( + trace_id=7379586022458917877, + span_id=2644033662113726488, + sampling_priority=1, + ), + ), + ("http-api", Context(trace_id=12345, span_id=67890, sampling_priority=2)), + ( + "kinesis", + Context( + trace_id=4948377316357291421, + span_id=2876253380018681026, + sampling_priority=1, + ), + ), + ( + "kinesis-batch", + Context( + trace_id=4948377316357291421, + span_id=2876253380018681026, + sampling_priority=1, + ), + ), + ("lambda-url", None), + ( + "rum-appsync", + Context( + trace_id=12345, + span_id=67890, + sampling_priority=1, + ), + ), + ("rum-appsync-no-headers", None), + ("rum-appsync-request-not-dict", None), + ("s3", None), + ( + "sns-b64-msg-attribute", + Context( + trace_id=4948377316357291421, + span_id=6746998015037429512, + sampling_priority=1, + ), + ), + ( + "sns-batch", + Context( + trace_id=4948377316357291421, + span_id=6746998015037429512, + sampling_priority=1, + ), + ), + ( + "sns-string-msg-attribute", + Context( + trace_id=4948377316357291421, + span_id=6746998015037429512, + sampling_priority=1, + ), + ), + ( + "sqs-batch", + Context( + trace_id=2684756524522091840, + span_id=7431398482019833808, + sampling_priority=1, + ), + ), + ( + "sqs-java-upstream", + Context( + trace_id=7925498337868555493, + span_id=5245570649555658903, + sampling_priority=1, + ), + ), + ( + "sns-sqs-java-upstream", + Context( + trace_id=4781801699472307582, + span_id=7752697518321801287, + sampling_priority=1, + ), + ), + ( + "sqs-string-msg-attribute", + Context( + trace_id=2684756524522091840, + span_id=7431398482019833808, + sampling_priority=1, + ), + ), + ({"headers": None}, None), +) + + +@pytest.mark.parametrize("event,expect", _test_extract_dd_trace_context) +def test_extract_dd_trace_context(event, expect): + if isinstance(event, str): + with open(f"{event_samples}{event}.json") as f: + event = json.load(f) + ctx = get_mock_context() + + actual, _, _ = extract_dd_trace_context(event, ctx) + assert (expect is None) is (actual is None) + assert (expect is None) or actual.trace_id == expect.trace_id + assert (expect is None) or actual.span_id == expect.span_id + assert (expect is None) or actual.sampling_priority == expect.sampling_priority class TestExtractAndGetDDTraceContext(unittest.TestCase): def setUp(self): - global dd_tracing_enabled - dd_tracing_enabled = False os.environ["_X_AMZN_TRACE_ID"] = fake_xray_header_value patcher = patch("datadog_lambda.tracing.send_segment") self.mock_send_segment = patcher.start() self.addCleanup(patcher.stop) - patcher = patch("datadog_lambda.tracing.is_lambda_context") + patcher = patch("datadog_lambda.config.Config.is_lambda_context") self.mock_is_lambda_context = patcher.start() self.mock_is_lambda_context.return_value = True self.addCleanup(patcher.stop) def tearDown(self): - global dd_tracing_enabled - dd_tracing_enabled = False del os.environ["_X_AMZN_TRACE_ID"] + @with_trace_propagation_style("datadog") def test_without_datadog_trace_headers(self): lambda_ctx = get_mock_context() - ctx, source = extract_dd_trace_context({}, lambda_ctx) + ctx, source, event_source = extract_dd_trace_context({}, lambda_ctx) self.assertEqual(source, "xray") - self.assertDictEqual( + self.assertEqual( ctx, - { - "trace-id": fake_xray_header_value_root_decimal, - "parent-id": fake_xray_header_value_parent_decimal, - "sampling-priority": "2", - }, + Context( + trace_id=int(fake_xray_header_value_root_decimal), + span_id=int(fake_xray_header_value_parent_decimal), + sampling_priority=2, + ), ) self.assertDictEqual( get_dd_trace_context(), @@ -92,20 +301,18 @@ def test_without_datadog_trace_headers(self): {}, ) - def test_with_incomplete_datadog_trace_headers(self): + @with_trace_propagation_style("datadog") + def test_with_non_object_event(self): lambda_ctx = get_mock_context() - ctx, source = extract_dd_trace_context( - {"headers": {TraceHeader.TRACE_ID: "123", TraceHeader.PARENT_ID: "321"}}, - lambda_ctx, - ) + ctx, source, event_source = extract_dd_trace_context(b"", lambda_ctx) self.assertEqual(source, "xray") - self.assertDictEqual( + self.assertEqual( ctx, - { - "trace-id": fake_xray_header_value_root_decimal, - "parent-id": fake_xray_header_value_parent_decimal, - "sampling-priority": "2", - }, + Context( + trace_id=int(fake_xray_header_value_root_decimal), + span_id=int(fake_xray_header_value_parent_decimal), + sampling_priority=2, + ), ) self.assertDictEqual( get_dd_trace_context(), @@ -114,40 +321,79 @@ def test_with_incomplete_datadog_trace_headers(self): TraceHeader.PARENT_ID: fake_xray_header_value_parent_decimal, TraceHeader.SAMPLING_PRIORITY: "2", }, + {}, ) - def test_with_complete_datadog_trace_headers(self): + @with_trace_propagation_style("datadog") + def test_with_incomplete_datadog_trace_headers(self): lambda_ctx = get_mock_context() - ctx, source = extract_dd_trace_context( - { - "headers": { - TraceHeader.TRACE_ID: "123", - TraceHeader.PARENT_ID: "321", - TraceHeader.SAMPLING_PRIORITY: "1", - } - }, + ctx, source, event_source = extract_dd_trace_context( + {"headers": {TraceHeader.TRACE_ID: "123"}}, lambda_ctx, ) - self.assertEqual(source, "event") - self.assertDictEqual( + self.assertEqual(source, "xray") + self.assertEqual( ctx, - {"trace-id": "123", "parent-id": "321", "sampling-priority": "1"}, + Context( + trace_id=int(fake_xray_header_value_root_decimal), + span_id=int(fake_xray_header_value_parent_decimal), + sampling_priority=2, + ), ) self.assertDictEqual( get_dd_trace_context(), { - TraceHeader.TRACE_ID: "123", + TraceHeader.TRACE_ID: fake_xray_header_value_root_decimal, TraceHeader.PARENT_ID: fake_xray_header_value_parent_decimal, - TraceHeader.SAMPLING_PRIORITY: "1", + TraceHeader.SAMPLING_PRIORITY: "2", }, ) + + def common_tests_with_trace_context_extraction_injection( + self, headers, event_containing_headers, lambda_context=get_mock_context() + ): + ctx, source, event_source = extract_dd_trace_context( + event_containing_headers, + lambda_context, + ) + self.assertEqual(source, "event") + expected_context = propagator.extract(headers) + self.assertEqual(ctx, expected_context) create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY) self.mock_send_segment.assert_called() self.mock_send_segment.assert_called_with( XraySubsegment.TRACE_KEY, - {"trace-id": "123", "parent-id": "321", "sampling-priority": "1"}, + expected_context, + ) + # when no active ddtrace context, xray context would be used + expected_context.span_id = int(fake_xray_header_value_parent_decimal) + expected_headers = {} + propagator.inject(expected_context, expected_headers) + dd_context_headers = get_dd_trace_context() + self.assertDictEqual(expected_headers, dd_context_headers) + + @with_trace_propagation_style("datadog") + def test_with_complete_datadog_trace_headers(self): + headers = { + TraceHeader.TRACE_ID: "123", + TraceHeader.PARENT_ID: "321", + TraceHeader.SAMPLING_PRIORITY: "1", + } + self.common_tests_with_trace_context_extraction_injection( + headers, {"headers": headers} ) + @with_trace_propagation_style("tracecontext") + def test_with_w3c_trace_headers(self): + headers = { + "traceparent": "00-0000000000000000000000000000007b-0000000000000141-01", + "tracestate": "dd=s:2;t.dm:-0,rojo=00f067aa0ba902b7,congo=t61rcWkgMzE", + } + self.common_tests_with_trace_context_extraction_injection( + headers, {"headers": headers} + ) + + @with_trace_propagation_style("datadog") def test_with_extractor_function(self): def extractor_foo(event, context): foo = event.get("foo", {}) @@ -159,7 +405,7 @@ def extractor_foo(event, context): return trace_id, parent_id, sampling_priority lambda_ctx = get_mock_context() - ctx, ctx_source = extract_dd_trace_context( + ctx, ctx_source, event_source = extract_dd_trace_context( { "foo": { TraceHeader.TRACE_ID: "123", @@ -171,13 +417,13 @@ def extractor_foo(event, context): extractor=extractor_foo, ) self.assertEqual(ctx_source, "event") - self.assertDictEqual( + self.assertEqual( ctx, - { - "trace-id": "123", - "parent-id": "321", - "sampling-priority": "1", - }, + Context( + trace_id=123, + span_id=321, + sampling_priority=1, + ), ) self.assertDictEqual( get_dd_trace_context(), @@ -188,12 +434,13 @@ def extractor_foo(event, context): }, ) + @with_trace_propagation_style("datadog") def test_graceful_fail_of_extractor_function(self): def extractor_raiser(event, context): raise Exception("kreator") lambda_ctx = get_mock_context() - ctx, ctx_source = extract_dd_trace_context( + ctx, ctx_source, event_source = extract_dd_trace_context( { "foo": { TraceHeader.TRACE_ID: "123", @@ -205,13 +452,13 @@ def extractor_raiser(event, context): extractor=extractor_raiser, ) self.assertEqual(ctx_source, "xray") - self.assertDictEqual( + self.assertEqual( ctx, - { - "trace-id": fake_xray_header_value_root_decimal, - "parent-id": fake_xray_header_value_parent_decimal, - "sampling-priority": "2", - }, + Context( + trace_id=int(fake_xray_header_value_root_decimal), + span_id=int(fake_xray_header_value_parent_decimal), + sampling_priority=2, + ), ) self.assertDictEqual( get_dd_trace_context(), @@ -222,8 +469,13 @@ def extractor_raiser(event, context): }, ) + @with_trace_propagation_style("datadog") def test_with_sqs_distributed_datadog_trace_data(self): - lambda_ctx = get_mock_context() + headers = { + TraceHeader.TRACE_ID: "123", + TraceHeader.PARENT_ID: "321", + TraceHeader.SAMPLING_PRIORITY: "1", + } sqs_event = { "Records": [ { @@ -238,13 +490,8 @@ def test_with_sqs_distributed_datadog_trace_data(self): }, "messageAttributes": { "_datadog": { - "stringValue": json.dumps( - { - TraceHeader.TRACE_ID: "123", - TraceHeader.PARENT_ID: "321", - TraceHeader.SAMPLING_PRIORITY: "1", - } - ) + "stringValue": json.dumps(headers), + "dataType": "String", } }, "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", @@ -254,118 +501,104 @@ def test_with_sqs_distributed_datadog_trace_data(self): } ] } - ctx, source = extract_dd_trace_context(sqs_event, lambda_ctx) - self.assertEqual(source, "event") - self.assertDictEqual( - ctx, - { - "trace-id": "123", - "parent-id": "321", - "sampling-priority": "1", - }, - ) - self.assertDictEqual( - get_dd_trace_context(), - { - TraceHeader.TRACE_ID: "123", - TraceHeader.PARENT_ID: fake_xray_header_value_parent_decimal, - TraceHeader.SAMPLING_PRIORITY: "1", - }, - ) - create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY) - self.mock_send_segment.assert_called_with( - XraySubsegment.TRACE_KEY, - {"trace-id": "123", "parent-id": "321", "sampling-priority": "1"}, - ) + self.common_tests_with_trace_context_extraction_injection(headers, sqs_event) - def test_with_legacy_client_context_datadog_trace_data(self): - lambda_ctx = get_mock_context( - custom={ - "_datadog": { - TraceHeader.TRACE_ID: "666", - TraceHeader.PARENT_ID: "777", - TraceHeader.SAMPLING_PRIORITY: "1", + @with_trace_propagation_style("tracecontext") + def test_with_sqs_distributed_w3c_trace_data(self): + headers = { + "traceparent": "00-0000000000000000000000000000007b-0000000000000141-01", + "tracestate": "dd=s:2;t.dm:-0,rojo=00f067aa0ba902b7,congo=t61rcWkgMzE", + } + sqs_event = { + "Records": [ + { + "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", + "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "body": "Test message.", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1545082649183", + "SenderId": "AIDAIENQZJOLO23YVJ4VO", + "ApproximateFirstReceiveTimestamp": "1545082649185", + }, + "messageAttributes": { + "_datadog": { + "stringValue": json.dumps(headers), + "dataType": "String", + } + }, + "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", + "awsRegion": "us-east-2", } - } - ) - ctx, source = extract_dd_trace_context({}, lambda_ctx) - self.assertEqual(source, "event") - self.assertDictEqual( - ctx, - { - "trace-id": "666", - "parent-id": "777", - "sampling-priority": "1", - }, - ) - self.assertDictEqual( - get_dd_trace_context(), - { - TraceHeader.TRACE_ID: "666", - TraceHeader.PARENT_ID: fake_xray_header_value_parent_decimal, - TraceHeader.SAMPLING_PRIORITY: "1", - }, + ] + } + self.common_tests_with_trace_context_extraction_injection(headers, sqs_event) + + @with_trace_propagation_style("datadog") + def test_with_legacy_client_context_datadog_trace_data(self): + headers = { + TraceHeader.TRACE_ID: "666", + TraceHeader.PARENT_ID: "777", + TraceHeader.SAMPLING_PRIORITY: "1", + } + lambda_ctx = get_mock_context(custom={"_datadog": headers}) + self.common_tests_with_trace_context_extraction_injection( + headers, {}, lambda_ctx ) - create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY) - self.mock_send_segment.assert_called() - self.mock_send_segment.assert_called_with( - XraySubsegment.TRACE_KEY, - {"trace-id": "666", "parent-id": "777", "sampling-priority": "1"}, + + @with_trace_propagation_style("tracecontext") + def test_with_legacy_client_context_w3c_trace_data(self): + headers = { + "traceparent": "00-0000000000000000000000000000029a-0000000000000309-01", + "tracestate": "dd=s:1;t.dm:-0,rojo=00f067aa0ba902b7,congo=t61rcWkgMzE", + } + lambda_ctx = get_mock_context(custom={"_datadog": headers}) + self.common_tests_with_trace_context_extraction_injection( + headers, {}, lambda_ctx ) + @with_trace_propagation_style("datadog") def test_with_new_client_context_datadog_trace_data(self): - lambda_ctx = get_mock_context( - custom={ - TraceHeader.TRACE_ID: "666", - TraceHeader.PARENT_ID: "777", - TraceHeader.SAMPLING_PRIORITY: "1", - } - ) - ctx, source = extract_dd_trace_context({}, lambda_ctx) - self.assertEqual(source, "event") - self.assertDictEqual( - ctx, - { - "trace-id": "666", - "parent-id": "777", - "sampling-priority": "1", - }, - ) - self.assertDictEqual( - get_dd_trace_context(), - { - TraceHeader.TRACE_ID: "666", - TraceHeader.PARENT_ID: fake_xray_header_value_parent_decimal, - TraceHeader.SAMPLING_PRIORITY: "1", - }, + headers = { + TraceHeader.TRACE_ID: "666", + TraceHeader.PARENT_ID: "777", + TraceHeader.SAMPLING_PRIORITY: "1", + } + lambda_ctx = get_mock_context(custom=headers) + self.common_tests_with_trace_context_extraction_injection( + headers, {}, lambda_ctx ) - create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY) - self.mock_send_segment.assert_called() - self.mock_send_segment.assert_called_with( - XraySubsegment.TRACE_KEY, - {"trace-id": "666", "parent-id": "777", "sampling-priority": "1"}, + + @with_trace_propagation_style("tracecontext") + def test_with_new_client_context_w3c_trace_data(self): + headers = { + "traceparent": "00-0000000000000000000000000000029a-0000000000000309-01", + "tracestate": "dd=s:1;t.dm:-0,rojo=00f067aa0ba902b7,congo=t61rcWkgMzE", + } + lambda_ctx = get_mock_context(custom=headers) + self.common_tests_with_trace_context_extraction_injection( + headers, {}, lambda_ctx ) + @with_trace_propagation_style("datadog") def test_with_complete_datadog_trace_headers_with_mixed_casing(self): lambda_ctx = get_mock_context() + headers = { + "X-Datadog-Trace-Id": "123", + "X-Datadog-Parent-Id": "321", + "X-Datadog-Sampling-Priority": "1", + } extract_dd_trace_context( - { - "headers": { - "X-Datadog-Trace-Id": "123", - "X-Datadog-Parent-Id": "321", - "X-Datadog-Sampling-Priority": "1", - } - }, + {"headers": headers}, lambda_ctx, ) - self.assertDictEqual( - get_dd_trace_context(), - { - TraceHeader.TRACE_ID: "123", - TraceHeader.PARENT_ID: fake_xray_header_value_parent_decimal, - TraceHeader.SAMPLING_PRIORITY: "1", - }, - ) + extract_headers = {} + context = propagator.extract(headers) + context.span_id = fake_xray_header_value_parent_decimal + propagator.inject(context, extract_headers) + self.assertDictEqual(extract_headers, get_dd_trace_context()) def test_with_complete_datadog_trace_headers_with_trigger_tags(self): trigger_tags = { @@ -388,80 +621,471 @@ def test_with_complete_datadog_trace_headers_with_trigger_tags(self): ] ) - -class TestXRayContextConversion(unittest.TestCase): - def test_convert_xray_trace_id(self): - self.assertEqual( - _convert_xray_trace_id("00000000e1be46a994272793"), "7043144561403045779" + def test_request_header_malformed(self): + """Testing that if a RUM AppSync event is malformed, the tracer will attempt + to get the trace context from the lambda context in the + extract_context_from_request_header_or_context function.""" + lambda_ctx = get_mock_context() + lambda_ctx.client_context = ClientContext( + custom={ + "_datadog": { + "x-datadog-parent-id": "67890", + "x-datadog-sampling-priority": "1", + "x-datadog-trace-id": "12345", + } + } + ) + request_header_event = { + "identity": "None", + "info": { + "fieldName": "getItems", + "parentTypeName": "Query", + "selectionSetGraphQL": "{\n id\n}", + "selectionSetList": ["id"], + }, + "prev": "None", + "request": "hello", + "source": "None", + } + ctx, source, _ = extract_dd_trace_context(request_header_event, lambda_ctx) + expected_context = Context( + trace_id=12345, + span_id=67890, + sampling_priority=1, ) - self.assertEqual( - _convert_xray_trace_id("bd862e3fe1be46a994272793"), "7043144561403045779" + self.assertEqual(ctx, expected_context) + self.assertEqual(source, "event") + + def _test_step_function_trace_data_common( + self, event, expected_trace_id, expected_span_id, expected_tid + ): + """Common test logic for step function trace data tests""" + lambda_ctx = get_mock_context() + expected_context = Context( + trace_id=expected_trace_id, + span_id=expected_span_id, + sampling_priority=1, + meta={"_dd.p.tid": expected_tid}, ) + expected_headers = { + TraceHeader.TRACE_ID: str(expected_trace_id), + TraceHeader.PARENT_ID: "10713633173203262661", + TraceHeader.SAMPLING_PRIORITY: "1", + TraceHeader.TAGS: f"_dd.p.tid={expected_tid}", + } - self.assertEqual( - _convert_xray_trace_id("ffffffffffffffffffffffff"), - "9223372036854775807", # 0x7FFFFFFFFFFFFFFF + ctx, source, _ = extract_dd_trace_context(event, lambda_ctx) + + self.assertEqual(source, "event") + self.assertEqual(ctx, expected_context) + self.assertEqual(get_dd_trace_context(), expected_headers) + + create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY) + self.mock_send_segment.assert_called_with( + XraySubsegment.TRACE_KEY, + expected_context, ) - def test_convert_xray_entity_id(self): - self.assertEqual( - _convert_xray_entity_id("53995c3f42cd8ad8"), "6023947403358210776" + @with_trace_propagation_style("datadog") + def test_step_function_trace_data(self): + """Test basic step function trace data extraction""" + sfn_event = { + "Execution": { + "Id": "arn:aws:states:sa-east-1:425362996713:execution:abhinav-activity-state-machine:72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "Name": "72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "RoleArn": "arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j", + "StartTime": "2024-12-04T19:38:04.069Z", + "RedriveCount": 0, + }, + "State": { + "Name": "Lambda Invoke", + "EnteredTime": "2024-12-04T19:38:04.118Z", + "RetryCount": 0, + }, + "StateMachine": { + "Id": "arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-activity-state-machine", + "Name": "abhinav-activity-state-machine", + }, + } + self._test_step_function_trace_data_common( + sfn_event, 435175499815315247, 3929055471293792800, "3e7a89d1b7310603" ) - self.assertEqual( - _convert_xray_entity_id("1000000000000000"), "1152921504606846976" + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_retry(self): + """Test step function trace data extraction with non-zero retry count""" + sfn_event = { + "Execution": { + "Id": "arn:aws:states:sa-east-1:425362996713:execution:abhinav-activity-state-machine:72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "Name": "72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "RoleArn": "arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j", + "StartTime": "2024-12-04T19:38:04.069Z", + "RedriveCount": 0, + }, + "State": { + "Name": "Lambda Invoke", + "EnteredTime": "2024-12-04T19:38:04.118Z", + "RetryCount": 1, + }, + "StateMachine": { + "Id": "arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-activity-state-machine", + "Name": "abhinav-activity-state-machine", + }, + } + self._test_step_function_trace_data_common( + sfn_event, 435175499815315247, 5063839446130725204, "3e7a89d1b7310603" ) - self.assertEqual( - _convert_xray_entity_id("ffffffffffffffff"), "18446744073709551615" + # https://github.com/DataDog/logs-backend/blob/65ea567150f24e5498008f3cf8cabef9ea995f5d/domains/serverless/apps/logs-to-traces-reducer/src/test/resources/test-json-files/stepfunctions/RedriveTest/snapshots/RedriveLambdaSuccessTraceMerging.json#L45-L46 + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_redrive(self): + """Test step function trace data extraction with non-zero redrive count""" + sfn_event = { + "Execution": { + "Id": "arn:aws:states:sa-east-1:425362996713:execution:abhinav-activity-state-machine:72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "Name": "72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "RoleArn": "arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j", + "StartTime": "2024-12-04T19:38:04.069Z", + "RedriveCount": 1, + }, + "State": { + "Name": "Lambda Invoke", + "EnteredTime": "2024-12-04T19:38:04.118Z", + "RetryCount": 0, + }, + "StateMachine": { + "Id": "arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-activity-state-machine", + "Name": "abhinav-activity-state-machine", + }, + } + self._test_step_function_trace_data_common( + sfn_event, 435175499815315247, 8782364156266188026, "3e7a89d1b7310603" ) - def test_convert_xray_sampling(self): - self.assertEqual(_convert_xray_sampling(True), str(SamplingPriority.USER_KEEP)) + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_lambda_root(self): + """Test JSONata style step function trace data extraction where there's an upstream Lambda""" + sfn_event = { + "_datadog": { + "Execution": { + "Id": "665c417c-1237-4742-aaca-8b3becbb9e75", + "RedriveCount": 0, + }, + "StateMachine": {}, + "State": { + "Name": "my-awesome-state", + "EnteredTime": "Mon Nov 13 12:43:33 PST 2023", + "RetryCount": 0, + }, + "x-datadog-trace-id": "5821803790426892636", + "x-datadog-tags": "_dd.p.dm=-0,_dd.p.tid=672a7cb100000000", + "serverless-version": "v1", + } + } + self._test_step_function_trace_data_common( + sfn_event, 5821803790426892636, 6880978411788117524, "672a7cb100000000" + ) - self.assertEqual( - _convert_xray_sampling(False), str(SamplingPriority.USER_REJECT) + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_sfn_root(self): + """Test JSONata style step function trace data extraction where there's an upstream step function""" + sfn_event = { + "_datadog": { + "Execution": { + "Id": "665c417c-1237-4742-aaca-8b3becbb9e75", + "RedriveCount": 0, + }, + "StateMachine": {}, + "State": { + "Name": "my-awesome-state", + "EnteredTime": "Mon Nov 13 12:43:33 PST 2023", + "RetryCount": 0, + }, + "RootExecutionId": "4875aba4-ae31-4a4c-bf8a-63e9eee31dad", + "serverless-version": "v1", + } + } + self._test_step_function_trace_data_common( + sfn_event, 4521899030418994483, 6880978411788117524, "12d1270d99cc5e03" ) + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_eventbridge(self): + """Test step function trace data extraction through EventBridge""" + eventbridge_event = { + "version": "0", + "id": "eaacd8db-02de-ab13-ed5a-8ffb84048294", + "detail-type": "StepFunctionTask", + "source": "my.eventbridge", + "account": "425362996713", + "time": "2025-03-13T15:17:34Z", + "region": "sa-east-1", + "resources": [ + "arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-inner-state-machine", + "arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:912eaa4c-291a-488a-bda3-d06bcc21203d", + ], + "detail": { + "Message": "Hello from Step Functions!", + "TaskToken": "AQCEAAAAKgAAAAMAAAAAAAAAAeMHr6sb8Ll5IKntjIiLGaBkaNeweo84kKYKDTvDaSAP1vjuYRJEGqFdHsKMyZL8ZcgAdanKpkbhPEN5hpoCe+BH9KblWeDsJxkDCk/meN5SaPlC1qS7Q/7/KqBq+tmAOCSy+MjdqFsnihy5Yo6g6C9uuPn7ccSB/609d8pznFm9nigEos/82emwi18lm67/+/bn4RTX4S7qV4RoGWUWUPeHfr34xWOipCt4SVDkoQPZdRVpq3wyRJP2zcK0zup24/opJqKKSCI5Q9orALNB2jEjDyQ9LE4mSrafoe0tcm/bOAGfrcpR3AwtArUiF6JPYd7Nw0XWWyPXFBjiQTJDhZFlGfllJ1N91eiN8wlzUX1+I0vw/t2PoEmuQ2VCJYCbl1ybjX/tQ97GZ9ogjY9N7VYy5uD5xfZ6VAyetUR06HUtbUIXTVxULm7wmsHb979W/fIQXsrxbFzc0+ypKaqGXJBoq7xX//irjpuNhWg1Wgfn0hxuXl5oN/LkqI83T8f9SdnJMxRDpaHDpttqbjVESB/Pf9o7gakjJj12+r2uiJNc81k50uhuHdFOGsImFHKV8hb1LGcq0ZzUKT5SbEDV2k+ezOP+O9Sk4c0unbpNLM3PKLKxVLhu2gtiIIVCHUHGmumW", + "_datadog": { + "Execution": { + "Id": "arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:912eaa4c-291a-488a-bda3-d06bcc21203d", + "StartTime": "2025-03-13T15:17:33.972Z", + "Name": "912eaa4c-291a-488a-bda3-d06bcc21203d", + "RoleArn": "arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j", + "RedriveCount": 0, + }, + "StateMachine": { + "Id": "arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-inner-state-machine", + "Name": "abhinav-inner-state-machine", + }, + "State": { + "Name": "EventBridge PutEvents", + "EnteredTime": "2025-03-13T15:17:34.008Z", + "RetryCount": 0, + }, + "Task": { + "Token": "AQCEAAAAKgAAAAMAAAAAAAAAAeMHr6sb8Ll5IKntjIiLGaBkaNeweo84kKYKDTvDaSAP1vjuYRJEGqFdHsKMyZL8ZcgAdanKpkbhPEN5hpoCe+BH9KblWeDsJxkDCk/meN5SaPlC1qS7Q/7/KqBq+tmAOCSy+MjdqFsnihy5Yo6g6C9uuPn7ccSB/609d8pznFm9nigEos/82emwi18lm67/+/bn4RTX4S7qV4RoGWUWUPeHfr34xWOipCt4SVDkoQPZdRVpq3wyRJP2zcK0zup24/opJqKKSCI5Q9orALNB2jEjDyQ9LE4mSrafoe0tcm/bOAGfrcpR3AwtArUiF6JPYd7Nw0XWWyPXFBjiQTJDhZFlGfllJ1N91eiN8wlzUX1+I0vw/t2PoEmuQ2VCJYCbl1ybjX/tQ97GZ9ogjY9N7VYy5uD5xfZ6VAyetUR06HUtbUIXTVxULm7wmsHb979W/fIQXsrxbFzc0+ypKaqGXJBoq7xX//irjpuNhWg1Wgfn0hxuXl5oN/LkqI83T8f9SdnJMxRDpaHDpttqbjVESB/Pf9o7gakjJj12+r2uiJNc81k50uhuHdFOGsImFHKV8hb1LGcq0ZzUKT5SbEDV2k+ezOP+O9Sk4c0unbpNLM3PKLKxVLhu2gtiIIVCHUHGmumW" + }, + "RootExecutionId": "arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:912eaa4c-291a-488a-bda3-d06bcc21203d", + "serverless-version": "v1", + }, + }, + } + self._test_step_function_trace_data_common( + eventbridge_event, + 3401561763239692811, + 10430178702434539423, + "a49ff3b7fb47b0b", + ) -class TestLogsInjection(unittest.TestCase): - def setUp(self): - patcher = patch("datadog_lambda.tracing.get_dd_trace_context") - self.mock_get_dd_trace_context = patcher.start() - self.mock_get_dd_trace_context.return_value = { - TraceHeader.TRACE_ID: "123", - TraceHeader.PARENT_ID: "456", + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_sqs(self): + """Test step function trace data extraction through SQS""" + sqs_event = { + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic:f1653ba3-2ff7-4c8e-9381-45a7a62f9708", + "Sns": { + "Type": "Notification", + "MessageId": "e39184ea-bfd8-5efa-96fe-e4a64a457ff7", + "TopicArn": "arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic", + "Subject": None, + "Message": "{}", + "Timestamp": "2025-03-13T15:01:49.942Z", + "SignatureVersion": "1", + "Signature": "WJHKq+pNOLgxa7+dB1dud02RM/30Jvz+KiMZzjRl38/Pphz90H24eGyIbnq3BJXYEyawFCHC6sq/5HcwXouGc5gbah6he+JpqXahMEs6cyMs2tg9SXxooRHEGv5iiZXKhnDcJYOrQ+iFExO9w+WFWfJjO2m/EDVVSYvuDjDV7mmTwAgEOD0zUvWpT7wOeKGG5Uk916Ppy3iMV7sCoHV/RwVikdhCWDDmxbdqteGduAXPdGESE/aj6kUx9ibEOKXyhC+7H1/j0tlhUchl6LZsTf1Gaiq2yEqKXKvsupcG3hRZ6FtIWP0jGlFhpW5EHc2oiHIVOsQceCYPqXYMCZvFuA==", + "SigningCertUrl": "https://sns.sa-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem", + "UnsubscribeUrl": "https://sns.sa-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic:f1653ba3-2ff7-4c8e-9381-45a7a62f9708", + "MessageAttributes": { + "_datadog": { + "Type": "String", + "Value": '{"Execution":{"Id":"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:79478846-0cff-44de-91f5-02c96ff65762","StartTime":"2025-03-13T15:01:49.738Z","Name":"79478846-0cff-44de-91f5-02c96ff65762","RoleArn":"arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j","RedriveCount":0},"StateMachine":{"Id":"arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-inner-state-machine","Name":"abhinav-inner-state-machine"},"State":{"Name":"SNS Publish","EnteredTime":"2025-03-13T15:01:49.768Z","RetryCount":0},"RootExecutionId":"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:79478846-0cff-44de-91f5-02c96ff65762","serverless-version":"v1"}', + } + }, + }, + } + ] } - self.addCleanup(patcher.stop) + self._test_step_function_trace_data_common( + sqs_event, 3818106616964044169, 15912108710769293902, "3a4fd1a254eb514a" + ) - patcher = patch("datadog_lambda.tracing.is_lambda_context") - self.mock_is_lambda_context = patcher.start() - self.mock_is_lambda_context.return_value = True - self.addCleanup(patcher.stop) + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_eventbridge_sqs(self): + """Test step function trace data extraction through EventBridge and SQS""" + eventbridge_sqs_event = { + "Records": [ + { + "messageId": "9ed082ad-2f4d-4309-ab99-9553d2be5613", + "receiptHandle": "AQEB6z7FatNIXbWOTC4Bx+udD0flrnT7XMehruTohl8O2KI2t9hvo5oxGIOhwcb+QtS5aRXsFE35TgGE8kZHlHK7Sa8jQUen6XmsPG7qB6BPdXjr0eunM2SDAtLj0mDSKx907VIKRYQG+qpI9ZyNK7Bi786oQIz2UkZGZru9zlXxJtAQiXBqfJ+OfTzhIwkPu04czU6lYfAbxdyNaBNdBEsTNJKPjquvcq1ZBVCHkn9L6wo8jha6XreoeS2WJ5N26ZLKtAl3wlSUByB92OKZU2mEuNboyY7bgK+nkx4N8fVVrafVXnY9YHuq60eQcZ/nusWFeJlVyN7NFypYP2IOn25xylltEACKbgUdEsFU2h5k7yI2DVk5eAt9vB6qmAJlgfkGsXG0SZrCADoIKXl9jpwajw==", + "body": '{"version":"0","id":"ff6d828b-b35e-abdf-64b6-6ea2cf698c0b","detail-type":"StepFunctionTask","source":"my.eventbridge","account":"425362996713","time":"2025-03-13T15:14:21Z","region":"sa-east-1","resources":["arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-inner-state-machine","arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:fe087266-fe48-4a31-a21b-691f4e7ea985"],"detail":{"Message":"Hello from Step Functions!","TaskToken":"AQCEAAAAKgAAAAMAAAAAAAAAAfi3HMLTw3u9h0vSmkjyHlK1tv5bQUyA7i+6LIvrBWu+3S+DMuQ79JpMtAuCaMN/AGSuGPO7OPeTNA/9v7/kzAsLoPzwPhbrDPXP4SVF1YIO663PvtX/tEWxnAfwLqwDyx8G8VEsVLcmiiOafFCKJwn0OP/DoAWc0sjhWwRxIoQ0ipBGhOqU8rO8SFZVvxUbkosNejnhT7B6314pC89JZLpXU7SxFe+XrgN+uRAvFxsH/+RwDf94xk5hhtukH7HzhJKWN2WCtUISd84pM/1V7ppDuJ3FHgJT22xQIbEGA9Q4o+pLLehzE2SHCdo7eWYQqN+7BanxBNMI6kBMaf5nuh9izAp38lsrmHJyO8NvXgWg+F9hoTZX4RpV9CCwvRFrCRcCeDq4/uJzbvB4AwwA2q2Llm0X8yH0pKvPZ2v7pl4nCWdnEgj920I8AmBCuozbKP7gJRnAqfx3MnOSkpZTeGnHkp0ly8EevwCT2zX/1GQnCAx02kBaDJgUMputFeruMBzwVtlEVBFUUgaWbJwHzz2htuAw282pdATrKfv4VV1N962uLBJ32wd9a92rX7VXXToitvZGIvf/Z7cu4xfAzxQH1rIQ3M4ojkR9r48qoYtnYDlEf+BkIL8L4+xpbRFSBk3p","_datadog":{"Execution":{"Id":"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:fe087266-fe48-4a31-a21b-691f4e7ea985","StartTime":"2025-03-13T15:14:21.730Z","Name":"fe087266-fe48-4a31-a21b-691f4e7ea985","RoleArn":"arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j","RedriveCount":0},"StateMachine":{"Id":"arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-inner-state-machine","Name":"abhinav-inner-state-machine"},"State":{"Name":"EventBridge PutEvents","EnteredTime":"2025-03-13T15:14:21.765Z","RetryCount":0},"Task":{"Token":"AQCEAAAAKgAAAAMAAAAAAAAAAfi3HMLTw3u9h0vSmkjyHlK1tv5bQUyA7i+6LIvrBWu+3S+DMuQ79JpMtAuCaMN/AGSuGPO7OPeTNA/9v7/kzAsLoPzwPhbrDPXP4SVF1YIO663PvtX/tEWxnAfwLqwDyx8G8VEsVLcmiiOafFCKJwn0OP/DoAWc0sjhWwRxIoQ0ipBGhOqU8rO8SFZVvxUbkosNejnhT7B6314pC89JZLpXU7SxFe+XrgN+uRAvFxsH/+RwDf94xk5hhtukH7HzhJKWN2WCtUISd84pM/1V7ppDuJ3FHgJT22xQIbEGA9Q4o+pLLehzE2SHCdo7eWYQqN+7BanxBNMI6kBMaf5nuh9izAp38lsrmHJyO8NvXgWg+F9hoTZX4RpV9CCwvRFrCRcCeDq4/uJzbvB4AwwA2q2Llm0X8yH0pKvPZ2v7pl4nCWdnEgj920I8AmBCuozbKP7gJRnAqfx3MnOSkpZTeGnHkp0ly8EevwCT2zX/1GQnCAx02kBaDJgUMputFeruMBzwVtlEVBFUUgaWbJwHzz2htuAw282pdATrKfv4VV1N962uLBJ32wd9a92rX7VXXToitvZGIvf/Z7cu4xfAzxQH1rIQ3M4ojkR9r48qoYtnYDlEf+BkIL8L4+xpbRFSBk3p"},"RootExecutionId":"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:fe087266-fe48-4a31-a21b-691f4e7ea985","serverless-version":"v1"}}}', + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1741878862068", + "SenderId": "AROAWGCM4HXUUNHLDXVER:6145b5ba998f311c8ac27f5cade2b915", + "ApproximateFirstReceiveTimestamp": "1741878862075", + }, + "messageAttributes": {}, + "md5OfBody": "e5cf8197b304a4dd4fd5db8e4842484b", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:sa-east-1:425362996713:abhinav-q", + "awsRegion": "sa-east-1", + } + ] + } + self._test_step_function_trace_data_common( + eventbridge_sqs_event, + 6527209323865742984, + 14276854885394865473, + "2ee7d9862d048173", + ) - def test_set_correlation_ids(self): - set_correlation_ids() - trace_id, span_id = get_correlation_ids() - self.assertEqual(trace_id, 123) - self.assertEqual(span_id, 456) + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_sns(self): + """Test step function trace data extraction through SNS""" + sns_event = { + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic:f1653ba3-2ff7-4c8e-9381-45a7a62f9708", + "Sns": { + "Type": "Notification", + "MessageId": "7bc0c17d-bf88-5ff4-af7f-a131463a0d90", + "TopicArn": "arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic", + "Subject": None, + "Message": "{}", + "Timestamp": "2025-03-13T15:19:14.245Z", + "SignatureVersion": "1", + "Signature": "r8RoYzq4uNcq0yj7sxcp8sTbFiDk8zqtocG7mJuE2MPVuR8O5eNg2ohofokUnC84xADlCq5k6ElP55lbbY36tQO+qDGdV6+TGN4bAL9FiQrDE6tQYYJdlv/sYE7iOOgnRBC9ljEdCIDNtQNGCfND/8JzatPg8KAy7xMRcLrGWu4xIMEysqNTz7rETfhdZjLQPssAht44KcoUJCH4/VuB+B9W1RhwA+M8Q3tqxzahIXzcgDM8OlmfkBlXo4FDVF3WUzjXLf9AMOg+66GupjQFtUpmRMkA8KXSV1HCso7e6nIIWtOnUoWeDDUfQPFFq4TNSlb6h2NuebaHdnW5nhxnJQ==", + "SigningCertUrl": "https://sns.sa-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem", + "UnsubscribeUrl": "https://sns.sa-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic:f1653ba3-2ff7-4c8e-9381-45a7a62f9708", + "MessageAttributes": { + "_datadog": { + "Type": "String", + "Value": '{"Execution":{"Id":"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:11623e4f-70ee-4330-8fbe-955152dea54c","StartTime":"2025-03-13T15:19:14.019Z","Name":"11623e4f-70ee-4330-8fbe-955152dea54c","RoleArn":"arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j","RedriveCount":0},"StateMachine":{"Id":"arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-inner-state-machine","Name":"abhinav-inner-state-machine"},"State":{"Name":"SNS Publish","EnteredTime":"2025-03-13T15:19:14.061Z","RetryCount":0},"RootExecutionId":"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:11623e4f-70ee-4330-8fbe-955152dea54c","serverless-version":"v1"}', + } + }, + }, + } + ] + } + self._test_step_function_trace_data_common( + sns_event, 1459500239678510857, 13193042003602978730, "fafc98885fd4647" + ) + + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_sns_sqs(self): + """Test step function trace data extraction through SNS and SQS""" + sns_sqs_event = { + "Records": [ + { + "messageId": "9ec3339f-cd1a-43ba-9681-3e9113b430d3", + "receiptHandle": "AQEBJ5gIvqEWQt39NHPMAoK57cGgKtrgTtckWeWdDRi2FeucYr6pBhNjzXuUrmoHZMozX1WaoABtfQ5+kX5ucDBpA2Ci3Q07Z4MYvA6X0Sw13HCkiBnLrHPmH/F3rUBjvdRkIIKqA2ACX58MdkaYGNpqsHTJHB613wa8z4zurK0u7eUIXrr+e+gtsuPD39hiWlJo7cpBVv7y178rzMX8gPQTnRJv1cjhCHENtjWTSmfFC5N+BIQNIcjFsTTDRSovZlNIfAEuS+uowgzk0DUyoTJD5nFTL8lQHeXGRCUQe58/UY9OwRXEFVPGZOQR4OI9Wa4Kf/keFypTk9YwC9DhSeKvzZ0wBvejyl1n0ztT45+XYoWfi0mxGWM5b7r9wT36RDmjnM6vszH/d3fhZSRPASxWBQ==", + "body": '{\n "Type" : "Notification",\n "MessageId" : "1f3078d0-c792-5cf3-a130-189c3b846a3f",\n "TopicArn" : "arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic",\n "Message" : "{}",\n "Timestamp" : "2025-03-13T15:29:26.348Z",\n "SignatureVersion" : "1",\n "Signature" : "mxOqAQ5o/isJrMS0PezHKRaA3g8Z/8YDbkToqhJub6I66LGtl+NYhyfTyllbgxvRP2XD2meKPRSgPI3nLyq8UHsWgyYwe3Tsv8QpRunCVE9Pebh+V1LGPWfjOiL0e+bnaj956QJD99560LJ6bzWP9QO584/zfOdcw6E5XQZfAI+pvEsf28Dy0WJO/lWTATRZDf8wGhmc7uKI1ZMsrOaNoUD8PXVqsI4yrJHxhzMb3SrC7YjI/PnNIbcn6ezwprbUdbZvyNAfJiE0k5IlppA089tMXC/ItgC7AgQhG9huPdKi5KdWGACK7gEwqmFwL+5T33sUXDaH2g58WhCs76pKEw==",\n "SigningCertURL" : "https://sns.sa-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem",\n "UnsubscribeURL" : "https://sns.sa-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:sa-east-1:425362996713:logs-to-traces-dev-topic:5f64545d-ae9a-4a5f-a7ee-798a0bd8519e",\n "MessageAttributes" : {\n "_datadog" : {"Type":"String","Value":"{\\"Execution\\":{\\"Id\\":\\"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:37ff72b8-0ee0-49e2-93c0-8a1764206a03\\",\\"StartTime\\":\\"2025-03-13T15:29:26.144Z\\",\\"Name\\":\\"37ff72b8-0ee0-49e2-93c0-8a1764206a03\\",\\"RoleArn\\":\\"arn:aws:iam::425362996713:role/service-role/StepFunctions-abhinav-activity-state-machine-role-22jpbgl6j\\",\\"RedriveCount\\":0},\\"StateMachine\\":{\\"Id\\":\\"arn:aws:states:sa-east-1:425362996713:stateMachine:abhinav-inner-state-machine\\",\\"Name\\":\\"abhinav-inner-state-machine\\"},\\"State\\":{\\"Name\\":\\"SNS Publish\\",\\"EnteredTime\\":\\"2025-03-13T15:29:26.182Z\\",\\"RetryCount\\":0},\\"RootExecutionId\\":\\"arn:aws:states:sa-east-1:425362996713:execution:abhinav-inner-state-machine:37ff72b8-0ee0-49e2-93c0-8a1764206a03\\",\\"serverless-version\\":\\"v1\\"}"}\n }\n}', + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1741879766424", + "SenderId": "AIDAIOA2GYWSHW4E2VXIO", + "ApproximateFirstReceiveTimestamp": "1741879766432", + }, + "messageAttributes": {}, + "md5OfBody": "52af59de28507d7e67324b46c95337d8", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:sa-east-1:425362996713:abhinav-q", + "awsRegion": "sa-east-1", + } + ] + } + self._test_step_function_trace_data_common( + sns_sqs_event, 5708348677301000120, 18223515719478572006, "45457f5f3fde3fa1" + ) + + +class TestXRayContextConversion(unittest.TestCase): + def test_convert_xray_trace_id(self): + self.assertEqual( + _convert_xray_trace_id("00000000e1be46a994272793"), 7043144561403045779 + ) + + self.assertEqual( + _convert_xray_trace_id("bd862e3fe1be46a994272793"), 7043144561403045779 + ) + + self.assertEqual( + _convert_xray_trace_id("ffffffffffffffffffffffff"), + 9223372036854775807, # 0x7FFFFFFFFFFFFFFF + ) + + def test_convert_xray_entity_id(self): + self.assertEqual( + _convert_xray_entity_id("53995c3f42cd8ad8"), 6023947403358210776 + ) + + self.assertEqual( + _convert_xray_entity_id("1000000000000000"), 1152921504606846976 + ) + + self.assertEqual( + _convert_xray_entity_id("ffffffffffffffff"), 18446744073709551615 + ) + + def test_convert_xray_sampling(self): + self.assertEqual(_convert_xray_sampling(True), SamplingPriority.USER_KEEP) + + self.assertEqual(_convert_xray_sampling(False), SamplingPriority.USER_REJECT) + + +class TestLogsInjection(unittest.TestCase): + def setUp(self): + patcher = patch("datadog_lambda.tracing.get_dd_trace_context_obj") + self.mock_get_dd_trace_context = patcher.start() + self.mock_get_dd_trace_context.return_value = Context( + trace_id=int(fake_xray_header_value_root_decimal), + span_id=int(fake_xray_header_value_parent_decimal), + sampling_priority=1, + ) + self.addCleanup(patcher.stop) + + patcher = patch("datadog_lambda.config.Config.is_lambda_context") + self.mock_is_lambda_context = patcher.start() + self.mock_is_lambda_context.return_value = True + self.addCleanup(patcher.stop) + + @patch("datadog_lambda.config.Config.trace_enabled", False) + def test_set_correlation_ids(self): + set_correlation_ids() + span = tracer.current_span() + self.assertEqual(span.trace_id, int(fake_xray_header_value_root_decimal)) + self.assertEqual(span.parent_id, int(fake_xray_header_value_parent_decimal)) + span.finish() + + def test_set_correlation_ids_handle_empty_trace_context(self): + # neither x-ray or ddtrace is used. no tracing context at all. + self.mock_get_dd_trace_context.return_value = Context() + # no exception thrown + set_correlation_ids() + span = tracer.current_span() + self.assertIsNone(span) class TestFunctionSpanTags(unittest.TestCase): def test_function(self): ctx = get_mock_context() - span = create_function_execution_span(ctx, "", False, {"source": ""}, False, {}) + span = create_function_execution_span( + context=ctx, + function_name="", + is_cold_start=False, + is_proactive_init=False, + trace_context_source={"source": ""}, + merge_xray_traces=False, + trigger_tags={}, + span_pointers=None, + ) self.assertEqual(span.get_tag("function_arn"), function_arn) self.assertEqual(span.get_tag("function_version"), "$LATEST") self.assertEqual(span.get_tag("resource_names"), "Function") self.assertEqual(span.get_tag("functionname"), "function") + self.assertEqual(span._links, []) def test_function_with_version(self): function_version = "1" ctx = get_mock_context( invoked_function_arn=function_arn + ":" + function_version ) - span = create_function_execution_span(ctx, "", False, {"source": ""}, False, {}) + span = create_function_execution_span( + context=ctx, + function_name="", + is_cold_start=False, + is_proactive_init=False, + trace_context_source={"source": ""}, + merge_xray_traces=False, + trigger_tags={}, + ) self.assertEqual(span.get_tag("function_arn"), function_arn) self.assertEqual(span.get_tag("function_version"), function_version) self.assertEqual(span.get_tag("resource_names"), "Function") @@ -470,7 +1094,15 @@ def test_function_with_version(self): def test_function_with_alias(self): function_alias = "alias" ctx = get_mock_context(invoked_function_arn=function_arn + ":" + function_alias) - span = create_function_execution_span(ctx, "", False, {"source": ""}, False, {}) + span = create_function_execution_span( + context=ctx, + function_name="", + is_cold_start=False, + is_proactive_init=False, + trace_context_source={"source": ""}, + merge_xray_traces=False, + trigger_tags={}, + ) self.assertEqual(span.get_tag("function_arn"), function_arn) self.assertEqual(span.get_tag("function_version"), function_alias) self.assertEqual(span.get_tag("resource_names"), "Function") @@ -479,12 +1111,13 @@ def test_function_with_alias(self): def test_function_with_trigger_tags(self): ctx = get_mock_context() span = create_function_execution_span( - ctx, - "", - False, - {"source": ""}, - False, - {"function_trigger.event_source": "cloudwatch-logs"}, + context=ctx, + function_name="", + is_cold_start=False, + is_proactive_init=False, + trace_context_source={"source": ""}, + merge_xray_traces=False, + trigger_tags={"function_trigger.event_source": "cloudwatch-logs"}, ) self.assertEqual(span.get_tag("function_arn"), function_arn) self.assertEqual(span.get_tag("resource_names"), "Function") @@ -493,27 +1126,69 @@ def test_function_with_trigger_tags(self): span.get_tag("function_trigger.event_source"), "cloudwatch-logs" ) + def test_function_with_span_pointers(self): + ctx = get_mock_context() + span = create_function_execution_span( + context=ctx, + function_name="", + is_cold_start=False, + is_proactive_init=False, + trace_context_source={"source": ""}, + merge_xray_traces=False, + trigger_tags={}, + span_pointers=[ + _SpanPointerDescription( + pointer_kind="some.kind", + pointer_direction=_SpanPointerDirection.UPSTREAM, + pointer_hash="some.hash", + extra_attributes={}, + ), + _SpanPointerDescription( + pointer_kind="other.kind", + pointer_direction=_SpanPointerDirection.DOWNSTREAM, + pointer_hash="other.hash", + extra_attributes={"extra": "stuff"}, + ), + ], + ) + self.assertEqual( + span._links, + [ + _SpanPointer( + pointer_kind="some.kind", + pointer_direction=_SpanPointerDirection.UPSTREAM, + pointer_hash="some.hash", + extra_attributes={}, + ), + _SpanPointer( + pointer_kind="other.kind", + pointer_direction=_SpanPointerDirection.DOWNSTREAM, + pointer_hash="other.hash", + extra_attributes={"extra": "stuff"}, + ), + ], + ) + class TestSetTraceRootSpan(unittest.TestCase): def setUp(self): - global dd_tracing_enabled - dd_tracing_enabled = False os.environ["_X_AMZN_TRACE_ID"] = fake_xray_header_value patcher = patch("datadog_lambda.tracing.send_segment") self.mock_send_segment = patcher.start() self.addCleanup(patcher.stop) - patcher = patch("datadog_lambda.tracing.is_lambda_context") + patcher = patch("datadog_lambda.config.Config.is_lambda_context") self.mock_is_lambda_context = patcher.start() self.mock_is_lambda_context.return_value = True self.addCleanup(patcher.stop) - patcher = patch("ddtrace.tracer.context_provider.activate") + patcher = patch("datadog_lambda.tracing.tracer.context_provider.activate") self.mock_activate = patcher.start() self.mock_activate.return_value = True self.addCleanup(patcher.stop) + patcher = patch("datadog_lambda.tracing.dd_trace_context", None) + self.mock_dd_trace_context = patcher.start() + self.addCleanup(patcher.stop) def tearDown(self): - global dd_tracing_enabled - dd_tracing_enabled = False del os.environ["_X_AMZN_TRACE_ID"] def test_mixed_parent_context_when_merging(self): @@ -521,7 +1196,7 @@ def test_mixed_parent_context_when_merging(self): # use the dd-trace trace-id and the x-ray parent-id # This allows parenting relationships like dd-trace -> x-ray -> dd-trace lambda_ctx = get_mock_context() - ctx, source = extract_dd_trace_context( + ctx, source, event_type = extract_dd_trace_context( { "headers": { TraceHeader.TRACE_ID: "123", @@ -542,3 +1217,2236 @@ def test_mixed_parent_context_when_merging(self): ) self.mock_activate.assert_called() self.mock_activate.assert_has_calls([call(expected_context)]) + + def test_set_dd_trace_py_root_no_span_id(self): + os.environ["_X_AMZN_TRACE_ID"] = "Root=1-5e272390-8c398be037738dc042009320" + + lambda_ctx = get_mock_context() + ctx, source, event_type = extract_dd_trace_context( + { + "headers": { + TraceHeader.TRACE_ID: "123", + TraceHeader.PARENT_ID: "321", + TraceHeader.SAMPLING_PRIORITY: "1", + } + }, + lambda_ctx, + ) + set_dd_trace_py_root(TraceContextSource.EVENT, True) + + expected_context = Context( + trace_id=123, # Trace Id from incomming context + span_id=321, # Span Id from incoming context + sampling_priority=1, # Sampling priority from incomming context + ) + self.mock_activate.assert_called() + self.mock_activate.assert_has_calls([call(expected_context)]) + + def test_set_dd_trace_py_root_none_context(self): + set_dd_trace_py_root(TraceContextSource.EVENT, True) + self.mock_activate.assert_not_called() + + +class TestServiceMapping(unittest.TestCase): + def setUp(self): + self.service_mapping = {} + + def get_service_mapping(self): + return global_service_mapping + + def set_service_mapping(self, new_service_mapping): + global_service_mapping.clear() + global_service_mapping.update(new_service_mapping) + + def test_create_service_mapping_invalid_input(self): + # Test case where the input is a string without a colon to split on + val = "api1" + self.assertEqual(create_service_mapping(val), {}) + + # Test case where the input is an empty string + val = "" + self.assertEqual(create_service_mapping(val), {}) + + # Test case where the key and value are identical + val = "api1:api1" + self.assertEqual(create_service_mapping(val), {}) + + # Test case where the key or value is missing + val = ":api1" + self.assertEqual(create_service_mapping(val), {}) + val = "api1:" + self.assertEqual(create_service_mapping(val), {}) + + def test_create_service_mapping(self): + val = "api1:service1,api2:service2" + expected_output = {"api1": "service1", "api2": "service2"} + self.assertEqual(create_service_mapping(val), expected_output) + + def test_get_service_mapping(self): + os.environ["DD_SERVICE_MAPPING"] = "api1:service1,api2:service2" + expected_output = {"api1": "service1", "api2": "service2"} + self.set_service_mapping( + create_service_mapping(os.environ["DD_SERVICE_MAPPING"]) + ) + self.assertEqual(self.get_service_mapping(), expected_output) + del os.environ["DD_SERVICE_MAPPING"] + + def test_set_service_mapping(self): + new_service_mapping = {"api3": "service3", "api4": "service4"} + self.set_service_mapping(new_service_mapping) + self.assertEqual(self.get_service_mapping(), new_service_mapping) + + def test_determine_service_name(self): + # Prepare the environment + os.environ["DD_SERVICE_MAPPING"] = "api1:service1,api2:service2" + self.set_service_mapping( + create_service_mapping(os.environ["DD_SERVICE_MAPPING"]) + ) + + # Case where specific key is in the service mapping + specific_key = "api1" + self.assertEqual( + determine_service_name( + self.get_service_mapping(), specific_key, "lambda_url", "default" + ), + "service1", + ) + + # Case where specific key is not in the service mapping, but generic key is + specific_key = "api3" + self.assertEqual( + determine_service_name( + self.get_service_mapping(), specific_key, "api2", "default" + ), + "service2", + ) + + # Case where neither specific nor generic keys are in the service mapping + specific_key = "api3" + self.assertEqual( + determine_service_name( + self.get_service_mapping(), specific_key, "api3", "default" + ), + "default", + ) + + # Test with DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED set to false + os.environ["DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED"] = "false" + self.assertEqual( + determine_service_name( + self.get_service_mapping(), "api4", "api4", "extracted", "fallback" + ), + "fallback", + ) + + # Test with DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED set to 0 + os.environ["DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED"] = "0" + self.assertEqual( + determine_service_name( + self.get_service_mapping(), "api4", "api4", "extracted", "fallback" + ), + "fallback", + ) + + # Test with DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED not set (default behavior) + if "DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED" in os.environ: + del os.environ["DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED"] + self.assertEqual( + determine_service_name( + self.get_service_mapping(), "api4", "api4", "extracted", "fallback" + ), + "extracted", + ) + + # Test with empty extracted key + self.assertEqual( + determine_service_name( + self.get_service_mapping(), "api4", "api4", " ", "fallback" + ), + "fallback", + ) + + del os.environ["DD_SERVICE_MAPPING"] + + def test_remaps_all_inferred_span_service_names_from_api_gateway_event(self): + new_service_mapping = {"lambda_api_gateway": "new-name"} + self.set_service_mapping(new_service_mapping) + event_sample_source = "api-gateway" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.apigateway.rest") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["requestContext"][ + "domainName" + ] = "different.execute-api.us-east-2.amazonaws.com" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.apigateway.rest") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_api_gateway_event( + self, + ): + new_service_mapping = {"1234567890": "new-name"} + self.set_service_mapping(new_service_mapping) + event_sample_source = "api-gateway" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.apigateway.rest") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["requestContext"]["apiId"] = "different" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.apigateway.rest") + self.assertEqual( + span2.service, "70ixmpl4fl.execute-api.us-east-2.amazonaws.com" + ) + + def test_remaps_specific_inferred_span_service_names_from_api_gateway_websocket_event( + self, + ): + self.set_service_mapping({"p62c47itsb": "new-name"}) + event_sample_source = "api-gateway-websocket-default" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.apigateway.websocket") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["requestContext"]["apiId"] = "different" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.apigateway.websocket") + self.assertEqual( + span2.service, "p62c47itsb.execute-api.eu-west-1.amazonaws.com" + ) + + def test_remaps_specific_inferred_span_service_names_from_api_gateway_http_event( + self, + ): + self.set_service_mapping({"x02yirxc7a": "new-name"}) + event_sample_source = "http-api" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.httpapi") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["requestContext"]["apiId"] = "different" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.httpapi") + self.assertEqual( + span2.service, "x02yirxc7a.execute-api.eu-west-1.amazonaws.com" + ) + + def test_remaps_all_inferred_span_service_names_from_lambda_url_event(self): + self.set_service_mapping({"lambda_url": "new-name"}) + event_sample_source = "lambda-url" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.lambda.url") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["requestContext"][ + "domainName" + ] = "different.lambda-url.eu-south-1.amazonaws.com" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.lambda.url") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_lambda_url_event( + self, + ): + self.set_service_mapping({"a8hyhsshac": "new-name"}) + event_sample_source = "lambda-url" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.lambda.url") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["requestContext"]["apiId"] = "different" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.lambda.url") + self.assertEqual( + span2.service, "a8hyhsshac.lambda-url.eu-south-1.amazonaws.com" + ) + + def test_remaps_all_inferred_span_service_names_from_sqs_event(self): + self.set_service_mapping({"lambda_sqs": "new-name"}) + event_sample_source = "sqs-string-msg-attribute" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.sqs") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0][ + "eventSourceARN" + ] = "arn:aws:sqs:eu-west-1:123456789012:different-sqs-url" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.sqs") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_sqs_event(self): + self.set_service_mapping({"InferredSpansQueueNode": "new-name"}) + event_sample_source = "sqs-string-msg-attribute" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.sqs") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0][ + "eventSourceARN" + ] = "arn:aws:sqs:eu-west-1:123456789012:different-sqs-url" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.sqs") + self.assertEqual(span2.service, "different-sqs-url") + + def test_remaps_all_inferred_span_service_names_from_sns_event(self): + self.set_service_mapping({"lambda_sns": "new-name"}) + event_sample_source = "sns-string-msg-attribute" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.sns") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0]["Sns"][ + "TopicArn" + ] = "arn:aws:sns:us-west-2:123456789012:different-sns-topic" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.sns") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_sns_event(self): + self.set_service_mapping({"serverlessTracingTopicPy": "new-name"}) + event_sample_source = "sns-string-msg-attribute" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.sns") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0]["Sns"][ + "TopicArn" + ] = "arn:aws:sns:us-west-2:123456789012:different-sns-topic" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.sns") + self.assertEqual(span2.service, "different-sns-topic") + + def test_remaps_all_inferred_span_service_names_from_kinesis_event(self): + self.set_service_mapping({"lambda_kinesis": "new-name"}) + event_sample_source = "kinesis" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.kinesis") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0][ + "eventSourceARN" + ] = "arn:aws:kinesis:eu-west-1:601427279990:stream/differentKinesisStream" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.kinesis") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_kinesis_event(self): + self.set_service_mapping({"Different_EXAMPLE": "new-name"}) + event_sample_source = "kinesis" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.kinesis") + self.assertEqual(span1.service, "kinesisStream") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0][ + "eventSourceARN" + ] = "arn:aws:kinesis:eu-west-1:601427279990:stream/DifferentKinesisStream" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.kinesis") + self.assertEqual(span2.service, "DifferentKinesisStream") + + def test_remaps_all_inferred_span_service_names_from_s3_event(self): + self.set_service_mapping({"lambda_s3": "new-name"}) + event_sample_source = "s3" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.s3") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0]["s3"]["bucket"][ + "arn" + ] = "arn:aws:s3:::different-example-bucket" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.s3") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_s3_event(self): + self.set_service_mapping({"example-bucket": "new-name"}) + event_sample_source = "s3" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.s3") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0]["s3"]["bucket"]["name"] = "different-example-bucket" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.s3") + self.assertEqual(span2.service, "different-example-bucket") + + def test_remaps_all_inferred_span_service_names_from_dynamodb_event(self): + self.set_service_mapping({"lambda_dynamodb": "new-name"}) + event_sample_source = "dynamodb" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.dynamodb") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0][ + "eventSourceARN" + ] = "arn:aws:dynamodb:us-east-1:123456789012:table/DifferentExampleTableWithStream/stream/2015-06-27T00:48:05.899" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.dynamodb") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_dynamodb_event(self): + self.set_service_mapping({"ExampleTableWithStream": "new-name"}) + event_sample_source = "dynamodb" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.dynamodb") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["Records"][0][ + "eventSourceARN" + ] = "arn:aws:dynamodb:us-east-1:123456789012:table/DifferentExampleTableWithStream/stream/2015-06-27T00:48:05.899" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.dynamodb") + self.assertEqual(span2.service, "DifferentExampleTableWithStream") + + def test_remaps_all_inferred_span_service_names_from_eventbridge_event(self): + self.set_service_mapping({"lambda_eventbridge": "new-name"}) + event_sample_source = "eventbridge-custom" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.eventbridge") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["source"] = "different.eventbridge.custom.event.sender" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.eventbridge") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_eventbridge_event( + self, + ): + self.set_service_mapping({"eventbridge.custom.event.sender": "new-name"}) + event_sample_source = "eventbridge-custom" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + original_event = json.load(event) + + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.eventbridge") + self.assertEqual(span1.service, "new-name") + + # Testing the second event + event2 = copy.deepcopy(original_event) + event2["source"] = "different.eventbridge.custom.event.sender" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.eventbridge") + self.assertEqual(span2.service, "different.eventbridge.custom.event.sender") + + +class _Span(object): + def __init__(self, service, start, span_type, parent_name=None, tags=None): + self.service = service + self.start = start + self.span_type = span_type + self.parent_name = parent_name + self.tags = tags or {} + + +_test_create_inferred_span = ( + ( + "api-gateway", + _Span( + service="70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + start=1428582896.0, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "1234567890", + "apiname": "1234567890", + "endpoint": "/path/to/resource", + "http.method": "POST", + "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "POST /{proxy+}", + "stage": "prod", + }, + ), + ), + ( + "api-gateway-non-proxy-async", + _Span( + service="lgxbo6a518.execute-api.eu-west-1.amazonaws.com", + start=1631210915.2510002, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "apiid": "lgxbo6a518", + "apiname": "lgxbo6a518", + "endpoint": "/http/get", + "http.method": "GET", + "http.url": "https://lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /http/get", + "stage": "dev", + }, + ), + ), + ( + "api-gateway-non-proxy", + _Span( + service="lgxbo6a518.execute-api.eu-west-1.amazonaws.com", + start=1631210915.2510002, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "lgxbo6a518", + "apiname": "lgxbo6a518", + "endpoint": "/http/get", + "http.method": "GET", + "http.url": "https://lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /http/get", + "stage": "dev", + }, + ), + ), + ( + "http-api", + _Span( + service="x02yirxc7a.execute-api.eu-west-1.amazonaws.com", + start=1631212283.738, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "x02yirxc7a", + "apiname": "x02yirxc7a", + "endpoint": "/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.source_ip": "38.122.226.210", + "http.url": "https://x02yirxc7a.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.user_agent": "curl/7.64.1", + "operation_name": "aws.httpapi", + "request_id": "123", + "resource_names": "GET /httpapi/get", + "stage": "$default", + }, + ), + ), + ( + "api-gateway-v1-parametrized", + _Span( + service="mcwkra0ya4.execute-api.sa-east-1.amazonaws.com", + start=1710529824.52, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "mcwkra0ya4", + "apiname": "mcwkra0ya4", + "endpoint": "/user/42", + "http.method": "GET", + "http.url": "https://mcwkra0ya4.execute-api.sa-east-1.amazonaws.com/user/42", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /user/{id}", + "stage": "dev", + }, + ), + ), + ( + "api-gateway-v2-parametrized", + _Span( + service="9vj54we5ih.execute-api.sa-east-1.amazonaws.com", + start=1710529905.066, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "9vj54we5ih", + "apiname": "9vj54we5ih", + "endpoint": "/user/42", + "http.method": "GET", + "http.url": "https://9vj54we5ih.execute-api.sa-east-1.amazonaws.com/user/42", + "operation_name": "aws.httpapi", + "request_id": "123", + "resource_names": "GET /user/{id}", + "stage": "$default", + }, + ), + ), + ( + "api-gateway-websocket-default", + _Span( + service="p62c47itsb.execute-api.eu-west-1.amazonaws.com", + start=1631285061.365, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "p62c47itsb", + "apiname": "p62c47itsb", + "connection_id": "Fc5SzcoYGjQCJlg=", + "endpoint": "$default", + "event_type": "MESSAGE", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com$default/", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "request_id": "123", + "resource_names": "$default", + "stage": "dev", + }, + ), + ), + ( + "api-gateway-websocket-connect", + _Span( + service="p62c47itsb.execute-api.eu-west-1.amazonaws.com", + start=1631284003.071, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "p62c47itsb", + "apiname": "p62c47itsb", + "connection_id": "Fc2tgfl3mjQCJfA=", + "endpoint": "$connect", + "event_type": "CONNECT", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com$connect/", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "request_id": "123", + "resource_names": "$connect", + "stage": "dev", + }, + ), + ), + ( + "api-gateway-websocket-disconnect", + _Span( + service="p62c47itsb.execute-api.eu-west-1.amazonaws.com", + start=1631284034.737, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "p62c47itsb", + "apiname": "p62c47itsb", + "connection_id": "Fc2tgfl3mjQCJfA=", + "endpoint": "$disconnect", + "event_type": "DISCONNECT", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com$disconnect/", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "request_id": "123", + "resource_names": "$disconnect", + "stage": "dev", + }, + ), + ), + ( + "sqs-string-msg-attribute", + _Span( + service="InferredSpansQueueNode", + start=1634662094.538, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "event_source_arn": "arn:aws:sqs:eu-west-1:601427279990:InferredSpansQueueNode", + "operation_name": "aws.sqs", + "queuename": "InferredSpansQueueNode", + "resource_names": "InferredSpansQueueNode", + "sender_id": "AROAYYB64AB3LSVUYFP5T:harv-inferred-spans-dev-initSender", + }, + ), + ), + ( + "sns-string-msg-attribute", + _Span( + service="serverlessTracingTopicPy", + start=1643638421.637, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "message_id": "87056a47-f506-5d77-908b-303605d3b197", + "operation_name": "aws.sns", + "resource_names": "serverlessTracingTopicPy", + "topic_arn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", + "topicname": "serverlessTracingTopicPy", + "type": "Notification", + }, + ), + ), + ( + "sns-b64-msg-attribute", + _Span( + service="serverlessTracingTopicPy", + start=1643638421.637, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "message_id": "87056a47-f506-5d77-908b-303605d3b197", + "operation_name": "aws.sns", + "resource_names": "serverlessTracingTopicPy", + "topic_arn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", + "topicname": "serverlessTracingTopicPy", + "type": "Notification", + }, + ), + ), + ( + "kinesisStream", + _Span( + service="kinesisStream", + start=1643638425.163, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "endpoint": None, + "event_id": "shardId-000000000002:49624230154685806402418173680709770494154422022871973922", + "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream", + "event_version": "1.0", + "http.method": None, + "http.url": None, + "operation_name": "aws.kinesis", + "partition_key": "partitionkey", + "request_id": None, + "resource_names": "kinesisStream", + "shardid": "shardId-000000000002", + "streamname": "kinesisStream", + }, + ), + ), + ( + "dynamodb", + _Span( + service="ExampleTableWithStream", + start=1428537600.0, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "endpoint": None, + "event_id": "c4ca4238a0b923820dcc509a6f75849b", + "event_name": "INSERT", + "event_source_arn": "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_version": "1.1", + "http.method": None, + "http.url": None, + "operation_name": "aws.dynamodb", + "request_id": None, + "resource_names": "ExampleTableWithStream", + "size_bytes": "26", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream", + }, + ), + ), + ( + "s3", + _Span( + service="example-bucket", + start=0.0, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "endpoint": None, + "event_name": "ObjectCreated:Put", + "http.method": None, + "http.url": None, + "object_etag": "0123456789abcdef0123456789abcdef", + "object_key": "test/key", + "object_size": "1024", + "operation_name": "aws.s3", + "request_id": None, + "resource_names": "example-bucket", + }, + ), + ), + ( + "eventbridge-custom", + _Span( + service="eventbridge.custom.event.sender", + start=1635989865.0, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "endpoint": None, + "http.method": None, + "http.url": None, + "operation_name": "aws.eventbridge", + "request_id": None, + "resource_names": "eventbridge.custom.event.sender", + }, + ), + ), + ( + "eventbridge-sqs", + _Span( + service="eventbridge-sqs-queue", + start=1691102943.638, + span_type="web", + parent_name="aws.eventbridge", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "endpoint": None, + "event_source_arn": "arn:aws:sqs:us-east-1:425362996713:eventbridge-sqs-queue", + "http.method": None, + "http.url": None, + "operation_name": "aws.sqs", + "queuename": "eventbridge-sqs-queue", + "request_id": None, + "resource_names": "eventbridge-sqs-queue", + "sender_id": "AIDAJXNJGGKNS7OSV23OI", + }, + ), + ), + ( + "api-gateway-no-apiid", + _Span( + service="70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + start=1428582896.0, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "None", + "apiname": "None", + "endpoint": "/path/to/resource", + "http.method": "POST", + "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "POST /{proxy+}", + "stage": "prod", + }, + ), + ), + ( + "authorizer-request-api-gateway-v1", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1663295021.832, + span_type="http", + parent_name="aws.apigateway.authorizer", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "endpoint": "/hello", + "http.method": "GET", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /hello", + "stage": "dev", + }, + ), + ), + ( + "authorizer-request-api-gateway-v1-cached", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1666714653.636, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "endpoint": "/hello", + "http.method": "GET", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /hello", + "stage": "dev", + }, + ), + ), + ( + "authorizer-token-api-gateway-v1", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1663295021.832, + span_type="http", + parent_name="aws.apigateway.authorizer", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "endpoint": "/hello", + "http.method": "GET", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /hello", + "stage": "dev", + }, + ), + ), + ( + "authorizer-token-api-gateway-v1-cached", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1666803622.99, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "endpoint": "/hello", + "http.method": "GET", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /hello", + "stage": "dev", + }, + ), + ), + ( + "authorizer-request-api-gateway-v2", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1664228639.5337753, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "endpoint": "/hello", + "http.method": "GET", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "operation_name": "aws.httpapi", + "request_id": "123", + "resource_names": "GET /hello", + "stage": "dev", + }, + ), + ), + ( + "authorizer-request-api-gateway-v2-cached", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1666715429.349, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "endpoint": "/hello", + "http.method": "GET", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "operation_name": "aws.httpapi", + "request_id": "123", + "resource_names": "GET /hello", + "stage": "dev", + }, + ), + ), + ( + "authorizer-request-api-gateway-websocket-connect", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1664388386.892, + span_type="web", + parent_name="aws.apigateway.authorizer", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "connection_id": "ZLr9QeNLmjQCIZA=", + "endpoint": "$connect", + "event_type": "CONNECT", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com$connect/", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "request_id": "123", + "resource_names": "$connect", + "stage": "dev", + }, + ), + ), + ( + "authorizer-request-api-gateway-websocket-message", + _Span( + service="amddr1rix9.execute-api.eu-west-1.amazonaws.com", + start=1664390397.1169999, + span_type="web", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "amddr1rix9", + "apiname": "amddr1rix9", + "connection_id": "ZLwtceO1mjQCI8Q=", + "endpoint": "main", + "event_type": "MESSAGE", + "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.commain/", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "request_id": "123", + "resource_names": "main", + "stage": "dev", + }, + ), + ), +) + + +@pytest.mark.parametrize("source,expect", _test_create_inferred_span) +@patch("ddtrace.trace.Span.finish", autospec=True) +def test_create_inferred_span(mock_span_finish, source, expect): + with open(f"{event_samples}{source}.json") as f: + event = json.load(f) + ctx = get_mock_context(aws_request_id="123") + + actual = create_inferred_span(event, ctx) + assert actual.service == expect.service + assert actual.start == expect.start + assert actual.span_type == expect.span_type + for tag, value in expect.tags.items(): + assert actual.get_tag(tag) == value, f"wrong value for tag {tag}" + + if expect.parent_name is not None: # there are two inferred spans + assert mock_span_finish.call_count == 1 + args, kwargs = mock_span_finish.call_args_list[0] + parent = args[0] + finish_time = kwargs.get("finish_time") or args[1] + assert parent.name == expect.parent_name + assert actual.parent_id == parent.span_id + assert finish_time == expect.start + else: # there is only one inferred span + assert mock_span_finish.call_count == 0 + + +class TestInferredSpans(unittest.TestCase): + @patch("datadog_lambda.tracing.submit_errors_metric") + def test_mark_trace_as_error_for_5xx_responses_getting_400_response_code( + self, mock_submit_errors_metric + ): + mark_trace_as_error_for_5xx_responses( + context="fake_context", status_code="400", span="empty_span" + ) + mock_submit_errors_metric.assert_not_called() + + @patch("datadog_lambda.tracing.submit_errors_metric") + def test_mark_trace_as_error_for_5xx_responses_sends_error_metric_and_set_error_tags( + self, mock_submit_errors_metric + ): + mock_span = Mock(ddtrace.trace.Span) + status_code = "500" + mark_trace_as_error_for_5xx_responses( + context="fake_context", status_code=status_code, span=mock_span + ) + mock_submit_errors_metric.assert_called_once() + self.assertEqual(1, mock_span.error) + + +class TestStepFunctionsTraceContext(unittest.TestCase): + def test_deterministic_m5_hash(self): + result = _deterministic_sha256_hash("some_testing_random_string", LOWER_64_BITS) + self.assertEqual(7456137785171041414, result) + + def test_deterministic_m5_hash__result_the_same_as_backend_1(self): + result = _deterministic_sha256_hash( + "arn:aws:states:sa-east-1:425362996713:stateMachine:MyStateMachine-b276uka1j" + "#lambda#1", + HIGHER_64_BITS, + ) + self.assertEqual(3711631873188331089, result) + + def test_deterministic_m5_hash__result_the_same_as_backend_2(self): + result = _deterministic_sha256_hash( + "arn:aws:states:sa-east-1:425362996713:stateMachine:MyStateMachine-b276uka1j" + "#lambda#2", + HIGHER_64_BITS, + ) + self.assertEqual(5759173372325510050, result) + + def test_deterministic_m5_hash__always_leading_with_zero(self): + for i in range(100): + result = _deterministic_sha256_hash(str(i), 64) + result_in_binary = bin(int(result)) + # Leading zeros will be omitted, so only test for full 64 bits present + if len(result_in_binary) == 66: # "0b" + 64 bits. + self.assertTrue(result_in_binary.startswith("0b0")) + + +class TestExceptionOutsideHandler(unittest.TestCase): + @patch("datadog_lambda.config.Config.trace_enabled", True) + @patch("datadog_lambda.tracing.submit_errors_metric") + @patch("time.time_ns", return_value=42) + def test_exception_outside_handler_tracing_enabled( + self, mock_time, mock_submit_errors_metric + ): + fake_error = ValueError("Some error message") + resource_name = "my_handler" + span_type = "aws.lambda" + mock_span = Mock() + with patch( + "datadog_lambda.tracing.tracer.trace", return_value=mock_span + ) as mock_trace: + emit_telemetry_on_exception_outside_of_handler( + fake_error, resource_name, 42 + ) + + mock_submit_errors_metric.assert_called_once_with(None) + + mock_trace.assert_called_once_with( + span_type, + service="aws.lambda", + resource=resource_name, + span_type="serverless", + ) + mock_span.set_tags.assert_called_once_with( + { + "error.status": 500, + "error.type": "ValueError", + "error.message": fake_error, + "error.stack": traceback.format_exc(), + "resource_names": resource_name, + "resource.name": resource_name, + "operation_name": span_type, + "status": "error", + } + ) + mock_span.finish.assert_called_once() + assert mock_span.error == 1 + assert mock_span.start_ns == 42 + + @patch("datadog_lambda.config.Config.trace_enabled", False) + @patch("datadog_lambda.tracing.submit_errors_metric") + @patch("time.time_ns", return_value=42) + def test_exception_outside_handler_tracing_disabled( + self, mock_time, mock_submit_errors_metric + ): + fake_error = ValueError("Some error message") + resource_name = "my_handler" + with patch("datadog_lambda.tracing.tracer.trace") as mock_trace: + emit_telemetry_on_exception_outside_of_handler( + fake_error, resource_name, 42 + ) + + mock_submit_errors_metric.assert_called_once_with(None) + mock_trace.assert_not_called() + + +class TestExtractDDContextWithDSMLogic(unittest.TestCase): + def setUp(self): + checkpoint_patcher = patch("ddtrace.data_streams.set_consume_checkpoint") + self.mock_checkpoint = checkpoint_patcher.start() + self.addCleanup(checkpoint_patcher.stop) + self.lambda_context = get_mock_context() + config_patcher = patch( + "datadog_lambda.config.Config.data_streams_enabled", True + ) + config_patcher.start() + self.addCleanup(config_patcher.stop) + + # SQS TESTS + + def test_sqs_context_propagated_string_value(self): + dd_data = {"dd-pathway-ctx-base64": "12345"} + dd_json_data = json.dumps(dd_data) + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "messageAttributes": { + "_datadog": {"dataType": "String", "stringValue": dd_json_data} + }, + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), "12345") + + def test_sqs_context_propagated_binary_value(self): + dd_data = {"dd-pathway-ctx-base64": "12345"} + dd_json_data = json.dumps(dd_data) + encoded_data = base64.b64encode(dd_json_data.encode()).decode() + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "messageAttributes": { + "_datadog": {"dataType": "Binary", "binaryValue": encoded_data} + }, + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), "12345") + + def test_sqs_no_datadog_message_attribute(self): + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "messageAttributes": {}, # No _datadog key + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sqs_empty_datadog_message_attribute(self): + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "messageAttributes": { + "_datadog": { + "dataType": "String", + "stringValue": "null", + } # json.loads("null") => None + }, + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sqs_no_DSM_context_in_message_attribute(self): + dd_data = {"NOT-DSM-KEY": "12345"} + dd_json_data = json.dumps(dd_data) + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "messageAttributes": { + "_datadog": {"dataType": "String", "stringValue": dd_json_data} + }, + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + @patch("datadog_lambda.tracing.logger") + def test_sqs_invalid_datadog_message_attribute(self, mock_logger): + test_cases = [ + { + "name": "invalid_base64", + "event": { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "messageAttributes": { + "_datadog": { + "dataType": "Binary", + "binaryValue": "invalid-base64", + } + }, + "eventSource": "aws:sqs", + } + ] + }, + "expected_log": ("The trace extractor returned with error %s", ANY), + }, + { + "name": "unsupported_datatype", + "event": { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "messageAttributes": { + "_datadog": { + "dataType": "Number", + "numberValue": 123, + } # Unsupported type + }, + "eventSource": "aws:sqs", + } + ] + }, + "expected_log": ( + "Datadog Lambda Python only supports extracting trace" + "context from String or Binary SQS/SNS message attributes", + ), + }, + ] + + for test_case in test_cases: + with self.subTest(test_case=test_case["name"]): + mock_logger.reset_mock() + self.mock_checkpoint.reset_mock() + + extract_context_from_sqs_or_sns_event_or_context( + test_case["event"], + self.lambda_context, + parse_event_source(test_case["event"]), + ) + + # Exception triggers logger + mock_logger.debug.assert_any_call(*test_case["expected_log"]) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + self.assertEqual( + args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue" + ) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sqs_source_arn_not_found(self): + event = { + "Records": [ + { + "eventSourceARN": "", + "messageAttributes": {}, + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.mock_checkpoint.assert_not_called() + + @patch("datadog_lambda.config.Config.data_streams_enabled", False) + def test_sqs_data_streams_disabled(self): + context_json = {"dd-pathway-ctx-base64": "12345"} + event_type = "sqs" + arn = "arn:aws:sqs:us-east-1:123456789012:test-queue" + + _dsm_set_checkpoint(context_json, event_type, arn) + + self.mock_checkpoint.assert_not_called() + + # SNS TESTS + + def test_sns_context_propagated_string_value(self): + dd_data = {"dd-pathway-ctx-base64": "12345"} + dd_json_data = json.dumps(dd_data) + + event = { + "Records": [ + { + "eventSourceARN": "", + "Sns": { + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": {"Type": "String", "Value": dd_json_data} + }, + }, + "eventSource": "aws:sns", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sns") + self.assertEqual(args[1], "arn:aws:sns:us-east-1:123456789012:test-topic") + carrier_get = args[2] + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), "12345") + + def test_sns_context_propagated_binary_value(self): + dd_data = {"dd-pathway-ctx-base64": "12345"} + dd_json_data = json.dumps(dd_data) + encoded_data = base64.b64encode(dd_json_data.encode()).decode() + + event = { + "Records": [ + { + "eventSourceARN": "", + "Sns": { + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": {"Type": "Binary", "Value": encoded_data} + }, + }, + "eventSource": "aws:sns", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sns") + self.assertEqual(args[1], "arn:aws:sns:us-east-1:123456789012:test-topic") + carrier_get = args[2] + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), "12345") + + def test_sns_no_datadog_message_attribute(self): + event = { + "Records": [ + { + "Sns": { + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": {}, # No _datadog key + }, + "eventSource": "aws:sns", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sns") + self.assertEqual(args[1], "arn:aws:sns:us-east-1:123456789012:test-topic") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sns_empty_datadog_message_attribute(self): + event = { + "Records": [ + { + "Sns": { + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": { + "Type": "String", + "Value": "null", + } # json.loads("null") => None + }, + }, + "eventSource": "aws:sns", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sns") + self.assertEqual(args[1], "arn:aws:sns:us-east-1:123456789012:test-topic") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sns_no_DSM_context_in_message_attribute(self): + dd_data = {"NOT-DSM-KEY": "12345"} + dd_json_data = json.dumps(dd_data) + + event = { + "Records": [ + { + "eventSourceARN": "", + "Sns": { + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": {"Type": "String", "Value": dd_json_data} + }, + }, + "eventSource": "aws:sns", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sns") + self.assertEqual(args[1], "arn:aws:sns:us-east-1:123456789012:test-topic") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + @patch("datadog_lambda.tracing.logger") + def test_sns_invalid_datadog_message_attribute(self, mock_logger): + test_cases = [ + { + "name": "invalid_base64", + "event": { + "Records": [ + { + "Sns": { + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": { + "Type": "Binary", + "Value": "invalid-base64", + } + }, + }, + "eventSource": "aws:sns", + } + ] + }, + "expected_log": ("The trace extractor returned with error %s", ANY), + }, + { + "name": "unsupported_datatype", + "event": { + "Records": [ + { + "Sns": { + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": { + "Type": "Number", + "numberValue": 123, + } # Unsupported type + }, + }, + "eventSource": "aws:sns", + } + ] + }, + "expected_log": ( + "Datadog Lambda Python only supports extracting trace" + "context from String or Binary SQS/SNS message attributes", + ), + }, + ] + + for test_case in test_cases: + with self.subTest(test_case=test_case["name"]): + mock_logger.reset_mock() + self.mock_checkpoint.reset_mock() + + extract_context_from_sqs_or_sns_event_or_context( + test_case["event"], + self.lambda_context, + parse_event_source(test_case["event"]), + ) + + # Exception triggers logger + mock_logger.debug.assert_any_call(*test_case["expected_log"]) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sns") + self.assertEqual( + args[1], "arn:aws:sns:us-east-1:123456789012:test-topic" + ) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sns_source_arn_not_found(self): + event = { + "Records": [ + { + "Sns": { + "TopicArn": "", + "MessageAttributes": {}, + }, + "eventSource": "aws:sns", + "eventSourceARN": "", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.mock_checkpoint.assert_not_called() + + @patch("datadog_lambda.config.Config.data_streams_enabled", False) + def test_sns_data_streams_disabled(self): + context_json = {"dd-pathway-ctx-base64": "12345"} + event_type = "sns" + arn = "arn:aws:sns:us-east-1:123456789012:test-topic" + + _dsm_set_checkpoint(context_json, event_type, arn) + + self.mock_checkpoint.assert_not_called() + + # SNS -> SQS TESTS + + def test_sns_to_sqs_context_propagated_string_value(self): + dd_data = {"dd-pathway-ctx-base64": "12345"} + dd_json_data = json.dumps(dd_data) + + sns_notification = { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": {"Type": "String", "Value": dd_json_data} + }, + "Message": "test message", + } + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "body": json.dumps(sns_notification), + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + # Should use SQS ARN, not SNS ARN + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), "12345") + + def test_sns_to_sqs_context_propagated_binary_value(self): + dd_data = {"dd-pathway-ctx-base64": "12345"} + dd_json_data = json.dumps(dd_data) + encoded_data = base64.b64encode(dd_json_data.encode()).decode() + + sns_notification = { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": {"Type": "Binary", "Value": encoded_data} + }, + "Message": "test message", + } + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "body": json.dumps(sns_notification), + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + # Should use SQS ARN, not SNS ARN + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), "12345") + + def test_sns_to_sqs_no_datadog_message_attribute(self): + sns_notification = { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": {}, # No _datadog key + "Message": "test message", + } + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "body": json.dumps(sns_notification), + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + # Should use SQS ARN, not SNS ARN + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sns_to_sqs_empty_datadog_message_attribute(self): + sns_notification = { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": { + "Type": "String", + "Value": "null", + } # json.loads("null") => None + }, + "Message": "test message", + } + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "body": json.dumps(sns_notification), + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + # Should use SQS ARN, not SNS ARN + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sns_to_sqs_no_DSM_context_in_message_attribute(self): + dd_data = {"NOT-DSM-KEY": "12345"} + dd_json_data = json.dumps(dd_data) + encoded_data = base64.b64encode(dd_json_data.encode()).decode() + + sns_notification = { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": {"Type": "Binary", "Value": encoded_data} + }, + "Message": "test message", + } + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "body": json.dumps(sns_notification), + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + # Should use SQS ARN, not SNS ARN + self.assertEqual(args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + @patch("datadog_lambda.tracing.logger") + def test_sns_to_sqs_invalid_datadog_message_attribute(self, mock_logger): + test_cases = [ + { + "name": "invalid_base64", + "sns_notification": { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": {"Type": "Binary", "Value": "not-base64"} + }, + "Message": "test message", + }, + "expected_log": ("The trace extractor returned with error %s", ANY), + }, + { + "name": "unsupported_datatype", + "sns_notification": { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": { + "_datadog": { + "Type": "Number", + "numberValue": 123, + } # Unsupported type + }, + "Message": "test message", + }, + "expected_log": ( + "Datadog Lambda Python only supports extracting trace" + "context from String or Binary SQS/SNS message attributes", + ), + }, + ] + + for test_case in test_cases: + with self.subTest(test_case=test_case["name"]): + mock_logger.reset_mock() + self.mock_checkpoint.reset_mock() + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", + "body": json.dumps(test_case["sns_notification"]), + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + # Exception triggers logger + mock_logger.debug.assert_any_call(*test_case["expected_log"]) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "sqs") + # Should use SQS ARN, not SNS ARN + self.assertEqual( + args[1], "arn:aws:sqs:us-east-1:123456789012:test-queue" + ) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_sns_to_sqs_source_arn_not_found(self): + sns_notification = { + "Type": "Notification", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:test-topic", + "MessageAttributes": {}, + "Message": "test message", + } + + event = { + "Records": [ + { + "eventSourceARN": "", # Empty SQS ARN + "body": json.dumps(sns_notification), + "eventSource": "aws:sqs", + } + ] + } + + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) + + self.mock_checkpoint.assert_not_called() + + @patch("datadog_lambda.config.Config.data_streams_enabled", False) + def test_sns_to_sqs_data_streams_disabled(self): + context_json = {"dd-pathway-ctx-base64": "12345"} + event_type = "sqs" + arn = "arn:aws:sqs:us-east-1:123456789012:test-queue" + + _dsm_set_checkpoint(context_json, event_type, arn) + + self.mock_checkpoint.assert_not_called() + + # KINESIS TESTS + + def test_kinesis_context_propagated_binary_value(self): + dd_data = {"dd-pathway-ctx-base64": "12345"} + kinesis_data = {"_datadog": dd_data, "message": "test"} + kinesis_data_str = json.dumps(kinesis_data) + encoded_data = base64.b64encode(kinesis_data_str.encode()).decode() + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream", + "kinesis": {"data": encoded_data}, + } + ] + } + + extract_context_from_kinesis_event(event, self.lambda_context) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "kinesis") + self.assertEqual( + args[1], "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" + ) + carrier_get = args[2] + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), "12345") + + def test_kinesis_no_datadog_message_attribute(self): + kinesis_data = {"message": "test"} # No _datadog key + kinesis_data_str = json.dumps(kinesis_data) + encoded_data = base64.b64encode(kinesis_data_str.encode()).decode() + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream", + "kinesis": {"data": encoded_data}, + } + ] + } + + extract_context_from_kinesis_event(event, self.lambda_context) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "kinesis") + self.assertEqual( + args[1], "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" + ) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_kinesis_empty_message_attribute(self): + kinesis_data = {"_datadog": None, "message": "test"} # _datadog is None + kinesis_data_str = json.dumps(kinesis_data) + encoded_data = base64.b64encode(kinesis_data_str.encode()).decode() + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream", + "kinesis": {"data": encoded_data}, + } + ] + } + + extract_context_from_kinesis_event(event, self.lambda_context) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "kinesis") + self.assertEqual( + args[1], "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" + ) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_kinesis_no_DSM_context_in_message_attribute(self): + dd_data = {"NOT-DSM-KEY": "12345"} + kinesis_data = {"_datadog": dd_data, "message": "test"} + kinesis_data_str = json.dumps(kinesis_data) + encoded_data = base64.b64encode(kinesis_data_str.encode()).decode() + + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream", + "kinesis": {"data": encoded_data}, + } + ] + } + + extract_context_from_kinesis_event(event, self.lambda_context) + + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "kinesis") + self.assertEqual( + args[1], "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" + ) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + @patch("datadog_lambda.tracing.logger") + def test_kinesis_invalid_datadog_message_attribute(self, mock_logger): + event = { + "Records": [ + { + "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream", + "kinesis": {"data": "invalid-base64"}, + } + ] + } + + extract_context_from_kinesis_event(event, self.lambda_context) + # Exception triggers logger + mock_logger.debug.assert_any_call( + "The trace extractor returned with error %s", + ANY, + ) + self.assertEqual(self.mock_checkpoint.call_count, 1) + args, _ = self.mock_checkpoint.call_args + self.assertEqual(args[0], "kinesis") + self.assertEqual( + args[1], "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" + ) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) + + def test_kinesis_source_arn_not_found(self): + kinesis_data = {"message": "test"} + kinesis_data_str = json.dumps(kinesis_data) + encoded_data = base64.b64encode(kinesis_data_str.encode()).decode() + + event = { + "Records": [ + { + "eventSourceARN": "", + "kinesis": {"data": encoded_data}, + } + ] + } + + extract_context_from_kinesis_event(event, self.lambda_context) + + self.mock_checkpoint.assert_not_called() + + @patch("datadog_lambda.config.Config.data_streams_enabled", False) + def test_kinesis_data_streams_disabled(self): + context_json = {"dd-pathway-ctx-base64": "12345"} + event_type = "kinesis" + arn = "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" + + _dsm_set_checkpoint(context_json, event_type, arn) diff --git a/tests/test_trigger.py b/tests/test_trigger.py index 01a98caf1..f10fcbbf0 100644 --- a/tests/test_trigger.py +++ b/tests/test_trigger.py @@ -4,22 +4,21 @@ from unittest.mock import MagicMock from datadog_lambda.trigger import ( + EventSubtypes, + EventTypes, parse_event_source, get_event_source_arn, extract_trigger_tags, extract_http_status_code_tag, + is_step_function_event, ) +from tests.utils import get_mock_context + event_samples = "tests/event_samples/" function_arn = "arn:aws:lambda:us-west-1:123457598159:function:python-layer-test" -def get_mock_context(invoked_function_arn=function_arn): - lambda_context = MagicMock() - lambda_context.invoked_function_arn = invoked_function_arn - return lambda_context - - class TestGetEventSourceAndARN(unittest.TestCase): def test_event_source_api_gateway(self): event_sample_source = "api-gateway" @@ -29,12 +28,87 @@ def test_event_source_api_gateway(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) self.assertEqual( event_source_arn, "arn:aws:apigateway:us-west-1::/restapis/1234567890/stages/prod", ) + def test_event_source_api_gateway_non_proxy(self): + event_sample_source = "api-gateway-non-proxy" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + event = json.load(event) + ctx = get_mock_context() + event_source = parse_event_source(event) + event_source_arn = get_event_source_arn(event_source, event, ctx) + self.assertEqual(event_source.to_string(), "api-gateway") + self.assertEqual(event_source.subtype, EventSubtypes.API_GATEWAY) + self.assertEqual( + event_source_arn, + "arn:aws:apigateway:us-west-1::/restapis/lgxbo6a518/stages/dev", + ) + + def test_event_source_api_gateway_websocket_connect(self): + event_sample_source = "api-gateway-websocket-connect" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + event = json.load(event) + ctx = get_mock_context() + event_source = parse_event_source(event) + event_source_arn = get_event_source_arn(event_source, event, ctx) + self.assertEqual(event_source.to_string(), "api-gateway") + self.assertEqual(event_source.subtype, EventSubtypes.WEBSOCKET) + self.assertEqual( + event_source_arn, + "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", + ) + + def test_event_source_api_gateway_websocket_default(self): + event_sample_source = "api-gateway-websocket-default" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + event = json.load(event) + ctx = get_mock_context() + event_source = parse_event_source(event) + event_source_arn = get_event_source_arn(event_source, event, ctx) + self.assertEqual(event_source.to_string(), "api-gateway") + self.assertEqual(event_source.subtype, EventSubtypes.WEBSOCKET) + self.assertEqual( + event_source_arn, + "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", + ) + + def test_event_source_api_gateway_websocket_disconnect(self): + event_sample_source = "api-gateway-websocket-disconnect" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + event = json.load(event) + ctx = get_mock_context() + event_source = parse_event_source(event) + event_source_arn = get_event_source_arn(event_source, event, ctx) + self.assertEqual(event_source.to_string(), "api-gateway") + self.assertEqual(event_source.subtype, EventSubtypes.WEBSOCKET) + self.assertEqual( + event_source_arn, + "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", + ) + + def test_event_source_api_gateway_http_api(self): + event_sample_source = "http-api" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + event = json.load(event) + ctx = get_mock_context() + event_source = parse_event_source(event) + event_source_arn = get_event_source_arn(event_source, event, ctx) + self.assertEqual(event_source.to_string(), "api-gateway") + self.assertEqual(event_source.subtype, EventSubtypes.HTTP_API) + self.assertEqual( + event_source_arn, + "arn:aws:apigateway:us-west-1::/restapis/x02yirxc7a/stages/$default", + ) + def test_event_source_application_load_balancer(self): event_sample_source = "application-load-balancer" test_file = event_samples + event_sample_source + ".json" @@ -43,7 +117,23 @@ def test_event_source_application_load_balancer(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) + self.assertEqual(event_source.subtype, EventSubtypes.ALB) + self.assertEqual( + event_source_arn, + "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-xyz/123abc", + ) + + def test_event_source_application_load_balancer_multi_value_headers(self): + event_sample_source = "application-load-balancer-multivalue-headers" + test_file = event_samples + event_sample_source + ".json" + with open(test_file, "r") as event: + event = json.load(event) + ctx = get_mock_context() + event_source = parse_event_source(event) + event_source_arn = get_event_source_arn(event_source, event, ctx) + self.assertEqual(event_source.event_type, EventTypes.ALB) + self.assertEqual(event_source.subtype, EventSubtypes.ALB_MULTI_VALUE_HEADERS) self.assertEqual( event_source_arn, "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-xyz/123abc", @@ -57,7 +147,7 @@ def test_event_source_cloudfront(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) self.assertEqual( event_source_arn, "arn:aws:cloudfront::123457598159:distribution/EXAMPLE" ) @@ -70,7 +160,7 @@ def test_event_source_cloudwatch_events(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) self.assertEqual( event_source_arn, "arn:aws:events:us-east-1:123456789012:rule/ExampleRule" ) @@ -83,7 +173,7 @@ def test_event_source_cloudwatch_logs(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) self.assertEqual( event_source_arn, "arn:aws:logs:us-west-1:123457598159:log-group:testLogGroup", @@ -97,7 +187,7 @@ def test_event_source_dynamodb(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) self.assertEqual( event_source_arn, "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", @@ -111,8 +201,11 @@ def test_event_source_kinesis(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) - self.assertEqual(event_source_arn, "arn:aws:kinesis:EXAMPLE") + self.assertEqual(event_source.to_string(), event_sample_source) + self.assertEqual( + event_source_arn, + "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream", + ) def test_event_source_s3(self): event_sample_source = "s3" @@ -122,32 +215,52 @@ def test_event_source_s3(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) self.assertEqual(event_source_arn, "arn:aws:s3:::example-bucket") def test_event_source_sns(self): event_sample_source = "sns" - test_file = event_samples + event_sample_source + ".json" + event_sample_name = "sns-string-msg-attribute" + test_file = event_samples + event_sample_name + ".json" with open(test_file, "r") as event: event = json.load(event) ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) + self.assertEqual(event_source.to_string(), event_sample_source) self.assertEqual( - event_source_arn, "arn:aws:sns:us-east-1:123456789012:ExampleTopic" + event_source_arn, + "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", ) def test_event_source_sqs(self): event_sample_source = "sqs" + event_sample_name = "sqs-string-msg-attribute" + test_file = event_samples + event_sample_name + ".json" + with open(test_file, "r") as event: + event = json.load(event) + ctx = get_mock_context() + event_source = parse_event_source(event) + event_source_arn = get_event_source_arn(event_source, event, ctx) + self.assertEqual(event_source.to_string(), event_sample_source) + self.assertEqual( + event_source_arn, + "arn:aws:sqs:eu-west-1:601427279990:InferredSpansQueueNode", + ) + + def test_event_source_stepfunctions(self): + event_sample_source = "states" test_file = event_samples + event_sample_source + ".json" with open(test_file, "r") as event: event = json.load(event) ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, event_sample_source) - self.assertEqual(event_source_arn, "arn:aws:sqs:us-east-1:123456789012:MyQueue") + self.assertEqual(event_source.to_string(), event_sample_source) + self.assertEqual( + event_source_arn, + "arn:aws:states:ca-central-1:425362996713:stateMachine:MyStateMachine-wsx8chv4d", + ) def test_event_source_unsupported(self): event_sample_source = "custom" @@ -157,9 +270,40 @@ def test_event_source_unsupported(self): ctx = get_mock_context() event_source = parse_event_source(event) event_source_arn = get_event_source_arn(event_source, event, ctx) - self.assertEqual(event_source, None) + self.assertEqual(event_source.to_string(), "unknown") self.assertEqual(event_source_arn, None) + def test_event_source_with_non_dict_request_context(self): + # Test with requestContext as a string instead of a dict + event = {"requestContext": "not_a_dict"} + event_source = parse_event_source(event) + # Should still return a valid event source (unknown in this case) + self.assertEqual(event_source.to_string(), "unknown") + + def test_event_source_with_invalid_domain_name(self): + # Test with domainName that isn't a string + event = {"requestContext": {"stage": "prod", "domainName": 12345}} + event_source = parse_event_source(event) + # Should detect as API Gateway since stage is present + self.assertEqual(event_source.to_string(), "api-gateway") + + def test_detect_lambda_function_url_domain_with_invalid_input(self): + from datadog_lambda.trigger import detect_lambda_function_url_domain + + # Test with non-string input + self.assertFalse(detect_lambda_function_url_domain(None)) + self.assertFalse(detect_lambda_function_url_domain(12345)) + self.assertFalse(detect_lambda_function_url_domain({"not": "a-string"})) + # Test with string that would normally cause an exception when split + self.assertFalse(detect_lambda_function_url_domain("")) + + def test_event_source_with_non_dict_event_record(self): + # Test with event_record that's not a dictionary + event = {"Records": "not_a_dict"} + event_source = parse_event_source(event) + # Should handle the first non-dict record gracefully and return unknown + self.assertEqual(event_source.to_string(), "unknown") + class GetTriggerTags(unittest.TestCase): def test_extract_trigger_tags_api_gateway(self): @@ -174,9 +318,99 @@ def test_extract_trigger_tags_api_gateway(self): { "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/1234567890/stages/prod", - "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/prod/path/to/resource", + "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com/prod/path/to/resource", "http.method": "POST", + "http.route": "/{proxy+}", + "span.kind": "server", + }, + ) + + def test_extract_trigger_tags_api_gateway_non_proxy(self): + event_sample_source = "api-gateway-non-proxy" + test_file = event_samples + event_sample_source + ".json" + ctx = get_mock_context() + with open(test_file, "r") as event: + event = json.load(event) + tags = extract_trigger_tags(event, ctx) + self.assertEqual( + tags, + { + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/lgxbo6a518/stages/dev", + "http.url": "https://lgxbo6a518.execute-api.eu-west-1.amazonaws.com/dev/http/get", + "http.method": "GET", + "http.route": "/http/get", + "span.kind": "server", + }, + ) + + def test_extract_trigger_tags_api_gateway_websocket_connect(self): + event_sample_source = "api-gateway-websocket-connect" + test_file = event_samples + event_sample_source + ".json" + ctx = get_mock_context() + with open(test_file, "r") as event: + event = json.load(event) + tags = extract_trigger_tags(event, ctx) + self.assertEqual( + tags, + { + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com/", + "span.kind": "server", + }, + ) + + def test_extract_trigger_tags_api_gateway_websocket_default(self): + event_sample_source = "api-gateway-websocket-default" + test_file = event_samples + event_sample_source + ".json" + ctx = get_mock_context() + with open(test_file, "r") as event: + event = json.load(event) + tags = extract_trigger_tags(event, ctx) + self.assertEqual( + tags, + { + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com/", + "span.kind": "server", + }, + ) + + def test_extract_trigger_tags_api_gateway_websocket_disconnect(self): + event_sample_source = "api-gateway-websocket-disconnect" + test_file = event_samples + event_sample_source + ".json" + ctx = get_mock_context() + with open(test_file, "r") as event: + event = json.load(event) + tags = extract_trigger_tags(event, ctx) + self.assertEqual( + tags, + { + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com/", + "span.kind": "server", + }, + ) + + def test_extract_trigger_tags_api_gateway_http_api(self): + event_sample_source = "http-api" + test_file = event_samples + event_sample_source + ".json" + ctx = get_mock_context() + with open(test_file, "r") as event: + event = json.load(event) + tags = extract_trigger_tags(event, ctx) + self.assertEqual( + tags, + { + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/x02yirxc7a/stages/$default", + "http.url": "https://x02yirxc7a.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.method": "GET", + "span.kind": "server", + "http.route": "/httpapi/get", }, ) @@ -192,8 +426,8 @@ def test_extract_trigger_tags_application_load_balancer(self): { "function_trigger.event_source": "application-load-balancer", "function_trigger.event_source_arn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-xyz/123abc", - "http.url_details.path": "/lambda", "http.method": "GET", + "span.kind": "server", }, ) @@ -268,7 +502,7 @@ def test_extract_trigger_tags_kinesis(self): tags, { "function_trigger.event_source": "kinesis", - "function_trigger.event_source_arn": "arn:aws:kinesis:EXAMPLE", + "function_trigger.event_source_arn": "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream", }, ) @@ -288,8 +522,8 @@ def test_extract_trigger_tags_s3(self): ) def test_extract_trigger_tags_sns(self): - event_sample_source = "sns" - test_file = event_samples + event_sample_source + ".json" + event_sample_name = "sns-string-msg-attribute" + test_file = event_samples + event_sample_name + ".json" ctx = get_mock_context() with open(test_file, "r") as event: event = json.load(event) @@ -298,13 +532,13 @@ def test_extract_trigger_tags_sns(self): tags, { "function_trigger.event_source": "sns", - "function_trigger.event_source_arn": "arn:aws:sns:us-east-1:123456789012:ExampleTopic", + "function_trigger.event_source_arn": "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", }, ) def test_extract_trigger_tags_sqs(self): - event_sample_source = "sqs" - test_file = event_samples + event_sample_source + ".json" + event_sample_name = "sqs-string-msg-attribute" + test_file = event_samples + event_sample_name + ".json" ctx = get_mock_context() with open(test_file, "r") as event: event = json.load(event) @@ -313,7 +547,22 @@ def test_extract_trigger_tags_sqs(self): tags, { "function_trigger.event_source": "sqs", - "function_trigger.event_source_arn": "arn:aws:sqs:us-east-1:123456789012:MyQueue", + "function_trigger.event_source_arn": "arn:aws:sqs:eu-west-1:601427279990:InferredSpansQueueNode", + }, + ) + + def test_extract_trigger_tags_stepfunctions(self): + event_sample_source = "states" + test_file = event_samples + event_sample_source + ".json" + ctx = get_mock_context() + with open(test_file, "r") as event: + event = json.load(event) + tags = extract_trigger_tags(event, ctx) + self.assertEqual( + tags, + { + "function_trigger.event_source": "states", + "function_trigger.event_source_arn": "arn:aws:states:ca-central-1:425362996713:stateMachine:MyStateMachine-wsx8chv4d", }, ) @@ -332,6 +581,51 @@ def test_extract_trigger_tags_list_type_event(self): tags = extract_trigger_tags(event, ctx) self.assertEqual(tags, {}) + def test_extract_http_tags_with_invalid_request_context(self): + from datadog_lambda.trigger import extract_http_tags + + # Test with requestContext as a string instead of a dict + event = {"requestContext": "not_a_dict", "path": "/test", "httpMethod": "GET"} + http_tags = extract_http_tags(event) + # Should still extract valid tags from the event + self.assertEqual( + http_tags, + { + "span.kind": "server", + "http.method": "GET", + }, + ) + + def test_extract_http_tags_with_invalid_apigateway_http(self): + from datadog_lambda.trigger import extract_http_tags + + # Test with http in requestContext that's not a dict + event = { + "requestContext": {"stage": "prod", "http": "not_a_dict"}, + "version": "2.0", + } + http_tags = extract_http_tags(event) + # Should not raise an exception + self.assertEqual(http_tags, {"span.kind": "server"}) + + def test_extract_http_tags_with_invalid_headers(self): + from datadog_lambda.trigger import extract_http_tags + + # Test with headers that's not a dict + event = {"headers": "not_a_dict"} + http_tags = extract_http_tags(event) + # Should not raise an exception + self.assertEqual(http_tags, {"span.kind": "server"}) + + def test_extract_http_tags_with_invalid_route(self): + from datadog_lambda.trigger import extract_http_tags + + # Test with routeKey that would cause a split error + event = {"routeKey": 12345} # Not a string + http_tags = extract_http_tags(event) + # Should not raise an exception + self.assertEqual(http_tags, {"span.kind": "server"}) + class ExtractHTTPStatusCodeTag(unittest.TestCase): def test_extract_http_status_code_tag_from_response_dict(self): @@ -346,3 +640,68 @@ def test_extract_http_status_code_tag_from_response_object(self): response.status_code = 403 status_code = extract_http_status_code_tag(trigger_tags, response) self.assertEqual(status_code, "403") + + +class IsStepFunctionEvent(unittest.TestCase): + def test_is_step_function_event_jsonata(self): + event = { + "_datadog": { + "Execution": { + "Id": "665c417c-1237-4742-aaca-8b3becbb9e75", + "RedriveCount": 0, + }, + "StateMachine": {}, + "State": { + "Name": "my-awesome-state", + "EnteredTime": "Mon Nov 13 12:43:33 PST 2023", + "RetryCount": 0, + }, + "x-datadog-trace-id": "5821803790426892636", + "x-datadog-tags": "_dd.p.dm=-0,_dd.p.tid=672a7cb100000000", + "serverless-version": "v1", + } + } + self.assertTrue(is_step_function_event(event)) + + def test_is_step_function_event_jsonpath(self): + event = { + "Execution": { + "Id": "665c417c-1237-4742-aaca-8b3becbb9e75", + "RedriveCount": 0, + }, + "StateMachine": {}, + "State": { + "Name": "my-awesome-state", + "EnteredTime": "Mon Nov 13 12:43:33 PST 2023", + "RetryCount": 0, + }, + } + self.assertTrue(is_step_function_event(event)) + + def test_is_step_function_event_legacy_lambda(self): + event = { + "Payload": { + "Execution": { + "Id": "665c417c-1237-4742-aaca-8b3becbb9e75", + "RedriveCount": 0, + }, + "StateMachine": {}, + "State": { + "Name": "my-awesome-state", + "EnteredTime": "Mon Nov 13 12:43:33 PST 2023", + "RetryCount": 0, + }, + } + } + self.assertTrue(is_step_function_event(event)) + + def test_is_step_function_event_dd_header(self): + event = { + "_datadog": { + "x-datadog-trace-id": "5821803790426892636", + "x-datadog-parent-id": "5821803790426892636", + "x-datadog-tags": "_dd.p.dm=-0,_dd.p.tid=672a7cb100000000", + "x-datadog-sampling-priority": "1", + } + } + self.assertFalse(is_step_function_event(event)) diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 000000000..ca3c8f03e --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,7 @@ +import importlib.metadata +from datadog_lambda import __version__ + + +def test_version(): + # test version in __init__ matches version in pyproject.toml + assert importlib.metadata.version("datadog-lambda") == __version__ diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py index 325405534..512a51f89 100644 --- a/tests/test_wrapper.py +++ b/tests/test_wrapper.py @@ -1,35 +1,32 @@ +import base64 +import json import os import unittest +import importlib -from unittest.mock import patch, call, ANY, MagicMock +from unittest.mock import MagicMock, patch, call, ANY +from datadog_lambda.constants import TraceHeader -from datadog_lambda.wrapper import datadog_lambda_wrapper +import datadog_lambda.wrapper as wrapper +import datadog_lambda.xray as xray + +from datadog_lambda.config import config from datadog_lambda.metric import lambda_metric from datadog_lambda.thread_stats_writer import ThreadStatsWriter +from ddtrace.trace import Span, tracer +from ddtrace.internal.constants import MAX_UINT_64BITS - -def get_mock_context( - aws_request_id="request-id-1", - memory_limit_in_mb="256", - invoked_function_arn="arn:aws:lambda:us-west-1:123457598159:function:python-layer-test:1", - function_version="1", - client_context={}, -): - lambda_context = MagicMock() - lambda_context.aws_request_id = aws_request_id - lambda_context.memory_limit_in_mb = memory_limit_in_mb - lambda_context.invoked_function_arn = invoked_function_arn - lambda_context.function_version = function_version - lambda_context.client_context = client_context - return lambda_context +from tests.utils import get_mock_context, reset_xray_connection class TestDatadogLambdaWrapper(unittest.TestCase): def setUp(self): # Force @datadog_lambda_wrapper to always create a real # (not no-op) wrapper. - datadog_lambda_wrapper._force_wrap = True + patch("ddtrace.internal.remoteconfig.worker.RemoteConfigPoller").start() + patch("ddtrace.internal.writer.AgentWriter.flush_queue").start() + wrapper.datadog_lambda_wrapper._force_wrap = True patcher = patch( "datadog.threadstats.reporters.HttpReporter.flush_distributions" ) @@ -38,7 +35,7 @@ def setUp(self): patcher = patch("datadog_lambda.wrapper.extract_dd_trace_context") self.mock_extract_dd_trace_context = patcher.start() - self.mock_extract_dd_trace_context.return_value = ({}, None) + self.mock_extract_dd_trace_context.return_value = ({}, None, None) self.addCleanup(patcher.stop) patcher = patch("datadog_lambda.wrapper.set_correlation_ids") @@ -49,39 +46,37 @@ def setUp(self): self.mock_inject_correlation_ids = patcher.start() self.addCleanup(patcher.stop) - patcher = patch("datadog_lambda.wrapper.patch_all") - self.mock_patch_all = patcher.start() - self.addCleanup(patcher.stop) - - patcher = patch("datadog_lambda.cold_start.is_cold_start") - self.mock_is_cold_start = patcher.start() - self.mock_is_cold_start.return_value = True + patcher = patch("datadog_lambda.tags.get_cold_start_tag") + self.mock_get_cold_start_tag = patcher.start() + self.mock_get_cold_start_tag.return_value = "cold_start:true" self.addCleanup(patcher.stop) - patcher = patch("datadog_lambda.tags.python_version_tuple") - self.mock_python_version_tuple = patcher.start() - self.mock_python_version_tuple.return_value = ("3", "9", "10") + patcher = patch("datadog_lambda.tags.runtime_tag", "runtime:python3.9") + self.mock_runtime_tag = patcher.start() self.addCleanup(patcher.stop) patcher = patch("datadog_lambda.metric.write_metric_point_to_stdout") self.mock_write_metric_point_to_stdout = patcher.start() self.addCleanup(patcher.stop) - patcher = patch("datadog_lambda.tags.get_library_version_tag") - self.mock_format_dd_lambda_layer_tag = patcher.start() + patcher = patch( + "datadog_lambda.tags.library_version_tag", "datadog_lambda:v6.6.6" + ) # Mock the layer version so we don't have to update tests on every version bump - self.mock_format_dd_lambda_layer_tag.return_value = "datadog_lambda:v6.6.6" + self.mock_library_version_tag = patcher.start() + self.addCleanup(patcher.stop) - patcher = patch("datadog_lambda.tags._format_dd_lambda_layer_tag") - self.mock_format_dd_lambda_layer_tag = patcher.start() - # Mock the layer version so we don't have to update tests on every version bump - self.mock_format_dd_lambda_layer_tag.return_value = ( - "dd_lambda_layer:datadog-python39_X.X.X" + patcher = patch( + "datadog_lambda.metric.dd_lambda_layer_tag", + "dd_lambda_layer:datadog-python39_X.X.X", ) + # Mock the layer version so we don't have to update tests on every version bump + self.mock_dd_lambda_layer_tag = patcher.start() self.addCleanup(patcher.stop) + @patch("datadog_lambda.config.Config.trace_enabled", False) def test_datadog_lambda_wrapper(self): - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) @@ -90,7 +85,6 @@ def lambda_handler(event, context): lambda_context = get_mock_context() lambda_handler(lambda_event, lambda_context) - self.mock_threadstats_flush_distributions.assert_has_calls( [ call( @@ -109,16 +103,18 @@ def lambda_handler(event, context): ] ) self.mock_extract_dd_trace_context.assert_called_with( - lambda_event, lambda_context, extractor=None + lambda_event, + lambda_context, + extractor=None, + decode_authorizer_context=False, ) self.mock_set_correlation_ids.assert_called() self.mock_inject_correlation_ids.assert_called() - self.mock_patch_all.assert_called() def test_datadog_lambda_wrapper_flush_to_log(self): os.environ["DD_FLUSH_TO_LOG"] = "True" - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) @@ -136,13 +132,14 @@ def test_datadog_lambda_wrapper_flush_in_thread(self): metric_module.lambda_stats.stop() metric_module.lambda_stats = ThreadStatsWriter(True) - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): import time lambda_metric("test.metric", 100) time.sleep(11) # assert flushing in the thread + # TODO(astuyve) flaky test here, sometimes this is zero self.assertEqual(self.mock_threadstats_flush_distributions.call_count, 1) lambda_metric("test.metric", 200) @@ -163,7 +160,7 @@ def test_datadog_lambda_wrapper_not_flush_in_thread(self): metric_module.lambda_stats.stop() metric_module.lambda_stats = ThreadStatsWriter(False) - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): import time @@ -183,23 +180,23 @@ def lambda_handler(event, context): metric_module.lambda_stats.stop() metric_module.lambda_stats = ThreadStatsWriter(False) + @patch("datadog_lambda.config.Config.trace_enabled", False) def test_datadog_lambda_wrapper_inject_correlation_ids(self): os.environ["DD_LOGS_INJECTION"] = "True" - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) lambda_event = {} lambda_handler(lambda_event, get_mock_context()) - self.mock_set_correlation_ids.assert_called() self.mock_inject_correlation_ids.assert_called() del os.environ["DD_LOGS_INJECTION"] def test_invocations_metric(self): - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) @@ -216,9 +213,9 @@ def lambda_handler(event, context): "region:us-west-1", "account_id:123457598159", "functionname:python-layer-test", - "resource:python-layer-test:1", - "cold_start:true", + "resource:python-layer-test", "memorysize:256", + "cold_start:true", "runtime:python3.9", "datadog_lambda:v6.6.6", "dd_lambda_layer:datadog-python39_X.X.X", @@ -229,7 +226,7 @@ def lambda_handler(event, context): ) def test_errors_metric(self): - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): raise RuntimeError() @@ -247,9 +244,9 @@ def lambda_handler(event, context): "region:us-west-1", "account_id:123457598159", "functionname:python-layer-test", - "resource:python-layer-test:1", - "cold_start:true", + "resource:python-layer-test", "memorysize:256", + "cold_start:true", "runtime:python3.9", "datadog_lambda:v6.6.6", "dd_lambda_layer:datadog-python39_X.X.X", @@ -263,9 +260,64 @@ def lambda_handler(event, context): "region:us-west-1", "account_id:123457598159", "functionname:python-layer-test", - "resource:python-layer-test:1", + "resource:python-layer-test", + "memorysize:256", "cold_start:true", + "runtime:python3.9", + "datadog_lambda:v6.6.6", + "dd_lambda_layer:datadog-python39_X.X.X", + ], + timestamp=None, + ), + ] + ) + + @patch("datadog_lambda.wrapper.extract_trigger_tags") + def test_5xx_sends_errors_metric_and_set_tags(self, mock_extract_trigger_tags): + mock_extract_trigger_tags.return_value = { + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/1234567890/stages/prod", + "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com/", + "http.url_details.path": "/prod/path/to/resource", + "http.method": "GET", + } + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return {"statusCode": 500, "body": "fake response body"} + + lambda_event = {} + + lambda_handler(lambda_event, get_mock_context()) + + self.mock_write_metric_point_to_stdout.assert_has_calls( + [ + call( + "aws.lambda.enhanced.invocations", + 1, + tags=[ + "region:us-west-1", + "account_id:123457598159", + "functionname:python-layer-test", + "resource:python-layer-test", + "memorysize:256", + "cold_start:true", + "runtime:python3.9", + "datadog_lambda:v6.6.6", + "dd_lambda_layer:datadog-python39_X.X.X", + ], + timestamp=None, + ), + call( + "aws.lambda.enhanced.errors", + 1, + tags=[ + "region:us-west-1", + "account_id:123457598159", + "functionname:python-layer-test", + "resource:python-layer-test", "memorysize:256", + "cold_start:true", "runtime:python3.9", "datadog_lambda:v6.6.6", "dd_lambda_layer:datadog-python39_X.X.X", @@ -276,7 +328,7 @@ def lambda_handler(event, context): ) def test_enhanced_metrics_cold_start_tag(self): - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) @@ -284,7 +336,7 @@ def lambda_handler(event, context): lambda_handler(lambda_event, get_mock_context()) - self.mock_is_cold_start.return_value = False + self.mock_get_cold_start_tag.return_value = "cold_start:false" lambda_handler( lambda_event, get_mock_context(aws_request_id="second-request-id") @@ -299,9 +351,9 @@ def lambda_handler(event, context): "region:us-west-1", "account_id:123457598159", "functionname:python-layer-test", - "resource:python-layer-test:1", - "cold_start:true", + "resource:python-layer-test", "memorysize:256", + "cold_start:true", "runtime:python3.9", "datadog_lambda:v6.6.6", "dd_lambda_layer:datadog-python39_X.X.X", @@ -315,9 +367,9 @@ def lambda_handler(event, context): "region:us-west-1", "account_id:123457598159", "functionname:python-layer-test", - "resource:python-layer-test:1", - "cold_start:false", + "resource:python-layer-test", "memorysize:256", + "cold_start:false", "runtime:python3.9", "datadog_lambda:v6.6.6", "dd_lambda_layer:datadog-python39_X.X.X", @@ -328,7 +380,7 @@ def lambda_handler(event, context): ) def test_enhanced_metrics_latest(self): - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) @@ -350,8 +402,8 @@ def lambda_handler(event, context): "account_id:123457598159", "functionname:python-layer-test", "resource:python-layer-test:Latest", - "cold_start:true", "memorysize:256", + "cold_start:true", "runtime:python3.9", "datadog_lambda:v6.6.6", "dd_lambda_layer:datadog-python39_X.X.X", @@ -362,7 +414,7 @@ def lambda_handler(event, context): ) def test_enhanced_metrics_alias(self): - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) @@ -384,8 +436,8 @@ def lambda_handler(event, context): "functionname:python-layer-test", "executedversion:1", "resource:python-layer-test:My_alias-1", - "cold_start:true", "memorysize:256", + "cold_start:true", "runtime:python3.9", "datadog_lambda:v6.6.6", "dd_lambda_layer:datadog-python39_X.X.X", @@ -395,10 +447,9 @@ def lambda_handler(event, context): ] ) + @patch("datadog_lambda.config.Config.enhanced_metrics_enabled", False) def test_no_enhanced_metrics_without_env_var(self): - os.environ["DD_ENHANCED_METRICS"] = "false" - - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): raise RuntimeError() @@ -409,32 +460,32 @@ def lambda_handler(event, context): self.mock_write_metric_point_to_stdout.assert_not_called() - del os.environ["DD_ENHANCED_METRICS"] - def test_only_one_wrapper_in_use(self): - patcher = patch("datadog_lambda.wrapper.submit_invocations_metric") + patcher = patch("datadog_lambda.metric.submit_invocations_metric") self.mock_submit_invocations_metric = patcher.start() self.addCleanup(patcher.stop) - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) # Turn off _force_wrap to emulate the nested wrapper scenario, # the second @datadog_lambda_wrapper should actually be no-op. - datadog_lambda_wrapper._force_wrap = False + wrapper.datadog_lambda_wrapper._force_wrap = False - lambda_handler_double_wrapped = datadog_lambda_wrapper(lambda_handler) + lambda_handler_double_wrapped = wrapper.datadog_lambda_wrapper(lambda_handler) lambda_event = {} lambda_handler_double_wrapped(lambda_event, get_mock_context()) - self.mock_patch_all.assert_called_once() self.mock_submit_invocations_metric.assert_called_once() def test_dd_requests_service_name_default(self): - @datadog_lambda_wrapper + # TODO(astuyve) this is now set by CI, so we need to null it out for this case + os.environ["DD_SERVICE"] = "aws.lambda" + + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): pass @@ -443,9 +494,466 @@ def lambda_handler(event, context): def test_dd_requests_service_name_set(self): os.environ["DD_SERVICE"] = "myAwesomeService" - @datadog_lambda_wrapper + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): pass self.assertEqual(os.environ.get("DD_REQUESTS_SERVICE_NAME"), "myAwesomeService") del os.environ["DD_SERVICE"] + + @patch("datadog_lambda.config.Config.make_inferred_span", False) + def test_encode_authorizer_span(self): + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return { + "principalId": "foo", + "policyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "execute-api:Invoke", + "Effect": "Allow", + "Resource": "dummy", + }, + ], + }, + "context": {"scope": "still here"}, + } + + lambda_event = {} + + lambda_context = get_mock_context() + test_span = tracer.trace("test_span") + trace_ctx = tracer.current_trace_context() + trace_ctx.sampling_priority = 1 + test_span.finish() + lambda_handler.inferred_span = test_span + result = lambda_handler(lambda_event, lambda_context) + raw_inject_data = result["context"]["_datadog"] + self.assertIsInstance(raw_inject_data, str) + inject_data = json.loads(base64.b64decode(raw_inject_data)) + self.assertEqual(inject_data[TraceHeader.PARENT_ID], str(trace_ctx.span_id)) + self.assertEqual( + inject_data[TraceHeader.TRACE_ID], str(MAX_UINT_64BITS & trace_ctx.trace_id) + ) + self.assertEqual(inject_data[TraceHeader.SAMPLING_PRIORITY], "1") + self.assertEqual(result["context"]["scope"], "still here") + + @patch("traceback.print_exc") + def test_different_return_type_no_error(self, MockPrintExc): + TEST_RESULTS = ["a str to return", 42, {"value": 42}, ["A", 42], None] + mock_context = get_mock_context() + for test_result in TEST_RESULTS: + + @wrapper.datadog_lambda_wrapper + def return_type_test(event, context): + return test_result + + result = return_type_test({}, mock_context) + self.assertEqual(result, test_result) + self.assertFalse(MockPrintExc.called) + + +class TestLambdaWrapperWithTraceContext(unittest.TestCase): + xray_root = "1-5e272390-8c398be037738dc042009320" + xray_parent = "94ae789b969f1cc5" + xray_daemon_envvar = "localhost:1234" + xray_trace_envvar = ( + f"Root={xray_root};Parent={xray_parent};Sampled=1;Lineage=c6c5b1b9:0" + ) + + @patch( + "os.environ", + { + "AWS_XRAY_DAEMON_ADDRESS": xray_daemon_envvar, + "_X_AMZN_TRACE_ID": xray_trace_envvar, + }, + ) + def test_event_bridge_sqs_payload(self): + reset_xray_connection() + + patcher = patch("datadog_lambda.xray.sock.send") + mock_send = patcher.start() + self.addCleanup(patcher.stop) + + def handler(event, context): + return tracer.current_trace_context() + + wrapper.dd_tracing_enabled = True + wrapped_handler = wrapper.datadog_lambda_wrapper(handler) + + event_trace_id = 3047453991382739997 + event_parent_id = 3047453991382739997 + event = { + "headers": { + "traceparent": ( + f"00-0000000000000000{hex(event_trace_id)[2:]}-{hex(event_parent_id)[2:]}-01" + ), + "tracestate": "dd=s:1;t.dm:-1", + "x-datadog-trace-id": str(event_trace_id), + "x-datadog-parent-id": str(event_parent_id), + "x-datadog-sampling-priority": "1", + }, + } + context = get_mock_context() + + result = wrapped_handler(event, context) + aws_lambda_span = wrapped_handler.span + + self.assertIsNotNone(result) + self.assertEqual(result.trace_id, event_trace_id) + self.assertEqual(result.span_id, aws_lambda_span.span_id) + self.assertEqual(result.sampling_priority, 1) + mock_send.assert_called_once() + (raw_payload,), _ = mock_send.call_args + payload = json.loads(raw_payload[33:]) # strip formatting prefix + self.assertEqual(self.xray_root, payload["trace_id"]) + self.assertEqual(self.xray_parent, payload["parent_id"]) + self.assertDictEqual( + { + "datadog": { + "trace": { + "trace-id": str(event_trace_id), + "parent-id": str(event_parent_id), + "sampling-priority": "1", + }, + }, + }, + payload["metadata"], + ) + + +class TestLambdaWrapperFlushExtension(unittest.TestCase): + @patch("datadog_lambda.config.Config.local_test", True) + @patch("datadog_lambda.wrapper.should_use_extension", True) + def test_local_test_true_flushing(self): + flushes = [] + lambda_event = {} + lambda_context = get_mock_context() + + def flush(): + flushes.append(1) + + @patch("datadog_lambda.wrapper.flush_extension", flush) + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + pass + + lambda_handler(lambda_event, lambda_context) + + self.assertEqual(len(flushes), 1) + + @patch("datadog_lambda.config.Config.local_test", False) + @patch("datadog_lambda.wrapper.should_use_extension", True) + def test_local_test_false_flushing(self): + flushes = [] + lambda_event = {} + lambda_context = get_mock_context() + + def flush(): + flushes.append(1) + + @patch("datadog_lambda.wrapper.flush_extension", flush) + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + pass + + lambda_handler(lambda_event, lambda_context) + + self.assertEqual(len(flushes), 0) + + +class TestLambdaWrapperAppsecBlocking(unittest.TestCase): + def setUp(self): + os.environ["DD_APPSEC_ENABLED"] = "true" + os.environ["DD_TRACE_ENABLED"] = "true" + + importlib.reload(wrapper) + + self.addCleanup(os.environ.pop, "DD_APPSEC_ENABLED", None) + self.addCleanup(os.environ.pop, "DD_TRACE_ENABLED", None) + self.addCleanup(lambda: importlib.reload(wrapper)) + + patcher = patch("datadog_lambda.wrapper.asm_set_context") + self.mock_asm_set_context = patcher.start() + self.addCleanup(patcher.stop) + + patcher = patch("datadog_lambda.wrapper.asm_start_request") + self.mock_asm_start_request = patcher.start() + self.addCleanup(patcher.stop) + + patcher = patch("datadog_lambda.wrapper.asm_start_response") + self.mock_asm_start_response = patcher.start() + self.addCleanup(patcher.stop) + + patcher = patch("datadog_lambda.wrapper.get_asm_blocked_response") + self.mock_get_asm_blocking_response = patcher.start() + self.addCleanup(patcher.stop) + + with open("tests/event_samples/api-gateway.json") as f: + self.api_gateway_request = json.loads(f.read()) + + self.fake_blocking_response = { + "statusCode": "403", + "headers": { + "Content-Type": "application/json", + }, + "body": '{"message": "Blocked by AppSec"}', + "isBase64Encoded": False, + } + + def test_blocking_before(self): + self.mock_get_asm_blocking_response.return_value = self.fake_blocking_response + + mock_handler = MagicMock() + + lambda_handler = wrapper.datadog_lambda_wrapper(mock_handler) + + response = lambda_handler(self.api_gateway_request, get_mock_context()) + self.assertEqual(response, self.fake_blocking_response) + + mock_handler.assert_not_called() + + self.mock_asm_set_context.assert_called_once() + self.mock_asm_start_request.assert_called_once() + self.mock_asm_start_response.assert_not_called() + + assert lambda_handler.span.get_tag("http.status_code") == "403" + + def test_blocking_during(self): + self.mock_get_asm_blocking_response.return_value = None + + def lambda_handler(event, context): + self.mock_get_asm_blocking_response.return_value = ( + self.fake_blocking_response + ) + raise wrapper.BlockingException() + + lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler) + + response = lambda_handler(self.api_gateway_request, get_mock_context()) + self.assertEqual(response, self.fake_blocking_response) + + self.mock_asm_set_context.assert_called_once() + self.mock_asm_start_request.assert_called_once() + self.mock_asm_start_response.assert_not_called() + + assert lambda_handler.span.get_tag("http.status_code") == "403" + + def test_blocking_after(self): + self.mock_get_asm_blocking_response.return_value = None + + def lambda_handler(event, context): + self.mock_get_asm_blocking_response.return_value = ( + self.fake_blocking_response + ) + return { + "statusCode": 200, + "body": "This should not be returned", + } + + lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler) + + response = lambda_handler(self.api_gateway_request, get_mock_context()) + self.assertEqual(response, self.fake_blocking_response) + + self.mock_asm_set_context.assert_called_once() + self.mock_asm_start_request.assert_called_once() + self.mock_asm_start_response.assert_called_once() + + assert lambda_handler.span.get_tag("http.status_code") == "403" + + def test_no_blocking_appsec_disabled(self): + os.environ["DD_APPSEC_ENABLED"] = "false" + + importlib.reload(wrapper) + + self.mock_get_asm_blocking_response.return_value = self.fake_blocking_response + + expected_response = { + "statusCode": 200, + "body": "This should be returned", + } + + def lambda_handler(event, context): + return expected_response + + lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler) + + response = lambda_handler(self.api_gateway_request, get_mock_context()) + self.assertEqual(response, expected_response) + + self.mock_get_asm_blocking_response.assert_not_called() + self.mock_asm_set_context.assert_not_called() + self.mock_asm_start_request.assert_not_called() + self.mock_asm_start_response.assert_not_called() + + assert lambda_handler.span.get_tag("http.status_code") == "200" + + +@patch("datadog_lambda.config.Config.exception_replay_enabled", True) +def test_exception_replay_enabled(monkeypatch): + importlib.reload(wrapper) + + original_SpanExceptionHandler_enable = wrapper.SpanExceptionHandler.enable + SpanExceptionHandler_enable_calls = [] + + def SpanExceptionHandler_enable(*args, **kwargs): + SpanExceptionHandler_enable_calls.append((args, kwargs)) + return original_SpanExceptionHandler_enable(*args, **kwargs) + + original_SignalUploader_periodic = wrapper.SignalUploader.periodic + SignalUploader_periodic_calls = [] + + def SignalUploader_periodic(*args, **kwargs): + SignalUploader_periodic_calls.append((args, kwargs)) + return original_SignalUploader_periodic(*args, **kwargs) + + monkeypatch.setattr( + "datadog_lambda.wrapper.SpanExceptionHandler.enable", + SpanExceptionHandler_enable, + ) + monkeypatch.setattr( + "datadog_lambda.wrapper.SignalUploader.periodic", SignalUploader_periodic + ) + + expected_response = { + "statusCode": 200, + "body": "This should be returned", + } + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return expected_response + + response = lambda_handler({}, get_mock_context()) + + assert response == expected_response + assert len(SpanExceptionHandler_enable_calls) == 1 + assert len(SignalUploader_periodic_calls) == 1 + + +@patch("datadog_lambda.config.Config.profiling_enabled", True) +def test_profiling_enabled(monkeypatch): + importlib.reload(wrapper) + + original_Profiler_start = wrapper.profiler.Profiler.start + Profiler_start_calls = [] + + def Profiler_start(*args, **kwargs): + Profiler_start_calls.append((args, kwargs)) + return original_Profiler_start(*args, **kwargs) + + monkeypatch.setattr("datadog_lambda.wrapper.is_new_sandbox", lambda: True) + monkeypatch.setattr( + "datadog_lambda.wrapper.profiler.Profiler.start", Profiler_start + ) + + expected_response = { + "statusCode": 200, + "body": "This should be returned", + } + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return expected_response + + response = lambda_handler({}, get_mock_context()) + + assert response == expected_response + assert len(Profiler_start_calls) == 1 + + +@patch("datadog_lambda.config.Config.llmobs_enabled", True) +def test_llmobs_enabled(monkeypatch): + importlib.reload(wrapper) + + original_LLMObs_enable = wrapper.LLMObs.enable + LLMObs_enable_calls = [] + + def LLMObs_enable(*args, **kwargs): + LLMObs_enable_calls.append((args, kwargs)) + return original_LLMObs_enable(*args, **kwargs) + + original_LLMObs_flush = wrapper.LLMObs.flush + LLMObs_flush_calls = [] + + def LLMObs_flush(*args, **kwargs): + LLMObs_flush_calls.append((args, kwargs)) + return original_LLMObs_flush(*args, **kwargs) + + monkeypatch.setattr("datadog_lambda.wrapper.LLMObs.enable", LLMObs_enable) + monkeypatch.setattr("datadog_lambda.wrapper.LLMObs.flush", LLMObs_flush) + + expected_response = { + "statusCode": 200, + "body": "This should be returned", + } + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return expected_response + + response = lambda_handler({}, get_mock_context()) + + assert response == expected_response + assert len(LLMObs_enable_calls) == 1 + assert len(LLMObs_flush_calls) == 1 + + +@patch("datadog_lambda.config.Config.trace_enabled", False) +def test_batch_item_failures_metric(): + with patch( + "datadog_lambda.metric.submit_batch_item_failures_metric" + ) as mock_submit: + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return { + "batchItemFailures": [ + {"itemIdentifier": "msg-1"}, + {"itemIdentifier": "msg-2"}, + ] + } + + lambda_handler({}, get_mock_context()) + mock_submit.assert_called_once() + call_args = mock_submit.call_args[0] + assert call_args[0] == { + "batchItemFailures": [ + {"itemIdentifier": "msg-1"}, + {"itemIdentifier": "msg-2"}, + ] + } + + +@patch("datadog_lambda.config.Config.trace_enabled", False) +def test_batch_item_failures_metric_no_failures(): + with patch( + "datadog_lambda.metric.submit_batch_item_failures_metric" + ) as mock_submit: + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return {"batchItemFailures": []} + + lambda_handler({}, get_mock_context()) + mock_submit.assert_called_once() + call_args = mock_submit.call_args[0] + assert call_args[0] == {"batchItemFailures": []} + + +@patch("datadog_lambda.config.Config.trace_enabled", False) +def test_batch_item_failures_metric_no_response(): + with patch( + "datadog_lambda.metric.submit_batch_item_failures_metric" + ) as mock_submit: + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return None + + lambda_handler({}, get_mock_context()) + mock_submit.assert_called_once() + call_args = mock_submit.call_args[0] + assert call_args[0] is None diff --git a/tests/test_xray.py b/tests/test_xray.py index 5c3cd4041..7f33f8915 100644 --- a/tests/test_xray.py +++ b/tests/test_xray.py @@ -1,25 +1,62 @@ import unittest import json +import os from unittest.mock import MagicMock, patch -from datadog_lambda.xray import get_xray_host_port, build_segment_payload, build_segment +from datadog_lambda.xray import build_segment_payload, build_segment, send_segment, sock +from tests.utils import reset_xray_connection class TestXRay(unittest.TestCase): + def setUp(self): + reset_xray_connection() + + def tearDown(self): + if os.environ.get("_X_AMZN_TRACE_ID"): + os.environ.pop("_X_AMZN_TRACE_ID") + if os.environ.get("AWS_XRAY_DAEMON_ADDRESS"): + os.environ.pop("AWS_XRAY_DAEMON_ADDRESS") + return super().tearDown() + def test_get_xray_host_port_empty_(self): - result = get_xray_host_port("") + result = sock._get_xray_host_port("") self.assertIsNone(result) def test_get_xray_host_port_invalid_value(self): - result = get_xray_host_port("myVar") + result = sock._get_xray_host_port("myVar") self.assertIsNone(result) def test_get_xray_host_port_success(self): - result = get_xray_host_port("mySuperHost:1000") + result = sock._get_xray_host_port("mySuperHost:1000") self.assertEqual("mySuperHost", result[0]) self.assertEqual(1000, result[1]) + def test_send_segment_sampled_out(self): + os.environ["AWS_XRAY_DAEMON_ADDRESS"] = "fake-agent.com:8080" + os.environ[ + "_X_AMZN_TRACE_ID" + ] = "Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=0;Lineage=c6c5b1b9:0" + + with patch( + "datadog_lambda.xray.sock.send", MagicMock(return_value=None) + ) as mock_send: + # XRay trace won't be sampled according to the trace header. + send_segment("my_key", {"data": "value"}) + self.assertFalse(mock_send.called) + + def test_send_segment_sampled(self): + os.environ["AWS_XRAY_DAEMON_ADDRESS"] = "fake-agent.com:8080" + os.environ[ + "_X_AMZN_TRACE_ID" + ] = "Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1;Lineage=c6c5b1b9:0" + with patch( + "datadog_lambda.xray.sock.send", MagicMock(return_value=None) + ) as mock_send: + # X-Ray trace will be sampled according to the trace header. + send_segment("my_key", {"data": "value"}) + self.assertTrue(mock_send.called) + def test_build_segment_payload_ok(self): exected_text = '{"format": "json", "version": 1}\nmyPayload' self.assertEqual(exected_text, build_segment_payload("myPayload")) diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 000000000..2d56ca0c0 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,37 @@ +from unittest.mock import MagicMock + +function_arn = "arn:aws:lambda:us-west-1:123457598159:function:python-layer-test" + + +class ClientContext(object): + def __init__(self, custom=None): + self.custom = custom + + +def get_mock_context( + aws_request_id="request-id-1", + memory_limit_in_mb="256", + invoked_function_arn=function_arn, + function_version="1", + function_name="Function", + custom=None, +): + lambda_context = MagicMock() + lambda_context.aws_request_id = aws_request_id + lambda_context.memory_limit_in_mb = memory_limit_in_mb + lambda_context.invoked_function_arn = invoked_function_arn + lambda_context.function_version = function_version + lambda_context.function_name = function_name + lambda_context.get_remaining_time_in_millis = lambda: 100 + lambda_context.client_context = ClientContext(custom) + return lambda_context + + +def reset_xray_connection(): + from datadog_lambda.xray import sock + + if hasattr(sock, "_host_port_tuple"): + del sock._host_port_tuple + if sock.sock: + sock.sock.close() + sock.sock = None