diff --git a/.flake8 b/.flake8 index 51b50a046..179ca3012 100644 --- a/.flake8 +++ b/.flake8 @@ -1,2 +1,3 @@ [flake8] -max-line-length = 100 \ No newline at end of file +max-line-length = 100 +extend-ignore = E203,E701 \ No newline at end of file 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 97a4fbbe4..787b5da36 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: @@ -41,7 +43,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Checkout @@ -62,75 +64,4 @@ jobs: - name: Run tests run: | source venv/bin/activate - nose2 -v - - integration-test: - runs-on: ubuntu-latest - strategy: - matrix: - runtime-param: ['3.7', '3.8', '3.9', '3.10', '3.11'] - 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: 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@v3 - - 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..e21f16336 --- /dev/null +++ b/.github/workflows/build_layer.yml @@ -0,0 +1,46 @@ +name: Build Layers for system-Tests + +on: + workflow_dispatch: + pull_request: + push: + branches: + - "main" + +jobs: + build: + runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} + + strategy: + fail-fast: false + matrix: + arch: [arm64, amd64] + python_version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download ddtrace Wheel + id: find-ddtrace-wheel + run: | + # Convert matrix.arch into pip platform tag + if [ "${{ matrix.arch }}" = "amd64" ]; then + PLATFORM_TAG="manylinux_2_17_x86_64" + else + PLATFORM_TAG="manylinux_2_17_aarch64" + fi + + pip download --no-index --no-deps --find-links https://dd-trace-py-builds.s3.amazonaws.com/main/index.html --pre --python-version "${{ matrix.python_version}}" --platform "${PLATFORM_TAG}" ddtrace + echo "wheel_path=$(find . -name "*.whl" | head -n 1)" >> $GITHUB_OUTPUT + + - 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 }} DD_TRACE_WHEEL="${{ steps.find-ddtrace-wheel.outputs.wheel_path }}" ./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 c056d09bc..000000000 --- a/.github/workflows/check-size.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: check-size - -on: pull_request - -jobs: - check-size: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.7 - - - 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 - 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/system_tests.yml b/.github/workflows/system_tests.yml new file mode 100644 index 000000000..e0e829f0f --- /dev/null +++ b/.github/workflows/system_tests.yml @@ -0,0 +1,40 @@ +name: System Tests + +on: + push: + branches: + - main + pull_request: + branches: + - "**" + schedule: + - cron: '00 03 * * *' + +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 + permissions: + contents: read + id-token: write + with: + library: python_lambda + binaries_artifact: binaries + scenarios_groups: tracer_release + skip_empty_scenarios: ${{ github.event_name == 'pull_request' }} + push_to_test_optimization: true diff --git a/.github/workflows/update-snapshots.yml b/.github/workflows/update-snapshots.yml deleted file mode 100644 index ed7097aed..000000000 --- a/.github/workflows/update-snapshots.yml +++ /dev/null @@ -1,66 +0,0 @@ -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 deleted file mode 100644 index 31025402f..000000000 --- a/.github/workflows/update_deps.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: update-deps - -on: - schedule: - - cron: "0 10 * * *" # Run at 10 am every day - -jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.7 - - - name: Update Dependencies - run: | - curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python - - source $HOME/.poetry/env - poetry build - poetry update - - - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 - with: - commit-message: update dependencies - title: Update Dependencies - body: | - Autogenerated PR to update all deps to latest versions - branch: update-dependencies 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..417398ec4 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,34 @@ +variables: + SKIP_E2E_TESTS: "false" + +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 + forward: + pipeline_variables: true + rules: + - when: on_success \ No newline at end of file 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 656b109fc..1e112f81d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ARG image -FROM $image +FROM $image as builder ARG runtime @@ -7,15 +7,111 @@ 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; \ + rm c++ && ln -s gcc10-c++ c++; \ + 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 + +# Remove unsupported appsec modules +RUN rm -rf \ + ./python/lib/$runtime/site-packages/ddtrace/appsec/_iast \ + ./python/lib/$runtime/site-packages/ddtrace/appsec/sca \ + ./python/lib/$runtime/site-packages/ddtrace/appsec/_shared + +# CI Visibility paths/integrations +RUN rm -rf \ + ./python/lib/$runtime/site-packages/ddtrace/contrib/coverage/ \ + ./python/lib/$runtime/site-packages/ddtrace/contrib/pytest/ \ + ./python/lib/$runtime/site-packages/ddtrace/contrib/pytest_bdd/ \ + ./python/lib/$runtime/site-packages/ddtrace/contrib/pytest_benchmark/ \ + ./python/lib/$runtime/site-packages/ddtrace/contrib/selenium/ \ + ./python/lib/$runtime/site-packages/ddtrace/contrib/unittest/ \ + ./python/lib/$runtime/site-packages/ddtrace/ext/ci_visibility \ + ./python/lib/$runtime/site-packages/ddtrace/ext/test_visibility \ + ./python/lib/$runtime/site-packages/ddtrace/internal/ci_visibility \ + ./python/lib/$runtime/site-packages/ddtrace/internal/coverage \ + ./python/lib/$runtime/site-packages/ddtrace/internal/test_visibility \ + ./python/lib/$runtime/site-packages/ddtrace/testing/ + +# Dogshell +RUN rm -rf ./python/lib/$runtime/site-packages/datadog/dogshell +RUN rm -rf ./python/lib/$runtime/site-packages/bin/dog* + +# 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* \ + ./python/lib/$runtime/site-packages/*__mypyc*.so # from 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 +# DEV: ddtrace>=4.7.0rc3 checks for .pyc files in addition to .py files for instrumentation +# discovery (DataDog/dd-trace-py#17196), so we can safely remove all .py files. +# For older versions, we need to keep patch.py files for instrumentation discovery. +RUN pip install --quiet packaging && \ + DDTRACE_VERSION=$(grep "^Version:" ./python/lib/$runtime/site-packages/ddtrace-*.dist-info/METADATA | awk '{print $2}') && \ + if python -c "from packaging.version import Version; exit(0 if Version('$DDTRACE_VERSION') >= Version('4.7.0rc3') else 1)"; then \ + find ./python/lib/$runtime/site-packages -name \*.py | xargs rm -rf; \ + else \ + find ./python/lib/$runtime/site-packages -name \*.py | grep -v ddtrace/contrib | xargs rm -rf && \ + find ./python/lib/$runtime/site-packages/ddtrace/contrib -name \*.py | grep -v patch.py | xargs rm -rf; \ + fi +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 +RUN find ./python/lib/$runtime/site-packages/ddtrace -name \*.pyi -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 {} \; + +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 757c929d0..a1199e8eb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![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.7, 3.8, 3.9, 3.10, and 3.11) 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. +Datadog Lambda Library for Python (3.8, 3.9, 3.10, 3.11, 3.12, 3.13, and 3.14) 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 @@ -16,6 +16,22 @@ Follow the [installation instructions](https://docs.datadoghq.com/serverless/ins 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. +For additional tracing configuration options, check out the [official documentation for Datadog trace client](https://ddtrace.readthedocs.io/en/stable/configuration.html). + +Besides the environment variables supported by dd-trace-py, the datadog-lambda-python library added following environment variables. + +| 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` | + + ## Opening Issues 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. @@ -32,6 +48,12 @@ The Continuous Profiler works by spawning a thread which periodically wakes up a ## Major Version Notes +### 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. + +### 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. + ### 4.x / Layer version 61+ - 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. @@ -51,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..e33eb71eb --- /dev/null +++ b/ci/datasources/regions.yaml @@ -0,0 +1,35 @@ +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-east-2" + - 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-6" + - 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..2b19cf1c4 --- /dev/null +++ b/ci/datasources/runtimes.yaml @@ -0,0 +1,57 @@ +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" + - name: "python314" + python_version: "3.14" + arch: "amd64" + image: "3.14.0" + - name: "python314" + python_version: "3.14" + arch: "arm64" + image: "3.14.0" diff --git a/ci/get_secrets.sh b/ci/get_secrets.sh new file mode 100755 index 000000000..5beaf9ded --- /dev/null +++ b/ci/get_secrets.sh @@ -0,0 +1,102 @@ +#!/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. + +# Loads secrets for CI jobs from Vault (gitlab-runner path below). +# +# Full mode (default): requires EXTERNAL_ID_NAME, ROLE_TO_ASSUME, and AWS_ACCOUNT. +# Fetches the external ID and DD API key, then assumes the AWS deployer role. +# +# API-key-only mode: set GET_SECRETS_API_KEY_ONLY=1 when sourcing. +# Loads DD_API_KEY only (e.g. unit-test Test Optimization). Uses DD_API_KEY from +# the environment when set; otherwise reads from Vault. Installs the vault CLI +# on slim images that do not include it. + +set -e + +VAULT_SECRETS_PATH="kv/k8s/gitlab-runner/datadog-lambda-python/secrets" +VAULT_CLI_VERSION="${VAULT_CLI_VERSION:-1.18.5}" + +_ensure_vault_cli() { + command -v vault >/dev/null 2>&1 && return + + local arch install_dir + case "$(uname -m)" in + x86_64 | amd64) arch=amd64 ;; + aarch64 | arm64) arch=arm64 ;; + *) printf "[Error] Unsupported architecture: %s\n" "$(uname -m)" >&2; exit 1 ;; + esac + + install_dir="${TMPDIR:-/tmp}/vault-cli-${VAULT_CLI_VERSION}-${arch}" + if [ -x "${install_dir}/vault" ]; then + export PATH="${install_dir}:${PATH}" + return + fi + + apt-get update -qq && apt-get install -y -qq curl unzip + printf "Installing vault CLI %s (%s)...\n" "$VAULT_CLI_VERSION" "$arch" + mkdir -p "$install_dir" + curl -fsSL \ + "https://releases.hashicorp.com/vault/${VAULT_CLI_VERSION}/vault_${VAULT_CLI_VERSION}_linux_${arch}.zip" \ + -o "${install_dir}/vault.zip" + unzip -qo "${install_dir}/vault.zip" -d "$install_dir" + rm -f "${install_dir}/vault.zip" + export PATH="${install_dir}:${PATH}" +} + +_get_dd_api_key() { + if [ -n "${DD_API_KEY:-}" ]; then + printf "Using DD_API_KEY from environment.\n" + else + printf "Getting DD API KEY...\n" + _ensure_vault_cli + DD_API_KEY=$(vault kv get -field=dd-api-key "$VAULT_SECRETS_PATH") + if [ -z "$DD_API_KEY" ]; then + printf "[Error] DD_API_KEY is empty after Vault lookup.\n" >&2 + return 1 2>/dev/null || exit 1 + fi + export DD_API_KEY + fi + + if [ -n "${GITLAB_ENV:-}" ]; then + echo "DD_API_KEY=${DD_API_KEY}" >>"$GITLAB_ENV" + fi +} + +if [ -n "${GET_SECRETS_API_KEY_ONLY:-}" ]; then + _get_dd_api_key + return 0 2>/dev/null || exit 0 +fi + +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 + +_ensure_vault_cli + +printf "Getting AWS External ID...\n" + +EXTERNAL_ID=$(vault kv get -field="$EXTERNAL_ID_NAME" "$VAULT_SECRETS_PATH") + +_get_dd_api_key + +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..1dc0df62c --- /dev/null +++ b/ci/input_files/build.yaml.tpl @@ -0,0 +1,297 @@ +{{- $e2e_region := "us-west-2" -}} + +stages: + - build + - test + - sign + - publish + - e2e + +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 + timeout: 15m + retry: 2 + +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_VERSION={{ $runtime.python_version }} ARCH={{ $runtime.arch }} IS_LINT="1" ./scripts/setup_python_env.sh + script: + - source venv/bin/activate + - ./scripts/check_format.sh + +unit-test ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: test + tags: + {{ if eq $runtime.arch "arm64" }} + - "arch:arm64" + {{ else }} + - "arch:amd64" + {{ end }} + image: registry.ddbuild.io/images/mirror/python:{{ $runtime.image }} + cache: &{{ $runtime.name }}-{{ $runtime.arch }}-cache + variables: + DD_CIVISIBILITY_AGENTLESS_ENABLED: "true" + DD_SERVICE: "datadog-lambda-python" + DD_ENV: "ci" + DD_TAGS: "python_version:{{ $runtime.python_version }},arch:{{ $runtime.arch }}" + before_script: + - GET_SECRETS_API_KEY_ONLY=1 source ./ci/get_secrets.sh + - PYTHON_VERSION={{ $runtime.python_version }} ARCH={{ $runtime.arch }} ./scripts/setup_python_env.sh + script: + - set -e + - source venv/bin/activate + - pytest -vv --ddtrace + retry: 2 + +integration-test ({{ $runtime.name }}-{{ $runtime.arch }}): + stage: test + tags: ["arch:amd64"] + image: registry.ddbuild.io/images/docker:20.10-py3 + rules: + - if: '$SKIP_E2E_TESTS == "true"' + when: never + - when: on_success + 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 + retry: 2 + +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: '$SKIP_E2E_TESTS == "true"' + when: never + - 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: + - ./scripts/setup_python_env.sh + 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 + rules: + - if: '$SKIP_E2E_TESTS == "true"' + when: never + - when: on_success + 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 + rules: + - if: '$SKIP_E2E_TESTS == "true"' + when: never + - when: on_success + script: + - ci/poll_e2e.sh diff --git a/ci/poll_e2e.sh b/ci/poll_e2e.sh new file mode 100755 index 000000000..3d56926a6 --- /dev/null +++ b/ci/poll_e2e.sh @@ -0,0 +1,38 @@ +curl -OL "binaries.ddbuild.io/dd-source/authanywhere/LATEST/authanywhere-linux-amd64" && mv "authanywhere-linux-amd64" /bin/authanywhere && chmod +x /bin/authanywhere + +BTI_CI_API_TOKEN=$(authanywhere --audience rapid-devex-ci) + +BTI_RESPONSE=$(curl --silent --request GET \ + --header "$BTI_CI_API_TOKEN" \ + --header "Content-Type: application/vnd.api+json" \ + "https://bti-ci-api.us1.ddbuild.io/internal/ci/gitlab/token?owner=DataDog&repository=datadog-lambda-python") + +GITLAB_TOKEN=$(echo "$BTI_RESPONSE" | jq -r '.token // empty') + +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_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 2 minutes..." + 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 2 minutes..." + fi + sleep 120 +done \ No newline at end of file diff --git a/ci/publish_layers.sh b/ci/publish_layers.sh new file mode 100755 index 000000000..d15931ac1 --- /dev/null +++ b/ci/publish_layers.sh @@ -0,0 +1,228 @@ +#!/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" + "python3.14" + "python3.14" +) +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" + "3.14-amd64" + "3.14-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_lambda_py-amd64-3.14.zip" + ".layers/datadog_lambda_py-arm64-3.14.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" + "Datadog-Python314" + "Datadog-Python314-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..4d5f08f3b --- /dev/null +++ b/ci/publish_pypi.sh @@ -0,0 +1,32 @@ +#!/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 +source venv/bin/activate +poetry publish --build --username __token__ --password $PYPI_TOKEN diff --git a/datadog_lambda/__init__.py b/datadog_lambda/__init__.py index 20b424432..059cead9e 100644 --- a/datadog_lambda/__init__.py +++ b/datadog_lambda/__init__.py @@ -1,17 +1,20 @@ -import os -import logging +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__) +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..88f2cbe27 100644 --- a/datadog_lambda/api.py +++ b/datadog_lambda/api.py @@ -1,13 +1,24 @@ -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" +SSM_FIPS_SUPPORTED_REGIONS = { + "us-east-1", + "us-east-2", + "us-west-1", + "us-west-2", + "ca-central-1", + "ca-west-1", +} +api_key = None def decrypt_kms_api_key(kms_client, ciphertext): + import base64 + from botocore.exceptions import ClientError """ @@ -26,7 +37,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 +50,96 @@ 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 = None + if config.fips_mode_enabled: + if LAMBDA_REGION in SSM_FIPS_SUPPORTED_REGIONS: + fips_endpoint = f"https://ssm-fips.{LAMBDA_REGION}.amazonaws.com" + else: + # Log warning if SSM FIPS endpoint is not supported for commercial region + if not config.is_gov_region: + logger.warning( + "FIPS mode is enabled, but '%s' does not support SSM FIPS endpoints. " + "Using standard SSM endpoint.", + LAMBDA_REGION, + ) + 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 +151,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..29648021a --- /dev/null +++ b/datadog_lambda/asm.py @@ -0,0 +1,253 @@ +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, blocked.get("block_id", "default") + ) + + 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 0a3ba34d1..260d491b8 100644 --- a/datadog_lambda/cold_start.py +++ b/datadog_lambda/cold_start.py @@ -1,13 +1,15 @@ import time -import os 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(init_timestamp_ns): @@ -18,6 +20,7 @@ def set_cold_start(init_timestamp_ns): global _cold_start global _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: @@ -29,6 +32,7 @@ def set_cold_start(init_timestamp_ns): _cold_start = False _proactive_initialization = False _lambda_container_initialized = True + from ddtrace.trace import tracer as _tracer def is_cold_start(): @@ -47,12 +51,29 @@ def is_new_sandbox(): 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:{}".format(str(is_proactive_init()).lower()) + return ( + "proactive_initialization:true" + if _proactive_initialization + else "proactive_initialization:false" + ) + + +def is_managed_instances_mode(): + """ + Checks if the Lambda function is running in managed instances mode. + In managed instances mode, we should not create cold start tracing spans + as the gap between the sandbox initialization and the first + invocation might not be be a great experience. + + Returns: + bool: True if running in managed instances mode, False otherwise + """ + return config.aws_lambda_initialization_type == "lambda-managed-instances" class ImportNode(object): @@ -62,6 +83,9 @@ def __init__(self, module_name, full_file_path, start_time_ns, end_time_ns=None) 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] = [] @@ -70,22 +94,18 @@ def __init__(self, module_name, full_file_path, start_time_ns, end_time_ns=None) def reset_node_stacks(): - global root_nodes - root_nodes = [] - global import_stack - import_stack = [] + root_nodes.clear() + import_stack.clear() def push_node(module_name, file_path): node = ImportNode(module_name, file_path, time.time_ns()) - global import_stack if import_stack: import_stack[-1].children.append(node) import_stack.append(node) def pop_node(module_name): - global import_stack if not import_stack: return node = import_stack.pop() @@ -94,7 +114,6 @@ def pop_node(module_name): 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 - global root_nodes root_nodes.append(node) @@ -139,19 +158,18 @@ def wrapped_find_spec(*args, **kwargs): def initialize_cold_start_tracing(): - if ( - is_new_sandbox() - and os.environ.get("DD_TRACE_ENABLED", "true").lower() == "true" - and os.environ.get("DD_COLD_START_TRACING", "true").lower() == "true" - ): - from sys import version_info, meta_path + # Skip cold start tracing initialization in managed instances mode + if is_managed_instances_mode(): + return - if version_info >= (3, 7): # current implementation only support version > 3.7 - for importer in meta_path: - try: - importer.find_spec = wrap_find_spec(importer.find_spec) - except Exception: - pass + 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): @@ -184,12 +202,14 @@ def trace(self, root_nodes: List[ImportNode] = root_nodes): cold_start_span = self.create_cold_start_span(cold_start_span_start_time_ns) while root_nodes: root_node = root_nodes.pop() - self.trace_tree(root_node, cold_start_span) + 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 ( - import_node.end_time_ns - import_node.start_time_ns + 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 ): diff --git a/datadog_lambda/config.py b/datadog_lambda/config.py new file mode 100644 index 000000000..b92c37ee4 --- /dev/null +++ b/datadog_lambda/config.py @@ -0,0 +1,168 @@ +# 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") + + aws_service_representation_enabled = _get_env( + "DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED", "true", as_bool + ) + remove_integration_service_names_enabled = _get_env( + "DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED", "false", as_bool + ) + + 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") + aws_lambda_initialization_type = _get_env("AWS_LAMBDA_INITIALIZATION_TYPE") + + @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", + ) + +# Remote configuration relies on /dev/shm which is unavailable in Lambda. +# Disable it before ddtrace loads to avoid the shared-memory warning. +if "DD_REMOTE_CONFIGURATION_ENABLED" not in os.environ: + os.environ["DD_REMOTE_CONFIGURATION_ENABLED"] = "false" + +# disable css to prevent double counting in lambda +os.environ["DD_TRACE_STATS_COMPUTATION_ENABLED"] = "false" + +# unset css aliases to ensure it is disabled +if "DD_TRACE_COMPUTE_STATS" in os.environ: + del os.environ["DD_TRACE_COMPUTE_STATS"] + +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 fd8afb3ed..6ab627384 100644 --- a/datadog_lambda/constants.py +++ b/datadog_lambda/constants.py @@ -3,9 +3,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -# Datadog trace sampling priority - +# Datadog trace sampling priority class SamplingPriority(object): USER_REJECT = -1 AUTO_REJECT = 0 @@ -18,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 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/durable.py b/datadog_lambda/durable.py new file mode 100644 index 000000000..35bf87c38 --- /dev/null +++ b/datadog_lambda/durable.py @@ -0,0 +1,126 @@ +# 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 re +import ujson as json + +logger = logging.getLogger(__name__) + +_TRACE_CHECKPOINT_PREFIX = "_datadog_" + + +def _parse_durable_execution_arn(arn): + """ + Parses a DurableExecutionArn to extract execution name and ID. + ARN format: + arn:aws:lambda:{region}:{account}:function:{func}:{version}/durable-execution/{name}/{id} + Returns (execution_name, execution_id) or None if parsing fails. + """ + match = re.search(r"/durable-execution/([^/]+)/([^/]+)$", arn) + if not match: + return None + execution_name, execution_id = match.group(1), match.group(2) + if not execution_name or not execution_id: + return None + return execution_name, execution_id + + +def extract_durable_function_tags(event): + """ + Extracts durable function tags from the Lambda event payload. + Returns a dict with durable function tags, or an empty dict if the event + is not a durable function invocation. + """ + if not isinstance(event, dict): + return {} + + durable_execution_arn = event.get("DurableExecutionArn") + if not isinstance(durable_execution_arn, str): + return {} + + parsed = _parse_durable_execution_arn(durable_execution_arn) + if not parsed: + logger.error("Failed to parse DurableExecutionArn: %s", durable_execution_arn) + return {} + execution_name, execution_id = parsed + # Use the number of operations to determine if it's the first invocation. This is + # what the durable execution SDK does to determine the replay status. + operations = event.get("InitialExecutionState", {}).get("Operations", []) + is_first_invocation = len(operations) == 1 + return { + "aws.durable.execution_name": execution_name, + "aws.durable.execution_id": execution_id, + "aws.durable.first_invocation": str(is_first_invocation).lower(), + } + + +VALID_DURABLE_STATUSES = {"SUCCEEDED", "FAILED", "PENDING"} + + +def _extract_context_from_durable_checkpoint(operation): + # Checkpoint data is written by the dd-trace-py in Datadog style + # (x-datadog-* headers). Extraction goes through the standard + # propagator.extract path, which honors DD_TRACE_PROPAGATION_STYLE_EXTRACT. + # The default extract list (datadog, tracecontext, baggage) already + # includes datadog. Customers who override the extract list MUST keep + # datadog in it. + if not isinstance(operation, dict): + return None + + step_details = operation.get("StepDetails") + if not isinstance(step_details, dict): + return None + + result = step_details.get("Result") + if isinstance(result, str): + try: + result = json.loads(result) + except Exception: + return None + + if not isinstance(result, dict): + return None + + from datadog_lambda.tracing import propagator + + return propagator.extract(result) + + +def extract_context_from_durable_execution(event): + operations = event.get("InitialExecutionState", {}).get("Operations") + if isinstance(operations, dict): + operations = list(operations.values()) + if not isinstance(operations, list) or not operations: + return None + + highest = -1 + best_operation = None + for operation in operations: + if not isinstance(operation, dict): + continue + name = operation.get("Name") + if not isinstance(name, str) or not name.startswith(_TRACE_CHECKPOINT_PREFIX): + continue + suffix = name[len(_TRACE_CHECKPOINT_PREFIX) :] + try: + number = int(suffix) + except (TypeError, ValueError): + continue + if number > highest: + highest = number + best_operation = operation + + return _extract_context_from_durable_checkpoint(best_operation) + + +def extract_durable_execution_status(response, event): + if not isinstance(event, dict) or "DurableExecutionArn" not in event: + return None + if not isinstance(response, dict): + return None + status = response.get("Status") + if status not in VALID_DURABLE_STATUSES: + return None + return status 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 ca23ed963..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" + + +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) + -if should_use_extension: +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,38 +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 + + 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 - if should_use_extension: 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 ) @@ -80,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): @@ -104,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, @@ -122,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) @@ -131,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 151801f62..67f6a14d7 100644 --- a/datadog_lambda/tag_object.py +++ b/datadog_lambda/tag_object.py @@ -4,21 +4,19 @@ # Copyright 2021 Datadog, Inc. from decimal import Decimal -import json -import logging +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: @@ -31,17 +29,17 @@ def tag_object(span, key, obj, depth=0): 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 hasattr(obj, "items"): for k, v in obj.items(): - formatted_key = "{}.{}".format(key, k) + 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 = "{}.{}".format(key, k) + formatted_key = f"{key}.{k}" tag_object(span, formatted_key, v, depth) return try: @@ -64,6 +62,6 @@ def _should_try_string(obj): def _redact_val(k, v): split_key = k.split(".").pop() or k - if split_key in redactable_keys: + if split_key.lower() in redactable_keys: return "redacted" return v 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 a9c223e30..5c094027a 100644 --- a/datadog_lambda/tracing.py +++ b/datadog_lambda/tracing.py @@ -2,11 +2,11 @@ # under the Apache License Version 2.0. # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -import hashlib import logging import os -import json -import base64 +import re +import traceback +import ujson as json from datetime import datetime, timezone from typing import Optional, Dict @@ -20,7 +20,6 @@ from datadog_lambda.constants import ( SamplingPriority, - TraceHeader, TraceContextSource, XrayDaemon, Headers, @@ -29,22 +28,26 @@ send_segment, parse_xray_header, ) -from ddtrace import tracer, patch, Span + +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, + resolve_multivalue_headers, ) +from datadog_lambda.durable import extract_context_from_durable_execution -dd_trace_otel_enabled = ( - os.environ.get("DD_TRACE_OTEL_ENABLED", "false").lower() == "true" -) -if dd_trace_otel_enabled: +if config.otel_enabled: from opentelemetry.trace import set_tracer_provider from ddtrace.opentelemetry import TracerProvider @@ -53,39 +56,56 @@ 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( @@ -93,19 +113,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.get("trace_id")), - "parent-id": _convert_xray_entity_id(xray_trace_entity.get("parent_id")), - "sampling-priority": _convert_xray_sampling(xray_trace_entity.get("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 @@ -115,26 +131,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( @@ -155,28 +166,14 @@ 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( @@ -196,33 +193,31 @@ def extract_context_from_http_event_or_context( EventTypes.API_GATEWAY, subtype=EventSubtypes.HTTP_API ) injected_authorizer_data = get_injected_authorizer_data(event, is_http_api) - if injected_authorizer_data: - try: - # fail fast on any KeyError here - trace_id = injected_authorizer_data[TraceHeader.TRACE_ID] - parent_id = injected_authorizer_data[TraceHeader.PARENT_ID] - sampling_priority = injected_authorizer_data.get( - TraceHeader.SAMPLING_PRIORITY - ) - return trace_id, parent_id, sampling_priority - except Exception as e: - logger.debug( - "extract_context_from_authorizer_event returned with error. \ - Continue without injecting the authorizer span %s", - e, - ) - - headers = event.get("headers", {}) or {} - lowercase_headers = {k.lower(): v for k, v in headers.items()} + 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 = resolve_multivalue_headers(event) + 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_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): @@ -237,7 +232,9 @@ def create_sns_event(message): } -def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): +def extract_context_from_sqs_or_sns_event_or_context( + event, lambda_context, event_source +): """ Extract Datadog trace context from an SQS event. @@ -249,66 +246,103 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): 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: - ( - trace_id, - parent_id, - sampling_priority, - ) = _extract_context_from_eventbridge_sqs_event(event) - 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", {}) + 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: - first_record = event.get("Records")[0] pass - msg_attributes = first_record.get( - "messageAttributes", - first_record.get("Sns", {}).get("MessageAttributes", {}), - ) - dd_payload = msg_attributes.get("_datadog", {}) - # SQS uses dataType and binaryValue/stringValue - # SNS uses Type and Value - dd_json_data_type = dd_payload.get("Type", dd_payload.get("dataType", "")) - if dd_json_data_type == "Binary": - dd_json_data = dd_payload.get( - "binaryValue", - dd_payload.get("Value", r"{}"), - ) - dd_json_data = base64.b64decode(dd_json_data) - elif dd_json_data_type == "String": - dd_json_data = dd_payload.get( - "stringValue", - dd_payload.get("Value", r"{}"), - ) - else: - logger.debug( - "Datadog Lambda Python only supports extracting trace" - "context from String or Binary SQS/SNS message attributes" - ) - 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) + 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" + ) - return trace_id, parent_id, sampling_priority + 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) @@ -320,36 +354,45 @@ def _extract_context_from_eventbridge_sqs_event(event): This is only possible if first record in `Records` contains a `body` field which contains the EventBridge `detail` as a JSON string. """ - try: - first_record = event.get("Records")[0] - if "body" in first_record: - body_str = first_record.get("body", {}) - body = json.loads(body_str) + 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") - detail = body.get("detail") - dd_context = detail.get("_datadog") - trace_id = dd_context.get(TraceHeader.TRACE_ID) - parent_id = dd_context.get(TraceHeader.PARENT_ID) - sampling_priority = dd_context.get(TraceHeader.SAMPLING_PRIORITY) - return trace_id, parent_id, sampling_priority - except Exception: - raise + 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) - trace_id = dd_context.get(TraceHeader.TRACE_ID) - parent_id = dd_context.get(TraceHeader.PARENT_ID) - sampling_priority = dd_context.get(TraceHeader.SAMPLING_PRIORITY) - return trace_id, parent_id, sampling_priority + + 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) @@ -358,57 +401,164 @@ def extract_context_from_eventbridge_event(event, 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) - data = record.get("kinesis", {}).get("data", None) + 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 not dd_ctx: - return extract_context_from_lambda_context(lambda_context) - - trace_id = dd_ctx.get(TraceHeader.TRACE_ID) - parent_id = dd_ctx.get(TraceHeader.PARENT_ID) - sampling_priority = dd_ctx.get(TraceHeader.SAMPLING_PRIORITY) - return trace_id, parent_id, sampling_priority + 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) - return extract_context_from_lambda_context(lambda_context) + # 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_md5_hash(s: str) -> str: - """MD5 here is to generate trace_id, not for any encryption.""" - hex_number = hashlib.md5(s.encode("ascii")).hexdigest() - binary = bin(int(hex_number, 16)) - binary_str = str(binary) - binary_str_remove_0b = binary_str[2:].rjust(128, "0") - most_significant_64_bits_without_leading_1 = "0" + binary_str_remove_0b[1:-64] - result = str(int(most_significant_64_bits_without_leading_1, 2)) - if result == "0" * 64: - return "1" +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 _extract_dd_trace_id_from_dd_data(dd_data, meta): + """ + Read native Datadog trace headers from a `_datadog` dict. + Returns the 64-bit trace_id and populates meta["_dd.p.tid"] when present. + Returns None if no usable trace id is found. + """ + if not dd_data or "x-datadog-trace-id" not in dd_data: + return None + trace_id = int(dd_data.get("x-datadog-trace-id")) + high_64_bit_trace_id = _parse_high_64_bits(dd_data.get("x-datadog-tags")) + if high_64_bit_trace_id: + meta["_dd.p.tid"] = high_64_bit_trace_id + return trace_id + + +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. + 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: - execution_id = event.get("Execution").get("Id") - state_name = event.get("State").get("Name") - state_entered_time = event.get("State").get("EnteredTime") - trace_id = _deterministic_md5_hash(execution_id) - parent_id = _deterministic_md5_hash( - execution_id + "#" + state_name + "#" + state_entered_time - ) + 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 = _extract_dd_trace_id_from_dd_data(event, meta) + 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 = event.get("Execution", {}) + dd_input = execution.get("Input", {}).get("_datadog") + trace_id = _extract_dd_trace_id_from_dd_data(dd_input, meta) + if trace_id is None: + execution_id = 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 trace_id, parent_id, sampling_priority + 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) @@ -419,17 +569,15 @@ 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: @@ -447,19 +595,26 @@ def is_authorizer_response(response) -> bool: def get_injected_authorizer_data(event, is_http_api) -> dict: try: - authorizer_headers = event.get("requestContext", {}).get("authorizer") + req_ctx = event.get("requestContext") + if not req_ctx: + return None + authorizer_headers = req_ctx.get("authorizer") if not authorizer_headers: return None - dd_data_raw = ( - authorizer_headers.get("lambda", {}).get("_datadog") - if is_http_api - else authorizer_headers.get("_datadog") - ) + 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 @@ -469,16 +624,19 @@ def get_injected_authorizer_data(event, is_http_api) -> dict: # 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 or event.get( - "requestContext", {} - ).get("requestId") == injected_data.get(Headers.Authorizing_Request_Id): + if authorizer_headers.get("integrationLatency", 0) > 0: return injected_data - else: + 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) - return None def extract_dd_trace_context( @@ -493,58 +651,38 @@ def extract_dd_trace_context( global dd_trace_context trace_context_source = None event_source = parse_event_source(event) + context = None if extractor is not None: - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_custom_extractor(extractor, event, lambda_context) - elif isinstance(event, (set, dict)) and "headers" in event: - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_from_http_event_or_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 or "multiValueHeaders" 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): - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_from_sqs_or_sns_event_or_context(event, lambda_context) + context = extract_context_from_sqs_or_sns_event_or_context( + event, lambda_context, event_source + ) elif event_source.equals(EventTypes.EVENTBRIDGE): - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_from_eventbridge_event(event, lambda_context) + context = extract_context_from_eventbridge_event(event, lambda_context) elif event_source.equals(EventTypes.KINESIS): - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_from_kinesis_event(event, lambda_context) + context = extract_context_from_kinesis_event(event, lambda_context) elif event_source.equals(EventTypes.STEPFUNCTIONS): - ( - trace_id, - parent_id, - sampling_priority, - ) = extract_context_from_step_functions(event, lambda_context) + context = extract_context_from_step_functions(event, lambda_context) + elif isinstance(event, dict) and "DurableExecutionArn" in event: + context = extract_context_from_durable_execution(event) else: - trace_id, parent_id, sampling_priority = extract_context_from_lambda_context( - lambda_context - ) + 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, @@ -556,7 +694,7 @@ def extract_dd_trace_context( 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. @@ -568,31 +706,45 @@ def get_dd_trace_context(): automatically, but this function can be used to manually inject the trace context to an outgoing request. """ - if dd_tracing_enabled: + if config.trace_enabled: dd_trace_py_context = _get_dd_trace_py_context() - if dd_trace_py_context is not None: - return _context_obj_to_headers(dd_trace_py_context) - - global dd_trace_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 {} + return None + + if not _is_context_complete(dd_trace_context): + return xray_context - if not dd_trace_context: - return _context_obj_to_headers(xray_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(), + ) - context = dd_trace_context.copy() - context["parent-id"] = xray_context.get("parent-id") - logger.debug("Set parent id from xray trace context: %s", context.get("parent-id")) - return _context_obj_to_headers(context) +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(): @@ -603,21 +755,19 @@ def set_correlation_ids(): 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() - if not context: + context = get_dd_trace_context_obj() + if not _is_context_complete(context): return - span = tracer.trace("dummy.span") - span.trace_id = int(context[TraceHeader.TRACE_ID]) - span.span_id = int(context[TraceHeader.PARENT_ID]) - + tracer.context_provider.activate(context) + tracer.trace("dummy.span") logger.debug("correlation ids set") @@ -632,9 +782,8 @@ def inject_correlation_ids(): # 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( @@ -650,28 +799,25 @@ 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.get("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: %s", - (span_context.trace_id, span_context.span_id), + "Set dd trace root context to: trace_id=%s span_id=%s", + context.trace_id, + context.span_id, ) @@ -694,6 +840,9 @@ def create_inferred_span( 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.event_type == EventTypes.ALB: + logger.debug("ALB event detected. Inferring a span") + return create_inferred_span_from_alb_event(event, context) elif event_source.equals( EventTypes.API_GATEWAY, subtype=EventSubtypes.HTTP_API ): @@ -732,9 +881,7 @@ def create_inferred_span( event_source.to_string(), e, ) - return None logger.debug("Unable to infer a span: unknown event type") - return None def create_service_mapping(val): @@ -749,55 +896,124 @@ def create_service_mapping(val): return new_service_mapping -def determine_service_name(service_mapping, specific_key, generic_key, default_value): - service_name = service_mapping.get(specific_key) - if service_name is None: - service_name = service_mapping.get(generic_key, default_value) - return service_name +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 + + # When integration service names are removed, inferred (synthetic) spans use + # the base service name (DD_SERVICE) instead of the AWS resource/instance + # representation. + if config.remove_integration_service_names_enabled and config.service: + return config.service + + # Check if AWS service representation is disabled + if not config.aws_service_representation_enabled: + 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 + ) -service_mapping = {} # Initialization code -service_mapping_str = os.getenv("DD_SERVICE_MAPPING", "") +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) - method = request_context.get("http", {}).get("method") - path = request_context.get("http", {}).get("path") - resource = "{0} {1}".format(method, path) + 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": domain + path, + "http.url": http_url, "endpoint": path, "http.method": method, - "resource_names": domain + path, + "resource_names": resource, "request_id": context.aws_request_id, } request_time_epoch = request_context.get("timeEpoch") - args = { - "service": service_name, - "resource": resource, - "span_type": "http", - } - tracer.set_tags( - {"_dd.origin": "lambda"} - ) # function urls don't count as lambda_inferred, + 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", **args) + 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 = request_time_epoch / 1000 + span.set_metric(InferredSpanInfo.METRIC, 1.0) + span.start_ns = int(request_time_epoch * 1e6) + return span + + +def create_inferred_span_from_alb_event(event, context): + request_context = event.get("requestContext") or {} + elb = request_context.get("elb") or {} + target_group_arn = elb.get("targetGroupArn") + + headers = resolve_multivalue_headers(event) + host = headers.get("host") + method = event.get("httpMethod") + path = event.get("path") + proto = headers.get("x-forwarded-proto", "http") + + # ALB has no api id; key the service mapping off the load-balancer host and + # fall back to it when DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED is on. + service_name = determine_service_name(service_mapping, host, "lambda_alb", host) + + http_url = "%s://%s%s" % (proto, host, path) if host and path is not None else None + if method and path is not None: + resource = f"{method} {path}" + else: + resource = method or path + + tags = { + "operation_name": "aws.alb", + "span.kind": "server", + "http.method": method, + "http.url": http_url, + "http.useragent": headers.get("user-agent"), + "endpoint": path, + "resource_names": resource, + "request_id": context.aws_request_id, + "target_group_arn": target_group_arn, + } + # Drop tags we couldn't derive so the span never carries malformed values. + tags = {key: value for key, value in tags.items() if value is not None} + + tracer.set_tags(_dd_origin) + # ALB events carry no request timestamp (unlike API GW requestTimeEpoch / + # Function URL timeEpoch), so the span starts at handler time. + span = tracer.trace( + "aws.alb", service=service_name, resource=resource, span_type="http" + ) + InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync") + if span: + span.set_tags(tags) + span.set_metric(InferredSpanInfo.METRIC, 1.0) return span def is_api_gateway_invocation_async(event): - return event.get("headers", {}).get("X-Amz-Invocation-Type") == "Event" + hdrs = event.get("headers") + if not hdrs: + return False + return hdrs.get("X-Amz-Invocation-Type") == "Event" def insert_upstream_authorizer_span( @@ -838,16 +1054,12 @@ def process_injected_data(event, request_time_epoch_ms, args, tags): 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 + integration_latency = int( + event["requestContext"]["authorizer"].get("integrationLatency", 0) + ) + finish_time_ns = max( + start_time_ns, (request_time_epoch_ms + integration_latency) * 1e6 + ) upstream_authorizer_span = insert_upstream_authorizer_span( args, tags, start_time_ns, finish_time_ns ) @@ -869,6 +1081,7 @@ def create_inferred_span_from_api_gateway_websocket_event( 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( @@ -876,9 +1089,10 @@ def create_inferred_span_from_api_gateway_websocket_event( ) tags = { "operation_name": "aws.apigateway.websocket", - "http.url": domain + endpoint, + "http.url": http_url, "endpoint": endpoint, "resource_names": endpoint, + "span.kind": "server", "apiid": api_id, "apiname": api_id, "stage": request_context.get("stage"), @@ -897,7 +1111,7 @@ def create_inferred_span_from_api_gateway_websocket_event( "resource": endpoint, "span_type": "web", } - tracer.set_tags({"_dd.origin": "lambda"}) + tracer.set_tags(_dd_origin) upstream_authorizer_span = None finish_time_ns = None if decode_authorizer_context: @@ -907,6 +1121,7 @@ def create_inferred_span_from_api_gateway_websocket_event( span = tracer.trace("aws.apigateway.websocket", **args) if span: span.set_tags(tags) + span.set_metric(InferredSpanInfo.METRIC, 1.0) span.start_ns = int( finish_time_ns if finish_time_ns is not None @@ -921,6 +1136,8 @@ def create_inferred_span_from_api_gateway_event( event, context, decode_authorizer_context: bool = True ): request_context = event.get("requestContext") + identity = request_context.get("identity") + domain = request_context.get("domainName", "") api_id = request_context.get("apiId") service_name = determine_service_name( @@ -928,13 +1145,16 @@ def create_inferred_span_from_api_gateway_event( ) method = event.get("httpMethod") path = event.get("path") - resource = "{0} {1}".format(method, 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": domain + path, + "http.url": http_url, "endpoint": path, "http.method": method, "resource_names": resource, + "http.useragent": identity.get("userAgent"), + "span.kind": "server", "apiid": api_id, "apiname": api_id, "stage": request_context.get("stage"), @@ -948,9 +1168,9 @@ def create_inferred_span_from_api_gateway_event( args = { "service": service_name, "resource": resource, - "span_type": "http", + "span_type": "web", } - tracer.set_tags({"_dd.origin": "lambda"}) + tracer.set_tags(_dd_origin) upstream_authorizer_span = None finish_time_ns = None if decode_authorizer_context: @@ -960,6 +1180,7 @@ def create_inferred_span_from_api_gateway_event( span = tracer.trace("aws.apigateway", **args) if span: span.set_tags(tags) + span.set_metric(InferredSpanInfo.METRIC, 1.0) # start time pushed by the inserted authorizer span span.start_ns = int( finish_time_ns @@ -971,6 +1192,16 @@ def create_inferred_span_from_api_gateway_event( 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 ): @@ -980,17 +1211,19 @@ def create_inferred_span_from_http_api_event( service_name = determine_service_name( service_mapping, api_id, "lambda_api_gateway", domain ) - method = request_context.get("http", {}).get("method") + http = request_context.get("http") or {} + method = http.get("method") path = event.get("rawPath") - resource = "{0} {1}".format(method, path) + 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": domain + path, - "http.method": request_context.get("http", {}).get("method"), - "http.protocol": request_context.get("http", {}).get("protocol"), - "http.source_ip": request_context.get("http", {}).get("sourceIp"), - "http.user_agent": request_context.get("http", {}).get("userAgent"), + "http.url": http_url, + "http.method": http.get("method"), + "http.protocol": http.get("protocol"), + "http.source_ip": http.get("sourceIp"), + "http.useragent": http.get("userAgent"), "resource_names": resource, "request_id": context.aws_request_id, "apiid": api_id, @@ -1002,12 +1235,7 @@ def create_inferred_span_from_http_api_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": "lambda"}) + 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) @@ -1015,9 +1243,12 @@ def create_inferred_span_from_http_api_event( inferred_span_start_ns = injected_authorizer_data.get( Headers.Parent_Span_Finish_Time ) - span = tracer.trace("aws.httpapi", **args) + span = tracer.trace( + "aws.httpapi", service=service_name, resource=resource, span_type="web" + ) if span: span.set_tags(tags) + span.set_metric(InferredSpanInfo.METRIC, 1.0) span.start_ns = int(inferred_span_start_ns) return span @@ -1029,23 +1260,20 @@ def create_inferred_span_from_sqs_event(event, context): 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", "sqs" + 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": event_record.get("attributes", {}).get("SenderId"), + "sender_id": attrs.get("SenderId"), } InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") - request_time_epoch = event_record.get("attributes", {}).get("SentTimestamp") - args = { - "service": service_name, - "resource": queue_name, - "span_type": "web", - } + request_time_epoch = attrs.get("SentTimestamp") start_time = int(request_time_epoch) / 1000 upstream_span = None @@ -1074,17 +1302,20 @@ def create_inferred_span_from_sqs_event(event, context): except Exception as e: logger.debug( - "Unable to create upstream span from SQS message, with error %s" % e + "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": "lambda"}) - span = tracer.trace("aws.sqs", **args) + 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.set_metric(InferredSpanInfo.METRIC, 1.0) span.start = start_time if upstream_span: span.parent_id = upstream_span.span_id @@ -1094,15 +1325,16 @@ def create_inferred_span_from_sqs_event(event, context): def create_inferred_span_from_sns_event(event, context): event_record = get_first_record(event) - sns_message = event_record.get("Sns") - topic_arn = event_record.get("Sns", {}).get("TopicArn") + 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", "sns" + 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"), @@ -1110,23 +1342,22 @@ def create_inferred_span_from_sns_event(event, context): } # Subject not available in SNS => SQS scenario - if "Subject" in sns_message and sns_message["Subject"]: - tags["subject"] = sns_message.get("Subject") + 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 = event_record.get("Sns", {}).get("Timestamp") + timestamp = sns_message.get("Timestamp") dt = datetime.strptime(timestamp, sns_dt_format) - args = { - "service": service_name, - "resource": topic_name, - "span_type": "web", - } - tracer.set_tags({"_dd.origin": "lambda"}) - span = tracer.trace("aws.sns", **args) + 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.set_metric(InferredSpanInfo.METRIC, 1.0) span.start = dt.replace(tzinfo=timezone.utc).timestamp() return span @@ -1135,36 +1366,34 @@ 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 = event_source_arn.split(":")[-1] + 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", "kinesis" + 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": event_record.get("kinesis", {}).get("partitionKey"), + "partition_key": kinesis.get("partitionKey"), } InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async") - request_time_epoch = event_record.get("kinesis", {}).get( - "approximateArrivalTimestamp" - ) + request_time_epoch = kinesis.get("approximateArrivalTimestamp") - args = { - "service": service_name, - "resource": stream_name, - "span_type": "web", - } - tracer.set_tags({"_dd.origin": "lambda"}) - span = tracer.trace("aws.kinesis", **args) + 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.set_metric(InferredSpanInfo.METRIC, 1.0) span.start = request_time_epoch return span @@ -1174,12 +1403,13 @@ def create_inferred_span_from_dynamodb_event(event, context): 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", "dynamodb" + service_mapping, table_name, "lambda_dynamodb", table_name, "dynamodb" ) - dynamodb_message = event_record.get("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"), @@ -1189,18 +1419,14 @@ def create_inferred_span_from_dynamodb_event(event, context): "size_bytes": str(dynamodb_message.get("SizeBytes")), } InferredSpanInfo.set_tags(tags, synchronicity="async", tag_source="self") - request_time_epoch = event_record.get("dynamodb", {}).get( - "ApproximateCreationDateTime" + 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" ) - args = { - "service": service_name, - "resource": table_name, - "span_type": "web", - } - tracer.set_tags({"_dd.origin": "lambda"}) - span = tracer.trace("aws.dynamodb", **args) if span: span.set_tags(tags) + span.set_metric(InferredSpanInfo.METRIC, 1.0) span.start = int(request_time_epoch) return span @@ -1208,34 +1434,36 @@ def create_inferred_span_from_dynamodb_event(event, context): def create_inferred_span_from_s3_event(event, context): event_record = get_first_record(event) - bucket_name = event_record.get("s3", {}).get("bucket", {}).get("name") + 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", "s3" + 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": event_record.get("s3", {}).get("bucket", {}).get("arn"), - "object_key": event_record.get("s3", {}).get("object", {}).get("key"), - "object_size": str(event_record.get("s3", {}).get("object", {}).get("size")), - "object_etag": event_record.get("s3", {}).get("object", {}).get("eTag"), + "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) - args = { - "service": service_name, - "resource": bucket_name, - "span_type": "web", - } - tracer.set_tags({"_dd.origin": "lambda"}) - span = tracer.trace("aws.s3", **args) + 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.set_metric(InferredSpanInfo.METRIC, 1.0) span.start = dt.replace(tzinfo=timezone.utc).timestamp() return span @@ -1243,11 +1471,12 @@ def create_inferred_span_from_s3_event(event, context): def create_inferred_span_from_eventbridge_event(event, context): source = event.get("source") service_name = determine_service_name( - service_mapping, source, "lambda_eventbridge", "eventbridge" + 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( @@ -1255,20 +1484,33 @@ def create_inferred_span_from_eventbridge_event(event, context): synchronicity="async", tag_source="self", ) - dt_format = "%Y-%m-%dT%H:%M:%SZ" + 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) - args = { - "service": service_name, - "resource": source, - "span_type": "web", - } - tracer.set_tags({"_dd.origin": "lambda"}) - span = tracer.trace("aws.eventbridge", **args) + 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.set_metric(InferredSpanInfo.METRIC, 1.0) span.start = dt.replace(tzinfo=timezone.utc).timestamp() + + # Since inferred span will later parent Lambda, preserve Lambda's current parent + if dd_trace_context and getattr(dd_trace_context, "span_id", None): + span.parent_id = dd_trace_context.span_id + return span @@ -1280,43 +1522,70 @@ def create_function_execution_span( trace_context_source, merge_xray_traces, trigger_tags, + durable_function_tags=None, parent_span=None, + span_pointers=None, ): - tags = {} + tags = None if context: function_arn = (context.invoked_function_arn or "").lower() tk = function_arn.split(":") function_arn = ":".join(tk[0:7]) if len(tk) > 7 else function_arn function_version = tk[7] if len(tk) > 7 else "$LATEST" tags = { + "span.kind": "server", "cold_start": str(is_cold_start).lower(), "function_arn": function_arn, "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) + if durable_function_tags: + tags.update(durable_function_tags) + 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 @@ -1331,6 +1600,7 @@ class InferredSpanInfo(object): BASE_NAME = "_inferred_span" SYNCHRONICITY = f"{BASE_NAME}.synchronicity" TAG_SOURCE = f"{BASE_NAME}.tag_source" + METRIC = f"_dd.{BASE_NAME}" @staticmethod def set_tags( @@ -1368,3 +1638,34 @@ def is_async(span: Span) -> bool: 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 bbb44b30e..6958b9de7 100644 --- a/datadog_lambda/trigger.py +++ b/datadog_lambda/trigger.py @@ -3,9 +3,8 @@ # 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 @@ -55,6 +54,10 @@ class EventSubtypes(_stringTypedEnum): 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: """ @@ -110,15 +113,19 @@ def get_first_record(event): def parse_event_source(event: dict) -> _EventSource: """Determines the source of the trigger event""" - if type(event) is not dict: + if not isinstance(event, dict): return _EventSource(EventTypes.UNKNOWN) - event_source = _EventSource(EventTypes.UNKNOWN) + 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"): if "domainName" in request_context and detect_lambda_function_url_domain( - request_context.get("domainName") + request_context.get("domainName", "") ): return _EventSource(EventTypes.LAMBDA_FUNCTION_URL) event_source = _EventSource(EventTypes.API_GATEWAY) @@ -126,11 +133,16 @@ def parse_event_source(event: dict) -> _EventSource: event_source.subtype = EventSubtypes.API_GATEWAY if "routeKey" in event: event_source.subtype = EventSubtypes.HTTP_API - if event.get("requestContext", {}).get("messageDirection"): + if request_context.get("messageDirection"): event_source.subtype = EventSubtypes.WEBSOCKET if request_context and request_context.get("elb"): - event_source = _EventSource(EventTypes.ALB) + 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 = _EventSource(EventTypes.CLOUDWATCH_LOGS) @@ -146,15 +158,14 @@ def parse_event_source(event: dict) -> _EventSource: if event.get("source") == "aws.events" or has_event_categories: event_source = _EventSource(EventTypes.CLOUDWATCH_EVENTS) - if "Execution" in event and "StateMachine" in event and "State" in event: + if is_step_function_event(event): event_source = _EventSource(EventTypes.STEPFUNCTIONS) event_record = get_first_record(event) - if event_record: - aws_event_source = event_record.get( - "eventSource", event_record.get("EventSource") + 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": @@ -165,15 +176,16 @@ def parse_event_source(event: dict) -> _EventSource: event_source = _EventSource(EventTypes.SNS) if aws_event_source == "aws:sqs": event_source = _EventSource(EventTypes.SQS) - if event_record.get("cf"): event_source = _EventSource(EventTypes.CLOUDFRONT) - return event_source + return event_source or _EventSource(EventTypes.UNKNOWN) 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 @@ -193,20 +205,26 @@ def parse_event_source_arn(source: _EventSource, event: dict, context: Any) -> s event_record = get_first_record(event) # e.g. arn:aws:s3:::lambda-xyz123-abc890 if source.to_string() == "s3": - return event_record.get("s3", {}).get("bucket", {}).get("arn") + 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.to_string() == "sns": - return event_record.get("Sns", {}).get("TopicArn") + sns = event_record.get("Sns") + if sns: + return sns.get("TopicArn") + return None # e.g. arn:aws:cloudfront::123456789012:distribution/ABC123XYZ if source.event_type == EventTypes.CLOUDFRONT: distribution_id = ( event_record.get("cf", {}).get("config", {}).get("distributionId") ) - return "arn:{}:cloudfront::{}:distribution/{}".format( - aws_arn, account_id, distribution_id - ) + return f"arn:{aws_arn}:cloudfront::{account_id}:distribution/{distribution_id}" # e.g. arn:aws:lambda:::url:: if source.equals(EventTypes.LAMBDA_FUNCTION_URL): @@ -223,31 +241,42 @@ def parse_event_source_arn(source: _EventSource, event: dict, context: Any) -> s # e.g. arn:aws:apigateway:us-east-1::/restapis/xyz123/stages/default if source.event_type == EventTypes.API_GATEWAY: request_context = event.get("requestContext") - return "arn:{}:apigateway:{}::/restapis/{}/stages/{}".format( - aws_arn, region, request_context.get("apiId"), request_context.get("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.event_type == EventTypes.ALB: request_context = event.get("requestContext") - return request_context.get("elb", {}).get("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.event_type == EventTypes.CLOUDWATCH_LOGS: + import base64 + with gzip.GzipFile( 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.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: _EventSource, event: dict, context: Any) -> str: event_source_arn = event.get("eventSourceARN") or event.get("eventSourceArn") @@ -264,38 +293,117 @@ def get_event_source_arn(source: _EventSource, event: dict, context: Any) -> str return event_source_arn +def resolve_multivalue_headers(event): + """ + Resolve request headers from single-value ``headers`` or ``multiValueHeaders`` + (first value per key, matching datadog-lambda-js). + """ + headers = event.get("headers") + if isinstance(headers, dict) and headers: + return headers + + multi_value = event.get("multiValueHeaders") + if not isinstance(multi_value, dict): + return {} + + resolved = {} + for key, value in multi_value.items(): + if isinstance(value, list): + if value: + resolved[key] = value[0] + elif isinstance(value, str): + resolved[key] = value + return resolved + + +def _get_header_case_insensitive(headers, name): + if not isinstance(headers, dict): + return None + name_lower = name.lower() + for key, value in headers.items(): + if isinstance(key, str) and key.lower() == name_lower and value: + return value + return None + + 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.get("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") + elif request_context and request_context.get("elb"): + # ALB events have no requestContext.stage; derive the URL from the + # forwarded host/proto headers and the top-level path. + alb_headers = resolve_multivalue_headers(event) + host = alb_headers.get("host") + if host: + proto = alb_headers.get("x-forwarded-proto", "http") + http_tags["http.url"] = proto + "://" + host + + user_agent = alb_headers.get("user-agent") + if user_agent: + http_tags["http.useragent"] = user_agent + + # ALB carries no route template, so use the request path as the route. + if path: + http_tags["http.route"] = path + 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") - if headers and headers.get("Referer"): - http_tags["http.referer"] = headers.get("Referer") + referer = _get_header_case_insensitive(resolve_multivalue_headers(event), "referer") + if referer: + http_tags["http.referer"] = 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 +_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 @@ -309,16 +417,15 @@ def extract_trigger_tags(event: dict, context: Any) -> dict: if event_source_arn: trigger_tags["function_trigger.event_source_arn"] = event_source_arn - if event_source.event_type in [ - EventTypes.API_GATEWAY, - EventTypes.ALB, - EventTypes.LAMBDA_FUNCTION_URL, - ]: + 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, Lambda Function URL, or ALB, @@ -329,15 +436,7 @@ def extract_http_status_code_tag(trigger_tags, response): 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. - str_http_triggers = [ - et.value - for et in [ - EventTypes.API_GATEWAY, - EventTypes.LAMBDA_FUNCTION_URL, - EventTypes.ALB, - ] - ] - if str_event_source not in str_http_triggers: + if str_event_source not in _str_http_triggers: return status_code = "200" @@ -350,3 +449,31 @@ 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) + if not isinstance(event, dict): + return False + + # 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..5318d6c0e --- /dev/null +++ b/datadog_lambda/version.py @@ -0,0 +1 @@ +__version__ = "8.128.0.dev0" diff --git a/datadog_lambda/wrapper.py b/datadog_lambda/wrapper.py index f9675c689..730579833 100644 --- a/datadog_lambda/wrapper.py +++ b/datadog_lambda/wrapper.py @@ -2,12 +2,11 @@ # under the Apache License Version 2.0. # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -import base64 import os import logging import traceback +import ujson as json from importlib import import_module -import json from time import time_ns from datadog_lambda.extension import should_use_extension, flush_extension @@ -16,26 +15,22 @@ is_cold_start, is_proactive_init, is_new_sandbox, + is_managed_instances_mode, ColdStartTracer, ) +from datadog_lambda.config import config from datadog_lambda.constants import ( TraceContextSource, XraySubsegment, Headers, - TraceHeader, -) -from datadog_lambda.metric import ( - flush_stats, - submit_invocations_metric, - submit_errors_metric, ) 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, @@ -44,39 +39,54 @@ InferredSpanInfo, is_authorizer_response, tracer, + propagator, +) +from datadog_lambda.durable import ( + extract_durable_function_tags, + extract_durable_execution_status, ) from datadog_lambda.trigger import ( extract_trigger_tags, extract_http_status_code_tag, ) -from datadog_lambda.tag_object import tag_object - -profiling_env_var = os.environ.get("DD_PROFILING_ENABLED", "false").lower() == "true" -if profiling_env_var: - from ddtrace.profiling import profiler logger = logging.getLogger(__name__) -dd_capture_lambda_payload_enabled = ( - os.environ.get("DD_CAPTURE_LAMBDA_PAYLOAD", "false").lower() == "true" -) +# 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() + +profiler = None +if config.profiling_enabled: + try: + from ddtrace.profiling import profiler + except Exception as e: + logger.error(f"Failed to initialize profiler: [{e.__class__.__name__})] {e}") + +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 -DD_FLUSH_TO_LOG = "DD_FLUSH_TO_LOG" -DD_LOGS_INJECTION = "DD_LOGS_INJECTION" -DD_MERGE_XRAY_TRACES = "DD_MERGE_XRAY_TRACES" -AWS_LAMBDA_FUNCTION_NAME = "AWS_LAMBDA_FUNCTION_NAME" -DD_TRACE_EXTRACTOR = "DD_TRACE_EXTRACTOR" -DD_TRACE_MANAGED_SERVICES = "DD_TRACE_MANAGED_SERVICES" -DD_ENCODE_AUTHORIZER_CONTEXT = "DD_ENCODE_AUTHORIZER_CONTEXT" -DD_DECODE_AUTHORIZER_CONTEXT = "DD_DECODE_AUTHORIZER_CONTEXT" -DD_COLD_START_TRACING = "DD_COLD_START_TRACING" -DD_MIN_COLD_START_DURATION = "DD_MIN_COLD_START_DURATION" -DD_COLD_START_TRACE_SKIP_LIB = "DD_COLD_START_TRACE_SKIP_LIB" DD_REQUESTS_SERVICE_NAME = "DD_REQUESTS_SERVICE_NAME" DD_SERVICE = "DD_SERVICE" -DD_ENV = "DD_ENV" - -env_env_var = os.environ.get(DD_ENV, None) init_timestamp_ns = time_ns() @@ -133,66 +143,25 @@ 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.service = os.environ.get(DD_SERVICE, None) - self.extractor_env = os.environ.get(DD_TRACE_EXTRACTOR, None) self.trace_extractor = None self.span = None self.inferred_span = None - depends_on_dd_tracing_enabled = ( - lambda original_boolean: dd_tracing_enabled and original_boolean - ) - self.make_inferred_span = depends_on_dd_tracing_enabled( - os.environ.get(DD_TRACE_MANAGED_SERVICES, "true").lower() == "true" - ) - self.encode_authorizer_context = depends_on_dd_tracing_enabled( - os.environ.get(DD_ENCODE_AUTHORIZER_CONTEXT, "true").lower() == "true" - ) - self.decode_authorizer_context = depends_on_dd_tracing_enabled( - os.environ.get(DD_DECODE_AUTHORIZER_CONTEXT, "true").lower() == "true" - ) - self.cold_start_tracing = depends_on_dd_tracing_enabled( - os.environ.get(DD_COLD_START_TRACING, "true").lower() == "true" - ) - self.min_cold_start_trace_duration = 3 - if DD_MIN_COLD_START_DURATION in os.environ: - try: - self.min_cold_start_trace_duration = int( - os.environ[DD_MIN_COLD_START_DURATION] - ) - except Exception: - logger.debug(f"Malformatted env {DD_MIN_COLD_START_DURATION}") - self.cold_start_trace_skip_lib = [ - "ddtrace.internal.compat", - "ddtrace.filters", - ] - if DD_COLD_START_TRACE_SKIP_LIB in os.environ: - try: - self.cold_start_trace_skip_lib = os.environ[ - DD_COLD_START_TRACE_SKIP_LIB - ].split(",") - except Exception: - logger.debug(f"Malformatted for env {DD_COLD_START_TRACE_SKIP_LIB}") self.response = None - if profiling_env_var: - self.prof = profiler.Profiler(env=env_env_var, service=self.service) - if self.extractor_env: - extractor_parts = self.extractor_env.rsplit(".", 1) + self.blocking_response = None + + if config.profiling_enabled and profiler: + 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 + mod_name, extractor_name = extractor_parts modified_extractor_name = modify_module_name(mod_name) extractor_module = import_module(modified_extractor_name) 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 @@ -200,8 +169,15 @@ def __init__(self, func): 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 as e: @@ -211,15 +187,25 @@ 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 Exception: + from datadog_lambda.metric import submit_errors_metric + submit_errors_metric(context) + if self.span: self.span.set_traceback() raise + except BaseException as e: + if "BlockingException" in type(e).__name__: + self.blocking_response = get_asm_blocked_response(self.event_source) finally: self._after(event, context) + if self.blocking_response: + return self.blocking_response + return self.response def _inject_authorizer_span_headers(self, request_id): reference_span = self.inferred_span if self.inferred_span else self.span @@ -236,98 +222,164 @@ def _inject_authorizer_span_headers(self, request_id): injected_headers = {} source_span = self.inferred_span if self.inferred_span else self.span span_context = source_span.context - injected_headers[TraceHeader.TRACE_ID] = str(span_context.trace_id) - injected_headers[TraceHeader.PARENT_ID] = str(span_context.span_id) - sampling_priority = span_context.sampling_priority - if sampling_priority is not None: - injected_headers[TraceHeader.SAMPLING_PRIORITY] = str( - span_context.sampling_priority - ) + 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 - datadog_data = base64.b64encode(json.dumps(injected_headers).encode()).decode() + + 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: self.response = None + self.blocking_response = None set_cold_start(init_timestamp_ns) - submit_invocations_metric(context) + + 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) + self.durable_function_tags = extract_durable_function_tags(event) # Extract Datadog trace context and source from incoming requests dd_context, trace_context_source, event_source = extract_dd_trace_context( event, context, extractor=self.trace_extractor, - decode_authorizer_context=self.decode_authorizer_context, + 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 self.make_inferred_span: + 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, self.decode_authorizer_context + 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(), - is_proactive_init(), - 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, + durable_function_tags=self.durable_function_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 profiling_env_var and is_new_sandbox(): - self.prof.start(stop_on_exit=False, profile_children=True) + if config.profiling_enabled and profiler and is_new_sandbox(): + self.prof.start() logger.debug("datadog_lambda_wrapper _before() done") 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 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 - ) + # Skip creating cold start spans in managed instances mode + # In managed instances, the tracer library handles cold start independently should_trace_cold_start = ( - dd_tracing_enabled and self.cold_start_tracing and is_new_sandbox() + config.cold_start_tracing + and is_new_sandbox() + and not is_managed_instances_mode() ) if should_trace_cold_start: trace_ctx = tracer.current_trace_context() if self.span: - if dd_capture_lambda_payload_enabled: + 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) + + durable_status = extract_durable_execution_status(self.response, event) + if durable_status: + self.span.set_tag( + "aws.durable.execution_status", + durable_status, + ) + 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 + ) + if self.inferred_span: if status_code: self.inferred_span.set_tag("http.status_code", status_code) - if self.service: - self.inferred_span.set_tag("peer.service", self.service) + if self.trigger_tags: + route = self.trigger_tags.get("http.route") + if route: + self.inferred_span.set_tag("http.route", route) + + event_source_arn = self.trigger_tags.get( + "function_trigger.event_source_arn" + ) + if event_source_arn: + self.inferred_span.set_tag("dd_resource_key", event_source_arn) + + 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) @@ -339,21 +391,35 @@ def _after(self, event, context): following_span = self.span or self.inferred_span ColdStartTracer( tracer, - self.function_name, + config.function_name, following_span.start_ns, trace_ctx, - self.min_cold_start_trace_duration, - self.cold_start_trace_skip_lib, + 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 self.flush_to_log or should_use_extension: - flush_stats() - if should_use_extension: + 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.encode_authorizer_context and is_authorizer_response(self.response): + if config.llmobs_enabled: + LLMObs.flush() + + # 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") ) @@ -363,9 +429,8 @@ def _after(self, event, context): def format_err_with_traceback(e): - return "Error {}. Traceback: {}".format( - e, traceback.format_exc().replace("\n", "\r") - ) + 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 bbaecb2ed..002d13b19 100644 --- a/datadog_lambda/xray.py +++ b/datadog_lambda/xray.py @@ -1,47 +1,60 @@ 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(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) - - -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): @@ -75,7 +88,6 @@ def generate_random_id(): def build_segment(context, key, metadata): - segment = json.dumps( { "id": generate_random_id(), @@ -90,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, "") @@ -116,4 +126,4 @@ def send_segment(key, metadata): 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 5b473ed9a..bf6c6fec4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,433 +1,404 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. - -[[package]] -name = "attrs" -version = "23.1.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, -] - -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] - -[[package]] -name = "boto3" -version = "1.28.13" -description = "The AWS SDK for Python" -optional = true -python-versions = ">= 3.7" -files = [ - {file = "boto3-1.28.13-py3-none-any.whl", hash = "sha256:b2d178c8a56fe3e4c9b123dccdff20e9555d12a597b72627fa659aa6295e238a"}, - {file = "boto3-1.28.13.tar.gz", hash = "sha256:db6443fd2c65d9f35f671b03bacb0592b62d06884395ed65d75922ccddc34c2e"}, -] - -[package.dependencies] -botocore = ">=1.31.13,<1.32.0" -jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.6.0,<0.7.0" - -[package.extras] -crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "botocore" -version = "1.31.13" +version = "1.36.8" description = "Low-level, data-driven core of boto 3." optional = true -python-versions = ">= 3.7" +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\"" files = [ - {file = "botocore-1.31.13-py3-none-any.whl", hash = "sha256:78b96afbd88b8bd4c0967611a4cedddd9ea33d8601309dc351f81cbb5479d976"}, - {file = "botocore-1.31.13.tar.gz", hash = "sha256:9a5080ea2a444f0447a7a1a79f64252ae2a1417b6c13a54656ee991cb610dd4e"}, + {file = "botocore-1.36.8-py3-none-any.whl", hash = "sha256:59d3fdfbae6d916b046e973bebcbeb70a102f9e570ca86d5ba512f1854b78fc2"}, + {file = "botocore-1.36.8.tar.gz", hash = "sha256:81c88e5566cf018e1411a68304dc1fb9e4156ca2b50a3a0f0befc274299e67fa"}, ] [package.dependencies] jmespath = ">=0.7.1,<2.0.0" python-dateutil = ">=2.1,<3.0.0" -urllib3 = ">=1.25.4,<1.27" +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 = ["awscrt (==0.16.26)"] +crt = ["awscrt (==0.23.4)"] [[package]] name = "bytecode" -version = "0.13.0" -description = "Python module to generate and modify bytecode" -optional = false -python-versions = ">=3.6" -files = [ - {file = "bytecode-0.13.0-py3-none-any.whl", hash = "sha256:e69f92e7d27f99d5d7d76e6a824bd3d9ff857c72b59927aaf87e1a620f67fe50"}, - {file = "bytecode-0.13.0.tar.gz", hash = "sha256:6af3c2f0a31ce05dce41f7eea5cc380e33f5e8fbb7dcee3b52467a00acd52fcd"}, -] - -[[package]] -name = "bytecode" -version = "0.14.2" +version = "0.16.1" description = "Python module to generate and modify bytecode" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.10\"" files = [ - {file = "bytecode-0.14.2-py3-none-any.whl", hash = "sha256:e368a2b9bbd7c986133c951250db94fb32f774cfc49752a9db9073bcf9899762"}, - {file = "bytecode-0.14.2.tar.gz", hash = "sha256:386378d9025d68ddb144870ae74330a492717b11b8c9164c4034e88add808f0c"}, + {file = "bytecode-0.16.1-py3-none-any.whl", hash = "sha256:1d4b61ed6bade4bff44127c8283bef8131a664ce4dbe09d64a88caf329939f35"}, + {file = "bytecode-0.16.1.tar.gz", hash = "sha256:8fbbb637c880f339e564858bc6c7984ede67ae97bc71343379a535a9a4baf398"}, ] [package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.10\""} +typing_extensions = {version = "*", markers = "python_version < \"3.10\""} [[package]] -name = "cattrs" -version = "23.1.2" -description = "Composable complex class support for attrs and dataclasses." +name = "bytecode" +version = "0.17.0" +description = "Python module to generate and modify bytecode" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version >= \"3.10\"" files = [ - {file = "cattrs-23.1.2-py3-none-any.whl", hash = "sha256:b2bb14311ac17bed0d58785e5a60f022e5431aca3932e3fc5cc8ed8639de50a4"}, - {file = "cattrs-23.1.2.tar.gz", hash = "sha256:db1c821b8c537382b2c7c66678c3790091ca0275ac486c76f3c8f3920e83c657"}, + {file = "bytecode-0.17.0-py3-none-any.whl", hash = "sha256:64fb10cde1db7ef5cc39bd414ecebd54ba3b40e1c4cf8121ca5e72f170916ff8"}, + {file = "bytecode-0.17.0.tar.gz", hash = "sha256:0c37efa5bd158b1b873f530cceea2c645611d55bd2dc2a4758b09f185749b6fd"}, ] -[package.dependencies] -attrs = ">=20" -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} -typing_extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.2.0,<5.0.0)"] -cbor2 = ["cbor2 (>=5.4.6,<6.0.0)"] -msgpack = ["msgpack (>=1.0.2,<2.0.0)"] -orjson = ["orjson (>=3.5.2,<4.0.0)"] -pyyaml = ["PyYAML (>=6.0,<7.0)"] -tomlkit = ["tomlkit (>=0.11.4,<0.12.0)"] -ujson = ["ujson (>=5.4.0,<6.0.0)"] - [[package]] name = "certifi" -version = "2023.7.22" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {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 = "3.2.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, -] - -[[package]] -name = "coverage" -version = "7.2.7" -description = "Code coverage measurement for Python" -optional = true python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, - {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, - {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, - {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, - {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, - {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, - {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, - {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, - {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, - {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, - {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, - {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, - {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, - {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, - {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, - {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, - {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, - {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, + {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.extras] -toml = ["tomli"] +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = true +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.46.0" +version = "0.51.0" description = "The Datadog Python library" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] files = [ - {file = "datadog-0.46.0-py2.py3-none-any.whl", hash = "sha256:3d7bcda6177b43be4cdb52e16b4bdd4f9005716c0dd7cfea009e018c36bb7a3d"}, - {file = "datadog-0.46.0.tar.gz", hash = "sha256:e4fbc92a85e2b0919a226896ae45fc5e4b356c0c57f1c2659659dfbe0789c674"}, + {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] requests = ">=2.6.0" [[package]] -name = "ddsketch" -version = "2.0.4" -description = "Distributed quantile sketches" +name = "ddtrace" +version = "3.19.7" +description = "Datadog APM client library" optional = false -python-versions = ">=2.7" +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.10\"" files = [ - {file = "ddsketch-2.0.4-py3-none-any.whl", hash = "sha256:3227a270fd686a29d3a7128f9352ccf852314410380fc11384356f1ae2a75938"}, - {file = "ddsketch-2.0.4.tar.gz", hash = "sha256:32f7314077fec8747d4faebaec2c854b5ffc399c5f552f73fa94024f48d74d64"}, + {file = "ddtrace-3.19.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:640847ed52bef189da0d2403c21be80c0dd425da19e65fb1b099b69db4506111"}, + {file = "ddtrace-3.19.7-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:428ef5a4bf0abaead6b24e422feb9121a29303246b70d4ea78cd892bfa0c9a58"}, + {file = "ddtrace-3.19.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:04169fddab36fcbb82248d6e02b3231e8fe732772d8f7b58b2342e414fdfe5fe"}, + {file = "ddtrace-3.19.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9d48387bb79f3ed3d0e812ce17545c065d8fa03336069cac1bae32b87e8e0b2f"}, + {file = "ddtrace-3.19.7-cp310-cp310-manylinux_2_28_i686.whl", hash = "sha256:35a41266f309911797da7be1f8b3dd2cef440814be59edf48b11c5496f6fa585"}, + {file = "ddtrace-3.19.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7c7f885aacac5959b210ec86cf861d54c1bf778bedde72cf22a0e11b4e3342da"}, + {file = "ddtrace-3.19.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:bb0c758cd60783e4ac29d98afb2ccdc00f918304f0191381b3bd9df7ba15bb64"}, + {file = "ddtrace-3.19.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1fa535aa2795bf776270e3373227cf14ef5164ce3b6e0953b7b66da3a3cf9d0f"}, + {file = "ddtrace-3.19.7-cp310-cp310-win32.whl", hash = "sha256:31993a4eb521e28eb52921ed2112ad813b779a2cabf5fafc620224bb6e661a53"}, + {file = "ddtrace-3.19.7-cp310-cp310-win_amd64.whl", hash = "sha256:306a5c803aa38c6808449c543ef4a00430da7fa959b801438a144a8d964055cb"}, + {file = "ddtrace-3.19.7-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:2c8bbfa3ab83e6a66ed69a2897479158040cc126b561eb33fec002323afc1507"}, + {file = "ddtrace-3.19.7-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:c708d863ce44762bf219554b47ae7f9fd28348d8502b498f7910a24d4bcb3526"}, + {file = "ddtrace-3.19.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:52d30d1fe4b4751de0909d11966c9fb3db509cb795a98ea40633a78ff39daa18"}, + {file = "ddtrace-3.19.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c9fe721ede05f197893664361873177df8551a820b7e5ac6d84da39e82bf175c"}, + {file = "ddtrace-3.19.7-cp311-cp311-manylinux_2_28_i686.whl", hash = "sha256:74b25220346fdac217d1b334c1d88bbae2c3ae5e101e53460f8193ed226d2759"}, + {file = "ddtrace-3.19.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:259261612982b1222731560d166edf4125f53d2a4a5468778a91b9b3d8577452"}, + {file = "ddtrace-3.19.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3b1a59d4347d0176ffe9841f2a01ca9b42bfd65760baf90337fd3b0718cceba5"}, + {file = "ddtrace-3.19.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:119b60f006944af39ec6eaa2ed3a9b96defbb537ad51592a60a8285643217094"}, + {file = "ddtrace-3.19.7-cp311-cp311-win32.whl", hash = "sha256:74e31b295267f6b5d02192566e382a33dd3c2254f545f43f2d241f1266de06d4"}, + {file = "ddtrace-3.19.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e00eaca60b53c206370b69641534d251b68f114406a7cdd96aa505be1e8a4e3"}, + {file = "ddtrace-3.19.7-cp311-cp311-win_arm64.whl", hash = "sha256:54fa6ccf40f9ad09787b4ccc2cfb6524ce87997a3424e3f92efe3f4bfed2008d"}, + {file = "ddtrace-3.19.7-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2a1b4ccf33d82cc03334f6f54b8e37711f0e46fddaade56769ac42e6c6683d98"}, + {file = "ddtrace-3.19.7-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:b6037dba7f0b7fa59b8e1ab44a2750fccc3e619917d451a94cc1bc108b16d3cb"}, + {file = "ddtrace-3.19.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:38b515c8b5100e6b3c513e58160eb268bddbd9783fa2cb6f7f65ee7c387936ee"}, + {file = "ddtrace-3.19.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:300807941a2f005aacf4ef3d81e94dd4034d9acf1bf3786e73c382659bd8b617"}, + {file = "ddtrace-3.19.7-cp312-cp312-manylinux_2_28_i686.whl", hash = "sha256:c74524559e7d21beb29b8e13c5090644525b5df03a6a7450e9286997e31ac9c9"}, + {file = "ddtrace-3.19.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:817abdd18b24ec0f881843af4c6bae55c4ecd997dc0c3688c4a45b0a18a1368c"}, + {file = "ddtrace-3.19.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c59faed5fa5330ffd5fe60284b1ec1a0525d7fc063787de227a418810851c2f3"}, + {file = "ddtrace-3.19.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:af3f1200c3e4c850a9c408047a6f83f5b87cbb0c641022a4107e566e5064c434"}, + {file = "ddtrace-3.19.7-cp312-cp312-win32.whl", hash = "sha256:6fd3409777c2549b5bf743abc3c1ab17ba7a1a399c3a580e2a4bac383a576e35"}, + {file = "ddtrace-3.19.7-cp312-cp312-win_amd64.whl", hash = "sha256:69448c80f440aee4d1a3e19295e66c44a84ae014da6c05a52d846b4b7ac821c9"}, + {file = "ddtrace-3.19.7-cp312-cp312-win_arm64.whl", hash = "sha256:30827b6bbbbb75f883717c59339e43feef31a7a31da623f2f291ac6e9a044c6f"}, + {file = "ddtrace-3.19.7-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:425bacf644a772aa3faca075234f3bc5d37972fa1f32932343b00653190cdab5"}, + {file = "ddtrace-3.19.7-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:dec566649d660bfe179d2d97d8217304a466c0294ac6cec84ab9ee5bd2c20056"}, + {file = "ddtrace-3.19.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:91e62d9d206150ddc360af2628615572f3bcc314ae420ab59041e6e493477993"}, + {file = "ddtrace-3.19.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:251607dec183356cfe1ec8f102f01ac556a38136216f74e31b5748b6fa994d97"}, + {file = "ddtrace-3.19.7-cp313-cp313-manylinux_2_28_i686.whl", hash = "sha256:6952e2e78f126dce55d4d988490bc76c24e439d52d2686ff618f8d7640534e61"}, + {file = "ddtrace-3.19.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82b7fbfedac7986274d2c947d247affdb9d918edcb6d65587ab9c1d8d81af9bf"}, + {file = "ddtrace-3.19.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b96f689ab0225d2d8934c4aa42a7ce1001b91fbf1ff8e8158a6428e0f0faece6"}, + {file = "ddtrace-3.19.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0995ac17c3e43fae6f6c2ac0d9a90d035ea13d629342f84ba7596ac002ce87"}, + {file = "ddtrace-3.19.7-cp313-cp313-win32.whl", hash = "sha256:846b695964580cb4d91c4600907119f38b57b792d7ff1f21793d2140157b820b"}, + {file = "ddtrace-3.19.7-cp313-cp313-win_amd64.whl", hash = "sha256:de1aabc50c663f27c1ae341d16b31bdc3b8fb1c28c4b8a683e9000cbfd11fa44"}, + {file = "ddtrace-3.19.7-cp313-cp313-win_arm64.whl", hash = "sha256:2d41fd500ec915be8b3b95cd7a5535f87323acbdc7e9b2c02797d83b6985b451"}, + {file = "ddtrace-3.19.7-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:528fb2565048e669cfe5ad0e24f4f39f73747977982c78339f9ece7e39430180"}, + {file = "ddtrace-3.19.7-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:29202bdd4496098b27907dfdfd85000549901461ebea6f0f90d19eb4ebac2b76"}, + {file = "ddtrace-3.19.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:abb3b5b8cac3247b01d381fe71aeb56b20f8759275619701418e53f0306eb6a0"}, + {file = "ddtrace-3.19.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d27d310e272aa7772fdf7087bd5056966448d8051586de75577076ad8c8e323"}, + {file = "ddtrace-3.19.7-cp314-cp314-manylinux_2_28_i686.whl", hash = "sha256:aec1ec1fbcdafa76362c7f468aab240224d14060c4cda73e9a0676293be471c5"}, + {file = "ddtrace-3.19.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:26c300dbb6d8c29b6fcd4847da29010a988150a28426c4cc46e7e1f3816ea195"}, + {file = "ddtrace-3.19.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:8c3a74eda7907e5d4a5a36c62e02ee41fca10de83ae2f592e0a63530d8eda7aa"}, + {file = "ddtrace-3.19.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:79cdb4246da2a6e32b768a0c7f952890ddeb9c8bea9228adf2d82bcf66849177"}, + {file = "ddtrace-3.19.7-cp314-cp314-win32.whl", hash = "sha256:759d49298575079e31da354780ca37220775c80a007bbe2ae7fb756a11210740"}, + {file = "ddtrace-3.19.7-cp314-cp314-win_amd64.whl", hash = "sha256:054ebbdd1e02e90874cda803b31721f4e4ab6d0d3833bc8e82de8b78f1fc9d57"}, + {file = "ddtrace-3.19.7-cp314-cp314-win_arm64.whl", hash = "sha256:ff953b2d7dc8a7d8e8d452aa0f9ac1e094e9deba371f3715bc73613bc1fa0069"}, + {file = "ddtrace-3.19.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:c0139817f0acce19aa0bd07e09bd9be0844c5561e1d8d3d6c0a46f13256587c4"}, + {file = "ddtrace-3.19.7-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:f67b6129039b91447e8f412b5fca83c264c8b471d688d1c3a1fd7c2dc05b3b03"}, + {file = "ddtrace-3.19.7-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c35e49e472e3639e8827c9b78d99a64caba74bf96a920c74c62c6ed36df5dbf2"}, + {file = "ddtrace-3.19.7-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9411e4ad0fbf9ebf7afd2420f171408bb0468b8c714657124ae1f1f2391193cf"}, + {file = "ddtrace-3.19.7-cp38-cp38-manylinux_2_28_i686.whl", hash = "sha256:482a43cb3f33a8373a207965579eded1a2699fb0e624f80746455c8a9c839b63"}, + {file = "ddtrace-3.19.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:79e6e53a290901b7df39bd2c176865ca906f66d7a0ed6ca6e862abbdd4b85b6b"}, + {file = "ddtrace-3.19.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5fa9aa40d7fedc5682a7ca82ec9e68d96fd5714e89c17342e76f8ef37300238d"}, + {file = "ddtrace-3.19.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6feaf4786d6b419a5fb225e91d97010273dfc1b7d046ed1d0996b6bd9b03aec0"}, + {file = "ddtrace-3.19.7-cp38-cp38-win32.whl", hash = "sha256:52a465d4509f1bd8154bfd7e0198e4f8d209cb3e7d30202299189b174fdab034"}, + {file = "ddtrace-3.19.7-cp38-cp38-win_amd64.whl", hash = "sha256:dfa876c29b4694db345eadacbd03d94dfc19569990da0488680039b985d84f62"}, + {file = "ddtrace-3.19.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:a7e978e52a718b01e71cce740ed77fca96a65ca2ff9c17c8e7be2757532057ee"}, + {file = "ddtrace-3.19.7-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:8e0dd6fa57f71f9adfc088aa9cf86e27ba86e94406329060742e362131ad49e5"}, + {file = "ddtrace-3.19.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22b712f9bab0471599ed8462b1640a81ea07aee7532c666fef6e6334d0b9c09e"}, + {file = "ddtrace-3.19.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51043397868ce03c5c629d1d03d15c29b9379f574b03ffa3bc2149892445c465"}, + {file = "ddtrace-3.19.7-cp39-cp39-manylinux_2_28_i686.whl", hash = "sha256:80f967464f04c2a4455ff2994af6cd12971f09e33f8c33c475dc9150cd1b5aad"}, + {file = "ddtrace-3.19.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f6712f94b8a08fe6746e7e48b76582c7c261c9a83474c4a8cc8ec1349e3810ad"}, + {file = "ddtrace-3.19.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a31cbe6c75fe6c07befd744993fb61159f02dc70689230b69161547cfbf5892b"}, + {file = "ddtrace-3.19.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3b7173b6395e3b9c8a20ca94433033b8647971b61648add055a24819fa3ce72f"}, + {file = "ddtrace-3.19.7-cp39-cp39-win32.whl", hash = "sha256:8d3066532620ea1e74639db041fb4aabbead9057a48adcd00c9aae65ca096bc9"}, + {file = "ddtrace-3.19.7-cp39-cp39-win_amd64.whl", hash = "sha256:4d7abb09a7a672efecc560c110c2668bfdfce8f6c28e45903af96441476872d2"}, + {file = "ddtrace-3.19.7.tar.gz", hash = "sha256:e531a7c6370458d0e61b498714969471514033f6851a4603ac62f2cac1adc925"}, ] [package.dependencies] -protobuf = {version = ">=3.0.0", markers = "python_version >= \"3.7\""} -six = "*" +bytecode = {version = ">=0.13.0,<1", markers = "python_version < \"3.11\""} +envier = ">=0.6.1,<0.7.0" +opentelemetry-api = ">=1,<2" +wrapt = ">=1,<3" + +[package.extras] +opentelemetry = ["opentelemetry-exporter-otlp (>=1,<2)"] +opentracing = ["opentracing (>=2,<3)"] [[package]] name = "ddtrace" -version = "1.15.2" +version = "4.7.1" description = "Datadog APM client library" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "ddtrace-1.15.2-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:ca0411333fbdb0fafa06d412bbd76ab8d2647cc9dcb8a7833952ce4fe09eb421"}, - {file = "ddtrace-1.15.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e2603749f97a5191b32f710c8ec5248bb58f4f9a1cb337559f93c5f0f8cea33b"}, - {file = "ddtrace-1.15.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8392087809e047f701e38ecc4f2990bcfe399a22c516a1dbcbdff50fb7382a79"}, - {file = "ddtrace-1.15.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:2f7649c24a7463be9b86d5f11ac6eaa2014896eaf409e67f3dc813a6bb0ed8b6"}, - {file = "ddtrace-1.15.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:dbdbc5bf3b2b56b8e61b241ee372d897b295344e269475f38e837c9bfe03ae2c"}, - {file = "ddtrace-1.15.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:23d39c72ad1844977a80d79206d773c3ec1f1346816b9e45427c25ef88597b4e"}, - {file = "ddtrace-1.15.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:da458bbbc4de14dd8e8f60aefe42a66c551a9f50c69c6e361acc7edab579a3e4"}, - {file = "ddtrace-1.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d07bb0c50d2df7ff9281bea83534db5127cee8ac2f94111c9544d03d49f60613"}, - {file = "ddtrace-1.15.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:499b3e3d0359e492792ecf8ab6efcf4b1991fbaa523338774333e9a2a66d9d37"}, - {file = "ddtrace-1.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedd0937f83e0d7b261960365fec5771f39ced599c90f589548a1738a586799d"}, - {file = "ddtrace-1.15.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7643d20991cd7e1c21e65d8b5c292a9dca8d124f69f9e96cc2b5fb8d47802c3a"}, - {file = "ddtrace-1.15.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3f6bb76fe33c2e4842236036f78b1bbdd4da0f2b846627ca7d72b01ac49b3076"}, - {file = "ddtrace-1.15.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ebc9b89501c8a557dab43170e4a12e90358130413a87a0276ccaa0038b0636a4"}, - {file = "ddtrace-1.15.2-cp310-cp310-win32.whl", hash = "sha256:c10ca0e3a63310d314ec7fa55d53f4b4434f06c4d321d64d757814679161bf5d"}, - {file = "ddtrace-1.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:6208635442ea52ff3f97b9fc64ac25772cda8f105a607a385e55bf524bceefc5"}, - {file = "ddtrace-1.15.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8524f460be02b402f63b11ad3b1177955c8608f814e1758b87f53f15bf9a7599"}, - {file = "ddtrace-1.15.2-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:5a2dd127a65e12189055818ab72d44d80587acaaf450c65624e0482d63ff9970"}, - {file = "ddtrace-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3350c647120fbc3355eb35ce054c88e63bc073d71949f377d59b1152a2ed0f4"}, - {file = "ddtrace-1.15.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:adb76713207f0ef688f68a539f9cb63e19cd149d48d36befb835f67f49395ed7"}, - {file = "ddtrace-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8ff5c250c5abfbbbd76a7d3167308a2373ad7e55ecf3c7c26a62fcd2be8a57"}, - {file = "ddtrace-1.15.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:264bed998870b63f548b96f57dd771014cd02ef0b21bb382e745900a7b72ef28"}, - {file = "ddtrace-1.15.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:20bfd8db155167d2ccfddc25b50649338534b12cb00f7ed08514af1eb6a4956e"}, - {file = "ddtrace-1.15.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:72479172bd10f5998188a05b0b4a109ccb2a93467a0aa1e6656d5396c83fb253"}, - {file = "ddtrace-1.15.2-cp311-cp311-win32.whl", hash = "sha256:23bee3d0eb971cc1565caa429620b82f2d69ef648e9c792046b9481188dba9ab"}, - {file = "ddtrace-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:65a29d23ecfbc7cc4ca1069a5586aa836ae3978e64251414933432078bc29bc2"}, - {file = "ddtrace-1.15.2-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:3a2852da4a76503211ca8b77a50fc86df36ba15fab04b45a6a17faa386f53839"}, - {file = "ddtrace-1.15.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:244180c6decb244c7fda929dc5969b3a510e5a4857239063de1fae139fac9837"}, - {file = "ddtrace-1.15.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:46f9ba0c282a62953f03d1add8eae8c80613244bb93a1ff997dad71d07ce6c72"}, - {file = "ddtrace-1.15.2-cp35-cp35m-win32.whl", hash = "sha256:a39dbf1ca657cc3a876143301e5d775e2f9bcf2ed1e9b4366fb3cf9d6a345a82"}, - {file = "ddtrace-1.15.2-cp35-cp35m-win_amd64.whl", hash = "sha256:7cfd9514e82871321e86897fe567c7548fc45da523df591f3e5adc6633a5781c"}, - {file = "ddtrace-1.15.2-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:3a2978b07d19d4ebf936fde1e455c61b3d88f103f1f9e360b9269fe1a1dc608a"}, - {file = "ddtrace-1.15.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e7795a7f65a6e844ab57a0b31d400e79c4a1f69d174fab8edc69e6d2db56962"}, - {file = "ddtrace-1.15.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aae5306b3b0ec48cb8ade3362629c31bd25999244addff0f4a2f6f3934509894"}, - {file = "ddtrace-1.15.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14fb33bd6d9fa70638d43de7b5170e1c9961d3fbc277314609941e108c45716d"}, - {file = "ddtrace-1.15.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:745ce3c9559fa331ef30208ff1ccaafe3ab3c02f2e01177c560c94acd6f4de27"}, - {file = "ddtrace-1.15.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7706d35215d2cca0a89581ec11da56e25742914ae0865b928034ee9ad7278cf3"}, - {file = "ddtrace-1.15.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0bc18e900d1495deb61093f1af38d94af6a1ca66dd541fd47bd093c3f3b80b4a"}, - {file = "ddtrace-1.15.2-cp36-cp36m-win32.whl", hash = "sha256:b13f4042ef3f391714aca5ca1f03ff3c24c1d201ab5af02f0405335aa5602ff5"}, - {file = "ddtrace-1.15.2-cp36-cp36m-win_amd64.whl", hash = "sha256:eb32e3b3d0f472447b3d427a075007135b3c39488c1fe0f1e097863f326a439b"}, - {file = "ddtrace-1.15.2-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:0953fd9a2555801d68674bb4905f64805efe1e02b3f11def21eb7655be046717"}, - {file = "ddtrace-1.15.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9436ec9cc00b70730d2c1777f11aca7f4863a49ddd27d0b1478e84c1a7667b6f"}, - {file = "ddtrace-1.15.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7215b21c1eaf56b38bf46c66193db3736ecadeb9ae1b9ca780a91addbaa9853"}, - {file = "ddtrace-1.15.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a5f7155b99fe9393bfa4f0e4ef2610ddf59e70aefcf99a95acae8b31e29cc4"}, - {file = "ddtrace-1.15.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:df103a600c2901dc54929ef58dee41887a0bb558efbf7e41a7489bd6264fcf44"}, - {file = "ddtrace-1.15.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d51a73238ad8ceff4232ffa94b860d61187b325e7fab746044dafa312d6bc415"}, - {file = "ddtrace-1.15.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bfc5777204c0c34465fc4ce38d8d1268d9f95ffcbf7e4025e9a5d3e87d3e17c3"}, - {file = "ddtrace-1.15.2-cp37-cp37m-win32.whl", hash = "sha256:9516dbfc974af9632d75e9c32b38e695b88ea18ebfa4580dd0f768bc05272fba"}, - {file = "ddtrace-1.15.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a510252a3d5be6c29db2c69cbd2535268532e8d568fae06b295a06041e1b969d"}, - {file = "ddtrace-1.15.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:82995243719c87aefc85d7df0e1ae61bba8ae1f805d48cbaf2132beb215f1968"}, - {file = "ddtrace-1.15.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:ca5dd51910a81451d236fccdbf5d3ca8e284aa3be56f08db92644f85ef88c56e"}, - {file = "ddtrace-1.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d76f485769c035df3ede4ad9830bac06aa8b69ac4617f2eb1251b1094468009"}, - {file = "ddtrace-1.15.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4dd5f5e477021b8810b2b685e1e16ba5a99f31239e22abc71794688b7f3e6e4d"}, - {file = "ddtrace-1.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ec73676c60cc3cf08430f19a59daccbbb5770edc74ad15a99bf4237a40d0fb"}, - {file = "ddtrace-1.15.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6b140f11b89d902174df05e8b9c1eb1b522a63e6c60c5d68ccac8913bb371bbb"}, - {file = "ddtrace-1.15.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c7c8a0e140d28e49cf8cd96cdec8e17232c5525ed5c154729b8afb6cb93a8e2b"}, - {file = "ddtrace-1.15.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0112d258c3a681a63e5f057b9e3ee8504b60d773d95baf195462d9ff4096caa9"}, - {file = "ddtrace-1.15.2-cp38-cp38-win32.whl", hash = "sha256:6ea7b80eb8019a70c999ef8cfd34fd6078a2ae154007d124d5e642531bf1a9d6"}, - {file = "ddtrace-1.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:282b8c9b46d7a8450325299cf348a0f1d8f9f34d174a0ea402bc1a1df4ad7cf3"}, - {file = "ddtrace-1.15.2-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:53b171404b59c1e030ea614e194d1483fb42437a02ffdd7f4a45175613dd7cb4"}, - {file = "ddtrace-1.15.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9ba06236dd8bd64776b7b734dd9421709670fef090857448e75c97acb30cdce7"}, - {file = "ddtrace-1.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6abe5ba4396c9f7633cab68d0e81c5fd94f7c77b046b3ee969eded068a522d7"}, - {file = "ddtrace-1.15.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:61a1b48f97a07e2f422ec01bb23861716300cebe4afd917ab36bb4db68904da4"}, - {file = "ddtrace-1.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86e186dc66802e2d71b94330c1635fd4c3f881a1bb71747be162a57b7602daaa"}, - {file = "ddtrace-1.15.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:762b5a0777454299c4ac62177578969ed551c973063f87a8825d9d073e5250ce"}, - {file = "ddtrace-1.15.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:889d359f4382fde41893ba5c00b412cbea8502e1b6bb6c83bf87fa6e63cbfabe"}, - {file = "ddtrace-1.15.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c4d3c9ce3456181e535b9da42bde7c850dc7224039fd083e95b05010c2ff9748"}, - {file = "ddtrace-1.15.2-cp39-cp39-win32.whl", hash = "sha256:69e47d28327a7afb263c16cc6bf1227e1b2bf1fdb2d559dce913a138a3f36807"}, - {file = "ddtrace-1.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:da780fbfe6dd749ee571a468b8e86f1fd4f51626d35626c2356f8a440efe0dfa"}, - {file = "ddtrace-1.15.2.tar.gz", hash = "sha256:e5c1a5965ea8d8260586769102d79522bc7d9758a271252bb58ee05d6c5cd9a8"}, +python-versions = "<3.15,>=3.9" +groups = ["main"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "ddtrace-4.7.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:74ba511e6669bd88dba1f9fe5d03170bc741305a97f6b8331f3d35ca754d8c82"}, + {file = "ddtrace-4.7.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:8149302841f058c68c57f1c89e4ee273d9f7de30fdeb2ae047d90a32dc1b6096"}, + {file = "ddtrace-4.7.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:44c15ab0f7bb7cc932e3ca7481eb0d9f3fa917247cc03375887bf50b9c6ece54"}, + {file = "ddtrace-4.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d3fe0451fddfacbed5ee62a91c632f01cacd57ec7152a6be67b916f4716f2e3"}, + {file = "ddtrace-4.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:be57f6a30560d92a01c780ead970df73fcf458a20c6aa4d936af8d1b0892a786"}, + {file = "ddtrace-4.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67726c736a02131f062bd63e18a0badfc0f000e2462a0a69c4e8680f54e37d66"}, + {file = "ddtrace-4.7.1-cp310-cp310-win32.whl", hash = "sha256:279397251be2d8b3fc848b231c04fc1be5d299b91c51b831d34795f9ec387e95"}, + {file = "ddtrace-4.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:ae1872e10c138827fb7cb759cdde26d1fe2f66449b95e19f5cc22609fe1ca02b"}, + {file = "ddtrace-4.7.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:df5b3716e47421bb9e925a1ae8592cf2169eadf9a3e62be56baa16d0656be876"}, + {file = "ddtrace-4.7.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:78da43378062c4905f09d1ff58d4b49bd61f9440977f2b7be5dc0dc427ddbbe3"}, + {file = "ddtrace-4.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cb6ae35e377e987c59a42971c550937404079fea4666a158849a47587b39cf7"}, + {file = "ddtrace-4.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b07a9c689f115e70a8946d3002275808c01b31a350d8159e3e6562ddee379ad0"}, + {file = "ddtrace-4.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e717ee7b8484ea85882fb5d0c349fcead2b023ff8ab6e965072d5c4064d607ba"}, + {file = "ddtrace-4.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:613a74ce4ea692e2a8435266ad361d44bfd018d1d694ab38709ebf7df692af14"}, + {file = "ddtrace-4.7.1-cp311-cp311-win32.whl", hash = "sha256:b5f5cdc530a8baf28647dae8ea85d446534770d70ea8a30a8d3dde00af412a5b"}, + {file = "ddtrace-4.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:27c8812da8a73e239eb0bece274ef8cc95eb3093910f049b2ca0542756e2fcb8"}, + {file = "ddtrace-4.7.1-cp311-cp311-win_arm64.whl", hash = "sha256:bad60c97ca058580c62e0ea4340d9dd86971c825fd65491a8e67d0998b2e6da3"}, + {file = "ddtrace-4.7.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:0331d57f4c21cabebc9819092a0527dc4677f7f509c877229d216255236d8b65"}, + {file = "ddtrace-4.7.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:be562ef7187e61a4c835e37fbd8a6d81f445d6811660929c94a9e6a9462c6fb4"}, + {file = "ddtrace-4.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5dd9d7fbd678bfa8d8e71278ea05cc257b0230221749554e87e4f1e9704c4efe"}, + {file = "ddtrace-4.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:57cff66524ed7e441cb14d98f402eb52a22455964375f8f5a696afddc1684eb9"}, + {file = "ddtrace-4.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9c5b4a96d19e905b4845a86aa7d94698414f1f427ffc0f092b80228f6b2b71a3"}, + {file = "ddtrace-4.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d353a200d9443e7db6e0528a9f148f98f9359dab7abec41571bf46f155de6bd9"}, + {file = "ddtrace-4.7.1-cp312-cp312-win32.whl", hash = "sha256:e998ef9d9a29648a06581a6ca8f53e8d1e67700b61105587909a69297e98660d"}, + {file = "ddtrace-4.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:51d671f2e2d8a4f0abe82511186849be3246b7d4dfb3a207465c7e1c772c42c2"}, + {file = "ddtrace-4.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:a95c13794f61f8016d117d28a9e301a2eba04121bf1fc90e20264ef8c7fab0a6"}, + {file = "ddtrace-4.7.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:d8c4c19d21331611a3f98e10489125eee426205043577013d1095b1c4b55f220"}, + {file = "ddtrace-4.7.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:f679951bb2cf749cf53214a7b4d76ac6912dc4f05a3371b094d4d679615d3446"}, + {file = "ddtrace-4.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2f64a6e9e7df59873e4ab60cd6ca707c7943379d572c4836acbebfc357b3e050"}, + {file = "ddtrace-4.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b7323dcd5d78a8c7d65955e4dcd3db560d00c9e7f2f2138705a6fde67603adb5"}, + {file = "ddtrace-4.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6103fb99c84c0d1bedb121ad085f89b69dd4712ad49f3a1745bbaf5573e93901"}, + {file = "ddtrace-4.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:57aa50af618880335fa813315034428811aecb6c78715436eeeaf7ff0b11ba49"}, + {file = "ddtrace-4.7.1-cp313-cp313-win32.whl", hash = "sha256:803b4b94f333e563a4521e545bc6d07ed2d2f4bad4843a9df29bf279c5d43cde"}, + {file = "ddtrace-4.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:c270b7d956c3186a17de358fb8c0600cb79c9028b769a0e1a975deab42a539d7"}, + {file = "ddtrace-4.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:de62971f25321416ac59f65afb2165482bc5b0ffbd450afa4ad586f3e0aa1c46"}, + {file = "ddtrace-4.7.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:022b058263acd3b8e8534d5cd2446330b9be296cab48d24d33f489d4da0f999e"}, + {file = "ddtrace-4.7.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:fc0c89c7ba67582a2fd4d6e2d803b94fd800dd4489cd777398a80c87fc0b216f"}, + {file = "ddtrace-4.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:89776d556ff27f95bcac17fcac4aeaf2173058e167c1923047007e7861079bdb"}, + {file = "ddtrace-4.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:26ad10decfd1072ec803aaf94ec5bf499cdbafe9d85fbf1608b6217d495b3edb"}, + {file = "ddtrace-4.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0424306e0668f0adaa57d6b327948f5775c568afa91c5603559cc6a82d934515"}, + {file = "ddtrace-4.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f5ffd1dfdee50236bf3b1a4dc699884387d04518a0bca5db7559e9fde932d744"}, + {file = "ddtrace-4.7.1-cp314-cp314-win32.whl", hash = "sha256:b7f6196521f00cf220ed4575de8832f9c77f110c5e05038a226f4bd39e89c688"}, + {file = "ddtrace-4.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:4906a58c510f00851aacd6033c0687a7d6db82a7c5d6ed9399dac247f49335ba"}, + {file = "ddtrace-4.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:ae9c3429e304cf0b1b6852213f29af20eee9997cda575b3dc8a267bb66f04b1f"}, + {file = "ddtrace-4.7.1-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:1e3244d00daaa0560b806fd71383b39e1cdf268292fd08b9823beacaa4131cc9"}, + {file = "ddtrace-4.7.1-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:4183df7ba4efe3e1d3a0e204dbd51badb2de826dc9c3da57477d0a17f2640752"}, + {file = "ddtrace-4.7.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0159bcf3b07916dfb5b6cc6cc7f80b08740b9c55f114657ab15563b17eb269e"}, + {file = "ddtrace-4.7.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8d35c1e41c5c65fb705eb0eadb51686eca4432af36c48555570558b6f57eae1c"}, + {file = "ddtrace-4.7.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:55555cb48a23892b5e3a89d84555de369df1fbd967b0397698b4178e6aff66ec"}, + {file = "ddtrace-4.7.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:622f8ae6ddf9167557d40b59134df94a72ee0b7318cb6aa03466883c9d972289"}, + {file = "ddtrace-4.7.1-cp39-cp39-win32.whl", hash = "sha256:4a601fe4e5c6bd31e0470420771eaf82576e30311b401bdb79c8dec68ef30d3d"}, + {file = "ddtrace-4.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:c4f778ae3fbe708a8360d68af8f36bd60be9d64af7d4cf670832f4a737ed252e"}, + {file = "ddtrace-4.7.1.tar.gz", hash = "sha256:51695b8b34881432ea9d46c42aa41343d5531d9fdddc1c65b721aa4b051ed848"}, ] [package.dependencies] -attrs = {version = ">=20", markers = "python_version > \"2.7\""} bytecode = [ - {version = ">=0.13.0,<0.14.0", markers = "python_version == \"3.7\""}, - {version = "*", markers = "python_version >= \"3.8\""}, -] -cattrs = {version = "*", markers = "python_version >= \"3.7\""} -ddsketch = ">=2.0.1" -envier = "*" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -opentelemetry-api = {version = ">=1", markers = "python_version >= \"3.7\""} -protobuf = {version = ">=3", markers = "python_version >= \"3.7\""} -six = ">=1.12.0" -typing-extensions = "*" -xmltodict = ">=0.12" + {version = ">=0.17.0,<1", markers = "python_version >= \"3.14.0\""}, + {version = ">=0.16.0,<1", markers = "python_version >= \"3.13.0\" and python_version < \"3.14.0\""}, + {version = ">=0.15.1,<1", markers = "python_version ~= \"3.12.0\""}, + {version = ">=0.14.0,<1", markers = "python_version ~= \"3.11.0\""}, + {version = ">=0.13.0,<1", markers = "python_version < \"3.11.0\""}, +] +envier = ">=0.6.1,<0.7.0" +opentelemetry-api = ">=1,<2" +wrapt = ">=1,<3" [package.extras] -opentracing = ["opentracing (>=2.0.0)"] +opentelemetry = ["opentelemetry-exporter-otlp (>=1,<2)"] +opentracing = ["opentracing (>=2,<3)"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["main"] files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {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)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] [[package]] name = "envier" -version = "0.4.0" +version = "0.6.1" description = "Python application configuration via the environment" optional = false -python-versions = ">=2.7" +python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "envier-0.4.0-py3-none-any.whl", hash = "sha256:7b91af0f16ea3e56d91ec082f038987e81b441fc19c657a8b8afe0909740a706"}, - {file = "envier-0.4.0.tar.gz", hash = "sha256:e68dcd1ed67d8b6313883e27dff3e701b7fba944d2ed4b7f53d0cc2e12364a82"}, + {file = "envier-0.6.1-py3-none-any.whl", hash = "sha256:73609040a76be48bbcb97074d9969666484aa0de706183a6e9ef773156a8a6a9"}, + {file = "envier-0.6.1.tar.gz", hash = "sha256:3309a01bb3d8850c9e7a31a5166d5a836846db2faecb79b9cb32654dd50ca9f9"}, ] [package.extras] @@ -435,13 +406,15 @@ mypy = ["mypy"] [[package]] name = "exceptiongroup" -version = "1.1.2" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" -optional = false +optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\" and python_version <= \"3.10\"" files = [ - {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, - {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -449,64 +422,73 @@ test = ["pytest (>=6)"] [[package]] name = "flake8" -version = "3.9.2" +version = "5.0.4" description = "the modular source code checker: pep8 pyflakes and co" optional = true -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, -] - -[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]] -name = "httpretty" -version = "0.9.7" -description = "HTTP client mock for Python" -optional = true -python-versions = "*" +python-versions = ">=3.6.1" +groups = ["main"] +markers = "extra == \"dev\"" files = [ - {file = "httpretty-0.9.7.tar.gz", hash = "sha256:66216f26b9d2c52e81808f3e674a6fb65d4bf719721394a1a9be926177e55fbe"}, + {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.4" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" +groups = ["main"] files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {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 = "6.7.0" +version = "8.5.0" description = "Read metadata from Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, - {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, + {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] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" +zipp = ">=3.20" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +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"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +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" @@ -514,6 +496,8 @@ version = "1.0.1" description = "JSON Matching Expressions" optional = true 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"}, @@ -521,102 +505,200 @@ files = [ [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" optional = true -python-versions = "*" +python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"dev\"" files = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, + {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" -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 = "nose2-0.9.2-py2.py3-none-any.whl", hash = "sha256:fd4b84c65ecea869080a23bdb8916716f5363df3b899933991c861ada8aa3f48"}, - {file = "nose2-0.9.2.tar.gz", hash = "sha256:8762f77925bbafcdf38331e0e2ee718756fb75ff74b1f9097cd08731ad59ab5e"}, + {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" +deprecated = ">=1.2.6" +importlib-metadata = ">=6.0,<=8.5.0" -[package.extras] -coverage-plugin = ["coverage (>=4.4.1)"] -doc = ["Sphinx (>=1.6.5)", "mock", "sphinx-rtd-theme"] +[[package]] +name = "packaging" +version = "24.2" +description = "Core utilities for Python packages" +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 = "opentelemetry-api" -version = "1.19.0" -description = "OpenTelemetry Python API" -optional = false -python-versions = ">=3.7" +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 = "opentelemetry_api-1.19.0-py3-none-any.whl", hash = "sha256:dcd2a0ad34b691964947e1d50f9e8c415c32827a1d87f0459a72deb9afdf5597"}, - {file = "opentelemetry_api-1.19.0.tar.gz", hash = "sha256:db374fb5bea00f3c7aa290f5d94cea50b659e6ea9343384c5f6c2bb5d5e8db65"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] -[package.dependencies] -deprecated = ">=1.2.6" -importlib-metadata = ">=6.0,<7.0" +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] -name = "protobuf" -version = "4.23.4" -description = "" -optional = false -python-versions = ">=3.7" +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 = "protobuf-4.23.4-cp310-abi3-win32.whl", hash = "sha256:5fea3c64d41ea5ecf5697b83e41d09b9589e6f20b677ab3c48e5f242d9b7897b"}, - {file = "protobuf-4.23.4-cp310-abi3-win_amd64.whl", hash = "sha256:7b19b6266d92ca6a2a87effa88ecc4af73ebc5cfde194dc737cf8ef23a9a3b12"}, - {file = "protobuf-4.23.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8547bf44fe8cec3c69e3042f5c4fb3e36eb2a7a013bb0a44c018fc1e427aafbd"}, - {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:fee88269a090ada09ca63551bf2f573eb2424035bcf2cb1b121895b01a46594a"}, - {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:effeac51ab79332d44fba74660d40ae79985901ac21bca408f8dc335a81aa597"}, - {file = "protobuf-4.23.4-cp37-cp37m-win32.whl", hash = "sha256:c3e0939433c40796ca4cfc0fac08af50b00eb66a40bbbc5dee711998fb0bbc1e"}, - {file = "protobuf-4.23.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9053df6df8e5a76c84339ee4a9f5a2661ceee4a0dab019e8663c50ba324208b0"}, - {file = "protobuf-4.23.4-cp38-cp38-win32.whl", hash = "sha256:e1c915778d8ced71e26fcf43c0866d7499891bca14c4368448a82edc61fdbc70"}, - {file = "protobuf-4.23.4-cp38-cp38-win_amd64.whl", hash = "sha256:351cc90f7d10839c480aeb9b870a211e322bf05f6ab3f55fcb2f51331f80a7d2"}, - {file = "protobuf-4.23.4-cp39-cp39-win32.whl", hash = "sha256:6dd9b9940e3f17077e820b75851126615ee38643c2c5332aa7a359988820c720"}, - {file = "protobuf-4.23.4-cp39-cp39-win_amd64.whl", hash = "sha256:0a5759f5696895de8cc913f084e27fd4125e8fb0914bb729a17816a33819f474"}, - {file = "protobuf-4.23.4-py3-none-any.whl", hash = "sha256:e9d0be5bf34b275b9f87ba7407796556abeeba635455d036c7351f7c183ef8ff"}, - {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"}, + {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" 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.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, + {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" 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 = "pygments" +version = "2.20.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version >= \"3.10\" and extra == \"dev\"" files = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, + {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"}, + {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"}, ] +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pytest" +version = "8.3.4" +description = "pytest: simple powerful testing with Python" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.10\" and 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" +version = "9.0.3" +description = "pytest: simple powerful testing with Python" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version >= \"3.10\" and extra == \"dev\"" +files = [ + {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"}, + {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"}, +] + +[package.dependencies] +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1.0.1" +packaging = ">=22" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "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" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +markers = "extra == \"dev\"" files = [ - {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"}, + {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] @@ -624,18 +706,20 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.31.0" +version = "2.32.4" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.10\"" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {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 = ">=2,<4" +charset_normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<3" @@ -644,174 +728,425 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "s3transfer" -version = "0.6.1" -description = "An Amazon S3 Transfer Manager" -optional = true -python-versions = ">= 3.7" +name = "requests" +version = "2.33.1" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version >= \"3.10\"" files = [ - {file = "s3transfer-0.6.1-py3-none-any.whl", hash = "sha256:3c0da2d074bf35d6870ef157158641178a4204a6e689e82546083e31e0311346"}, - {file = "s3transfer-0.6.1.tar.gz", hash = "sha256:640bb492711f4c0c0905e1f62b6aaeb771881935ad27884852411f8e9cacbca9"}, + {file = "requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a"}, + {file = "requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517"}, ] [package.dependencies] -botocore = ">=1.12.36,<2.0a.0" +certifi = ">=2023.5.7" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.26,<3" [package.extras] -crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<8)"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +optional = true +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +markers = "extra == \"dev\"" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[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]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.10\"" +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 = "ujson" +version = "5.10.0" +description = "Ultra fast JSON encoder and decoder for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.10\"" +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 = "ujson" +version = "5.12.0" +description = "Ultra fast JSON encoder and decoder for Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version >= \"3.10\"" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "ujson-5.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:38051f36423f084b909aaadb3b41c9c6a2958e86956ba21a8489636911e87504"}, + {file = "ujson-5.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:457fabc2700a8e6ddb85bc5a1d30d3345fe0d3ec3ee8161a4e032ec585801dfa"}, + {file = "ujson-5.12.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:57930ac9519099b852e190d2c04b1fb5d97ea128db33bce77ed874eccb4c7f09"}, + {file = "ujson-5.12.0-cp310-cp310-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:9b3b86ec3e818f3dd3e13a9de628e88a9990f4af68ecb0b12dd3de81227f0a26"}, + {file = "ujson-5.12.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:460e76a4daff214ae33ab959494962c93918cb44714ea3e3f748b14aa37f8a87"}, + {file = "ujson-5.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e584d0cdd37cac355aca52ed788d1a2d939d6837e2870d3b70e585db24025a50"}, + {file = "ujson-5.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0fe9128e75c6aa6e9ae06c1408d6edd9179a2fef0fe6d9cda3166b887eba521d"}, + {file = "ujson-5.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3ed5cb149892141b1e77ef312924a327f2cc718b34247dae346ed66329e1b8be"}, + {file = "ujson-5.12.0-cp310-cp310-win32.whl", hash = "sha256:973b7d7145b1ac553a7466a64afa8b31ec2693d7c7fff6a755059e0a2885dfd2"}, + {file = "ujson-5.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d072a403d82aef8090c6d4f728e3a727dfdba1ad3b7fa3a052c3ecbd37e73cb"}, + {file = "ujson-5.12.0-cp310-cp310-win_arm64.whl", hash = "sha256:55ede2a7a051b3b7e71a394978a098d71b3783e6b904702ff45483fad434ae2d"}, + {file = "ujson-5.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58a11cb49482f1a095a2bd9a1d81dd7c8fb5d2357f959ece85db4e46a825fd00"}, + {file = "ujson-5.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9b3cf13facf6f77c283af0e1713e5e8c47a0fe295af81326cb3cb4380212e797"}, + {file = "ujson-5.12.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb94245a715b4d6e24689de12772b85329a1f9946cbf6187923a64ecdea39e65"}, + {file = "ujson-5.12.0-cp311-cp311-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:0fe6b8b8968e11dd9b2348bd508f0f57cf49ab3512064b36bc4117328218718e"}, + {file = "ujson-5.12.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89e302abd3749f6d6699691747969a5d85f7c73081d5ed7e2624c7bd9721a2ab"}, + {file = "ujson-5.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0727363b05ab05ee737a28f6200dc4078bce6b0508e10bd8aab507995a15df61"}, + {file = "ujson-5.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b62cb9a7501e1f5c9ffe190485501349c33e8862dde4377df774e40b8166871f"}, + {file = "ujson-5.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a6ec5bf6bc361f2f0f9644907a36ce527715b488988a8df534120e5c34eeda94"}, + {file = "ujson-5.12.0-cp311-cp311-win32.whl", hash = "sha256:006428d3813b87477d72d306c40c09f898a41b968e57b15a7d88454ecc42a3fb"}, + {file = "ujson-5.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:40aa43a7a3a8d2f05e79900858053d697a88a605e3887be178b43acbcd781161"}, + {file = "ujson-5.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:561f89cc82deeae82e37d4a4764184926fb432f740a9691563a391b13f7339a4"}, + {file = "ujson-5.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:09b4beff9cc91d445d5818632907b85fb06943b61cb346919ce202668bf6794a"}, + {file = "ujson-5.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca0c7ce828bb76ab78b3991904b477c2fd0f711d7815c252d1ef28ff9450b052"}, + {file = "ujson-5.12.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d79c6635ccffcbfc1d5c045874ba36b594589be81d50d43472570bb8de9c57"}, + {file = "ujson-5.12.0-cp312-cp312-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:7e07f6f644d2c44d53b7a320a084eef98063651912c1b9449b5f45fcbdc6ccd2"}, + {file = "ujson-5.12.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:085b6ce182cdd6657481c7c4003a417e0655c4f6e58b76f26ee18f0ae21db827"}, + {file = "ujson-5.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:16b4fe9c97dc605f5e1887a9e1224287291e35c56cbc379f8aa44b6b7bcfe2bb"}, + {file = "ujson-5.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0d2e8db5ade3736a163906154ca686203acc7d1d30736cbf577c730d13653d84"}, + {file = "ujson-5.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:93bc91fdadcf046da37a214eaa714574e7e9b1913568e93bb09527b2ceb7f759"}, + {file = "ujson-5.12.0-cp312-cp312-win32.whl", hash = "sha256:2a248750abce1c76fbd11b2e1d88b95401e72819295c3b851ec73399d6849b3d"}, + {file = "ujson-5.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:1b5c6ceb65fecd28a1d20d1eba9dbfa992612b86594e4b6d47bb580d2dd6bcb3"}, + {file = "ujson-5.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:9a5fcbe7b949f2e95c47ea8a80b410fcdf2da61c98553b45a4ee875580418b68"}, + {file = "ujson-5.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:15d416440148f3e56b9b244fdaf8a09fcf5a72e4944b8e119f5bf60417a2bfc8"}, + {file = "ujson-5.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0dd3676ea0837cd70ea1879765e9e9f6be063be0436de9b3ea4b775caf83654"}, + {file = "ujson-5.12.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7bbf05c38debc90d1a195b11340cc85cb43ab3e753dc47558a3a84a38cbc72da"}, + {file = "ujson-5.12.0-cp313-cp313-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:3c2f947e55d3c7cfe124dd4521ee481516f3007d13c6ad4bf6aeb722e190eb1b"}, + {file = "ujson-5.12.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ea6206043385343aff0b7da65cf73677f6f5e50de8f1c879e557f4298cac36a"}, + {file = "ujson-5.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb349dbba57c76eec25e5917e07f35aabaf0a33b9e67fc13d188002500106487"}, + {file = "ujson-5.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:937794042342006f707837f38d721426b11b0774d327a2a45c0bd389eb750a87"}, + {file = "ujson-5.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ad57654570464eb1b040b5c353dee442608e06cff9102b8fcb105565a44c9ed"}, + {file = "ujson-5.12.0-cp313-cp313-win32.whl", hash = "sha256:76bf3e7406cf23a3e1ca6a23fb1fb9ea82f4f6bd226fe226e09146b0194f85dc"}, + {file = "ujson-5.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:15e555c4caca42411270b2ed2b2ebc7b3a42bb04138cef6c956e1f1d49709fe2"}, + {file = "ujson-5.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:bd03472c36fa3a386a6deb887113b9e3fa40efba8203eb4fe786d3c0ccc724f6"}, + {file = "ujson-5.12.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85833bca01aa5cae326ac759276dc175c5fa3f7b3733b7d543cf27f2df12d1ef"}, + {file = "ujson-5.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d22cad98c2a10bbf6aa083a8980db6ed90d4285a841c4de892890c2b28286ef9"}, + {file = "ujson-5.12.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99cc80facad240b0c2fb5a633044420878aac87a8e7c348b9486450cba93f27c"}, + {file = "ujson-5.12.0-cp314-cp314-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:d1831c07bd4dce53c4b666fa846c7eba4b7c414f2e641a4585b7f50b72f502dc"}, + {file = "ujson-5.12.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e00cec383eab2406c9e006bd4edb55d284e94bb943fda558326048178d26961"}, + {file = "ujson-5.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f19b3af31d02a2e79c5f9a6deaab0fb3c116456aeb9277d11720ad433de6dfc6"}, + {file = "ujson-5.12.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:bacbd3c69862478cbe1c7ed4325caedec580d8acf31b8ee1b9a1e02a56295cad"}, + {file = "ujson-5.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94c5f1621cbcab83c03be46441f090b68b9f307b6c7ec44d4e3f6d5997383df4"}, + {file = "ujson-5.12.0-cp314-cp314-win32.whl", hash = "sha256:e6369ac293d2cc40d52577e4fa3d75a70c1aae2d01fa3580a34a4e6eff9286b9"}, + {file = "ujson-5.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:31348a0ffbfc815ce78daac569d893349d85a0b57e1cd2cdbba50b7f333784da"}, + {file = "ujson-5.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:6879aed770557f0961b252648d36f6fdaab41079d37a2296b5649fd1b35608e0"}, + {file = "ujson-5.12.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7ddb08b3c2f9213df1f2e3eb2fbea4963d80ec0f8de21f0b59898e34f3b3d96d"}, + {file = "ujson-5.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0a3ae28f0b209be5af50b54ca3e2123a3de3a57d87b75f1e5aa3d7961e041983"}, + {file = "ujson-5.12.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30ad4359413c8821cc7b3707f7ca38aa8bc852ba3b9c5a759ee2d7740157315"}, + {file = "ujson-5.12.0-cp314-cp314t-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:02f93da7a4115e24f886b04fd56df1ee8741c2ce4ea491b7ab3152f744ad8f8e"}, + {file = "ujson-5.12.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3ff4ede90ed771140caa7e1890de17431763a483c54b3c1f88bd30f0cc1affc0"}, + {file = "ujson-5.12.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bf9cc97f05048ac8f3e02cd58f0fe62b901453c24345bfde287f4305dcc31c"}, + {file = "ujson-5.12.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:2324d9a0502317ffc35d38e153c1b2fa9610ae03775c9d0f8d0cca7b8572b04e"}, + {file = "ujson-5.12.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:50524f4f6a1c839714dbaff5386a1afb245d2d5ec8213a01fbc99cea7307811e"}, + {file = "ujson-5.12.0-cp314-cp314t-win32.whl", hash = "sha256:f7a0430d765f9bda043e6aefaba5944d5f21ec43ff4774417d7e296f61917382"}, + {file = "ujson-5.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:ccbfd94e59aad4a2566c71912b55f0547ac1680bfac25eb138e6703eb3dd434e"}, + {file = "ujson-5.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:42d875388fbd091c7ea01edfff260f839ba303038ffb23475ef392012e4d63dd"}, + {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:bf85a00ac3b56a1e7a19c5be7b02b5180a0895ac4d3c234d717a55e86960691c"}, + {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:64df53eef4ac857eb5816a56e2885ccf0d7dff6333c94065c93b39c51063e01d"}, + {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c0aed6a4439994c9666fb8a5b6c4eac94d4ef6ddc95f9b806a599ef83547e3b"}, + {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efae5df7a8cc8bdb1037b0f786b044ce281081441df5418c3a0f0e1f86fe7bb3"}, + {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:8712b61eb1b74a4478cfd1c54f576056199e9f093659334aeb5c4a6b385338e5"}, + {file = "ujson-5.12.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:871c0e5102e47995b0e37e8df7819a894a6c3da0d097545cd1f9f1f7d7079927"}, + {file = "ujson-5.12.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:56ba3f7abbd6b0bb282a544dc38406d1a188d8bb9164f49fdb9c2fee62cb29da"}, + {file = "ujson-5.12.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c5a52987a990eb1bae55f9000994f1afdb0326c154fb089992f839ab3c30688"}, + {file = "ujson-5.12.0-pp311-pypy311_pp73-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:adf28d13a33f9d750fe7a78fb481cac298fa257d8863d8727b2ea4455ea41235"}, + {file = "ujson-5.12.0-pp311-pypy311_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51acc750ec7a2df786cdc868fb16fa04abd6269a01d58cf59bafc57978773d8e"}, + {file = "ujson-5.12.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:ab9056d94e5db513d9313b34394f3a3b83e6301a581c28ad67773434f3faccab"}, + {file = "ujson-5.12.0.tar.gz", hash = "sha256:14b2e1eb528d77bc0f4c5bd1a7ebc05e02b5b41beefb7e8567c9675b8b13bcf4"}, ] [[package]] name = "urllib3" -version = "1.26.16" +version = "1.26.20" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +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.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, - {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, + {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] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +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 = "2.6.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version >= \"3.10\"" +files = [ + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, +] + +[package.extras] +brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] + [[package]] name = "wrapt" -version = "1.15.0" +version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, - {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, - {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, - {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, - {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, - {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, - {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, - {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, - {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, - {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, - {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, - {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, - {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, - {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, - {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, - {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, - {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, - {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, - {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, -] - -[[package]] -name = "xmltodict" -version = "0.13.0" -description = "Makes working with XML feel like you are working with JSON" -optional = false -python-versions = ">=3.4" +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, - {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, + {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 = "zipp" -version = "3.15.0" +version = "3.20.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, + {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 = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +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", "flake8", "httpretty", "nose2", "requests"] +dev = ["botocore", "flake8", "pytest", "pytest", "pytest-benchmark", "requests", "requests"] [metadata] -lock-version = "2.0" -python-versions = ">=3.7.0,<4" -content-hash = "e65f36c4d06687bde43b04ec23d980e60dd755362e54032b4293a3bf0d5c2054" +lock-version = "2.1" +python-versions = ">=3.8.0,<3.15" +content-hash = "3da1bc2540691200481913d90171aa3a6a3700cb32059b9462dfd64f9f51d092" diff --git a/pyproject.toml b/pyproject.toml index 6227fdf01..8776a3af9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "datadog_lambda" -version = "4.80.0" +version = "8.128.0.dev0" description = "The Datadog AWS Lambda Library" authors = ["Datadog, Inc. "] license = "Apache-2.0" @@ -16,37 +16,55 @@ packages = [ { include = "datadog_lambda" } ] classifiers = [ - "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", + "Programming Language :: Python :: 3.14", ] [tool.poetry.dependencies] -python = ">=3.7.0,<4" -datadog = ">=0.41.0,<1.0.0" +python = ">=3.8.0,<3.15" +datadog = ">=0.51.0,<1.0.0" wrapt = "^1.11.2" -ddtrace = "1.15.2" -urllib3 = "<2.0.0" -importlib_metadata = {version = "*", python = "<3.8"} -boto3 = { version = "^1.10.33", optional = true } -typing_extensions = {version = "^4.0", python = "<3.8"} -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 } - +ddtrace = [ + {version = ">=3.19.1,<4", python = ">=3.8,<3.10"}, + {version = ">=4.1.1,<5,!=4.6.*", python = ">=3.10"} +] +ujson = [ + {version = ">=5.10.0,<5.12.0", python = ">=3.8,<3.10"}, + {version = "^5.12.0", python = ">=3.10"}, +] +urllib3 = [ + {version = ">=1.25.4,<1.27", python = ">=3.8,<3.10"}, + {version = "^2.6.3", python = ">=3.10"}, +] +botocore = { version = "^1.34.0", optional = true } +requests = [ + { version = "^2.22.0", optional = true, python = ">=3.8,<3.10" }, + { version = "^2.33.0", optional = true, python = ">=3.10" }, +] +pytest = [ + { version = "^8.3.4", optional = true, python = ">=3.8,<3.10" }, + { version = "^9.0.3", optional = true, python = ">=3.10" }, +] +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/_spec_ddtrace_dep.sh b/scripts/_spec_ddtrace_dep.sh new file mode 100644 index 000000000..bb64bb178 --- /dev/null +++ b/scripts/_spec_ddtrace_dep.sh @@ -0,0 +1,82 @@ +#!/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/). + +# Shared helpers for rewriting the ddtrace dependency in pyproject.toml. +# Sourced by scripts/build_layers.sh and scripts/setup_python_env.sh, so the +# layer build and the unit-test/lint/publish jobs use the same env-var +# contract and resolve the dep in a single pip pass. +# +# Env-var contract (highest precedence first): +# DD_TRACE_COMMIT Specific dd-trace-py commit SHA from GitHub. +# DD_TRACE_COMMIT_BRANCH dd-trace-py branch name from GitHub. +# DD_TRACE_WHEEL Path to a pre-built ddtrace .whl file. +# UPSTREAM_PIPELINE_ID GitLab pipeline ID from dd-trace-py. Looks up the +# matching wheel from S3, trying the smaller +# serverless build first then falling back to the +# standard manylinux2014 build. +# +# When none of these are set, spec_ddtrace_dep is a no-op. +# +# When UPSTREAM_PIPELINE_ID is set, also requires: +# PYTHON_VERSION e.g. "3.12" (used to build the cpXY platform tag) +# ARCH "amd64" (default) or "arm64" + +# Replace the ddtrace dependency block in pyproject.toml. +# Usage: replace_ddtrace_dep "ddtrace = { ... }" +replace_ddtrace_dep() { + echo "Replacing ddtrace dep with: $1" + perl -i -0777 -pe "s|ddtrace = \[[^\]]*\]|$1|gs" pyproject.toml +} + +# Search S3 for a wheel matching basename + index, then rewrite the ddtrace +# dep to point at the downloaded file. Globals required: +# S3_BASE, PY_TAG, PLATFORM +# Returns 0 on success, 1 if no matching wheel was found at the index. +_search_and_spec_s3_wheel() { + local basename=$1 + local index=$2 + local search_pattern="${basename}-[^\"]*${PY_TAG}[^\"]*${PLATFORM}[^\"]*\.whl" + local index_url="${S3_BASE}/index-${index}.html" + echo "Searching for wheel ${search_pattern} in ${index_url}" + local wheel_file + wheel_file=$(curl -sSfL "${index_url}" | grep -o "${search_pattern}" | head -n 1 || true) + if [ -z "$wheel_file" ]; then + return 1 + fi + curl -sSfL "${S3_BASE}/${wheel_file}" -o "${wheel_file}" + echo "Using S3 wheel: ${wheel_file}" + replace_ddtrace_dep "${basename} = { file = \"${wheel_file}\" }" +} + +# Rewrite pyproject.toml's ddtrace dep based on the env-var precedence above. +# No-op if no override env var is set. Returns non-zero if UPSTREAM_PIPELINE_ID +# is set but no matching S3 wheel is found. +spec_ddtrace_dep() { + if [ -n "${DD_TRACE_COMMIT:-}" ]; then + replace_ddtrace_dep "ddtrace = { git = \"https://github.com/DataDog/dd-trace-py.git\", rev = \"${DD_TRACE_COMMIT}\" }" + elif [ -n "${DD_TRACE_COMMIT_BRANCH:-}" ]; then + replace_ddtrace_dep "ddtrace = { git = \"https://github.com/DataDog/dd-trace-py.git\", branch = \"${DD_TRACE_COMMIT_BRANCH}\" }" + elif [ -n "${DD_TRACE_WHEEL:-}" ]; then + local basename + basename=$(sed 's/^.*\///' <<< "${DD_TRACE_WHEEL%%-*}") + replace_ddtrace_dep "${basename} = { file = \"${DD_TRACE_WHEEL}\" }" + elif [ -n "${UPSTREAM_PIPELINE_ID:-}" ]; then + if [ -z "${PYTHON_VERSION:-}" ]; then + echo "ERROR: PYTHON_VERSION must be set when UPSTREAM_PIPELINE_ID is set" >&2 + return 1 + fi + S3_BASE="https://dd-trace-py-builds.s3.amazonaws.com/${UPSTREAM_PIPELINE_ID}" + PY_TAG="cp$(echo "$PYTHON_VERSION" | tr -d '.')" + if [ "$ARCH" = "amd64" ]; then + PLATFORM="manylinux2014_x86_64" + else + PLATFORM="manylinux2014_aarch64" + fi + _search_and_spec_s3_wheel "ddtrace_serverless" "serverless" \ + || _search_and_spec_s3_wheel "ddtrace" "manylinux2014" \ + || { echo "ERROR: No matching ddtrace wheel for ${PY_TAG} ${PLATFORM} in pipeline ${UPSTREAM_PIPELINE_ID}, skipping version patch!" >&2; } + fi +} diff --git a/scripts/add_new_region.sh b/scripts/add_new_region.sh index 1b1753cfd..210436294 100755 --- a/scripts/add_new_region.sh +++ b/scripts/add_new_region.sh @@ -12,8 +12,38 @@ set -e OLD_REGION='us-east-1' -LAYER_NAMES=("Datadog-Python37" "Datadog-Python38" "Datadog-Python38-ARM" "Datadog-Python39" "Datadog-Python39-ARM" "Datadog-Python310" "Datadog-Python310-ARM" "Datadog-Python311" "Datadog-Python311-ARM") -PYTHON_VERSIONS_FOR_AWS_CLI=("python3.7" "python3.8" "python3.8" "python3.9" "python3.9" "python3.10" "python3.10" "python3.11" "python3.11") +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" + "Datadog-Python314" + "Datadog-Python314-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" + "python3.14" + "python3.14" +) NEW_REGION=$1 publish_layer() { diff --git a/scripts/build_layers.sh b/scripts/build_layers.sh index 976ba5d1e..7c3bd5fae 100755 --- a/scripts/build_layers.sh +++ b/scripts/build_layers.sh @@ -6,15 +6,65 @@ # Copyright 2019 Datadog, Inc. # Builds datadog-lambda-python layers for Lambda functions - -# Usage: PYTHON_VERSION=3.7 ./build_layers.sh -# If PYTHON_VERSION is not specified, all versions will be built. +# +# Usage: +# PYTHON_VERSION=12 ARCH=arm ./scripts/build_layers.sh +# +# Environment variables: +# PYTHON_VERSION Python minor version. Accepts shorthand (e.g. 12) or full (e.g. 3.12). +# If not set, all supported versions are built. +# ARCH Target architecture. Accepts shorthand: arm, amd, x86, aarch64 +# or full: arm64, amd64. If not set, both are built. +# +# dd-trace-py overrides (mutually exclusive, highest priority first): +# DD_TRACE_COMMIT Specific dd-trace-py commit SHA to build from GitHub. +# DD_TRACE_COMMIT_BRANCH dd-trace-py branch name to build from GitHub. +# DD_TRACE_WHEEL Path to a pre-built ddtrace .whl file. +# UPSTREAM_PIPELINE_ID GitLab pipeline ID from dd-trace-py. Downloads the +# matching pre-built wheel from S3 (via +# index-manylinux2014.html) for each python/arch. +# +# Examples: +# # Build a single layer for Python 3.12 on arm64 +# PYTHON_VERSION=12 ARCH=arm ./scripts/build_layers.sh +# +# # Build with a specific dd-trace-py commit (for git bisect) +# DD_TRACE_COMMIT=abc123 PYTHON_VERSION=12 ARCH=arm ./scripts/build_layers.sh set -e LAYER_DIR=".layers" LAYER_FILES_PREFIX="datadog_lambda_py" -AVAILABLE_PYTHON_VERSIONS=("3.7" "3.8" "3.9" "3.10" "3.11") +AVAILABLE_PYTHON_VERSIONS=("3.8" "3.9" "3.10" "3.11" "3.12" "3.13" "3.14") +AVAILABLE_ARCHS=("arm64" "amd64") + +if [ -n "$ARCH" ]; then + case "$ARCH" in + arm|arm64|aarch64) ARCH="arm64" ;; + amd|amd64|x86|x86_64) ARCH="amd64" ;; + esac +fi + +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 + +# Normalize Python version shorthand (e.g. 12 -> 3.12, 3.12 -> 3.12) +if [ -n "$PYTHON_VERSION" ]; then + if [[ "$PYTHON_VERSION" =~ ^[0-9]+$ ]]; then + PYTHON_VERSION="3.${PYTHON_VERSION}" + fi +fi # Determine which Python versions to build layers for if [ -z "$PYTHON_VERSION" ]; then @@ -28,9 +78,21 @@ else echo "EXITING SCRIPT." exit 1 fi - PYTHON_VERSIONS=$PYTHON_VERSION + PYTHON_VERSIONS=("$PYTHON_VERSION") fi +# Backup pyproject.toml so modifications don't persist across runs +cp pyproject.toml pyproject.toml.bak +cleanup() { + mv pyproject.toml.bak pyproject.toml 2>/dev/null || true +} +trap cleanup EXIT + +# Source the shared ddtrace-dep specification logic. spec_ddtrace_dep reads +# DD_TRACE_COMMIT / DD_TRACE_COMMIT_BRANCH / DD_TRACE_WHEEL / UPSTREAM_PIPELINE_ID +# (PYTHON_VERSION + ARCH for the S3 path) and rewrites the ddtrace dep block +# in pyproject.toml. +source "$(dirname "$0")/_spec_ddtrace_dep.sh" function make_path_absolute { echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")" @@ -41,20 +103,15 @@ function docker_build_zip { destination=$(make_path_absolute $2) arch=$3 - # Install datadogpy in a docker container to avoid the mess from switching # 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 and copy the output /build/python to the temp dir - dockerId=$(docker create datadog-lambda-python-${arch}:$1) - docker cp $dockerId:/build/python $temp_dir/python - + --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 +125,15 @@ mkdir $LAYER_DIR for python_version in "${PYTHON_VERSIONS[@]}" do - if [ "$python_version" != "3.7" ]; 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}" + # Restore pyproject.toml to a clean state before each iteration so the + # rewrite is deterministic regardless of what the previous loop did. + cp pyproject.toml.bak pyproject.toml + PYTHON_VERSION="${python_version}" ARCH="${architecture}" spec_ddtrace_dep + 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 df5a67187..783a17d6a 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==22.3.0 +pip install -Iv black==25.11.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 5d8399087..de9a8c4d4 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 -# 7 mb size limit -MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 7 \* 1024) -MAX_LAYER_UNCOMPRESSED_SIZE_KB=$(expr 24 \* 1024) +set -e +MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 9 \* 1024 + 15) # 9231 KB +MAX_LAYER_UNCOMPRESSED_SIZE_KB=$(expr 25 \* 1024) # 25600 KB LAYER_FILES_PREFIX="datadog_lambda_py" LAYER_DIR=".layers" -VERSIONS=("3.7" "3.8" "3.9" "3.10" "3.11") -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 +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 c0b541afc..d2710a7e7 100755 --- a/scripts/list_layers.sh +++ b/scripts/list_layers.sh @@ -10,7 +10,22 @@ set -e -LAYER_NAMES=("Datadog-Python37" "Datadog-Python38" "Datadog-Python38-ARM" "Datadog-Python39" "Datadog-Python39-ARM" "Datadog-Python310" "Datadog-Python310-ARM" "Datadog-Python311" "Datadog-Python311-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" + "Datadog-Python314" + "Datadog-Python314-ARM" +) AVAILABLE_REGIONS=$(aws ec2 describe-regions | jq -r '.[] | .[] | .RegionName') LAYERS_MISSING_REGIONS=() diff --git a/scripts/publish_govcloud.sh b/scripts/publish_govcloud.sh new file mode 100755 index 000000000..19c8c17ca --- /dev/null +++ b/scripts/publish_govcloud.sh @@ -0,0 +1,113 @@ +#! /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: +# +# CI_COMMIT_TAG= ENVIRONMENT=[us1-staging-fed|us1-fed|us2-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 +elif [ $ENVIRONMENT = "us2-fed" ]; then + AWS_VAULT_ROLE=sso-govcloud-fed-us2-lambda-layer-operator + + 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, us1-fed, or us2-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" "3.14"; 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 d379cb67e..31a514d13 100755 --- a/scripts/publish_layers.sh +++ b/scripts/publish_layers.sh @@ -13,12 +13,62 @@ set -e # Makes sure any subprocesses will be terminated with this process trap "pkill -P $$; exit 1;" INT -PYTHON_VERSIONS_FOR_AWS_CLI=("python3.7" "python3.8" "python3.8" "python3.9" "python3.9" "python3.10" "python3.10" "python3.11" "python3.11") -LAYER_PATHS=(".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" ".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") -AVAILABLE_LAYERS=("Datadog-Python37" "Datadog-Python38" "Datadog-Python38-ARM" "Datadog-Python39" "Datadog-Python39-ARM" "Datadog-Python310" "Datadog-Python310-ARM" "Datadog-Python311" "Datadog-Python311-ARM") -ARCHS=("amd64" "amd64" "amd64""amd64" "amd64" "arm64" "amd64" "arm64" "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" + "python3.14" + "python3.14" +) +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_lambda_py-amd64-3.14.zip" + ".layers/datadog_lambda_py-arm64-3.14.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" + "Datadog-Python314" + "Datadog-Python314-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 +152,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 +191,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 e8838c5a1..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,11 +38,6 @@ else NEW_VERSION=$1 fi -# Ensure AWS access before proceeding -ddsaml2aws login -a govcloud-us1-fed-human-engineering -AWS_PROFILE=govcloud-us1-fed-human-engineering aws sts get-caller-identity -aws-vault exec sso-prod-engineering -- aws sts get-caller-identity - # Ensure pypi registry access read -p "Do you have access to PyPI (y/n)?" CONT if [ "$CONT" != "y" ]; then @@ -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..." @@ -66,33 +75,46 @@ echo echo "Signing layers for commercial AWS regions" 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 sso-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" -ddsaml2aws 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 pyproject.toml -m "Bump 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/run_integration_tests.sh b/scripts/run_integration_tests.sh index beb91921c..aa47b279c 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 sso-serverless-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 sso-serverless-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=("python37" "python38" "python39" "python310" "python311") LOGS_WAIT_SECONDS=20 @@ -28,13 +27,15 @@ mismatch_found=false # [0]: serverless runtime name # [1]: python version # [2]: random 8-character ID to avoid collisions with other runs -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)) +python314=("python3.14" "3.14" $(xxd -l 4 -c 4 -p < /dev/random)) -PARAMETERS_SETS=("python37" "python38" "python39" "python310" "python311") +PARAMETERS_SETS=("python38" "python39" "python310" "python311" "python312" "python313" "python314") if [ -z "$RUNTIME_PARAM" ]; then echo "Python version not specified, running for all python versions." @@ -57,6 +58,11 @@ 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 @@ -72,6 +78,12 @@ 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) @@ -85,13 +97,11 @@ 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] @@ -101,7 +111,7 @@ 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" @@ -115,7 +125,7 @@ python version : ${!python_version} and run id : ${!run_id}" input_event_name=$(echo "$input_event_file" | sed "s/.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 @@ -157,7 +167,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 @@ -189,7 +199,7 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do sed '/^$/d' | # Normalize Lambda runtime REPORT logs 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' | + sed -E 's/(python:3\.[0-9]+\.)[a-zA-Z0-9\.]+/\1vX/g' | # Normalize HTTP headers sed -E "s/(x-datadog-parent-id:|x-datadog-trace-id:|Content-Length:)[0-9]+/\1XXXX/g" | # Remove Account ID @@ -200,9 +210,11 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do 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/(datadogpy\/)([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 @@ -231,11 +243,15 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do 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/(\"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/(\"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" | @@ -247,8 +263,9 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do echo "Writing logs to $function_snapshot_path because no snapshot exists yet" echo "$logs" >$function_snapshot_path else - # Compare new logs to snapshots - diff_output=$(echo "$logs" | sort | diff -w - <(sort $function_snapshot_path)) + # Compare new logs to snapshots (LC_ALL=C: stable sort; parse-json.js sorts object keys so + # e.g. span meta key order / trailing-comma lines do not vary between runs) + diff_output=$(echo "$logs" | LC_ALL=C sort | diff -w - <(LC_ALL=C sort $function_snapshot_path)) if [ $? -eq 1 ]; then if [ -n "$UPDATE_SNAPSHOTS" ]; then # If $UPDATE_SNAPSHOTS is set to true write the new logs over the current snapshot diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh index 193a6d001..59d572187 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.7" "3.8" "3.9" "3.10" "3.11") +PYTHON_VERSIONS=("3.8" "3.9" "3.10" "3.11" "3.12" "3.13" "3.14") for python_version in "${PYTHON_VERSIONS[@]}" do @@ -18,7 +18,7 @@ do --build-arg python_version=$python_version docker run -w /test \ datadog-lambda-python-test:$python_version \ - nose2 -v + pytest -vv docker run -w /test \ datadog-lambda-python-test:$python_version \ flake8 datadog_lambda/ diff --git a/scripts/setup_python_env.sh b/scripts/setup_python_env.sh new file mode 100755 index 000000000..42dfa7108 --- /dev/null +++ b/scripts/setup_python_env.sh @@ -0,0 +1,74 @@ +#!/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/). + +# Sets up the Python environment for the lint, unit-test, and publish-pypi +# CI jobs (and for local repro of those flows). Replaces the inline +# .python-before-script anchor previously defined in +# ci/input_files/build.yaml.tpl. +# +# Steps: +# 1. (Optional) Rewrite pyproject.toml's ddtrace dep based on the +# env-var contract documented in scripts/_spec_ddtrace_dep.sh +# (DD_TRACE_COMMIT / DD_TRACE_COMMIT_BRANCH / DD_TRACE_WHEEL / +# UPSTREAM_PIPELINE_ID). When dd-trace-py's CI triggers this repo's +# pipeline it sets UPSTREAM_PIPELINE_ID, so the unit-test job +# exercises the PR's wheel rather than the released ddtrace. +# 2. Create and activate a virtualenv ("venv/"). +# 3. Install lambda-python's runtime + dev dependencies. pip resolves the +# whole graph in one pass against the (possibly rewritten) pyproject.toml, +# so any version conflicts surface as install errors instead of +# runtime surprises. +# 4. Install poetry. +# +# Same dep-resolution path as scripts/build_layers.sh — both source +# scripts/_spec_ddtrace_dep.sh. +# +# DD_TRACE_COMMIT / DD_TRACE_COMMIT_BRANCH build ddtrace from source, which +# requires cargo, cmake, and a C/C++ toolchain — not present in the slim +# Python runner images. They are intended for local repro / git-bisect +# workflows. The dd-trace-py CI trigger uses UPSTREAM_PIPELINE_ID. +# +# Venv contract: this script sources venv/bin/activate inside its own +# subshell, so the activation does NOT persist into the calling job. Calling +# jobs must `source venv/bin/activate` themselves before running their +# command (matching the existing pattern in build.yaml.tpl). +# +# Environment variables: +# PYTHON_VERSION Python minor version (e.g. 3.12 or just 12). Required +# when the UPSTREAM_PIPELINE_ID branch is taken. +# ARCH "amd64" or "arm64". Required for correct ddtrace wheel +# selection when UPSTREAM_PIPELINE_ID is set (GitLab matrix +# should pass the runtime arch; if unset, host arch is used). + +set -e + +if [ -z "${IS_LINT:-}" ] || [ "${IS_LINT}" = "0" ] || [ "${IS_LINT}" = "false" ]; then + # Normalize Python version shorthand (e.g. 12 -> 3.12, 3.12 -> 3.12) + if [ -n "${PYTHON_VERSION:-}" ]; then + if [[ "$PYTHON_VERSION" =~ ^[0-9]+$ ]]; then + PYTHON_VERSION="3.${PYTHON_VERSION}" + fi + fi + + # Backup pyproject.toml so the rewrite doesn't persist across runs (matters + # for local invocations; CI runners are ephemeral but cheap to be tidy). + cp pyproject.toml pyproject.toml.bak + cleanup() { + mv pyproject.toml.bak pyproject.toml 2>/dev/null || true + } + trap cleanup EXIT + + source "$(dirname "$0")/_spec_ddtrace_dep.sh" + spec_ddtrace_dep +fi + +pip install virtualenv +virtualenv venv +source venv/bin/activate +pip install .[dev] +pip install poetry + +python -c "import ddtrace; print('ddtrace version:', ddtrace.__version__)" diff --git a/scripts/sign_layers.sh b/scripts/sign_layers.sh index 3c9aa6628..d3c890d38 100755 --- a/scripts/sign_layers.sh +++ b/scripts/sign_layers.sh @@ -9,7 +9,6 @@ set -e LAYER_DIR=".layers" LAYER_FILES=( - "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" @@ -18,6 +17,12 @@ LAYER_FILES=( "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" + "datadog_lambda_py-amd64-3.14.zip" + "datadog_lambda_py-arm64-3.14.zip" ) SIGNING_PROFILE_NAME="DatadogLambdaSigningProfile" @@ -40,6 +45,18 @@ if [ "$1" = "prod" ]; then 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 diff --git a/tests/Dockerfile b/tests/Dockerfile index 948de1bcd..585c0fbe0 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -1,8 +1,13 @@ 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 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-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/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/authorizer-request-api-gateway-v1.json b/tests/event_samples/authorizer-request-api-gateway-v1.json index d14b7aa01..7496c5ed2 100644 --- a/tests/event_samples/authorizer-request-api-gateway-v1.json +++ b/tests/event_samples/authorizer-request-api-gateway-v1.json @@ -55,7 +55,7 @@ "requestContext": { "resourceId": "0et54l", "authorizer": { - "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM0Nzg3MDU5OTU3OTcyMjEyMDkiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI4NDcxMjg4MjYzMzg0MjE2ODk2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjMyOTUwMjE4MjcuNTIxLCAieC1kYXRhZG9nLWF1dGhvcml6aW5nLXJlcXVlc3RpZCI6ICJhYmMxMjMifQ==", + "_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM0Nzg3MDU5OTU3OTcyMjEyMDkiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI4NDcxMjg4MjYzMzg0MjE2ODk2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjMyOTUwMjE4Mjc1MjEwMDAsICJ4LWRhdGFkb2ctYXV0aG9yaXppbmctcmVxdWVzdGlkIjogImFiYzEyMyJ9", "scope": "this is just a string", "principalId": "foo", "integrationLatency": 1897 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/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-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/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/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/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/package-lock.json b/tests/integration/package-lock.json new file mode 100644 index 000000000..c761c5503 --- /dev/null +++ b/tests/integration/package-lock.json @@ -0,0 +1,1194 @@ +{ + "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==", + "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.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "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==", + "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==", + "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.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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==", + "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.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "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/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "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==", + "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.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serverless-plugin-datadog": { + "version": "2.34.1", + "resolved": "https://registry.npmjs.org/serverless-plugin-datadog/-/serverless-plugin-datadog-2.34.1.tgz", + "integrity": "sha512-oDLh+73a7UPgagvWbMGkbTXK2n7+zGeN8aGDhxza5P0jJFpdwICFArkC72CTLOVcY4JYpgB7VAvbbVS9HAamOA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-fetch": "^2.6.1" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "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/split2/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/split2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "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/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "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/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "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..3744185e3 100644 --- a/tests/integration/package.json +++ b/tests/integration/package.json @@ -1,5 +1,9 @@ { "devDependencies": { - "serverless-plugin-datadog": "^2.18.0" + "serverless-plugin-datadog": "^2.18.0", + "serverless-python-requirements": "^6.1.2" + }, + "overrides": { + "minimatch": "^3.1.3" } } diff --git a/tests/integration/parse-json.js b/tests/integration/parse-json.js index 0e54e0dc2..5aaed46e6 100644 --- a/tests/integration/parse-json.js +++ b/tests/integration/parse-json.js @@ -7,10 +7,24 @@ var rl = readline.createInterface({ terminal: false }); +function sortKeys (value) { + if (value === null || typeof value !== 'object') { + return value + } + if (Array.isArray(value)) { + return value.map(sortKeys) + } + var sorted = {} + Object.keys(value).sort().forEach(function (key) { + sorted[key] = sortKeys(value[key]) + }) + return sorted +} + rl.on('line', function(line){ try { const obj = JSON.parse(line) - console.log(JSON.stringify(obj, null, 2)) + console.log(JSON.stringify(sortKeys(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..0275d888c --- /dev/null +++ b/tests/integration/requirements.txt @@ -0,0 +1,5 @@ +certifi==2024.12.14 +charset-normalizer==3.4.1 +idna==3.10 +requests==2.32.4; python_version < "3.10" +requests==2.33.1; python_version >= "3.10" diff --git a/tests/integration/serverless.yml b/tests/integration/serverless.yml index bb64c3972..8c7e62f08 100644 --- a/tests/integration/serverless.yml +++ b/tests/integration/serverless.yml @@ -6,6 +6,7 @@ provider: region: eu-west-1 tracing: lambda: "PassThrough" + architecture: ${env:SLS_ARCH} environment: DD_INTEGRATION_TEST: true DD_TRACE_ENABLED: true @@ -19,11 +20,26 @@ provider: iam: # IAM permissions require that all functions are deployed with this 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) @@ -31,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 @@ -41,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 index d746aba4f..14d4bd670 100644 --- a/tests/integration/snapshots/logs/async-metrics_python310.log +++ b/tests/integration/snapshots/logs/async-metrics_python310.log @@ -1,163 +1,182 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:true", "memorysize:1024", + "cold_start:true", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -166,158 +185,354 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python310_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python310_X.X.X" + ], + "v": 21 +} +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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -326,151 +541,168 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -479,166 +711,183 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -647,158 +896,176 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -807,155 +1074,185 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "trace_id": "XXXX", - "parent_id": "XXXX", - "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -964,156 +1261,174 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1122,155 +1437,173 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1279,163 +1612,181 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python310", "resource:integration-tests-python-XXXX-async-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python310", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python310", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python310", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/logs/async-metrics_python311.log b/tests/integration/snapshots/logs/async-metrics_python311.log index ff437d8e4..62054e97c 100644 --- a/tests/integration/snapshots/logs/async-metrics_python311.log +++ b/tests/integration/snapshots/logs/async-metrics_python311.log @@ -1,163 +1,182 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:true", "memorysize:1024", + "cold_start:true", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -166,158 +185,354 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python311_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python311_X.X.X" + ], + "v": 21 +} +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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -326,151 +541,168 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -479,166 +711,183 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -647,158 +896,176 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -807,155 +1074,185 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "trace_id": "XXXX", - "parent_id": "XXXX", - "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -964,156 +1261,174 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1122,155 +1437,173 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1279,163 +1612,181 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python311", "resource:integration-tests-python-XXXX-async-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python311", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python311", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python311", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] 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..8217a7576 --- /dev/null +++ b/tests/integration/snapshots/logs/async-metrics_python312.log @@ -0,0 +1,1795 @@ +INIT_START Runtime Version: python:3.12.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway", + "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "true", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_version": "1.1", + "language": "python", + "operation_name": "aws.dynamodb", + "peer.service": "integration-tests-python", + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.dynamodb", + "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", + "peer.service": "integration-tests-python", + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.eventbridge", + "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "eventbridge", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", + "endpoint": "/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", + "http.source_ip": "XXXX", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.httpapi", + "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", + "partition_key": "XXXX", + "peer.service": "integration-tests-python", + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.kinesis", + "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", + "object_key": "test/key", + "object_size": "1024", + "operation_name": "aws.s3", + "peer.service": "integration-tests-python", + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", + "peer.service": "integration-tests-python", + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sns", + "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", + "operation_name": "aws.sqs", + "peer.service": "integration-tests-python", + "queuename": "my-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sqs", + "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 21 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", + "event_type": "MESSAGE", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway.websocket", + "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python312", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python312", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/async-metrics_python37.log b/tests/integration/snapshots/logs/async-metrics_python313.log similarity index 57% rename from tests/integration/snapshots/logs/async-metrics_python37.log rename to tests/integration/snapshots/logs/async-metrics_python313.log index e28bb9b39..b1b5afd6e 100644 --- a/tests/integration/snapshots/logs/async-metrics_python37.log +++ b/tests/integration/snapshots/logs/async-metrics_python313.log @@ -1,163 +1,182 @@ -INIT_START Runtime Version: python:3.7.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:true", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:true", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "true", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -166,158 +185,354 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 +} +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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "dynamodb", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -326,151 +541,168 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", - "function_trigger.event_source": "eventbridge" + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", + "function_trigger.event_source": "eventbridge", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -479,166 +711,183 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -647,158 +896,176 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "kinesis", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -807,155 +1074,185 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "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", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "s3", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -964,156 +1261,174 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "sns", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1122,155 +1437,173 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "sqs", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1279,163 +1612,181 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-async-metrics_python37", - "resource:integration-tests-python-XXXX-async-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-async-metrics_python313", + "resource:integration-tests-python-XXXX-async-metrics_python313", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.13", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python313", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python313", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python313", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/logs/async-metrics_python314.log b/tests/integration/snapshots/logs/async-metrics_python314.log new file mode 100644 index 000000000..51fb97994 --- /dev/null +++ b/tests/integration/snapshots/logs/async-metrics_python314.log @@ -0,0 +1,1795 @@ +INIT_START Runtime Version: python:3.14.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:true", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway", + "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "true", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_version": "1.1", + "language": "python", + "operation_name": "aws.dynamodb", + "peer.service": "integration-tests-python", + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.dynamodb", + "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", + "peer.service": "integration-tests-python", + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.eventbridge", + "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "eventbridge", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", + "endpoint": "/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", + "http.source_ip": "XXXX", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.httpapi", + "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", + "partition_key": "XXXX", + "peer.service": "integration-tests-python", + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.kinesis", + "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", + "object_key": "test/key", + "object_size": "1024", + "operation_name": "aws.s3", + "peer.service": "integration-tests-python", + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", + "peer.service": "integration-tests-python", + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sns", + "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", + "operation_name": "aws.sqs", + "peer.service": "integration-tests-python", + "queuename": "my-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sqs", + "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-async-metrics_python314", + "resource:integration-tests-python-XXXX-async-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 21 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", + "event_type": "MESSAGE", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway.websocket", + "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python314", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python314", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms 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 c146ef0fd..d086acb20 100644 --- a/tests/integration/snapshots/logs/async-metrics_python38.log +++ b/tests/integration/snapshots/logs/async-metrics_python38.log @@ -1,163 +1,172 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:true", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -166,158 +175,336 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python38_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python38_X.X.X" + ], + "v": 21 +} +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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -326,151 +513,158 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -479,166 +673,173 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -647,158 +848,166 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -807,155 +1016,175 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "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", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -964,156 +1193,164 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1122,155 +1359,163 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1279,163 +1524,171 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python38", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python38", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python38", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/logs/async-metrics_python39.log b/tests/integration/snapshots/logs/async-metrics_python39.log index bc0fb4e85..1383dd98a 100644 --- a/tests/integration/snapshots/logs/async-metrics_python39.log +++ b/tests/integration/snapshots/logs/async-metrics_python39.log @@ -1,163 +1,172 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:true", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -166,158 +175,336 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python39_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "hello.dog", + "t": [ + "team:serverless", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "tests.integration.count", + "t": [ + "test:integration", + "role:hello", + "dd_lambda_layer:datadog-python39_X.X.X" + ], + "v": 21 +} +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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -326,151 +513,158 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -479,166 +673,173 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -647,158 +848,166 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -807,155 +1016,175 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "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", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -964,156 +1193,164 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1122,155 +1359,163 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1279,163 +1524,171 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", " END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "hello.dog", - "v": 1, "e": XXXX, + "m": "hello.dog", "t": [ "team:serverless", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } { - "m": "tests.integration.count", - "v": 21, "e": XXXX, + "m": "tests.integration.count", "t": [ "test:integration", "role:hello", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 21 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-async-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-async-metrics_python39", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-async-metrics_python39", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-async-metrics_python39", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-async-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/logs/sync-metrics_python310.log b/tests/integration/snapshots/logs/sync-metrics_python310.log index fc71ef6da..e61f20151 100644 --- a/tests/integration/snapshots/logs/sync-metrics_python310.log +++ b/tests/integration/snapshots/logs/sync-metrics_python310.log @@ -1,181 +1,205 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:true", "memorysize:1024", + "cold_start:true", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -184,176 +208,400 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python310_X.X.X" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -362,169 +610,191 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -533,184 +803,206 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -719,176 +1011,199 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -897,173 +1212,208 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "trace_id": "XXXX", - "parent_id": "XXXX", - "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1072,174 +1422,197 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1248,173 +1621,196 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1423,181 +1819,204 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python310", "resource:integration-tests-python-XXXX-sync-metrics_python310", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.10", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python310_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python310", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python310", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python310", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python310", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python310", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python310_X.X.X", "service:integration-tests-python"], "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-python310_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/logs/sync-metrics_python311.log b/tests/integration/snapshots/logs/sync-metrics_python311.log index b83c99208..5f5c9ae95 100644 --- a/tests/integration/snapshots/logs/sync-metrics_python311.log +++ b/tests/integration/snapshots/logs/sync-metrics_python311.log @@ -1,181 +1,205 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:true", "memorysize:1024", + "cold_start:true", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -184,176 +208,400 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python311_X.X.X" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -362,169 +610,191 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -533,184 +803,206 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -719,176 +1011,199 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -897,173 +1212,208 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "trace_id": "XXXX", - "parent_id": "XXXX", - "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1072,174 +1422,197 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1248,173 +1621,196 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1423,181 +1819,204 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-sync-metrics_python311", "resource:integration-tests-python-XXXX-sync-metrics_python311", - "cold_start:false", "memorysize:1024", + "cold_start:false", "runtime:python3.11", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python311_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python311", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python311", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python311", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python311", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python311", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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-python311_X.X.X", "service:integration-tests-python"], "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-python311_X.X.X", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/logs/sync-metrics_python37.log b/tests/integration/snapshots/logs/sync-metrics_python312.log similarity index 53% rename from tests/integration/snapshots/logs/sync-metrics_python37.log rename to tests/integration/snapshots/logs/sync-metrics_python312.log index 5bc76a998..5d3161872 100644 --- a/tests/integration/snapshots/logs/sync-metrics_python37.log +++ b/tests/integration/snapshots/logs/sync-metrics_python312.log @@ -1,181 +1,205 @@ -INIT_START Runtime Version: python:3.7.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:true", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:true", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "true", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -184,176 +208,400 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "dynamodb", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -362,169 +610,191 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", - "function_trigger.event_source": "eventbridge" + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", + "function_trigger.event_source": "eventbridge", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -533,184 +803,206 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -719,176 +1011,199 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -{ - "traces": [ - [ - { - "trace_id": "XXXX", - "parent_id": "XXXX", - "span_id": "XXXX", - "service": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", +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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "kinesis", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -897,173 +1212,208 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "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", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "s3", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1072,174 +1422,197 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "sns", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1248,173 +1621,196 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "sqs", - "function_trigger.event_source_arn": "XXXX" + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1423,181 +1819,204 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-1", "account_id:XXXX", - "functionname:integration-tests-python-XXXX-sync-metrics_python37", - "resource:integration-tests-python-XXXX-sync-metrics_python37", - "cold_start:false", + "functionname:integration-tests-python-XXXX-sync-metrics_python312", + "resource:integration-tests-python-XXXX-sync-metrics_python312", "memorysize:1024", - "runtime:python3.7", + "cold_start:false", + "runtime:python3.12", "datadog_lambda:vXX", - "dd_lambda_layer:datadog-python37_X.X.X" - ] + "dd_lambda_layer:datadog-python312_X.X.X" + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python37", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.svc_src": "m", "cold_start": "false", - "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-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", - "span.name": "aws.lambda", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python312", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python312", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python312", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python312", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", + "_dd.base_service": "integration-tests-python", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] 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..5f36fcaa8 --- /dev/null +++ b/tests/integration/snapshots/logs/sync-metrics_python313.log @@ -0,0 +1,2025 @@ +INIT_START Runtime Version: python:3.13.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway", + "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "true", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python313_X.X.X" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_version": "1.1", + "language": "python", + "operation_name": "aws.dynamodb", + "peer.service": "integration-tests-python", + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.dynamodb", + "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", + "peer.service": "integration-tests-python", + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.eventbridge", + "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "eventbridge", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", + "endpoint": "/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", + "http.source_ip": "XXXX", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.httpapi", + "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", + "partition_key": "XXXX", + "peer.service": "integration-tests-python", + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.kinesis", + "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", + "object_key": "test/key", + "object_size": "1024", + "operation_name": "aws.s3", + "peer.service": "integration-tests-python", + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", + "peer.service": "integration-tests-python", + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sns", + "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", + "operation_name": "aws.sqs", + "peer.service": "integration-tests-python", + "queuename": "my-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sqs", + "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", + "event_type": "MESSAGE", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway.websocket", + "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python313", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python313", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python313", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python313", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB diff --git a/tests/integration/snapshots/logs/sync-metrics_python314.log b/tests/integration/snapshots/logs/sync-metrics_python314.log new file mode 100644 index 000000000..f9b4399d3 --- /dev/null +++ b/tests/integration/snapshots/logs/sync-metrics_python314.log @@ -0,0 +1,2025 @@ +INIT_START Runtime Version: python:3.14.vX Runtime Version ARN: arn:aws:lambda:eu-west-1:XXXX:eu-west-1 +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:true", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway", + "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "true", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "http.method": "GET", + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "event_version": "1.1", + "language": "python", + "operation_name": "aws.dynamodb", + "peer.service": "integration-tests-python", + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.dynamodb", + "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", + "peer.service": "integration-tests-python", + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.eventbridge", + "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "eventbridge", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", + "endpoint": "/httpapi/get", + "http.method": "GET", + "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", + "http.source_ip": "XXXX", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.httpapi", + "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX$default", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "http.method": "GET", + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", + "event_id": "XXXX", + "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", + "partition_key": "XXXX", + "peer.service": "integration-tests-python", + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.kinesis", + "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", + "object_key": "test/key", + "object_size": "1024", + "operation_name": "aws.s3", + "peer.service": "integration-tests-python", + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", + "peer.service": "integration-tests-python", + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sns", + "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", + "operation_name": "aws.sqs", + "peer.service": "integration-tests-python", + "queuename": "my-queue", + "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", + "sender_id": "AIDAIENQZJOLO23YVJ4VO", + "span.kind": "server" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.sqs", + "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "t": [ + "region:eu-west-1", + "account_id:XXXX", + "functionname:integration-tests-python-XXXX-sync-metrics_python314", + "resource:integration-tests-python-XXXX-sync-metrics_python314", + "memorysize:1024", + "cold_start:false", + "runtime:python3.14", + "datadog_lambda:vXX", + "dd_lambda_layer:datadog-python314_X.X.X" + ], + "v": 1 +} +HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate, zstd","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, zstd","Accept:*/*","Connection:keep-alive","User-Agent:python-requests/X.X.X","traceparent:XXX","tracestate:XXX +{ + "traces": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_dd.svc_src": "m", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", + "event_type": "MESSAGE", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", + "peer.service": "integration-tests-python", + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" + }, + "metrics": { + "_dd._inferred_span": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.apigateway.websocket", + "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "_dd.svc_src": "m", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python314", + "function_trigger.event_source": "api-gateway", + "function_trigger.event_source_arn": "XXXX", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python314", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python314", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1 + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python314", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.status_msg": "OK", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate, zstd","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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.base_service": "integration-tests-python", + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.svc_src": "requests", + "_dd.tags.process": "entrypoint.basedir:runtime,entrypoint.name:bootstrap,entrypoint.type:script,entrypoint.workdir:task,svc.user:true", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.status_msg": "Accepted", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms 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 213e64aa7..1293ded9b 100644 --- a/tests/integration/snapshots/logs/sync-metrics_python38.log +++ b/tests/integration/snapshots/logs/sync-metrics_python38.log @@ -1,181 +1,191 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:true", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -184,176 +194,374 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python38_X.X.X" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -362,169 +570,177 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -533,184 +749,192 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -719,176 +943,185 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -897,173 +1130,194 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "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", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1072,174 +1326,183 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1248,173 +1511,182 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1423,181 +1695,190 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.8", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python38_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python38", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python38", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python38", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python38", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python38", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/logs/sync-metrics_python39.log b/tests/integration/snapshots/logs/sync-metrics_python39.log index 54ab2bad2..507eeda04 100644 --- a/tests/integration/snapshots/logs/sync-metrics_python39.log +++ b/tests/integration/snapshots/logs/sync-metrics_python39.log @@ -1,181 +1,191 @@ 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, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:true", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.rest", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/", - "endpoint": "/", - "http.method": "GET", - "resource_names": "GET /", - "apiid": "XXXX", - "apiname": "XXXX", - "stage": "Prod", - "request_id": "XXXX", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "sync", "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/70ixmpl4fl/stages/Prod", + "endpoint": "/", + "http.method": "GET", + "http.route": "/", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "Prod" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway", "parent_id": "XXXX", + "resource": "GET /", + "service": "XXXX.execute-api.us-east-2.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.us-east-2.amazonaws.com", - "http.url_details.path": "/Prod/", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "http.method": "GET", - "http.status_code": "200" + "http.route": "/", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/Prod/", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -184,176 +194,374 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms (init: XXXX ms) Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": [ [ { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", + "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "language": "python", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "runtime-id": "XXXX", + "span.kind": "server", + "span.name": "aws.lambda" + }, + "metrics": { + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "aws.lambda", + "parent_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", + "service": "integration-tests-python", + "span_id": "XXXX", + "start": "XXXX", "trace_id": "XXXX", + "type": "serverless" + }, + { + "duration": "XXXX", + "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1 + }, + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "dynamodb", - "resource": "ExampleTableWithStream", - "name": "aws.dynamodb", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { + "duration": "XXXX", "error": 0, + "meta": { + "_dd.origin": "lambda", + "component": "requests", + "http.method": "GET", + "http.status_code": "200", + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1 + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "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": [ + [ + { "duration": "XXXX", + "error": 0, "meta": { + "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "component": "requests", + "http.method": "POST", + "http.status_code": "202", + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", "runtime-id": "XXXX", + "span.kind": "client" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_sampling_priority_v1": 1, + "process_id": XXXX + }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + } + ] + ] +} +END Duration: XXXX ms Memory Used: XXXX MB +START +{ + "e": XXXX, + "m": "aws.lambda.enhanced.invocations", + "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" + ], + "v": 1 +} +{ + "e": XXXX, + "m": "datadog.serverless.dynamodb.stream.type", + "t": [ + "streamtype:NEW_AND_OLD_IMAGES", + "dd_lambda_layer:datadog-python39_X.X.X" + ], + "v": 1 +} +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": [ + [ + { + "duration": "XXXX", + "error": 0, + "meta": { "_dd.origin": "lambda", - "operation_name": "aws.dynamodb", - "resource_names": "ExampleTableWithStream", - "tablename": "ExampleTableWithStream", - "event_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "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_source_arn": "arn:aws:dynamodb:us-east-1:XXXX:us-east-1/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", "event_version": "1.1", - "stream_view_type": "NEW_AND_OLD_IMAGES", - "size_bytes": "26", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "language": "python", + "operation_name": "aws.dynamodb", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "ExampleTableWithStream", + "runtime-id": "XXXX", + "size_bytes": "26", + "span.kind": "server", + "stream_view_type": "NEW_AND_OLD_IMAGES", + "tablename": "ExampleTableWithStream" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.dynamodb", "parent_id": "XXXX", + "resource": "ExampleTableWithStream", + "service": "ExampleTableWithStream", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + }, + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "e2af34d333891f765c7f02d2da80895e", + "ptr.kind": "aws.dynamodb.item" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_trigger.event_source": "dynamodb", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -362,169 +570,177 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "eventbridge.custom.event.sender", - "name": "aws.eventbridge", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.eventbridge", - "resource_names": "eventbridge.custom.event.sender", - "detail_type": "testdetail", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "detail_type": "testdetail", + "language": "python", + "operation_name": "aws.eventbridge", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "eventbridge.custom.event.sender", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.eventbridge", "parent_id": "XXXX", + "resource": "eventbridge.custom.event.sender", + "service": "eventbridge.custom.event.sender", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_trigger.event_source": "eventbridge", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -533,184 +749,192 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.httpapi", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "XXXX", + "apiname": "XXXX", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/x02yirxc7a/stages/$default", "endpoint": "/httpapi/get", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", "http.protocol": "HTTP/1.1", + "http.route": "/httpapi/get", "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.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "http.useragent": "curl/7.64.1", + "language": "python", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "GET /httpapi/get", + "runtime-id": "XXXX", + "stage": "$default" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "aws.httpapi", "parent_id": "XXXX", + "resource": "GET /httpapi/get", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX$default", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "http.method": "GET", - "http.status_code": "200" + "http.route": "/httpapi/get", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -719,176 +943,185 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "kinesis", - "resource": "EXAMPLE", - "name": "aws.kinesis", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.kinesis", - "resource_names": "EXAMPLE", - "streamname": "EXAMPLE", - "shardid": "shardId-XXXX", - "event_source_arn": "arn:aws:kinesis:EXAMPLE", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:kinesis:EXAMPLE", "event_id": "XXXX", "event_name": "aws:kinesis:record", + "event_source_arn": "arn:aws:kinesis:EXAMPLE", "event_version": "1.0", + "language": "python", + "operation_name": "aws.kinesis", "partition_key": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "EXAMPLE", + "runtime-id": "XXXX", + "shardid": "shardId-XXXX", + "span.kind": "server", + "streamname": "EXAMPLE" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.kinesis", "parent_id": "XXXX", + "resource": "EXAMPLE", + "service": "EXAMPLE", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_trigger.event_source": "kinesis", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -897,173 +1130,194 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "s3", - "resource": "example-bucket", - "name": "aws.s3", "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.s3", - "resource_names": "example-bucket", - "event_name": "ObjectCreated:Put", - "bucketname": "example-bucket", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", "bucket_arn": "arn:aws:s3:::example-bucket", + "bucketname": "example-bucket", + "dd_resource_key": "arn:aws:s3:::example-bucket", + "event_name": "ObjectCreated:Put", + "language": "python", + "object_etag": "XXXX", "object_key": "test/key", "object_size": "1024", - "object_etag": "XXXX", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", + "operation_name": "aws.s3", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "example-bucket", + "runtime-id": "XXXX", + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "aws.s3", + "parent_id": "XXXX", + "resource": "example-bucket", + "service": "example-bucket", + "span_id": "XXXX", + "span_links": [ + { + "attributes": { + "link.kind": "span-pointer", + "ptr.dir": "u", + "ptr.hash": "1dc3e5d00dae48c1f07d95371a747788", + "ptr.kind": "aws.s3.object" + }, + "span_id": "XXXX", + "trace_id": "XXXX" + } + ], + "trace_id": "XXXX", "type": "web" }, { - "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", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_trigger.event_source": "s3", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1072,174 +1326,183 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", - "resource": "sns-lambda", - "name": "aws.sns", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.sns", - "resource_names": "sns-lambda", - "topicname": "sns-lambda", - "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", - "message_id": "XXXX", - "type": "Notification", - "subject": "TestInvoke", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", "_inferred_span.synchronicity": "async", "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "language": "python", + "message_id": "XXXX", + "operation_name": "aws.sns", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "resource_names": "sns-lambda", + "runtime-id": "XXXX", + "span.kind": "server", + "subject": "TestInvoke", + "topic_arn": "arn:aws:sns:us-east-2:XXXX:us-east-2-lambda", + "topicname": "sns-lambda", + "type": "Notification" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sns", "parent_id": "XXXX", + "resource": "sns-lambda", + "service": "sns-lambda", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_trigger.event_source": "sns", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1248,173 +1511,182 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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": "sqs", - "resource": "my-queue", - "name": "aws.sqs", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "async", + "_inferred_span.tag_source": "self", + "dd_resource_key": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", + "language": "python", "operation_name": "aws.sqs", - "resource_names": "my-queue", + "peer.service": "integration-tests-python", "queuename": "my-queue", - "event_source_arn": "arn:aws:sqs:us-east-2:XXXX:us-east-2-queue", "receipt_handle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "resource_names": "my-queue", + "runtime-id": "XXXX", "sender_id": "AIDAIENQZJOLO23YVJ4VO", - "_inferred_span.synchronicity": "async", - "_inferred_span.tag_source": "self", - "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "span.kind": "server" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.sqs", "parent_id": "XXXX", + "resource": "my-queue", + "service": "my-queue", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "cold_start": "false", + "datadog_lambda": "X.X.X", + "dd_trace": "X.X.X", "function_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", + "function_trigger.event_source": "sqs", + "function_trigger.event_source_arn": "XXXX", "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", "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" + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] @@ -1423,181 +1695,190 @@ HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept END Duration: XXXX ms Memory Used: XXXX MB START { - "m": "aws.lambda.enhanced.invocations", - "v": 1, "e": XXXX, + "m": "aws.lambda.enhanced.invocations", "t": [ "region:eu-west-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", + "cold_start:false", "runtime:python3.9", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python39_X.X.X" - ] + ], + "v": 1 } -HTTP GET https://datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} -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:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "x-datadog-trace-id:XXXX"] Data: {} +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", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", - "operation_name": "aws.apigateway.websocket", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default", - "endpoint": "$default", - "resource_names": "$default", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", + "_dd.peer.service.source": "peer.service", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", "apiid": "XXXX", "apiname": "XXXX", - "stage": "dev", - "request_id": "XXXX", "connection_id": "XXXX=", + "dd_resource_key": "arn:aws:apigateway:eu-west-1:XXXX:eu-west-1/restapis/p62c47itsb/stages/dev", + "endpoint": "$default", "event_type": "MESSAGE", - "message_direction": "IN", - "_inferred_span.synchronicity": "sync", - "_inferred_span.tag_source": "self", "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default", + "language": "python", + "message_direction": "IN", + "operation_name": "aws.apigateway.websocket", "peer.service": "integration-tests-python", - "_dd.p.dm": "-0", - "language": "python" + "request_id": "XXXX", + "resource_names": "$default", + "runtime-id": "XXXX", + "span.kind": "server", + "stage": "dev" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, + "_dd._inferred_span": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, - "type": "web" - }, - { - "trace_id": "XXXX", + "name": "aws.apigateway.websocket", "parent_id": "XXXX", + "resource": "$default", + "service": "XXXX.execute-api.eu-west-1.amazonaws.com", "span_id": "XXXX", - "service": "aws.lambda", - "resource": "integration-tests-python-XXXX-sync-metrics_python39", - "name": "aws.lambda", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "web" + }, + { "duration": "XXXX", + "error": 0, "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_arn": "arn:aws:lambda:eu-west-1:XXXX:eu-west-1-tests-python-XXXX-sync-metrics_python39", "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "XXXX", - "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com", - "http.status_code": "200" + "function_version": "$LATEST", + "functionname": "integration-tests-python-XXXX-sync-metrics_python39", + "http.status_code": "200", + "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com", + "request_id": "XXXX", + "resource_names": "integration-tests-python-XXXX-sync-metrics_python39", + "span.kind": "server", + "span.name": "aws.lambda" }, "metrics": { "_dd.top_level": 1 }, - "type": "serverless" - }, - { - "trace_id": "XXXX", + "name": "aws.lambda", "parent_id": "XXXX", - "span_id": "XXXX", + "resource": "integration-tests-python-XXXX-sync-metrics_python39", "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, + "span_id": "XXXX", "start": "XXXX", + "trace_id": "XXXX", + "type": "serverless" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1, "_dd.top_level": 1 }, - "type": "http" - }, - { - "trace_id": "XXXX", + "name": "requests.request", "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", "span_id": "XXXX", - "service": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, "start": "XXXX", + "trace_id": "XXXX", + "type": "http" + }, + { "duration": "XXXX", + "error": 0, "meta": { "_dd.origin": "lambda", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "GET", - "http.url": "https://www.datadoghq.com/", "http.status_code": "200", - "http.useragent": "python-requests/X.X.X" + "http.url": "https://www.datadoghq.com/", + "http.useragent": "python-requests/X.X.X", + "out.host": "www.datadoghq.com", + "span.kind": "client" }, "metrics": { "_dd.measured": 1 }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "GET /", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "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 x86_64)", "traceparent:XXX", "tracestate:dd=s:1;t.dm:-0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-tags:_dd.p.dm=-0", "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", "service:integration-tests-python"], "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", "service:integration-tests-python"], "interval": 10}]} +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": "integration-tests-python", - "resource": "requests.request", - "name": "requests.request", - "error": 0, - "start": "XXXX", "duration": "XXXX", + "error": 0, "meta": { - "runtime-id": "XXXX", "_dd.origin": "lambda", + "_dd.p.dm": "-0", + "_dd.p.tid": "XXXX", "component": "requests", - "span.kind": "client", "http.method": "POST", - "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "http.status_code": "202", - "http.useragent": "datadogpy/XX (python XX; os linux; arch x86_64)", - "_dd.p.dm": "-0", - "language": "python" + "http.url": "https://api.datadoghq.com/api/v1/distribution_points", + "http.useragent": "datadogpy/XX (python XX; os linux; arch XXXX)", + "language": "python", + "out.host": "api.datadoghq.com", + "runtime-id": "XXXX", + "span.kind": "client" }, "metrics": { - "process_id": XXXX, - "_dd.agent_psr": 1, "_dd.measured": 1, "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_sampling_priority_v1": 1, + "process_id": XXXX }, + "name": "requests.request", + "parent_id": "XXXX", + "resource": "POST /api/v1/distribution_points", + "service": "requests", + "span_id": "XXXX", + "start": "XXXX", + "trace_id": "XXXX", "type": "http" } ] diff --git a/tests/integration/snapshots/return_values/async-metrics_appsync.json b/tests/integration/snapshots/return_values/async-metrics_appsync.json new file mode 100644 index 000000000..1ad668ecc --- /dev/null +++ b/tests/integration/snapshots/return_values/async-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_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/yarn.lock b/tests/integration/yarn.lock index 867a90abe..babc7de92 100644 --- a/tests/integration/yarn.lock +++ b/tests/integration/yarn.lock @@ -2,7 +2,718 @@ # yarn lockfile v1 +"2-thenable@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/2-thenable/-/2-thenable-1.0.0.tgz#56e9a2e363293b1e507f501aac1aa9927670b2fc" + integrity sha512-HqiDzaLDFCXkcCO/SwoyhRwqYtINFHF7t9BDRq4x90TOKNAJpiqUt9X5lQ08bwxYzc067HUywDjGySpebHcUpw== + dependencies: + d "1" + es5-ext "^0.10.47" + +"@iarna/toml@^2.2.5": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" + integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +appdirectory@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/appdirectory/-/appdirectory-0.1.0.tgz#eb6c816320e7b2ab16f5ed997f28d8205df56375" + integrity sha512-DJ5DV8vZXBbusyiyPlH28xppwS8eAMRuuyMo88xeEcf4bV64lbLtbxRxqixZuJBXsZzLtXFmA13GwVjJc7vdQw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +brace-expansion@^1.1.7: + version "1.1.18" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.18.tgz#3ce74d89885136be1535341f8c3d4425c29a5cab" + integrity sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +child-process-ext@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/child-process-ext/-/child-process-ext-2.1.1.tgz#f7cf4e68fef60c4c8ee911e1b402413191467dc3" + 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.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + 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.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + 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.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-spawn@^6.0.5: + version "6.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57" + 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, d@^1.0.1, d@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.2.tgz#2aefd554b81981e7dccf72d6842ae725cb17e5de" + 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.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +duration@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/duration/-/duration-0.2.2.tgz#ddf149bc3bc6901150fe9017111d016b3357f529" + 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.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + 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.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + 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.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + 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.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" + integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== + dependencies: + d "^1.0.2" + ext "^1.7.0" + +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + 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.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + 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.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + 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.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + 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.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob-all@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.3.1.tgz#6be2d5d8276902319f640fbf839fbe15b35e7667" + 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.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + 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.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-primitive@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-3.0.1.tgz#98c4db1abff185485a657fc2905052b940524d05" + integrity sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jsonfile@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62" + integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jszip@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + 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.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + +lodash.uniqby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" + integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww== + +lodash.values@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347" + integrity sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q== + +log@^6.0.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/log/-/log-6.3.2.tgz#8e37a672b06161acc994e2b679726c7f3c011016" + 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.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e" + integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== + dependencies: + brace-expansion "^1.1.7" + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-fetch@^2.6.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + 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.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +readable-stream@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + 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.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + 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.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + 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.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +semver@^5.5.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^7.6.0: + version "7.7.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" + integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== + 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" - integrity sha512-RUdCNjUk+uUKQYgQBjK0WNeYJ7lM2/RScqg/LjVSfv5EACeJ3iIUPz1c4bS2jtiH05al8qXudNb6QDkv9zxG7w== + version "2.34.1" + resolved "https://registry.yarnpkg.com/serverless-plugin-datadog/-/serverless-plugin-datadog-2.34.1.tgz#be9de0f9515be1211fdb578db650b716340b9470" + integrity sha512-oDLh+73a7UPgagvWbMGkbTXK2n7+zGeN8aGDhxza5P0jJFpdwICFArkC72CTLOVcY4JYpgB7VAvbbVS9HAamOA== + dependencies: + node-fetch "^2.6.1" + +serverless-python-requirements@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/serverless-python-requirements/-/serverless-python-requirements-6.1.2.tgz#21a222c06ac52736c969b60e251a7e2f606a6a33" + 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.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-value@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-4.1.0.tgz#aa433662d87081b75ad88a4743bd450f044e7d09" + 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.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +sha256-file@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sha256-file/-/sha256-file-1.0.0.tgz#02cade5e658da3fbc167c3270bdcdfd5409f1b65" + integrity sha512-nqf+g0veqgQAkDx0U2y2Tn2KWyADuuludZTw9A7J3D+61rKlIIl9V5TS4mfnwKuXZOH9B7fQyjYJ9pKRHIsAyg== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +shell-quote@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.10.0.tgz#482033e192e4f5c07151521ffa03400ec71b1b0f" + integrity sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA== + +split2@^3.1.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" + integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== + dependencies: + readable-stream "^3.0.0" + +sprintf-kit@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/sprintf-kit/-/sprintf-kit-2.0.2.tgz#e79f0c6076d2bc656b5fb55fa43b737ca98d3ecf" + integrity sha512-lnapdj6W4LflHZGKvl9eVkz5YF0xaTrqpRWVA4cNVOTedwqifIP8ooGImldzT/4IAN5KXFQAyXTdLidYVQdyag== + dependencies: + es5-ext "^0.10.64" + +stream-promise@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/stream-promise/-/stream-promise-3.2.0.tgz#bad976f2d0e1f11d56cc95cc11907cfd869a27ff" + integrity sha512-P+7muTGs2C8yRcgJw/PPt61q7O517tDHiwYEzMWo1GSBCcZedUMT/clz7vUNsSxFphIlJ6QUL4GexQKlfJoVtA== + dependencies: + "2-thenable" "^1.0.0" + es5-ext "^0.10.49" + is-stream "^1.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + 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" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +type@^2.5.0, type@^2.7.2, type@^2.7.3: + version "2.7.3" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.3.tgz#436981652129285cc3ba94f392886c2637ea0486" + integrity sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ== + +uni-global@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/uni-global/-/uni-global-1.0.0.tgz#3583c449e87a2d9dc270ea221410a649bcdad040" + integrity sha512-WWM3HP+siTxzIWPNUg7hZ4XO8clKi6NoCAJJWnuRL+BAqyFXF8gC03WNyTefGoUXYc47uYgXxpKLIEvo65PEHw== + dependencies: + type "^2.5.0" + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-module@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + 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.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + 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..0cb42a0ac --- /dev/null +++ b/tests/test_api.py @@ -0,0 +1,184 @@ +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): + self.env_patcher.stop() + + @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_supported_region(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-east-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-east-1.amazonaws.com" + ) + self.assertEqual(api_key, "test-api-key") + + @patch("datadog_lambda.config.Config.fips_mode_enabled", True) + @patch("datadog_lambda.config.Config.is_gov_region", True) + @patch("botocore.session.Session.create_client") + def test_ssm_gov_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=None) + 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_unsupported_region(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"] = "eu-west-1" + os.environ["DD_API_KEY_SSM_NAME"] = "test-ssm-param" + + with self.assertLogs("datadog_lambda.api", level="WARNING") as log_context: + api_key = api.get_api_key() + + mock_boto3_client.assert_called_with("ssm", endpoint_url=None) + self.assertEqual(api_key, "test-api-key") + self.assertTrue( + any( + "does not support SSM FIPS endpoints" in log_msg + for log_msg in log_context.output + ) + ) + + @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["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 index 65193e1de..5fc11e2cf 100644 --- a/tests/test_cold_start.py +++ b/tests/test_cold_start.py @@ -1,12 +1,63 @@ +import os import time import unittest -import datadog_lambda.cold_start as cold_start + from sys import modules, meta_path -import os 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_is_managed_instances_mode_when_set(self): + os.environ["AWS_LAMBDA_INITIALIZATION_TYPE"] = "lambda-managed-instances" + self.assertTrue(cold_start.is_managed_instances_mode()) + # Clean up + if "AWS_LAMBDA_INITIALIZATION_TYPE" in os.environ: + del os.environ["AWS_LAMBDA_INITIALIZATION_TYPE"] + + def test_is_not_managed_instances_mode_when_not_set(self): + if "AWS_LAMBDA_INITIALIZATION_TYPE" in os.environ: + del os.environ["AWS_LAMBDA_INITIALIZATION_TYPE"] + self.assertFalse(cold_start.is_managed_instances_mode()) + + def test_is_not_managed_instances_mode_with_different_value(self): + os.environ["AWS_LAMBDA_INITIALIZATION_TYPE"] = "on-demand" + self.assertFalse(cold_start.is_managed_instances_mode()) + # Clean up + if "AWS_LAMBDA_INITIALIZATION_TYPE" in os.environ: + del os.environ["AWS_LAMBDA_INITIALIZATION_TYPE"] + + def test_initialize_cold_start_tracing_skips_in_managed_instances(self): + # Set managed instances mode + os.environ["AWS_LAMBDA_INITIALIZATION_TYPE"] = "lambda-managed-instances" + os.environ["DD_COLD_START_TRACING"] = "true" + cold_start._cold_start = True + cold_start._lambda_container_initialized = False + + # Reset node stacks and wrapped loaders to get clean state + cold_start.reset_node_stacks() + cold_start.already_wrapped_loaders.clear() + + # Count wrapped loaders before + wrapped_loaders_before = len(cold_start.already_wrapped_loaders) + + # Initialize cold start tracing - should skip in managed instances mode + cold_start.initialize_cold_start_tracing() + + # Verify no loaders were wrapped + wrapped_loaders_after = len(cold_start.already_wrapped_loaders) + self.assertEqual(wrapped_loaders_before, wrapped_loaders_after) + + # Clean up + if "AWS_LAMBDA_INITIALIZATION_TYPE" in os.environ: + del os.environ["AWS_LAMBDA_INITIALIZATION_TYPE"] + if "DD_COLD_START_TRACING" in os.environ: + del os.environ["DD_COLD_START_TRACING"] + def test_proactive_init(self): cold_start._cold_start = True cold_start._proactive_initialization = False @@ -234,3 +285,43 @@ def test_trace_ignore_libs(self): 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 = load_span = None + for span in spans: + if span.resource == "tabnanny": + import_span = span + elif span.name == "aws.lambda": + function_span = span + elif span.name == "aws.lambda.load": + load_span = span + + assert function_span is not None + assert import_span is not None + assert import_span.parent_id == function_span.span_id + assert import_span.trace_id == function_span.trace_id + assert load_span is not None + assert load_span.trace_id == function_span.trace_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_durable.py b/tests/test_durable.py new file mode 100644 index 000000000..a4f7c2f2d --- /dev/null +++ b/tests/test_durable.py @@ -0,0 +1,178 @@ +# 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 unittest + +from datadog_lambda.durable import ( + _parse_durable_execution_arn, + extract_durable_function_tags, + extract_durable_execution_status, +) + + +class TestParseDurableExecutionArn(unittest.TestCase): + def test_returns_name_and_id_for_valid_arn(self): + arn = "arn:aws:lambda:us-east-1:123456789012:function:my-func:$LATEST/durable-execution/order-123/550e8400-e29b-41d4-a716-446655440001" + result = _parse_durable_execution_arn(arn) + self.assertEqual(result, ("order-123", "550e8400-e29b-41d4-a716-446655440001")) + + def test_returns_none_for_arn_without_durable_execution_marker(self): + arn = "arn:aws:lambda:us-east-1:123456789012:function:my-func:$LATEST" + result = _parse_durable_execution_arn(arn) + self.assertIsNone(result) + + def test_returns_none_for_malformed_arn_with_only_execution_name(self): + arn = "arn:aws:lambda:us-east-1:123456789012:function:my-func:$LATEST/durable-execution/order-123" + result = _parse_durable_execution_arn(arn) + self.assertIsNone(result) + + def test_returns_none_for_malformed_arn_with_empty_execution_name(self): + arn = "arn:aws:lambda:us-east-1:123456789012:function:my-func:$LATEST/durable-execution//550e8400-e29b-41d4-a716-446655440002" + result = _parse_durable_execution_arn(arn) + self.assertIsNone(result) + + def test_returns_none_for_malformed_arn_with_empty_execution_id(self): + arn = "arn:aws:lambda:us-east-1:123456789012:function:my-func:$LATEST/durable-execution/order-123/" + result = _parse_durable_execution_arn(arn) + self.assertIsNone(result) + + def test_works_with_numeric_version_qualifier(self): + arn = "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004" + result = _parse_durable_execution_arn(arn) + self.assertEqual( + result, ("my-execution", "550e8400-e29b-41d4-a716-446655440004") + ) + + +class TestExtractDurableFunctionTags(unittest.TestCase): + def test_sets_first_invocation_true_when_only_execution_operation(self): + # One operation (the current EXECUTION operation itself) → not replaying → first invocation + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004", + "CheckpointToken": "some-token", + "InitialExecutionState": {"Operations": [{"OperationType": "EXECUTION"}]}, + } + result = extract_durable_function_tags(event) + self.assertEqual( + result, + { + "aws.durable.execution_name": "my-execution", + "aws.durable.execution_id": "550e8400-e29b-41d4-a716-446655440004", + "aws.durable.first_invocation": "true", + }, + ) + + def test_sets_first_invocation_false_when_multiple_operations(self): + # More than one operation → replaying → not first invocation + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004", + "CheckpointToken": "some-token", + "InitialExecutionState": { + "Operations": [ + {"OperationType": "EXECUTION"}, + {"OperationType": "STEP"}, + ] + }, + } + result = extract_durable_function_tags(event) + self.assertEqual( + result, + { + "aws.durable.execution_name": "my-execution", + "aws.durable.execution_id": "550e8400-e29b-41d4-a716-446655440004", + "aws.durable.first_invocation": "false", + }, + ) + + def test_returns_empty_dict_for_regular_lambda_event(self): + event = { + "body": '{"key": "value"}', + "headers": {"Content-Type": "application/json"}, + } + result = extract_durable_function_tags(event) + self.assertEqual(result, {}) + + def test_returns_empty_dict_when_event_is_none(self): + result = extract_durable_function_tags(None) + self.assertEqual(result, {}) + + def test_returns_empty_dict_when_event_is_not_a_dict(self): + result = extract_durable_function_tags("not-a-dict") + self.assertEqual(result, {}) + + def test_returns_empty_dict_when_durable_execution_arn_is_not_a_string(self): + event = {"DurableExecutionArn": 12345} + result = extract_durable_function_tags(event) + self.assertEqual(result, {}) + + def test_returns_empty_dict_when_durable_execution_arn_cannot_be_parsed(self): + event = {"DurableExecutionArn": "invalid-arn-without-durable-execution-marker"} + result = extract_durable_function_tags(event) + self.assertEqual(result, {}) + + def test_returns_empty_dict_when_event_is_empty(self): + result = extract_durable_function_tags({}) + self.assertEqual(result, {}) + + +class TestExtractDurableExecutionStatus(unittest.TestCase): + def test_returns_succeeded(self): + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123:function:f:1/durable-execution/n/id" + } + response = {"Status": "SUCCEEDED", "Result": "some-result"} + self.assertEqual(extract_durable_execution_status(response, event), "SUCCEEDED") + + def test_returns_failed(self): + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123:function:f:1/durable-execution/n/id" + } + response = {"Status": "FAILED", "Error": "some-error"} + self.assertEqual(extract_durable_execution_status(response, event), "FAILED") + + def test_returns_pending(self): + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123:function:f:1/durable-execution/n/id" + } + response = {"Status": "PENDING"} + self.assertEqual(extract_durable_execution_status(response, event), "PENDING") + + def test_returns_none_for_non_durable_event(self): + event = {"key": "value"} + response = {"Status": "SUCCEEDED"} + self.assertIsNone(extract_durable_execution_status(response, event)) + + def test_returns_none_for_non_dict_response(self): + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123:function:f:1/durable-execution/n/id" + } + self.assertIsNone(extract_durable_execution_status("string", event)) + + def test_returns_none_for_missing_status(self): + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123:function:f:1/durable-execution/n/id" + } + response = {"Result": "some-result"} + self.assertIsNone(extract_durable_execution_status(response, event)) + + def test_returns_none_for_invalid_status(self): + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123:function:f:1/durable-execution/n/id" + } + response = {"Status": "INVALID"} + self.assertIsNone(extract_durable_execution_status(response, event)) + + def test_returns_none_for_non_dict_event(self): + response = {"Status": "SUCCEEDED"} + self.assertIsNone(extract_durable_execution_status(response, "not-a-dict")) + + def test_returns_none_for_none_event(self): + response = {"Status": "SUCCEEDED"} + self.assertIsNone(extract_durable_execution_status(response, None)) + + def test_returns_none_for_none_response(self): + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-1:123:function:f:1/durable-execution/n/id" + } + self.assertIsNone(extract_durable_execution_status(None, event)) 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 8e5ac3aa3..bd04bf4c7 100644 --- a/tests/test_tag_object.py +++ b/tests/test_tag_object.py @@ -28,7 +28,63 @@ def test_tag_object(self): ], True, ) - self.assertEqual(1, 1) + + @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() + expected_value = str(payload) + + tag_object(spanMock, "function.request", payload) + spanMock.set_tag.assert_has_calls( + [ + call( + "function.request", + expected_value, + ), + ], + True, + ) def test_redacted_tag_object(self): payload = { @@ -50,6 +106,18 @@ def test_redacted_tag_object(self): True, ) + def test_redacted_tag_object_case_insensitive(self): + payload = { + "Authorization": "secret", + "headers": {"X-AUTHORIZATION": "another"}, + } + spanMock = MagicMock() + tag_object(spanMock, "function.request", payload) + spanMock.set_tag.assert_any_call("function.request.Authorization", "redacted") + spanMock.set_tag.assert_any_call( + "function.request.headers.X-AUTHORIZATION", "redacted" + ) + def test_json_tag_object(self): payload = { "token": "world", 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 24e6dcdd5..a74e0139a 100644 --- a/tests/test_tracing.py +++ b/tests/test_tracing.py @@ -1,22 +1,32 @@ -import unittest +import base64 +import copy +import functools import json +import traceback +import pytest import os -import copy +import unittest +from types import SimpleNamespace -from unittest.mock import MagicMock, Mock, patch, call +from unittest.mock import Mock, patch, call, ANY import ddtrace -from ddtrace import tracer -from ddtrace.context import Context +from ddtrace.trace import Context, tracer +from ddtrace._trace.span import Span +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 ( - _deterministic_md5_hash, + HIGHER_64_BITS, + LOWER_64_BITS, + _deterministic_sha256_hash, create_inferred_span, extract_dd_trace_context, create_dd_dummy_metadata_subsegment, @@ -28,13 +38,19 @@ _convert_xray_trace_id, _convert_xray_entity_id, _convert_xray_sampling, - InferredSpanInfo, - extract_context_from_eventbridge_event, 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 EventTypes + +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" @@ -46,85 +62,239 @@ event_samples = "tests/event_samples/" -span_to_finish = None - - -def _clean_up_span(): - global span_to_finish - if span_to_finish is not None: - span_to_finish.finish() - span_to_finish = None - - -def register_span(span): - global span_to_finish - _clean_up_span() - span_to_finish = span - return span - - -def wrapped_span_creator(span_creator_func): - def result_func(*args, **kwargs): - return register_span(span_creator_func(*args, **kwargs)) - - return result_func - - -create_inferred_span = wrapped_span_creator(create_inferred_span) +def with_trace_propagation_style(style): + style_list = list(style.split(",")) + + 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 + + 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), + ), + ( + "application-load-balancer", + 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), +) -class ClientContext(object): - def __init__(self, custom=None): - self.custom = custom +@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() -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 + 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, 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(), @@ -136,17 +306,18 @@ def test_without_datadog_trace_headers(self): {}, ) + @with_trace_propagation_style("datadog") def test_with_non_object_event(self): lambda_ctx = get_mock_context() 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(), @@ -158,20 +329,21 @@ def test_with_non_object_event(self): {}, ) + @with_trace_propagation_style("datadog") def test_with_incomplete_datadog_trace_headers(self): lambda_ctx = get_mock_context() ctx, source, event_source = extract_dd_trace_context( - {"headers": {TraceHeader.TRACE_ID: "123", TraceHeader.PARENT_ID: "321"}}, + {"headers": {TraceHeader.TRACE_ID: "123"}}, 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(), @@ -182,38 +354,89 @@ def test_with_incomplete_datadog_trace_headers(self): }, ) - def test_with_complete_datadog_trace_headers(self): - lambda_ctx = get_mock_context() + 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( - { - "headers": { - TraceHeader.TRACE_ID: "123", - TraceHeader.PARENT_ID: "321", - TraceHeader.SAMPLING_PRIORITY: "1", - } - }, - lambda_ctx, + event_containing_headers, + lambda_context, ) 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", - }, - ) + 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_extracts_durable_trace_context_from_latest_checkpoint_operation_map(self): + lambda_ctx = get_mock_context() + headers = { + TraceHeader.TRACE_ID: "123", + TraceHeader.PARENT_ID: "321", + TraceHeader.SAMPLING_PRIORITY: "1", + } + + event = { + "DurableExecutionArn": "arn:aws:lambda:us-east-2:123456789012:function:demo:1/durable-execution/demo/abc", + "CheckpointToken": "token", + "InitialExecutionState": { + "Operations": { + "0": {"Type": "EXECUTION"}, + "1": { + "Name": "_datadog_0", + "StepDetails": { + "Result": { + TraceHeader.TRACE_ID: "999", + TraceHeader.PARENT_ID: "888", + TraceHeader.SAMPLING_PRIORITY: "1", + } + }, + }, + "2": { + "Name": "_datadog_1", + "StepDetails": {"Result": headers}, + }, + } + }, + } + + ctx, source, _ = extract_dd_trace_context(event, lambda_ctx) + + self.assertEqual(source, "event") + self.assertEqual(ctx, Context(trace_id=123, span_id=321, sampling_priority=1)) + + @with_trace_propagation_style("datadog") def test_with_extractor_function(self): def extractor_foo(event, context): foo = event.get("foo", {}) @@ -237,13 +460,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(), @@ -254,6 +477,7 @@ 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") @@ -271,13 +495,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(), @@ -288,8 +512,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": [ { @@ -304,13 +533,7 @@ 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", } }, @@ -321,118 +544,104 @@ def test_with_sqs_distributed_datadog_trace_data(self): } ] } - ctx, source, event_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, event_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, event_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 = { @@ -455,84 +664,582 @@ 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" - ) - - self.assertEqual( - _convert_xray_trace_id("bd862e3fe1be46a994272793"), "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", + } + } ) - - self.assertEqual( - _convert_xray_trace_id("ffffffffffffffffffffffff"), - "9223372036854775807", # 0x7FFFFFFFFFFFFFFF + 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, ) - def test_convert_xray_entity_id(self): - self.assertEqual( - _convert_xray_entity_id("53995c3f42cd8ad8"), "6023947403358210776" - ) + self.assertEqual(ctx, expected_context) + self.assertEqual(source, "event") - self.assertEqual( - _convert_xray_entity_id("1000000000000000"), "1152921504606846976" - ) + 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_entity_id("ffffffffffffffff"), "18446744073709551615" - ) + ctx, source, _ = extract_dd_trace_context(event, lambda_ctx) - def test_convert_xray_sampling(self): - self.assertEqual(_convert_xray_sampling(True), str(SamplingPriority.USER_KEEP)) + self.assertEqual(source, "event") + self.assertEqual(ctx, expected_context) + self.assertEqual(get_dd_trace_context(), expected_headers) - self.assertEqual( - _convert_xray_sampling(False), str(SamplingPriority.USER_REJECT) + create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY) + self.mock_send_segment.assert_called_with( + XraySubsegment.TRACE_KEY, + expected_context, + ) + + @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" + ) + + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_with_input_datadog(self): + """Legacy SFN context with upstream trace in Execution.Input._datadog""" + sfn_event = { + "Execution": { + "Id": "arn:aws:states:sa-east-1:425362996713:execution:rstrat-sfn-lambda-jsonpath-demo-dev-state-machine:7d67bd1e-57df-4021-8b52-f55d5cad1169", + "Input": { + "hello": "world", + "_datadog": { + "x-datadog-trace-id": "12766418539254701015", + "x-datadog-parent-id": "5497030307431673011", + "x-datadog-sampling-priority": "1", + "x-datadog-tags": "_dd.p.dm=-0,_dd.p.tid=69f4ed3a00000000", + "traceparent": "00-69f4ed3a00000000b12b6e05a63cdbd7-4c495ff0aa056cb3-01", + "tracestate": "dd=p:4c495ff0aa056cb3;s:1;t.dm:-0;t.tid:69f4ed3a00000000", + }, + }, + "StartTime": "2026-05-01T18:13:14.130Z", + "Name": "7d67bd1e-57df-4021-8b52-f55d5cad1169", + "RoleArn": "arn:aws:iam::425362996713:role/rstrat-sfn-lambda-jsonpat-StepFunctionsExecutionRol-mtfEz4KEzBEE", + "RedriveCount": 0, + }, + "State": { + "Name": "InvokeDownstreamSecond", + "EnteredTime": "2026-05-01T18:13:16.310Z", + "RetryCount": 0, + }, + "StateMachine": { + "Id": "arn:aws:states:sa-east-1:425362996713:stateMachine:rstrat-sfn-lambda-jsonpath-demo-dev-state-machine", + "Name": "rstrat-sfn-lambda-jsonpath-demo-dev-state-machine", + }, + } + self._test_step_function_trace_data_common( + sfn_event, 12766418539254701015, 5718818197702795437, "69f4ed3a00000000" + ) + + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_input_datadog_without_tid(self): + """Execution.Input._datadog without _dd.p.tid still preserves upstream trace id""" + sfn_event = { + "Execution": { + "Id": "arn:aws:states:sa-east-1:425362996713:execution:abhinav-activity-state-machine:72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "Input": { + "_datadog": { + "x-datadog-trace-id": "5821803790426892636", + }, + }, + "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", + }, + } + lambda_ctx = get_mock_context() + expected_context = Context( + trace_id=5821803790426892636, + span_id=3929055471293792800, + sampling_priority=1, + meta={}, ) + ctx, source, _ = extract_dd_trace_context(sfn_event, lambda_ctx) -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", + self.assertEqual(source, "event") + self.assertEqual(ctx, expected_context) + + @with_trace_propagation_style("datadog") + def test_step_function_trace_data_input_without_datadog(self): + """Execution.Input without _datadog falls back to deterministic trace id""" + sfn_event = { + "Execution": { + "Id": "arn:aws:states:sa-east-1:425362996713:execution:abhinav-activity-state-machine:72a7ca3e-901c-41bb-b5a3-5f279b92a316", + "Input": {"hello": "world"}, + "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" + ) + + @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" + ) + + # 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" + ) + + @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" + ) + + @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", + ) + + @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._test_step_function_trace_data_common( + sqs_event, 3818106616964044169, 15912108710769293902, "3a4fd1a254eb514a" + ) + + @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", + ) + + @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.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) + @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, 123) - self.assertEqual(span.span_id, 456) + 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() + @patch("datadog_lambda.config.Config.trace_enabled", False) 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 = {} - # no exception thrown - set_correlation_ids() - span = tracer.current_span() - self.assertIsNone(span) + # Incomplete trace context: no dummy span should be created. Do not assert + # tracer.current_span() is None — pytest's CI Visibility plugin (--ddtrace) + # keeps a root test span active for the duration of the test. + self.mock_get_dd_trace_context.return_value = Context() + with patch.object(tracer, "trace") as mock_trace: + set_correlation_ids() + mock_trace.assert_not_called() + + +def _expected_span_pointer_link( + pointer_kind, + pointer_direction, + pointer_hash, + extra_attributes=None, +): + extra_attributes = extra_attributes or {} + return SimpleNamespace( + trace_id=0, + span_id=0, + attributes={ + "ptr.kind": pointer_kind, + "ptr.dir": pointer_direction.value, + "ptr.hash": pointer_hash, + "link.kind": "span-pointer", + **extra_attributes, + }, + ) class TestFunctionSpanTags(unittest.TestCase): def test_function(self): ctx = get_mock_context() span = create_function_execution_span( - ctx, "", False, False, {"source": ""}, False, {} + 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") + try: + self.assertEqual(Span._get_links(span), []) + except: + self.assertEqual(span._links, []) def test_function_with_version(self): function_version = "1" @@ -540,7 +1247,13 @@ def test_function_with_version(self): invoked_function_arn=function_arn + ":" + function_version ) span = create_function_execution_span( - ctx, "", False, False, {"source": ""}, False, {} + 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) @@ -551,7 +1264,13 @@ 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, False, {"source": ""}, False, {} + 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) @@ -561,13 +1280,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, - 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") @@ -576,16 +1295,63 @@ 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"}, + ), + ], + ) + try: + actual_links = Span._get_links(span) + except: + actual_links = span._links + expected_links = [ + _expected_span_pointer_link( + "some.kind", + _SpanPointerDirection.UPSTREAM, + "some.hash", + {}, + ), + _expected_span_pointer_link( + "other.kind", + _SpanPointerDirection.DOWNSTREAM, + "other.hash", + {"extra": "stuff"}, + ), + ] + self.assertEqual(len(actual_links), len(expected_links)) + for actual, expected in zip(actual_links, expected_links): + self.assertEqual(actual.trace_id, expected.trace_id) + self.assertEqual(actual.span_id, expected.span_id) + self.assertEqual(actual.attributes, expected.attributes) + 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) @@ -593,10 +1359,11 @@ def setUp(self): 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): @@ -626,164 +1393,45 @@ 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" -class TestAuthorizerInferredSpans(unittest.TestCase): - def setUp(self): - patcher = patch("ddtrace.Span.finish", autospec=True) - self.mock_span_stop = patcher.start() - self.addCleanup(patcher.stop) - - def tearDown(self): - _clean_up_span() - - def test_create_inferred_span_from_authorizer_request_api_gateway_v1_event(self): - event_sample_source = "authorizer-request-api-gateway-v1" - finish_time = ( - 1663295021.832 # request_time_epoch + integrationLatency for api-gateway-v1 - ) - span = self._authorizer_span_testing_items(event_sample_source, finish_time) - self._basic_common_checks(span, "aws.apigateway.rest") - - def test_create_inferred_span_from_authorizer_request_api_gateway_v1_cached_event( - self, - ): - event_sample_source = "authorizer-request-api-gateway-v1-cached" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "abc123" # injected data's requestId is abc321 - span = create_inferred_span(event, ctx) - self.mock_span_stop.assert_not_called() # NO authorizer span is injected - self._basic_common_checks(span, "aws.apigateway.rest") - - def test_create_inferred_span_from_authorizer_token_api_gateway_v1_event(self): - event_sample_source = "authorizer-token-api-gateway-v1" - finish_time = ( - 1663295021.832 # request_time_epoch + integrationLatency for api-gateway-v1 + 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, ) - span = self._authorizer_span_testing_items(event_sample_source, finish_time) - self._basic_common_checks(span, "aws.apigateway.rest") - - def test_create_inferred_span_from_authorizer_token_api_gateway_v2_cached_event( - self, - ): - event_sample_source = "authorizer-token-api-gateway-v1-cached" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "abc123" # injected data's requestId is abc321 - span = create_inferred_span(event, ctx) - self.mock_span_stop.assert_not_called() # NO authorizer span is injected - self._basic_common_checks(span, "aws.apigateway.rest") - - def test_create_inferred_span_from_authorizer_request_api_gateway_v2_event(self): - event_sample_source = "authorizer-request-api-gateway-v2" - finish_time = 1664228639533775400 # use the injected parent span finish time as an approximation - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "abc123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") - self.mock_span_stop.assert_not_called() - self.assertEqual(span.start_ns, finish_time) - self._basic_common_checks(span, "aws.httpapi") - - def test_create_inferred_span_from_authorizer_request_api_gateway_v2_cached_event( - self, - ): - event_sample_source = "authorizer-request-api-gateway-v2-cached" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "abc123" # injected data's requestId is abc321 - span = create_inferred_span(event, ctx) - self.mock_span_stop.assert_not_called() # NO authorizer span is injected - self._basic_common_checks(span, "aws.httpapi") + set_dd_trace_py_root(TraceContextSource.EVENT, True) - def test_create_inferred_span_from_authorizer_request_api_gateway_websocket_connect_event( - self, - ): - event_sample_source = "authorizer-request-api-gateway-websocket-connect" - finish_time = ( - 1664388386.892 # request_time_epoch + integrationLatency in websocket case - ) - span = self._authorizer_span_testing_items(event_sample_source, finish_time) - self._basic_common_checks( - span, "aws.apigateway.websocket", "web", "$connect", None + 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_create_inferred_span_from_authorizer_request_api_gateway_websocket_message_event( - self, - ): - event_sample_source = "authorizer-request-api-gateway-websocket-message" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "abc123" # injected data's requestId is abc321 - span = create_inferred_span(event, ctx) - self.mock_span_stop.assert_not_called() # NO authorizer span is injected - self._basic_common_checks(span, "aws.apigateway.websocket", "web", "main", None) - - def _authorizer_span_testing_items(self, event_sample_source, finish_time): - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "abc123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") - - # checking the upstream_authorizer_span - self.mock_span_stop.assert_called_once() - args, kwargs = self.mock_span_stop.call_args_list[0] - self.assertEqual(kwargs.get("finish_time", args[1]), finish_time) - self.assertEqual(span.start, finish_time) - authorizer_span = args[0] - self.assertEqual(authorizer_span.name, "aws.apigateway.authorizer") - self.assertEqual(span.parent_id, authorizer_span.span_id) - return span - - def _basic_common_checks( - self, - span, - operation_name, - span_type="http", - route_key="/hello", - http_method="GET", - ): - self.assertEqual(span.get_tag("apiid"), "amddr1rix9") - self.assertEqual(span.get_tag("apiname"), "amddr1rix9") - self.assertEqual(span.get_tag("stage"), "dev") - self.assertEqual(span.get_tag("operation_name"), operation_name) - self.assertEqual(span.span_type, span_type) - self.assertEqual( - span.service, - "amddr1rix9.execute-api.eu-west-1.amazonaws.com", - ) - self.assertEqual( - span.get_tag("http.url"), - "amddr1rix9.execute-api.eu-west-1.amazonaws.com" + route_key, - ) - self.assertEqual(span.get_tag("endpoint"), route_key) - self.assertEqual(span.get_tag("http.method"), http_method) - self.assertEqual( - span.get_tag("resource_names"), - f"{http_method} {route_key}" if http_method else route_key, - ) - self.assertEqual(span.get_tag("request_id"), "abc123") + 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 = {} + # These tests exercise the AWS service-representation / service-mapping + # resolution, which only applies when DD_SERVICE is not set. Pin + # config.service to None so the tests are deterministic regardless of + # whether DD_SERVICE is present in the environment (e.g. in CI). + service_patcher = patch("datadog_lambda.config.Config.service", None) + service_patcher.start() + self.addCleanup(service_patcher.stop) def get_service_mapping(self): return global_service_mapping @@ -823,12 +1471,14 @@ def test_get_service_mapping(self): 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) + @patch("datadog_lambda.config.Config.service", None) def test_determine_service_name(self): # Prepare the environment os.environ["DD_SERVICE_MAPPING"] = "api1:service1,api2:service2" @@ -863,6 +1513,111 @@ def test_determine_service_name(self): "default", ) + # Test with DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED disabled + with patch( + "datadog_lambda.config.Config.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 enabled (default) + with patch( + "datadog_lambda.config.Config.aws_service_representation_enabled", True + ): + 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_determine_service_name_with_remove_integration_flag(self): + # By default (flag off), inferred spans use the AWS resource name even + # when DD_SERVICE is set. + with patch("datadog_lambda.config.Config.service", "my-service"): + self.assertEqual( + determine_service_name( + {}, "queue-name", "lambda_sqs", "queue-name", "sqs" + ), + "queue-name", + ) + + # With DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED, inferred + # spans use DD_SERVICE instead of the AWS resource name. + with patch( + "datadog_lambda.config.Config." + "remove_integration_service_names_enabled", + True, + ): + self.assertEqual( + determine_service_name( + {}, "queue-name", "lambda_sqs", "queue-name", "sqs" + ), + "my-service", + ) + + # An explicit service mapping still wins over DD_SERVICE. + self.assertEqual( + determine_service_name( + {"lambda_sqs": "mapped-service"}, + "queue-name", + "lambda_sqs", + "queue-name", + "sqs", + ), + "mapped-service", + ) + + # DD_SERVICE is used even when AWS service representation is + # disabled. + with patch( + "datadog_lambda.config.Config." + "aws_service_representation_enabled", + False, + ): + self.assertEqual( + determine_service_name( + {}, "queue-name", "lambda_sqs", "queue-name", "sqs" + ), + "my-service", + ) + + # When DD_SERVICE is not set, the flag has no effect (resource name). + with patch("datadog_lambda.config.Config.service", None): + with patch( + "datadog_lambda.config.Config." + "remove_integration_service_names_enabled", + True, + ): + self.assertEqual( + determine_service_name( + {}, "queue-name", "lambda_sqs", "queue-name", "sqs" + ), + "queue-name", + ) + 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) @@ -875,7 +1630,6 @@ def test_remaps_all_inferred_span_service_names_from_api_gateway_event(self): 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 @@ -884,7 +1638,6 @@ def test_remaps_all_inferred_span_service_names_from_api_gateway_event(self): "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( @@ -901,14 +1654,12 @@ def test_remaps_specific_inferred_span_service_names_from_api_gateway_event( 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" ) @@ -951,14 +1702,12 @@ def test_remaps_specific_inferred_span_service_names_from_api_gateway_http_event 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" ) @@ -1055,7 +1804,28 @@ def test_remaps_specific_inferred_span_service_names_from_sqs_event(self): ] = "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, "sqs") + self.assertEqual(span2.service, "different-sqs-url") + + def test_create_inferred_span_uses_dd_service_with_remove_integration_flag( + self, + ): + # With DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED and DD_SERVICE + # set, inferred spans use DD_SERVICE instead of the AWS resource 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" + + with patch("datadog_lambda.config.Config.service", "my-dd-service"), patch( + "datadog_lambda.config.Config." "remove_integration_service_names_enabled", + True, + ): + span = create_inferred_span(original_event, ctx) + self.assertEqual(span.get_tag("operation_name"), "aws.sqs") + self.assertEqual(span.service, "my-dd-service") def test_remaps_all_inferred_span_service_names_from_sns_event(self): self.set_service_mapping({"lambda_sns": "new-name"}) @@ -1101,7 +1871,7 @@ def test_remaps_specific_inferred_span_service_names_from_sns_event(self): ] = "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, "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"}) @@ -1138,7 +1908,7 @@ def test_remaps_specific_inferred_span_service_names_from_kinesis_event(self): span1 = create_inferred_span(original_event, ctx) self.assertEqual(span1.get_tag("operation_name"), "aws.kinesis") - self.assertEqual(span1.service, "kinesis") + self.assertEqual(span1.service, "kinesisStream") # Testing the second event event2 = copy.deepcopy(original_event) @@ -1147,7 +1917,7 @@ def test_remaps_specific_inferred_span_service_names_from_kinesis_event(self): ] = "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, "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"}) @@ -1191,7 +1961,7 @@ def test_remaps_specific_inferred_span_service_names_from_s3_event(self): 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, "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"}) @@ -1237,7 +2007,7 @@ def test_remaps_specific_inferred_span_service_names_from_dynamodb_event(self): ] = "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, "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"}) @@ -1281,736 +2051,1871 @@ def test_remaps_specific_inferred_span_service_names_from_eventbridge_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, "eventbridge") + self.assertEqual(span2.service, "different.eventbridge.custom.event.sender") + def test_remaps_all_inferred_span_service_names_from_alb_event(self): + self.set_service_mapping({"lambda_alb": "new-name"}) + with open(f"{event_samples}application-load-balancer.json") as event: + original_event = json.load(event) -class TestInferredSpans(unittest.TestCase): - def tearDown(self): - _clean_up_span() + ctx = get_mock_context() + ctx.aws_request_id = "123" + + span1 = create_inferred_span(original_event, ctx) + self.assertEqual(span1.get_tag("operation_name"), "aws.alb") + self.assertEqual(span1.service, "new-name") + + event2 = copy.deepcopy(original_event) + event2["headers"]["host"] = "different-alb.us-east-2.elb.amazonaws.com" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.alb") + self.assertEqual(span2.service, "new-name") + + def test_remaps_specific_inferred_span_service_names_from_alb_event(self): + host = "lambda-alb-123578498.us-east-2.elb.amazonaws.com" + self.set_service_mapping({host: "mapped-alb-service"}) + with open(f"{event_samples}application-load-balancer.json") as event: + original_event = json.load(event) - def test_create_inferred_span_from_api_gateway_event(self): - event_sample_source = "api-gateway" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - 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.alb") + self.assertEqual(span1.service, "mapped-alb-service") + + event2 = copy.deepcopy(original_event) + event2["headers"]["host"] = "other-alb.us-east-2.elb.amazonaws.com" + span2 = create_inferred_span(event2, ctx) + self.assertEqual(span2.get_tag("operation_name"), "aws.alb") + self.assertEqual(span2.service, "other-alb.us-east-2.elb.amazonaws.com") + + +class TestAlbInferredSpan(unittest.TestCase): + ALB_SAMPLE = "application-load-balancer" + ALB_MULTIVALUE = "application-load-balancer-multivalue-headers" + ALB_HOST = "lambda-alb-123578498.us-east-2.elb.amazonaws.com" + ALB_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" + ) + + def _load_event(self, sample_name): + with open(f"{event_samples}{sample_name}.json") as event_file: + return json.load(event_file) + + def test_create_inferred_span_from_alb_event(self): + event = self._load_event(self.ALB_SAMPLE) + ctx = get_mock_context(aws_request_id="123") + span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.apigateway.rest") + + self.assertIsNotNone(span) + self.assertEqual(span.name, "aws.alb") + self.assertEqual(span.span_type, "http") + self.assertEqual(span.service, self.ALB_HOST) + self.assertEqual(span.resource, "GET /lambda") + self.assertEqual(span.get_tag("operation_name"), "aws.alb") + self.assertEqual(span.get_tag("span.kind"), "server") + self.assertEqual(span.get_tag("http.method"), "GET") self.assertEqual( - span.service, - "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + span.get_tag("http.url"), + "http://%s/lambda" % self.ALB_HOST, ) + self.assertEqual(span.get_tag("http.useragent"), self.ALB_USER_AGENT) + self.assertEqual(span.get_tag("endpoint"), "/lambda") + self.assertEqual(span.get_tag("resource_names"), "GET /lambda") + self.assertEqual(span.get_tag("request_id"), "123") + self.assertEqual(span.get_tag("_inferred_span.synchronicity"), "sync") + self.assertEqual(span.get_tag("_inferred_span.tag_source"), "self") + self.assertEqual(span.get_metric("_dd._inferred_span"), 1.0) self.assertEqual( - span.get_tag("http.url"), - "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", + span.get_tag("target_group_arn"), + "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-xyz/123abc", ) - self.assertEqual(span.get_tag("endpoint"), "/path/to/resource") - self.assertEqual(span.get_tag("http.method"), "POST") + + def test_create_inferred_span_omits_tags_when_headers_missing(self): + event = self._load_event(self.ALB_SAMPLE) + del event["headers"] + event["httpMethod"] = None + event["path"] = None + + span = create_inferred_span(event, get_mock_context()) + + self.assertIsNotNone(span) + self.assertNotIn("http.url", span.get_tags()) + self.assertNotIn("http.method", span.get_tags()) + self.assertNotIn("http.useragent", span.get_tags()) + + def test_multivalue_headers_subtype_emits_inferred_span(self): + event = self._load_event(self.ALB_MULTIVALUE) + span = create_inferred_span(event, get_mock_context()) + self.assertIsNotNone(span) + self.assertEqual(span.name, "aws.alb") + self.assertEqual(span.get_tag("http.method"), "GET") self.assertEqual( - span.get_tag("resource_names"), - "POST /path/to/resource", + span.get_tag("http.url"), + "http://%s/lambda" % self.ALB_HOST, ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "1234567890") - self.assertEqual(span.get_tag("apiname"), "1234567890") - self.assertEqual(span.get_tag("stage"), "prod") - self.assertEqual(span.start, 1428582896.0) - self.assertEqual(span.span_type, "http") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") + self.assertEqual(span.get_tag("http.useragent"), self.ALB_USER_AGENT) - def test_create_inferred_span_from_api_gateway_non_proxy_event_async(self): - event_sample_source = "api-gateway-non-proxy-async" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) + @with_trace_propagation_style("datadog") + def test_inbound_datadog_context_from_multivalue_headers(self): + event = self._load_event(self.ALB_MULTIVALUE) ctx = get_mock_context() - ctx.aws_request_id = "123" + + parent_ctx, source, _ = extract_dd_trace_context(event, ctx) + self.assertIsNotNone(parent_ctx) + self.assertEqual(parent_ctx.trace_id, 12345) + self.assertEqual(parent_ctx.span_id, 67890) + + set_dd_trace_py_root(source, merge_xray_traces=False) span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.apigateway.rest") - self.assertEqual( - span.service, - "lgxbo6a518.execute-api.eu-west-1.amazonaws.com", - ) + self.assertEqual(span.trace_id, parent_ctx.trace_id) + self.assertEqual(span.parent_id, parent_ctx.span_id) + + @with_trace_propagation_style("datadog") + def test_inbound_datadog_context_parents_inferred_span(self): + event = self._load_event(self.ALB_SAMPLE) + ctx = get_mock_context() + + parent_ctx, source, _ = extract_dd_trace_context(event, ctx) + set_dd_trace_py_root(source, merge_xray_traces=False) + span = create_inferred_span(event, ctx) + + self.assertEqual(span.trace_id, parent_ctx.trace_id) + self.assertEqual(span.parent_id, parent_ctx.span_id) + + def test_inbound_w3c_context_extracted_from_alb_event(self): + event = self._load_event(self.ALB_SAMPLE) + event["headers"] = { + "host": self.ALB_HOST, + "user-agent": self.ALB_USER_AGENT, + "x-forwarded-proto": "http", + "traceparent": "00-0000000000000000000000000000abcd-000000000000004d-01", + "tracestate": "dd=s:1", + } + + ctx, source, _ = extract_dd_trace_context(event, get_mock_context()) + + self.assertIsNotNone(ctx) + self.assertEqual(source, TraceContextSource.EVENT) + self.assertEqual(ctx.trace_id, 0xABCD) + self.assertEqual(ctx.span_id, 0x4D) + + def test_http_url_uses_https_when_forwarded_proto_is_https(self): + event = self._load_event(self.ALB_SAMPLE) + event["headers"]["x-forwarded-proto"] = "https" + + span = create_inferred_span(event, get_mock_context()) + self.assertEqual( span.get_tag("http.url"), - "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", - ) - self.assertEqual(span.get_tag("endpoint"), "/http/get") - self.assertEqual(span.get_tag("http.method"), "GET") - self.assertEqual( - span.get_tag("resource_names"), - "GET /http/get", + "https://%s/lambda" % self.ALB_HOST, ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "lgxbo6a518") - self.assertEqual(span.get_tag("apiname"), "lgxbo6a518") - self.assertEqual(span.get_tag("stage"), "dev") - self.assertEqual(span.start, 1631210915.2510002) - self.assertEqual(span.span_type, "http") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") - def test_create_inferred_span_from_api_gateway_non_proxy_event_sync(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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.apigateway.rest") - self.assertEqual( - span.service, - "lgxbo6a518.execute-api.eu-west-1.amazonaws.com", - ) - self.assertEqual( - span.get_tag("http.url"), - "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", - ) - self.assertEqual(span.get_tag("endpoint"), "/http/get") - self.assertEqual(span.get_tag("http.method"), "GET") - self.assertEqual( - span.get_tag("resource_names"), - "GET /http/get", - ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "lgxbo6a518") - self.assertEqual(span.get_tag("apiname"), "lgxbo6a518") - self.assertEqual(span.get_tag("stage"), "dev") - self.assertEqual(span.start, 1631210915.2510002) - self.assertEqual(span.span_type, "http") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") + def test_http_url_excludes_query_string(self): + event = self._load_event(self.ALB_SAMPLE) - def test_create_inferred_span_from_http_api_event(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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.httpapi") - self.assertEqual( - span.service, - "x02yirxc7a.execute-api.eu-west-1.amazonaws.com", - ) - self.assertEqual( - span.get_tag("http.url"), - "x02yirxc7a.execute-api.eu-west-1.amazonaws.com/httpapi/get", - ) - self.assertEqual(span.get_tag("endpoint"), "/httpapi/get") - self.assertEqual(span.get_tag("http.method"), "GET") - self.assertEqual( - span.get_tag("resource_names"), - "GET /httpapi/get", - ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "x02yirxc7a") - self.assertEqual(span.get_tag("apiname"), "x02yirxc7a") - self.assertEqual(span.get_tag("stage"), "$default") - self.assertEqual(span.get_tag("http.protocol"), "HTTP/1.1") - self.assertEqual(span.get_tag("http.source_ip"), "38.122.226.210") - self.assertEqual(span.get_tag("http.user_agent"), "curl/7.64.1") - self.assertEqual(span.start, 1631212283.738) - self.assertEqual(span.span_type, "http") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") + span = create_inferred_span(event, get_mock_context()) - def test_create_inferred_span_from_api_gateway_websocket_default_event(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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.apigateway.websocket") - self.assertEqual( - span.service, - "p62c47itsb.execute-api.eu-west-1.amazonaws.com", - ) - self.assertEqual( - span.get_tag("http.url"), - "p62c47itsb.execute-api.eu-west-1.amazonaws.com$default", - ) - self.assertEqual(span.get_tag("endpoint"), "$default") - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "$default", - ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "p62c47itsb") - self.assertEqual(span.get_tag("apiname"), "p62c47itsb") - self.assertEqual(span.get_tag("stage"), "dev") - self.assertEqual(span.get_tag("connection_id"), "Fc5SzcoYGjQCJlg=") - self.assertEqual(span.get_tag("event_type"), "MESSAGE") - self.assertEqual(span.get_tag("message_direction"), "IN") - self.assertEqual(span.start, 1631285061.365) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") - - def test_create_inferred_span_from_api_gateway_websocket_connect_event(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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.apigateway.websocket") - self.assertEqual( - span.service, - "p62c47itsb.execute-api.eu-west-1.amazonaws.com", - ) - self.assertEqual( - span.get_tag("http.url"), - "p62c47itsb.execute-api.eu-west-1.amazonaws.com$connect", - ) - self.assertEqual(span.get_tag("endpoint"), "$connect") - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "$connect", - ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "p62c47itsb") - self.assertEqual(span.get_tag("apiname"), "p62c47itsb") - self.assertEqual(span.get_tag("stage"), "dev") - self.assertEqual(span.get_tag("connection_id"), "Fc2tgfl3mjQCJfA=") - self.assertEqual(span.get_tag("event_type"), "CONNECT") - self.assertEqual(span.get_tag("message_direction"), "IN") - self.assertEqual(span.start, 1631284003.071) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") - - def test_create_inferred_span_from_api_gateway_websocket_disconnect_event(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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.apigateway.websocket") - self.assertEqual( - span.service, - "p62c47itsb.execute-api.eu-west-1.amazonaws.com", - ) - self.assertEqual( - span.get_tag("http.url"), - "p62c47itsb.execute-api.eu-west-1.amazonaws.com$disconnect", - ) - self.assertEqual(span.get_tag("endpoint"), "$disconnect") - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "$disconnect", - ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "p62c47itsb") - self.assertEqual(span.get_tag("apiname"), "p62c47itsb") - self.assertEqual(span.get_tag("stage"), "dev") - self.assertEqual(span.get_tag("connection_id"), "Fc2tgfl3mjQCJfA=") - self.assertEqual(span.get_tag("event_type"), "DISCONNECT") - self.assertEqual(span.get_tag("message_direction"), "IN") - self.assertEqual(span.start, 1631284034.737) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") - - def test_create_inferred_span_from_sqs_event_string_msg_attr(self): - 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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.sqs") - self.assertEqual( - span.service, - "sqs", - ) self.assertEqual( span.get_tag("http.url"), - None, - ) - self.assertEqual(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "InferredSpansQueueNode", - ) - self.assertEqual(span.get_tag("request_id"), None) - self.assertEqual(span.get_tag("queuename"), "InferredSpansQueueNode") - self.assertEqual( - span.get_tag("event_source_arn"), - "arn:aws:sqs:eu-west-1:601427279990:InferredSpansQueueNode", - ) - self.assertEqual( - span.get_tag("sender_id"), - "AROAYYB64AB3LSVUYFP5T:harv-inferred-spans-dev-initSender", - ) - self.assertEqual(span.start, 1634662094.538) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") + "http://%s/lambda" % self.ALB_HOST, + ) + self.assertNotIn("query=", span.get_tag("http.url") or "") + + +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="web", + 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", + "http.useragent": "Custom User Agent String", + "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="web", + 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", + "http.useragent": "curl/7.64.1", + "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="web", + 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", + "http.useragent": "curl/7.64.1", + "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="web", + 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.useragent": "curl/7.64.1", + "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="web", + 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", + "http.useragent": "curl/8.1.2", + "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="web", + 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", + "http.useragent": "curl/8.1.2", + "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="web", + 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", + "http.useragent": "Custom User Agent String", + "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="web", + 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", + "http.useragent": "PostmanRuntime/7.29.2", + "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="web", + 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", + "http.useragent": "PostmanRuntime/7.29.2", + "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="web", + 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", + "http.useragent": "PostmanRuntime/7.29.2", + "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="web", + 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", + "http.useragent": "PostmanRuntime/7.29.2", + "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="web", + 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", + "http.useragent": "curl/7.64.1", + "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="web", + 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", + "http.useragent": "PostmanRuntime/7.29.2", + "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", + }, + ), + ), +) - def test_create_inferred_span_from_sns_event_string_msg_attr(self): - 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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.sns") - self.assertEqual( - span.service, - "sns", - ) - self.assertEqual( - span.get_tag("http.url"), - None, - ) - self.assertEqual(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "serverlessTracingTopicPy", - ) - self.assertEqual(span.get_tag("topicname"), "serverlessTracingTopicPy") - self.assertEqual( - span.get_tag("topic_arn"), - "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", - ) - self.assertEqual( - span.get_tag("message_id"), "87056a47-f506-5d77-908b-303605d3b197" - ) - self.assertEqual(span.get_tag("type"), "Notification") - self.assertEqual(span.get_tag("subject"), None) - self.assertEqual(span.start, 1643638421.637) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") - - def test_create_inferred_span_from_sns_event_b64_msg_attr(self): - event_sample_name = "sns-b64-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() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.sns") - self.assertEqual( - span.service, - "sns", - ) - self.assertEqual( - span.get_tag("http.url"), - None, - ) - self.assertEqual(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "serverlessTracingTopicPy", - ) - self.assertEqual(span.get_tag("topicname"), "serverlessTracingTopicPy") - self.assertEqual( - span.get_tag("topic_arn"), - "arn:aws:sns:eu-west-1:601427279990:serverlessTracingTopicPy", + +@pytest.mark.parametrize("source,expect", _test_create_inferred_span) +@patch("ddtrace.trace.Span.finish", autospec=True) +@patch("datadog_lambda.config.Config.service", None) +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 + + +@patch("ddtrace.trace.Span.finish", autospec=True) +def test_authorizer_span_no_negative_duration_when_clock_skew(mock_span_finish): + """ + Simulate the case where requestTimeEpoch + integrationLatency < parentSpanFinishTime + (i.e., API Gateway's reported end is before the authorizer lambda's self-reported finish). + This 1ms discrepancy would produce a negative duration. + """ + with open(f"{event_samples}authorizer-request-api-gateway-v1.json") as f: + event = json.load(f) + + authorizer_ctx = json.loads( + base64.b64decode(event["requestContext"]["authorizer"]["_datadog"]) + ) + parent_finish_time_ns = authorizer_ctx["x-datadog-parent-span-finish-time"] + request_time_epoch_ms = event["requestContext"]["requestTimeEpoch"] + # Set integrationLatency 1ms below the parent span's finish time to simulate clock skew. + event["requestContext"]["authorizer"]["integrationLatency"] = ( + parent_finish_time_ns // 1_000_000 - request_time_epoch_ms - 1 + ) + + ctx = get_mock_context(aws_request_id="123") + create_inferred_span(event, ctx) + + args = mock_span_finish.call_args_list[0].args + authorizer_span, finish_time = args[0], args[1] + + assert finish_time >= authorizer_span.start, ( + f"Authorizer span has negative duration: " + f"finish_time={finish_time} < start={authorizer_span.start}" + ) + + +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" ) - self.assertEqual( - span.get_tag("message_id"), "87056a47-f506-5d77-908b-303605d3b197" + 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 ) - self.assertEqual(span.get_tag("type"), "Notification") - self.assertEqual(span.get_tag("subject"), None) - self.assertEqual(span.start, 1643638421.637) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") + mock_submit_errors_metric.assert_called_once() + self.assertEqual(1, mock_span.error) - def test_create_inferred_span_from_kinesis_event(self): - event_sample_source = "kinesis" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.kinesis") - self.assertEqual( - span.service, - "kinesis", + +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( - span.get_tag("http.url"), - None, + 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(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "stream/kinesisStream", + 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", + } ) - self.assertEqual(span.get_tag("request_id"), None) - self.assertEqual(span.get_tag("streamname"), "stream/kinesisStream") - self.assertEqual(span.get_tag("shardid"), "shardId-000000000002") - self.assertEqual( - span.get_tag("event_source_arn"), - "arn:aws:kinesis:eu-west-1:601427279990:stream/kinesisStream", + 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 ) - self.assertEqual( - span.get_tag("event_id"), - "shardId-000000000002:49624230154685806402418173680709770494154422022871973922", - ) - self.assertEqual(span.get_tag("event_name"), "aws:kinesis:record") - self.assertEqual(span.get_tag("event_version"), "1.0") - self.assertEqual(span.get_tag("partition_key"), "partitionkey") - self.assertEqual(span.start, 1643638425.163) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") - - def test_create_inferred_span_from_dynamodb_event(self): - event_sample_source = "dynamodb" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.dynamodb") - self.assertEqual( - span.service, - "dynamodb", + 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( - span.get_tag("http.url"), - None, + + 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(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "ExampleTableWithStream", + + 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(span.get_tag("request_id"), None) - self.assertEqual(span.get_tag("tablename"), "ExampleTableWithStream") - self.assertEqual( - span.get_tag("event_source_arn"), - "arn:aws:dynamodb:us-east-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", - ) - self.assertEqual(span.get_tag("event_id"), "c4ca4238a0b923820dcc509a6f75849b") - self.assertEqual(span.get_tag("event_name"), "INSERT") - self.assertEqual(span.get_tag("event_version"), "1.1") - self.assertEqual(span.get_tag("stream_view_type"), "NEW_AND_OLD_IMAGES") - self.assertEqual(span.get_tag("size_bytes"), "26") - self.assertEqual(span.start, 1428537600.0) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") - - def test_create_inferred_span_from_s3_event(self): - event_sample_source = "s3" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.s3") - self.assertEqual( - span.service, - "s3", + 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( - span.get_tag("http.url"), - None, + + 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.assertEqual(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "example-bucket", - ) - self.assertEqual(span.get_tag("request_id"), None) - self.assertEqual(span.get_tag("event_name"), "ObjectCreated:Put") - self.assertEqual(span.get_tag("bucketname"), "example-bucket") - self.assertEqual(span.get_tag("bucket_arn"), "arn:aws:s3:::example-bucket") - self.assertEqual(span.get_tag("object_key"), "test/key") - self.assertEqual(span.get_tag("object_size"), "1024") - self.assertEqual( - span.get_tag("object_etag"), "0123456789abcdef0123456789abcdef" + + 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(span.start, 0.0) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") - def test_create_inferred_span_from_eventbridge_event(self): - event_sample_source = "eventbridge-custom" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.eventbridge") - self.assertEqual( - span.service, - "eventbridge", + 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( - span.get_tag("http.url"), - None, + + 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(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "eventbridge.custom.event.sender", - ) - self.assertEqual(span.get_tag("request_id"), None) - self.assertEqual(span.start, 1635989865.0) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") - - def test_create_inferred_span_from_eventbridge_sqs_event(self): - event_sample_name = "eventbridge-sqs" - test_file = event_samples + event_sample_name + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.sqs") - self.assertEqual( - span.service, - "sqs", + 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( - span.get_tag("http.url"), - None, + 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(span.get_tag("endpoint"), None) - self.assertEqual(span.get_tag("http.method"), None) - self.assertEqual( - span.get_tag("resource_names"), - "eventbridge-sqs-queue", + + 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.assertEqual(span.get_tag("request_id"), None) - self.assertEqual(span.get_tag("queuename"), "eventbridge-sqs-queue") - self.assertEqual( - span.get_tag("event_source_arn"), - "arn:aws:sqs:us-east-1:425362996713:eventbridge-sqs-queue", + + 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( - span.get_tag("sender_id"), - "AIDAJXNJGGKNS7OSV23OI", + + 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(span.start, 1691102943.638) - self.assertEqual(span.span_type, "web") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "async") - def test_extract_context_from_eventbridge_event(self): - event_sample_source = "eventbridge-custom" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - trace, parent, sampling = extract_context_from_eventbridge_event(event, ctx) - self.assertEqual(trace, "12345") - self.assertEqual(parent, "67890"), - self.assertEqual(sampling, "2") + 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_extract_dd_trace_context_for_eventbridge(self): - event_sample_source = "eventbridge-custom" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_type = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "12345") - self.assertEqual(context["parent-id"], "67890") + @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", + } + ] + } - def test_extract_context_from_eventbridge_sqs_event(self): - event_sample_source = "eventbridge-sqs" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) + 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", + } - ctx = get_mock_context() - context, source, event_type = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "7379586022458917877") - self.assertEqual(context["parent-id"], "2644033662113726488") - self.assertEqual(context["sampling-priority"], "1") + event = { + "Records": [ + { + "eventSourceARN": "", # Empty SQS ARN + "body": json.dumps(sns_notification), + "eventSource": "aws:sqs", + } + ] + } - def test_extract_context_from_sqs_event_with_string_msg_attr(self): - event_sample_source = "sqs-string-msg-attribute" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_type = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "2684756524522091840") - self.assertEqual(context["parent-id"], "7431398482019833808") - self.assertEqual(context["sampling-priority"], "1") + extract_context_from_sqs_or_sns_event_or_context( + event, self.lambda_context, parse_event_source(event) + ) - def test_extract_context_from_sqs_batch_event(self): - event_sample_source = "sqs-batch" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_source = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "2684756524522091840") - self.assertEqual(context["parent-id"], "7431398482019833808") - self.assertEqual(context["sampling-priority"], "1") + self.mock_checkpoint.assert_not_called() - def test_extract_context_from_sns_event_with_string_msg_attr(self): - event_sample_source = "sns-string-msg-attribute" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_source = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "4948377316357291421") - self.assertEqual(context["parent-id"], "6746998015037429512") - self.assertEqual(context["sampling-priority"], "1") + @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" - def test_extract_context_from_sns_event_with_b64_msg_attr(self): - event_sample_source = "sns-b64-msg-attribute" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_source = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "4948377316357291421") - self.assertEqual(context["parent-id"], "6746998015037429512") - self.assertEqual(context["sampling-priority"], "1") + _dsm_set_checkpoint(context_json, event_type, arn) - def test_extract_context_from_sns_batch_event(self): - event_sample_source = "sns-batch" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_source = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "4948377316357291421") - self.assertEqual(context["parent-id"], "6746998015037429512") - self.assertEqual(context["sampling-priority"], "1") + self.mock_checkpoint.assert_not_called() - def test_extract_context_from_kinesis_event(self): - event_sample_source = "kinesis" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_source = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "4948377316357291421") - self.assertEqual(context["parent-id"], "2876253380018681026") - self.assertEqual(context["sampling-priority"], "1") + # KINESIS TESTS - def test_extract_context_from_kinesis_batch_event(self): - event_sample_source = "kinesis-batch" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - context, source, event_source = extract_dd_trace_context(event, ctx) - self.assertEqual(context["trace-id"], "4948377316357291421") - self.assertEqual(context["parent-id"], "2876253380018681026") - self.assertEqual(context["sampling-priority"], "1") + 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() - def test_create_inferred_span_from_api_gateway_event_no_apiid(self): - event_sample_source = "api-gateway-no-apiid" - test_file = event_samples + event_sample_source + ".json" - with open(test_file, "r") as event: - event = json.load(event) - ctx = get_mock_context() - ctx.aws_request_id = "123" - span = create_inferred_span(event, ctx) - self.assertEqual(span.get_tag("operation_name"), "aws.apigateway.rest") + 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( - span.service, - "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + 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( - span.get_tag("http.url"), - "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", + args[1], "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" ) - self.assertEqual(span.get_tag("endpoint"), "/path/to/resource") - self.assertEqual(span.get_tag("http.method"), "POST") + 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( - span.get_tag("resource_names"), - "POST /path/to/resource", + args[1], "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream" ) - self.assertEqual(span.get_tag("request_id"), "123") - self.assertEqual(span.get_tag("apiid"), "None") - self.assertEqual(span.get_tag("apiname"), "None") - self.assertEqual(span.get_tag("stage"), "prod") - self.assertEqual(span.start, 1428582896.0) - self.assertEqual(span.span_type, "http") - self.assertEqual(span.get_tag(InferredSpanInfo.TAG_SOURCE), "self") - self.assertEqual(span.get_tag(InferredSpanInfo.SYNCHRONICITY), "sync") + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) - @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() + 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() - @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.span.Span) - status_code = "500" - mark_trace_as_error_for_5xx_responses( - context="fake_context", status_code=status_code, span=mock_span + 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" ) - mock_submit_errors_metric.assert_called_once() - self.assertEqual(1, mock_span.error) + carrier_get = args[2] + # None indicates no DSM context propagation + self.assertEqual(carrier_get("dd-pathway-ctx-base64"), None) - def test_no_error_with_nonetype_headers(self): - lambda_ctx = get_mock_context() - ctx, source, event_type = extract_dd_trace_context( - {"headers": None}, - lambda_ctx, + @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" ) - self.assertEqual(ctx, None) + 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() -class TestStepFunctionsTraceContext(unittest.TestCase): - def test_deterministic_m5_hash(self): - result = _deterministic_md5_hash("some_testing_random_string") - self.assertEqual("2251275791555400689", result) + event = { + "Records": [ + { + "eventSourceARN": "", + "kinesis": {"data": encoded_data}, + } + ] + } - def test_deterministic_m5_hash__result_the_same_as_backend(self): - result = _deterministic_md5_hash( - "arn:aws:states:sa-east-1:601427271234:express:DatadogStateMachine:acaf1a67-336a-e854-1599-2a627eb2dd8a" - ":c8baf081-31f1-464d-971f-70cb17d01111#step-one#2022-12-08T21:08:19.224Z" - ) - self.assertEqual("8034507082463708833", result) + extract_context_from_kinesis_event(event, self.lambda_context) - def test_deterministic_m5_hash__always_leading_with_zero(self): - for i in range(100): - result = _deterministic_md5_hash(str(i)) - 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")) + 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 2f5148113..eb21f1e32 100644 --- a/tests/test_trigger.py +++ b/tests/test_trigger.py @@ -5,22 +5,20 @@ 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" @@ -120,6 +118,22 @@ def test_event_source_application_load_balancer(self): 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.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", @@ -234,6 +248,20 @@ def test_event_source_sqs(self): "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.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" test_file = event_samples + event_sample_source + ".json" @@ -245,6 +273,37 @@ def test_event_source_unsupported(self): 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): @@ -259,9 +318,10 @@ 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", }, ) @@ -277,9 +337,10 @@ def test_extract_trigger_tags_api_gateway_non_proxy(self): { "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/lgxbo6a518/stages/dev", - "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/dev/http/get", + "http.url": "https://lgxbo6a518.execute-api.eu-west-1.amazonaws.com/dev/http/get", "http.method": "GET", + "http.route": "/http/get", + "span.kind": "server", }, ) @@ -295,7 +356,8 @@ def test_extract_trigger_tags_api_gateway_websocket_connect(self): { "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", - "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "span.kind": "server", }, ) @@ -311,7 +373,8 @@ def test_extract_trigger_tags_api_gateway_websocket_default(self): { "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", - "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "span.kind": "server", }, ) @@ -327,7 +390,8 @@ def test_extract_trigger_tags_api_gateway_websocket_disconnect(self): { "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev", - "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com", + "span.kind": "server", }, ) @@ -343,9 +407,10 @@ def test_extract_trigger_tags_api_gateway_http_api(self): { "function_trigger.event_source": "api-gateway", "function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/x02yirxc7a/stages/$default", - "http.url": "x02yirxc7a.execute-api.eu-west-1.amazonaws.com", - "http.url_details.path": "/httpapi/get", + "http.url": "https://x02yirxc7a.execute-api.eu-west-1.amazonaws.com/httpapi/get", "http.method": "GET", + "span.kind": "server", + "http.route": "/httpapi/get", }, ) @@ -361,11 +426,50 @@ 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", + "http.url": "http://lambda-alb-123578498.us-east-2.elb.amazonaws.com/lambda", + "http.route": "/lambda", + "http.useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36", + "span.kind": "server", }, ) + def test_extract_trigger_tags_application_load_balancer_multivalue_headers(self): + event_sample_source = "application-load-balancer-multivalue-headers" + 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) + + assert tags.get("function_trigger.event_source") == "application-load-balancer" + assert tags.get("http.method") == "GET" + assert tags.get("http.route") == "/lambda" + assert tags.get("http.url") == ( + "http://lambda-alb-123578498.us-east-2.elb.amazonaws.com/lambda" + ) + assert tags.get("http.useragent").startswith("Mozilla/5.0") + + def test_extract_trigger_tags_alb_referer_from_lowercase_headers(self): + event_sample_source = "application-load-balancer" + with open(event_samples + event_sample_source + ".json") as event_file: + event = json.load(event_file) + event["headers"]["referer"] = "https://example.com/page" + + tags = extract_trigger_tags(event, get_mock_context()) + + self.assertEqual(tags.get("http.referer"), "https://example.com/page") + + def test_extract_trigger_tags_alb_referer_from_multivalue_headers(self): + event_sample_source = "application-load-balancer-multivalue-headers" + with open(event_samples + event_sample_source + ".json") as event_file: + event = json.load(event_file) + event["multiValueHeaders"]["referer"] = ["https://example.com/page"] + + tags = extract_trigger_tags(event, get_mock_context()) + + self.assertEqual(tags.get("http.referer"), "https://example.com/page") + def test_extract_trigger_tags_cloudfront(self): event_sample_source = "cloudfront" test_file = event_samples + event_sample_source + ".json" @@ -486,6 +590,21 @@ def test_extract_trigger_tags_sqs(self): }, ) + 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", + }, + ) + def test_extract_trigger_tags_unsupported(self): event_sample_source = "custom" test_file = event_samples + event_sample_source + ".json" @@ -501,6 +620,64 @@ 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_referer_case_insensitive(self): + from datadog_lambda.trigger import extract_http_tags + + event = {"headers": {"Referer": "https://example.com/capitalized"}} + http_tags = extract_http_tags(event) + self.assertEqual( + http_tags.get("http.referer"), "https://example.com/capitalized" + ) + + event = {"headers": {"referer": "https://example.com/lowercase"}} + http_tags = extract_http_tags(event) + self.assertEqual(http_tags.get("http.referer"), "https://example.com/lowercase") + + 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): @@ -515,3 +692,72 @@ 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)) + + def test_is_step_function_event_payload_not_dict(self): + event = {"Payload": "This is a string, not a dict"} + 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 c85d8bb4f..26a53b0c5 100644 --- a/tests/test_wrapper.py +++ b/tests/test_wrapper.py @@ -2,29 +2,25 @@ import json import os import unittest +import importlib +import sys +import pytest -from unittest.mock import patch, call, ANY, MagicMock +from unittest.mock import MagicMock, patch, call, ANY from datadog_lambda.constants import TraceHeader 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 tests.utils import get_mock_context, reset_xray_connection -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 +MAX_UINT_64BITS = (1 << 64) - 1 class TestDatadogLambdaWrapper(unittest.TestCase): @@ -32,10 +28,8 @@ def setUp(self): # Force @datadog_lambda_wrapper to always create a real # (not no-op) wrapper. patch("ddtrace.internal.remoteconfig.worker.RemoteConfigPoller").start() - patch("ddtrace.internal.writer.AgentWriter.flush_queue").start() wrapper.datadog_lambda_wrapper._force_wrap = True - wrapper.dd_tracing_enabled = True patcher = patch( "datadog.threadstats.reporters.HttpReporter.flush_distributions" ) @@ -55,40 +49,36 @@ 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): - wrapper.dd_tracing_enabled = False - @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): lambda_metric("test.metric", 100) @@ -98,7 +88,6 @@ def lambda_handler(event, context): lambda_context = get_mock_context() lambda_handler(lambda_event, lambda_context) - wrapper.dd_tracing_enabled = True self.mock_threadstats_flush_distributions.assert_has_calls( [ call( @@ -124,9 +113,9 @@ def lambda_handler(event, context): ) 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): + self.addCleanup(os.environ.pop, "DD_FLUSH_TO_LOG", None) os.environ["DD_FLUSH_TO_LOG"] = "True" @wrapper.datadog_lambda_wrapper @@ -138,8 +127,6 @@ def lambda_handler(event, context): self.mock_threadstats_flush_distributions.assert_not_called() - del os.environ["DD_FLUSH_TO_LOG"] - def test_datadog_lambda_wrapper_flush_in_thread(self): # force ThreadStats to flush in thread import datadog_lambda.metric as metric_module @@ -154,6 +141,7 @@ def lambda_handler(event, context): 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) @@ -194,9 +182,10 @@ 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): + self.addCleanup(os.environ.pop, "DD_LOGS_INJECTION", None) os.environ["DD_LOGS_INJECTION"] = "True" - wrapper.dd_tracing_enabled = False @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): @@ -204,12 +193,9 @@ def lambda_handler(event, context): lambda_event = {} lambda_handler(lambda_event, get_mock_context()) - wrapper.dd_tracing_enabled = True 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): @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): @@ -228,9 +214,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", @@ -259,9 +245,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", @@ -275,9 +261,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", @@ -292,7 +278,7 @@ 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": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", + "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com", "http.url_details.path": "/prod/path/to/resource", "http.method": "GET", } @@ -314,9 +300,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", @@ -330,9 +316,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", @@ -351,7 +337,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") @@ -366,9 +352,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", @@ -382,9 +368,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", @@ -417,8 +403,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", @@ -451,8 +437,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", @@ -462,9 +448,8 @@ 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" - @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): raise RuntimeError() @@ -476,10 +461,8 @@ 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) @@ -497,10 +480,13 @@ def lambda_handler(event, context): 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): + # TODO(astuyve) this is now set by CI, so we need to null it out for this case + self.addCleanup(os.environ.pop, "DD_SERVICE", None) + os.environ["DD_SERVICE"] = "aws.lambda" + @wrapper.datadog_lambda_wrapper def lambda_handler(event, context): pass @@ -508,6 +494,7 @@ def lambda_handler(event, context): self.assertEqual(os.environ.get("DD_REQUESTS_SERVICE_NAME"), "aws.lambda") def test_dd_requests_service_name_set(self): + self.addCleanup(os.environ.pop, "DD_SERVICE", None) os.environ["DD_SERVICE"] = "myAwesomeService" @wrapper.datadog_lambda_wrapper @@ -515,8 +502,8 @@ 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): @@ -538,23 +525,21 @@ def lambda_handler(event, context): lambda_event = {} lambda_context = get_mock_context() - mock_span = MagicMock() - mock_span.context.span_id = "123" - mock_span.context.trace_id = "456" - mock_span.context.sampling_priority = "1" - mock_span.context.dd_origin = None - mock_span.start_ns = 1668127541671386817 - mock_span.duration_ns = 1e8 - lambda_handler.inferred_span = mock_span - lambda_handler.make_inferred_span = False + 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.assertEquals(inject_data[TraceHeader.PARENT_ID], "123") - self.assertEquals(inject_data[TraceHeader.TRACE_ID], "456") - self.assertEquals(inject_data[TraceHeader.SAMPLING_PRIORITY], "1") - self.assertEquals(result["context"]["scope"], "still here") + 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): @@ -567,17 +552,600 @@ def return_type_test(event, context): return test_result result = return_type_test({}, mock_context) - self.assertEquals(result, test_result) + self.assertEqual(result, test_result) self.assertFalse(MockPrintExc.called) -class TestLambdaDecoratorSettings(unittest.TestCase): - def test_some_envs_should_depend_on_dd_tracing_enabled(self): - wrapper.dd_tracing_enabled = False - os.environ[wrapper.DD_TRACE_MANAGED_SERVICES] = "true" - os.environ[wrapper.DD_ENCODE_AUTHORIZER_CONTEXT] = "true" - os.environ[wrapper.DD_DECODE_AUTHORIZER_CONTEXT] = "true" - decorator = wrapper._LambdaDecorator(func=None) - self.assertFalse(decorator.make_inferred_span) - self.assertFalse(decorator.encode_authorizer_context) - self.assertFalse(decorator.decode_authorizer_context) +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.dict( + os.environ, + { + "AWS_XRAY_DAEMON_ADDRESS": xray_daemon_envvar, + "_X_AMZN_TRACE_ID": xray_trace_envvar, + }, + clear=True, + ) + 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 + + class BlockingException(BaseException): + pass + + def lambda_handler(event, context): + self.mock_get_asm_blocking_response.return_value = ( + self.fake_blocking_response + ) + raise 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_handler_exception_propagates_when_appsec_enabled(self): + # Regression guard: before the fix, `return` in the `finally` block + # would silently swallow handler exceptions when no blocking response + # was set, preventing them from reaching the caller. + self.mock_get_asm_blocking_response.return_value = None + + class HandlerError(Exception): + pass + + def lambda_handler(event, context): + raise HandlerError("handler error") + + lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler) + + with self.assertRaises(HandlerError): + lambda_handler(self.api_gateway_request, get_mock_context()) + + def test_no_blocking_appsec_disabled(self): + self.addCleanup(os.environ.pop, "DD_APPSEC_ENABLED", None) + 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) + + Profiler_start_calls: list = [] + Profiler_stop_calls: list = [] + + real_Profiler_start = wrapper.profiler.Profiler.start + real_Profiler_stop = wrapper.profiler.Profiler.stop + + def Profiler_start(*args: object, **kwargs: object) -> None: + Profiler_start_calls.append((args, kwargs)) + return real_Profiler_start(*args, **kwargs) + + def Profiler_stop(*args: object, **kwargs: object) -> None: + Profiler_stop_calls.append((args, kwargs)) + return real_Profiler_stop(*args, **kwargs) + + monkeypatch.setattr("datadog_lambda.wrapper.is_new_sandbox", lambda: True) + monkeypatch.setattr( + "datadog_lambda.wrapper.profiler.Profiler.start", Profiler_start + ) + monkeypatch.setattr("datadog_lambda.wrapper.profiler.Profiler.stop", Profiler_stop) + + 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 + + lambda_handler.prof.stop() + + +@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 + + +@patch("datadog_lambda.config.Config.profiling_enabled", True) +def test_profiling_import_errors_caught(monkeypatch): + # when importing profiler fails, disable profiling instead of crashing app + monkeypatch.setitem( + sys.modules, "ddtrace.profiling", None + ) # force ModuleNotFoundError + importlib.reload(wrapper) + assert not hasattr(wrapper.datadog_lambda_wrapper, "prof") + + +class TestAlbInferredSpanWrapper(unittest.TestCase): + """End-to-end wrapper tests for the inferred aws.alb span (FRSLES-851).""" + + def setUp(self): + patch("ddtrace.internal.remoteconfig.worker.RemoteConfigPoller").start() + wrapper.datadog_lambda_wrapper._force_wrap = True + + patcher = patch( + "datadog.threadstats.reporters.HttpReporter.flush_distributions" + ) + self.mock_flush_distributions = patcher.start() + self.addCleanup(patcher.stop) + + patcher = patch("datadog_lambda.xray.send_segment") + self.mock_send_segment = patcher.start() + self.addCleanup(patcher.stop) + + patcher = patch("datadog_lambda.wrapper.create_dd_dummy_metadata_subsegment") + self.mock_create_dd_dummy_metadata_subsegment = patcher.start() + self.addCleanup(patcher.stop) + + with open("tests/event_samples/application-load-balancer.json") as f: + self.alb_event = json.load(f) + + def _alb_response(self, status_code=200): + return { + "statusCode": status_code, + "statusDescription": f"{status_code} OK", + "headers": {"Content-Type": "application/json"}, + "body": "{}", + "isBase64Encoded": False, + } + + @patch("datadog_lambda.config.Config.trace_enabled", True) + @patch("datadog_lambda.config.Config.make_inferred_span", True) + def test_wrapper_emits_inferred_alb_span_with_http_tags(self): + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return self._alb_response(200) + + lambda_handler(self.alb_event, get_mock_context()) + + inferred = lambda_handler.inferred_span + execution = lambda_handler.span + + self.assertIsNotNone(inferred) + self.assertEqual(inferred.name, "aws.alb") + self.assertEqual(inferred.get_tag("operation_name"), "aws.alb") + self.assertEqual(inferred.get_tag("http.method"), "GET") + self.assertEqual( + inferred.get_tag("http.url"), + "http://lambda-alb-123578498.us-east-2.elb.amazonaws.com/lambda", + ) + self.assertEqual(inferred.get_tag("http.status_code"), "200") + self.assertEqual(inferred.get_tag("http.route"), "/lambda") + self.assertEqual(execution.parent_id, inferred.span_id) + + @patch("datadog_lambda.config.Config.trace_enabled", True) + @patch("datadog_lambda.config.Config.make_inferred_span", True) + @patch("datadog_lambda.config.Config.service", "alb-demo-downstream") + def test_wrapper_sets_peer_service_and_dd_resource_key(self): + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return self._alb_response(200) + + lambda_handler(self.alb_event, get_mock_context()) + + inferred = lambda_handler.inferred_span + + self.assertEqual(inferred.get_tag("peer.service"), "alb-demo-downstream") + self.assertEqual( + inferred.get_tag("dd_resource_key"), + "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-xyz/123abc", + ) + + @patch("datadog_lambda.config.Config.trace_enabled", True) + @patch("datadog_lambda.config.Config.make_inferred_span", False) + def test_wrapper_skips_inferred_alb_span_when_disabled(self): + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return self._alb_response(200) + + lambda_handler(self.alb_event, get_mock_context()) + + self.assertIsNone(lambda_handler.inferred_span) + self.assertIsNotNone(lambda_handler.span) + + @patch("datadog_lambda.config.Config.trace_enabled", True) + @patch("datadog_lambda.config.Config.make_inferred_span", True) + def test_wrapper_inferred_alb_span_joins_inbound_datadog_context(self): + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return self._alb_response(200) + + lambda_handler(self.alb_event, get_mock_context()) + + inferred = lambda_handler.inferred_span + + self.assertIsNotNone(inferred) + # Fixture carries x-datadog-trace-id=12345, x-datadog-parent-id=67890 + self.assertEqual(inferred.trace_id, 12345) + self.assertEqual(inferred.parent_id, 67890) + + @patch("datadog_lambda.config.Config.trace_enabled", True) + @patch("datadog_lambda.config.Config.make_inferred_span", True) + def test_wrapper_sets_error_on_inferred_alb_span_for_5xx(self): + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return self._alb_response(502) + + lambda_handler(self.alb_event, get_mock_context()) + + inferred = lambda_handler.inferred_span + execution = lambda_handler.span + + self.assertEqual(inferred.get_tag("http.status_code"), "502") + self.assertEqual(execution.get_tag("http.status_code"), "502") + self.assertEqual(execution.error, 1) + + @patch("datadog_lambda.config.Config.trace_enabled", True) + @patch("datadog_lambda.config.Config.make_inferred_span", True) + def test_wrapper_emits_inferred_alb_span_for_multivalue_headers(self): + with open( + "tests/event_samples/application-load-balancer-multivalue-headers.json" + ) as f: + event = json.load(f) + + @wrapper.datadog_lambda_wrapper + def lambda_handler(event, context): + return self._alb_response(200) + + lambda_handler(event, get_mock_context()) + + inferred = lambda_handler.inferred_span + execution = lambda_handler.span + + self.assertIsNotNone(inferred) + self.assertEqual(inferred.name, "aws.alb") + self.assertEqual(inferred.get_tag("http.method"), "GET") + self.assertEqual( + inferred.get_tag("http.url"), + "http://lambda-alb-123578498.us-east-2.elb.amazonaws.com/lambda", + ) + self.assertEqual(inferred.get_tag("http.status_code"), "200") + self.assertEqual(inferred.get_tag("http.route"), "/lambda") + self.assertEqual(execution.parent_id, inferred.span_id) diff --git a/tests/test_xray.py b/tests/test_xray.py index ac3594a99..8177e46e8 100644 --- a/tests/test_xray.py +++ b/tests/test_xray.py @@ -4,15 +4,14 @@ from unittest.mock import MagicMock, patch -from datadog_lambda.xray import ( - get_xray_host_port, - build_segment_payload, - build_segment, - send_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") @@ -21,26 +20,26 @@ def tearDown(self): 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" + os.environ["_X_AMZN_TRACE_ID"] = ( + "Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=0;Lineage=c6c5b1b9:0" + ) with patch( - "datadog_lambda.xray.send", MagicMock(return_value=None) + "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"}) @@ -48,11 +47,11 @@ def test_send_segment_sampled_out(self): 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" + os.environ["_X_AMZN_TRACE_ID"] = ( + "Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1;Lineage=c6c5b1b9:0" + ) with patch( - "datadog_lambda.xray.send", MagicMock(return_value=None) + "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"}) 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