diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt index 4a1af0d411..a76b8eea89 100644 --- a/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt @@ -21,7 +21,7 @@ object AndroidConfig { const val MIN_SDK_FOR_AUTO = 29 const val BUILD_TOOLS_VERSION = "36.0.0" - val VERSION = Version(2, 26, 0, Version.Type.Snapshot) + val VERSION = Version(3, 0, 0, Version.Type.Snapshot) } // TODO RUM-628 Switch to Java 17 bytecode diff --git a/ci/pipelines/default-pipeline.yml b/ci/pipelines/default-pipeline.yml index d1fd6bf142..08384177c3 100644 --- a/ci/pipelines/default-pipeline.yml +++ b/ci/pipelines/default-pipeline.yml @@ -6,9 +6,6 @@ include: stages: - ci-image - security - - analysis - - test # TODO RUM-1622 cleanup eventually - - test-pyramid - publish - notify @@ -75,427 +72,14 @@ create_key: - pubkeys -# STATIC ANALYSIS - -static-analysis: - stage: analysis - variables: - DETEKT_PUBLIC_API: "true" - DETEKT_GENERATE_CLASSPATH_BUILD_TASK: "printSdkDebugRuntimeClasspath" - DETEKT_CLASSPATH_FILE_PATH: "sdk_classpath" - FLAVORED_ANDROID_LINT: ":tools:lint:lint" - trigger: - include: "https://gitlab-templates.ddbuild.io/mobile/v34714656-060be019/static-analysis.yml" - strategy: depend - -analysis:detekt-custom: - tags: - - "arch:amd64" - image: $CI_IMAGE_DOCKER - stage: analysis - timeout: 1h - script: - - ./gradlew assembleLibrariesRelease --stacktrace - - ./gradlew unzipAarForDetekt --stacktrace - - ./gradlew :tools:detekt:jar --stacktrace - - ./gradlew printDetektClasspath --stacktrace - - curl -sSLO https://github.com/detekt/detekt/releases/download/v1.23.4/detekt-cli-1.23.4-all.jar - - ./gradlew :dd-sdk-android-core:customDetektRules - - ./gradlew :dd-sdk-android-internal:customDetektRules - - ./gradlew :features:dd-sdk-android-logs:customDetektRules - - ./gradlew :features:dd-sdk-android-ndk:customDetektRules - - ./gradlew :features:dd-sdk-android-rum:customDetektRules - - ./gradlew :features:dd-sdk-android-session-replay:customDetektRules - - ./gradlew :features:dd-sdk-android-session-replay-material:customDetektRules - - ./gradlew :features:dd-sdk-android-session-replay-compose:customDetektRules - - ./gradlew :features:dd-sdk-android-trace-internal:customDetektRules - - ./gradlew :features:dd-sdk-android-trace:customDetektRules - - ./gradlew :features:dd-sdk-android-trace-otel:customDetektRules - - ./gradlew :features:dd-sdk-android-webview:customDetektRules - - ./gradlew :integrations:dd-sdk-android-coil:customDetektRules - - ./gradlew :integrations:dd-sdk-android-compose:customDetektRules - - ./gradlew :integrations:dd-sdk-android-fresco:customDetektRules - - ./gradlew :integrations:dd-sdk-android-glide:customDetektRules - - ./gradlew :integrations:dd-sdk-android-okhttp:customDetektRules - - ./gradlew :integrations:dd-sdk-android-okhttp-otel:customDetektRules - - ./gradlew :integrations:dd-sdk-android-rum-coroutines:customDetektRules - - ./gradlew :integrations:dd-sdk-android-rx:customDetektRules - - ./gradlew :integrations:dd-sdk-android-sqldelight:customDetektRules - - ./gradlew :integrations:dd-sdk-android-timber:customDetektRules - - ./gradlew :integrations:dd-sdk-android-trace-coroutines:customDetektRules - - ./gradlew :integrations:dd-sdk-android-tv:customDetektRules - - # TODO RUM-1622 cleanup this section # TESTS -test:debug: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test - timeout: 1h - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - cache/caches/ - - cache/notifications/ - policy: pull - script: - - rm -rf ~/.gradle/daemon/ - - export DD_AGENT_HOST="$BUILDENV_HOST_IP" - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :dd-sdk-android-core:testDebugUnitTest --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :dd-sdk-android-internal:testDebugUnitTest --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :unitTestDebugFeatures --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :unitTestDebugIntegrations --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :unitTestDebugSamples --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - artifacts: - when: always - expire_in: 1 week - reports: - junit: "**/build/test-results/testDebugUnitTest/*.xml" - -test:tools: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test - timeout: 1h - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - cache/caches/ - - cache/notifications/ - policy: pull - script: - - rm -rf ~/.gradle/daemon/ - - export DD_AGENT_HOST="$BUILDENV_HOST_IP" - - GRADLE_OPTS="-Xmx3072m" ./gradlew :unitTestTools --stacktrace --no-daemon --build-cache --gradle-user-home cache/ - -test:kover: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test - timeout: 1h - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - cache/caches/ - - cache/notifications/ - script: - - pip3 install datadog - - rm -rf ~/.gradle/daemon/ - - export DD_AGENT_HOST="$BUILDENV_HOST_IP" - - export DD_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.api_key --with-decryption --query "Parameter.Value" --out text) - - export DD_APP_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.app_key --with-decryption --query "Parameter.Value" --out text) - - CODECOV_TOKEN=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.codecov-token --with-decryption --query "Parameter.Value" --out text) - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :dd-sdk-android-core:koverXmlReportRelease --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :dd-sdk-android-internal:koverXmlReportRelease --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :koverReportFeatures --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :koverReportIntegrations --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - - bash <(cat ./ci/scripts/codecov.sh) -t $CODECOV_TOKEN - artifacts: - when: always - expire_in: 1 week - reports: - junit: "**/build/test-results/testReleaseUnitTest/*.xml" - -# TEST PYRAMID -# the steps in this section should reflect our test pyramid strategy - -test-pyramid:core-it-min-api: - tags: [ "macos:sonoma", "specific:true" ] - stage: test-pyramid - timeout: 1h - variables: - ANDROID_API: "21" - ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" - ANDROID_PLATFORM: "platforms;android-$ANDROID_API" - ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" - script: - - !reference [.snippets, install-android-api-components] - - !reference [.snippets, run-core-it-instrumented] - -test-pyramid:core-it-latest-api: - tags: [ "macos:sonoma", "specific:true" ] - stage: test-pyramid - timeout: 1h - variables: - ANDROID_API: "36" - ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" - ANDROID_PLATFORM: "platforms;android-$ANDROID_API" - ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" - script: - - !reference [.snippets, install-android-api-components] - - !reference [.snippets, run-core-it-instrumented] - -test-pyramid:core-it-median-api: - tags: [ "macos:sonoma", "specific:true" ] - stage: test-pyramid - timeout: 1h - variables: - ANDROID_API: "28" - ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" - ANDROID_PLATFORM: "platforms;android-$ANDROID_API" - ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" - script: - - !reference [.snippets, install-android-api-components] - - !reference [.snippets, run-core-it-instrumented] - -test-pyramid:single-fit-logs: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - cache/caches/ - - cache/notifications/ - policy: pull - script: - - rm -rf ~/.gradle/daemon/ - - export DD_AGENT_HOST="$BUILDENV_HOST_IP" - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :reliability:single-fit:logs:testReleaseUnitTest --stacktrace --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - artifacts: - when: always - expire_in: 1 week - reports: - junit: "**/build/test-results/testReleaseUnitTest/*.xml" - -test-pyramid:single-fit-rum: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - cache/caches/ - - cache/notifications/ - policy: pull - script: - - rm -rf ~/.gradle/daemon/ - - export DD_AGENT_HOST="$BUILDENV_HOST_IP" - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :reliability:single-fit:rum:testReleaseUnitTest --stacktrace --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - artifacts: - when: always - expire_in: 1 week - reports: - junit: "**/build/test-results/testReleaseUnitTest/*.xml" - -test-pyramid:single-fit-trace: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - cache/caches/ - - cache/notifications/ - policy: pull - script: - - rm -rf ~/.gradle/daemon/ - - export DD_AGENT_HOST="$BUILDENV_HOST_IP" - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :reliability:single-fit:trace:testReleaseUnitTest --stacktrace --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - artifacts: - when: always - expire_in: 1 week - reports: - junit: "**/build/test-results/testReleaseUnitTest/*.xml" - -test-pyramid:single-fit-okhttp: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - cache/caches/ - - cache/notifications/ - policy: pull - script: - - rm -rf ~/.gradle/daemon/ - - export DD_AGENT_HOST="$BUILDENV_HOST_IP" - - GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :reliability:single-fit:okhttp:testReleaseUnitTest --stacktrace --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG - artifacts: - when: always - expire_in: 1 week - reports: - junit: "**/build/test-results/testReleaseUnitTest/*.xml" - -# RUN INSTRUMENTED TESTS ON MIN API (21), LATEST API (34) and MEDIAN API (28) - -test-pyramid:legacy-integration-instrumented-min-api: - tags: [ "macos:sonoma", "specific:true" ] - stage: test-pyramid - timeout: 1h - variables: - ANDROID_API: "21" - ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" - ANDROID_PLATFORM: "platforms;android-$ANDROID_API" - ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" - script: - - !reference [.snippets, install-android-api-components] - - !reference [.snippets, run-legacy-integration-instrumented] - -test-pyramid:legacy-integration-instrumented-latest-api: - tags: [ "macos:sonoma", "specific:true" ] - stage: test-pyramid - timeout: 1h - variables: - ANDROID_API: "36" - ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" - ANDROID_PLATFORM: "platforms;android-$ANDROID_API" - ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" - script: - - !reference [.snippets, install-android-api-components] - - !reference [.snippets, run-legacy-integration-instrumented] - -test-pyramid:legacy-integration-instrumented-median-api: - tags: [ "macos:sonoma", "specific:true" ] - stage: test-pyramid - timeout: 1h - variables: - ANDROID_API: "28" - ANDROID_EMULATOR_IMAGE: "system-images;android-$ANDROID_API;google_apis;${ANDROID_ARCH}" - ANDROID_PLATFORM: "platforms;android-$ANDROID_API" - ANDROID_BUILD_TOOLS: "build-tools;$ANDROID_API.0.0" - script: - - !reference [.snippets, install-android-api-components] - - !reference [.snippets, run-legacy-integration-instrumented] - -test-pyramid:detekt-api-coverage: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - script: - - mkdir -p ./config/ - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.gradle-properties --with-decryption --query "Parameter.Value" --out text >> ./gradle.properties - - GRADLE_OPTS="-Xmx4096M" ./gradlew assembleLibrariesDebug --stacktrace --no-daemon - - GRADLE_OPTS="-Xmx4096M" ./gradlew printSdkDebugRuntimeClasspath --stacktrace --no-daemon - - GRADLE_OPTS="-Xmx4096M" ./gradlew :tools:detekt:jar --stacktrace --no-daemon - - curl -sSLO https://github.com/detekt/detekt/releases/download/v1.23.4/detekt-cli-1.23.4-all.jar - - java -jar detekt-cli-1.23.4-all.jar --config detekt_test_pyramid.yml --plugins tools/detekt/build/libs/detekt.jar -ex "**/*.kts" --jvm-target 11 -cp $(cat sdk_classpath) - # For now we just print the uncovered apis, eventually we will fail if it's not empty - - grep -v -f apiUsage.log apiSurface.log - -test-pyramid:publish-e2e-synthetics: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - only: - - develop - script: - - mkdir -p ./config/ - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.gradle-properties --with-decryption --query "Parameter.Value" --out text >> ./gradle.properties - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore --with-decryption --query "Parameter.Value" --out text | base64 -d > ./sample-android.keystore - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_config_json --with-decryption --query "Parameter.Value" --out text > ./config/us1.json - - export E2E_STORE_PASSWD=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore-password --with-decryption --query "Parameter.Value" --out text) - - export E2E_DD_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_api_key --with-decryption --query "Parameter.Value" --out text) - - export E2E_DD_APP_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_app_key --with-decryption --query "Parameter.Value" --out text) - - export E2E_MOBILE_APP_ID=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_mobile_app_id --with-decryption --query "Parameter.Value" --out text) - - GRADLE_OPTS="-Xmx4096M" ./gradlew assembleLibrariesRelease --stacktrace --no-daemon - - GRADLE_OPTS="-Xmx4096M" ./gradlew :sample:kotlin:packageUs1Release --stacktrace --no-daemon - - npm update -g @datadog/datadog-ci - - echo "Using datadog-ci $(npx @datadog/datadog-ci version)" - - npx @datadog/datadog-ci synthetics upload-application --appKey "$E2E_DD_APP_KEY" --apiKey "$E2E_DD_API_KEY" --mobileApp "sample/kotlin/build/outputs/apk/us1/release/kotlin-us1-release.apk" --mobileApplicationId "$E2E_MOBILE_APP_ID" --versionName "$CI_COMMIT_SHORT_SHA" --latest - artifacts: - when: always - expire_in: 1 week - paths: - - sample/kotlin/build/outputs/apk/us1/release/kotlin-us1-release.apk - -test-pyramid:publish-webview-synthetics: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - only: - - develop - script: - - mkdir -p ./config/ - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.gradle-properties --with-decryption --query "Parameter.Value" --out text >> ./gradle.properties - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore --with-decryption --query "Parameter.Value" --out text | base64 -d > ./sample-android.keystore - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.webview_config_json --with-decryption --query "Parameter.Value" --out text > ./config/us1.json - - export E2E_STORE_PASSWD=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore-password --with-decryption --query "Parameter.Value" --out text) - - export E2E_DD_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.webview_api_key --with-decryption --query "Parameter.Value" --out text) - - export E2E_DD_APP_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.webview_app_key --with-decryption --query "Parameter.Value" --out text) - - export E2E_MOBILE_APP_ID=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.webview_mobile_app_id --with-decryption --query "Parameter.Value" --out text) - - GRADLE_OPTS="-Xmx4096M" ./gradlew assembleLibrariesRelease --stacktrace --no-daemon - - GRADLE_OPTS="-Xmx4096M" ./gradlew :sample:kotlin:packageUs1Release --stacktrace --no-daemon - - npm update -g @datadog/datadog-ci - - echo "Using datadog-ci $(npx @datadog/datadog-ci version)" - - npx @datadog/datadog-ci synthetics upload-application --appKey "$E2E_DD_APP_KEY" --apiKey "$E2E_DD_API_KEY" --mobileApp "sample/kotlin/build/outputs/apk/us1/release/kotlin-us1-release.apk" --mobileApplicationId "$E2E_MOBILE_APP_ID" --versionName "$CI_COMMIT_SHORT_SHA" --latest - artifacts: - when: always - expire_in: 1 week - paths: - - sample/kotlin/build/outputs/apk/us1/release/kotlin-us1-release.apk - -test-pyramid:publish-staging-synthetics: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - only: - - develop - script: - - mkdir -p ./config/ - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.gradle-properties --with-decryption --query "Parameter.Value" --out text >> ./gradle.properties - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore --with-decryption --query "Parameter.Value" --out text | base64 -d > ./sample-android.keystore - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_staging_config_json --with-decryption --query "Parameter.Value" --out text > ./config/staging.json - - export E2E_STORE_PASSWD=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore-password --with-decryption --query "Parameter.Value" --out text) - - export E2E_DD_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_staging_api_key --with-decryption --query "Parameter.Value" --out text) - - export E2E_DD_APP_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_staging_app_key --with-decryption --query "Parameter.Value" --out text) - - export E2E_MOBILE_APP_ID=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.e2e_staging_mobile_app_id --with-decryption --query "Parameter.Value" --out text) - - GRADLE_OPTS="-Xmx4096M" ./gradlew assembleLibrariesRelease --stacktrace --no-daemon - - GRADLE_OPTS="-Xmx4096M" ./gradlew :sample:kotlin:packageStagingRelease --stacktrace --no-daemon - - npm update -g @datadog/datadog-ci - - echo "Using datadog-ci $(npx @datadog/datadog-ci version)" - - npx @datadog/datadog-ci synthetics upload-application --appKey "$E2E_DD_APP_KEY" --apiKey "$E2E_DD_API_KEY" --mobileApp "sample/kotlin/build/outputs/apk/staging/release/kotlin-staging-release.apk" --mobileApplicationId "$E2E_MOBILE_APP_ID" --versionName "$CI_COMMIT_SHORT_SHA" --latest --datadogSite "datad0g.com" - artifacts: - when: always - expire_in: 1 week - paths: - - sample/kotlin/build/outputs/apk/staging/release/kotlin-staging-release.apk - -test-pyramid:publish-benchmark-synthetics: - tags: [ "arch:amd64" ] - image: $CI_IMAGE_DOCKER - stage: test-pyramid - timeout: 1h - only: - - develop - script: - - mkdir -p ./config/ - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.gradle-properties --with-decryption --query "Parameter.Value" --out text >> ./gradle.properties - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore --with-decryption --query "Parameter.Value" --out text | base64 -d > ./sample-benchmark.keystore - - aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.benchmark_config_json --with-decryption --query "Parameter.Value" --out text > ./config/benchmark.json - - export BM_STORE_PASSWD=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.keystore-password --with-decryption --query "Parameter.Value" --out text) - - export BM_DD_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.benchmark_api_key --with-decryption --query "Parameter.Value" --out text) - - export BM_DD_APP_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.benchmark_app_key --with-decryption --query "Parameter.Value" --out text) - - export BM_MOBILE_APP_ID=$(aws ssm get-parameter --region us-east-1 --name ci.dd-sdk-android.benchmark_mobile_app_id --with-decryption --query "Parameter.Value" --out text) - - GRADLE_OPTS="-Xmx4096M" ./gradlew assembleLibrariesRelease --stacktrace --no-daemon - - GRADLE_OPTS="-Xmx4096M" ./gradlew :sample:benchmark:packageRelease --stacktrace --no-daemon - - npm update -g @datadog/datadog-ci - - echo "Using datadog-ci $(npx @datadog/datadog-ci version)" - - npx @datadog/datadog-ci synthetics upload-application --appKey "$BM_DD_APP_KEY" --apiKey "$BM_DD_API_KEY" --mobileApp "sample/benchmark/build/outputs/apk/release/benchmark-release.apk" --mobileApplicationId "$BM_MOBILE_APP_ID" --versionName "$CI_COMMIT_SHORT_SHA" --latest - artifacts: - when: always - expire_in: 1 week - paths: - - sample/benchmark/build/outputs/apk/release/benchmark-release.apk - # PUBLISH ARTIFACTS ON MAVEN publish:release-core: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -510,9 +94,7 @@ publish:release-core: publish:release-internal: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -528,9 +110,7 @@ publish:release-internal: # region Publish features/* publish:release-trace-api: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -543,12 +123,9 @@ publish:release-trace-api: paths: - features/dd-sdk-android-trace-api/verification-metadata.xml - publish:release-trace-internal: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -563,9 +140,7 @@ publish:release-trace-internal: publish:release-trace: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -580,9 +155,7 @@ publish:release-trace: publish:release-trace-otel: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -597,9 +170,7 @@ publish:release-trace-otel: publish:release-logs: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -614,9 +185,7 @@ publish:release-logs: publish:release-rum: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -631,9 +200,7 @@ publish:release-rum: publish:release-ndk: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -648,9 +215,7 @@ publish:release-ndk: publish:release-session-replay: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -665,9 +230,7 @@ publish:release-session-replay: publish:release-session-replay-material: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -682,9 +245,7 @@ publish:release-session-replay-material: publish:release-session-replay-compose: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -699,9 +260,7 @@ publish:release-session-replay-compose: publish:release-webview: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -720,9 +279,7 @@ publish:release-webview: publish:release-coil: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -737,9 +294,7 @@ publish:release-coil: publish:release-compose: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -754,9 +309,7 @@ publish:release-compose: publish:release-fresco: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -771,9 +324,7 @@ publish:release-fresco: publish:release-glide: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -788,9 +339,7 @@ publish:release-glide: publish:release-trace-coroutines: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -805,9 +354,7 @@ publish:release-trace-coroutines: publish:release-rum-coroutines: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -822,9 +369,7 @@ publish:release-rum-coroutines: publish:release-rx: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -839,9 +384,7 @@ publish:release-rx: publish:release-sqldelight: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -856,9 +399,7 @@ publish:release-sqldelight: publish:release-timber: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -873,9 +414,7 @@ publish:release-timber: publish:release-android-tv: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -890,9 +429,7 @@ publish:release-android-tv: publish:release-okhttp: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -907,9 +444,7 @@ publish:release-okhttp: publish:release-okhttp-otel: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m @@ -926,9 +461,7 @@ publish:release-okhttp-otel: publish:release-benchmark: tags: [ "arch:amd64" ] - only: - - tags - - develop + when: manual image: $CI_IMAGE_DOCKER stage: publish timeout: 30m diff --git a/features/dd-sdk-android-logs/api/apiSurface b/features/dd-sdk-android-logs/api/apiSurface index 06581caf54..145f63da6d 100644 --- a/features/dd-sdk-android-logs/api/apiSurface +++ b/features/dd-sdk-android-logs/api/apiSurface @@ -35,17 +35,17 @@ data class com.datadog.android.log.LogsConfiguration fun setEventMapper(com.datadog.android.event.EventMapper): Builder fun build(): LogsConfiguration data class com.datadog.android.log.model.LogEvent - constructor(Device, Os, Status, kotlin.String, kotlin.String, kotlin.String, Logger, Usr? = null, Account? = null, Network? = null, Error? = null, kotlin.String? = null, kotlin.String, kotlin.collections.MutableMap = mutableMapOf()) + constructor(LogEventDevice, Os, Status, kotlin.String, kotlin.String, kotlin.String, Logger, Dd, Usr? = null, Account? = null, Network? = null, Error? = null, kotlin.String? = null, kotlin.String, kotlin.collections.MutableMap = mutableMapOf()) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): LogEvent fun fromJsonObject(com.google.gson.JsonObject): LogEvent - data class Device + data class LogEventDevice constructor(Type? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.List? = null, kotlin.String? = null, kotlin.Number? = null, kotlin.Boolean? = null, kotlin.Number? = null) fun toJson(): com.google.gson.JsonElement companion object - fun fromJson(kotlin.String): Device - fun fromJsonObject(com.google.gson.JsonObject): Device + fun fromJson(kotlin.String): LogEventDevice + fun fromJsonObject(com.google.gson.JsonObject): LogEventDevice data class Os constructor(kotlin.String, kotlin.String, kotlin.String? = null, kotlin.String) fun toJson(): com.google.gson.JsonElement @@ -58,6 +58,12 @@ data class com.datadog.android.log.model.LogEvent companion object fun fromJson(kotlin.String): Logger fun fromJsonObject(com.google.gson.JsonObject): Logger + data class Dd + constructor(DdDevice) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Dd + fun fromJsonObject(com.google.gson.JsonObject): Dd data class Usr constructor(kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.MutableMap = mutableMapOf()) fun toJson(): com.google.gson.JsonElement @@ -82,6 +88,12 @@ data class com.datadog.android.log.model.LogEvent companion object fun fromJson(kotlin.String): Error fun fromJsonObject(com.google.gson.JsonObject): Error + data class DdDevice + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): DdDevice + fun fromJsonObject(com.google.gson.JsonObject): DdDevice data class Client constructor(SimCarrier? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String) fun toJson(): com.google.gson.JsonElement diff --git a/features/dd-sdk-android-logs/api/dd-sdk-android-logs.api b/features/dd-sdk-android-logs/api/dd-sdk-android-logs.api index 4dd58fdc08..8cefa9ef22 100644 --- a/features/dd-sdk-android-logs/api/dd-sdk-android-logs.api +++ b/features/dd-sdk-android-logs/api/dd-sdk-android-logs.api @@ -86,24 +86,25 @@ public final class com/datadog/android/log/LogsConfiguration$Builder { public final class com/datadog/android/log/model/LogEvent { public static final field Companion Lcom/datadog/android/log/model/LogEvent$Companion; - public fun (Lcom/datadog/android/log/model/LogEvent$Device;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V - public synthetic fun (Lcom/datadog/android/log/model/LogEvent$Device;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/datadog/android/log/model/LogEvent$Device; - public final fun component10 ()Lcom/datadog/android/log/model/LogEvent$Network; - public final fun component11 ()Lcom/datadog/android/log/model/LogEvent$Error; - public final fun component12 ()Ljava/lang/String; + public fun (Lcom/datadog/android/log/model/LogEvent$LogEventDevice;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Dd;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V + public synthetic fun (Lcom/datadog/android/log/model/LogEvent$LogEventDevice;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Dd;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/log/model/LogEvent$LogEventDevice; + public final fun component10 ()Lcom/datadog/android/log/model/LogEvent$Account; + public final fun component11 ()Lcom/datadog/android/log/model/LogEvent$Network; + public final fun component12 ()Lcom/datadog/android/log/model/LogEvent$Error; public final fun component13 ()Ljava/lang/String; - public final fun component14 ()Ljava/util/Map; + public final fun component14 ()Ljava/lang/String; + public final fun component15 ()Ljava/util/Map; public final fun component2 ()Lcom/datadog/android/log/model/LogEvent$Os; public final fun component3 ()Lcom/datadog/android/log/model/LogEvent$Status; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; public final fun component6 ()Ljava/lang/String; public final fun component7 ()Lcom/datadog/android/log/model/LogEvent$Logger; - public final fun component8 ()Lcom/datadog/android/log/model/LogEvent$Usr; - public final fun component9 ()Lcom/datadog/android/log/model/LogEvent$Account; - public final fun copy (Lcom/datadog/android/log/model/LogEvent$Device;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lcom/datadog/android/log/model/LogEvent; - public static synthetic fun copy$default (Lcom/datadog/android/log/model/LogEvent;Lcom/datadog/android/log/model/LogEvent$Device;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/log/model/LogEvent; + public final fun component8 ()Lcom/datadog/android/log/model/LogEvent$Dd; + public final fun component9 ()Lcom/datadog/android/log/model/LogEvent$Usr; + public final fun copy (Lcom/datadog/android/log/model/LogEvent$LogEventDevice;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Dd;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lcom/datadog/android/log/model/LogEvent; + public static synthetic fun copy$default (Lcom/datadog/android/log/model/LogEvent;Lcom/datadog/android/log/model/LogEvent$LogEventDevice;Lcom/datadog/android/log/model/LogEvent$Os;Lcom/datadog/android/log/model/LogEvent$Status;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/log/model/LogEvent$Logger;Lcom/datadog/android/log/model/LogEvent$Dd;Lcom/datadog/android/log/model/LogEvent$Usr;Lcom/datadog/android/log/model/LogEvent$Account;Lcom/datadog/android/log/model/LogEvent$Network;Lcom/datadog/android/log/model/LogEvent$Error;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/log/model/LogEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent; @@ -111,8 +112,9 @@ public final class com/datadog/android/log/model/LogEvent { public final fun getAdditionalProperties ()Ljava/util/Map; public final fun getBuildId ()Ljava/lang/String; public final fun getDate ()Ljava/lang/String; + public final fun getDd ()Lcom/datadog/android/log/model/LogEvent$Dd; public final fun getDdtags ()Ljava/lang/String; - public final fun getDevice ()Lcom/datadog/android/log/model/LogEvent$Device; + public final fun getDevice ()Lcom/datadog/android/log/model/LogEvent$LogEventDevice; public final fun getError ()Lcom/datadog/android/log/model/LogEvent$Error; public final fun getLogger ()Lcom/datadog/android/log/model/LogEvent$Logger; public final fun getMessage ()Ljava/lang/String; @@ -189,46 +191,44 @@ public final class com/datadog/android/log/model/LogEvent$Companion { public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent; } -public final class com/datadog/android/log/model/LogEvent$Device { - public static final field Companion Lcom/datadog/android/log/model/LogEvent$Device$Companion; - public fun ()V - public fun (Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;)V - public synthetic fun (Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/datadog/android/log/model/LogEvent$Type; - public final fun component10 ()Ljava/lang/Boolean; - public final fun component11 ()Ljava/lang/Number; - public final fun component2 ()Ljava/lang/String; - public final fun component3 ()Ljava/lang/String; - public final fun component4 ()Ljava/lang/String; - public final fun component5 ()Ljava/lang/String; - public final fun component6 ()Ljava/lang/String; - public final fun component7 ()Ljava/util/List; - public final fun component8 ()Ljava/lang/String; - public final fun component9 ()Ljava/lang/Number; - public final fun copy (Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;)Lcom/datadog/android/log/model/LogEvent$Device; - public static synthetic fun copy$default (Lcom/datadog/android/log/model/LogEvent$Device;Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/log/model/LogEvent$Device; +public final class com/datadog/android/log/model/LogEvent$Dd { + public static final field Companion Lcom/datadog/android/log/model/LogEvent$Dd$Companion; + public fun (Lcom/datadog/android/log/model/LogEvent$DdDevice;)V + public final fun component1 ()Lcom/datadog/android/log/model/LogEvent$DdDevice; + public final fun copy (Lcom/datadog/android/log/model/LogEvent$DdDevice;)Lcom/datadog/android/log/model/LogEvent$Dd; + public static synthetic fun copy$default (Lcom/datadog/android/log/model/LogEvent$Dd;Lcom/datadog/android/log/model/LogEvent$DdDevice;ILjava/lang/Object;)Lcom/datadog/android/log/model/LogEvent$Dd; public fun equals (Ljava/lang/Object;)Z - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$Device; - public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$Device; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$Dd; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$Dd; + public final fun getDevice ()Lcom/datadog/android/log/model/LogEvent$DdDevice; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/log/model/LogEvent$Dd$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$Dd; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$Dd; +} + +public final class com/datadog/android/log/model/LogEvent$DdDevice { + public static final field Companion Lcom/datadog/android/log/model/LogEvent$DdDevice$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$DdDevice; + public static synthetic fun copy$default (Lcom/datadog/android/log/model/LogEvent$DdDevice;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/log/model/LogEvent$DdDevice; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$DdDevice; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$DdDevice; public final fun getArchitecture ()Ljava/lang/String; - public final fun getBatteryLevel ()Ljava/lang/Number; - public final fun getBrand ()Ljava/lang/String; - public final fun getBrightnessLevel ()Ljava/lang/Number; - public final fun getLocale ()Ljava/lang/String; - public final fun getLocales ()Ljava/util/List; - public final fun getModel ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun getPowerSavingMode ()Ljava/lang/Boolean; - public final fun getTimeZone ()Ljava/lang/String; - public final fun getType ()Lcom/datadog/android/log/model/LogEvent$Type; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; public fun toString ()Ljava/lang/String; } -public final class com/datadog/android/log/model/LogEvent$Device$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$Device; - public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$Device; +public final class com/datadog/android/log/model/LogEvent$DdDevice$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$DdDevice; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$DdDevice; } public final class com/datadog/android/log/model/LogEvent$Error { @@ -268,6 +268,48 @@ public final class com/datadog/android/log/model/LogEvent$Error$Companion { public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$Error; } +public final class com/datadog/android/log/model/LogEvent$LogEventDevice { + public static final field Companion Lcom/datadog/android/log/model/LogEvent$LogEventDevice$Companion; + public fun ()V + public fun (Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;)V + public synthetic fun (Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/log/model/LogEvent$Type; + public final fun component10 ()Ljava/lang/Boolean; + public final fun component11 ()Ljava/lang/Number; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun component5 ()Ljava/lang/String; + public final fun component6 ()Ljava/lang/String; + public final fun component7 ()Ljava/util/List; + public final fun component8 ()Ljava/lang/String; + public final fun component9 ()Ljava/lang/Number; + public final fun copy (Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;)Lcom/datadog/android/log/model/LogEvent$LogEventDevice; + public static synthetic fun copy$default (Lcom/datadog/android/log/model/LogEvent$LogEventDevice;Lcom/datadog/android/log/model/LogEvent$Type;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/log/model/LogEvent$LogEventDevice; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$LogEventDevice; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$LogEventDevice; + public final fun getArchitecture ()Ljava/lang/String; + public final fun getBatteryLevel ()Ljava/lang/Number; + public final fun getBrand ()Ljava/lang/String; + public final fun getBrightnessLevel ()Ljava/lang/Number; + public final fun getLocale ()Ljava/lang/String; + public final fun getLocales ()Ljava/util/List; + public final fun getModel ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getPowerSavingMode ()Ljava/lang/Boolean; + public final fun getTimeZone ()Ljava/lang/String; + public final fun getType ()Lcom/datadog/android/log/model/LogEvent$Type; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/log/model/LogEvent$LogEventDevice$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/log/model/LogEvent$LogEventDevice; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/log/model/LogEvent$LogEventDevice; +} + public final class com/datadog/android/log/model/LogEvent$Logger { public static final field Companion Lcom/datadog/android/log/model/LogEvent$Logger$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V diff --git a/features/dd-sdk-android-logs/src/main/json/log/log-schema.json b/features/dd-sdk-android-logs/src/main/json/log/log-schema.json index 454ae26ebf..ea81b460d9 100644 --- a/features/dd-sdk-android-logs/src/main/json/log/log-schema.json +++ b/features/dd-sdk-android-logs/src/main/json/log/log-schema.json @@ -66,6 +66,31 @@ ], "readOnly": true }, + "_dd": { + "type": "object", + "description": "Datadog internal information", + "properties": { + "device": { + "type": "object", + "description": "Information about the device that produced this log.", + "properties": { + "architecture": { + "type": "string", + "description": "The CPU architecture of the device", + "readOnly": true + } + }, + "required": [ + "architecture" + ], + "readOnly": true + } + }, + "required": [ + "device" + ], + "readOnly": true + }, "usr": { "type": "object", "description": "User properties", @@ -239,6 +264,7 @@ "date", "service", "logger", + "_dd", "ddtags", "device", "os" diff --git a/features/dd-sdk-android-logs/src/main/kotlin/com/datadog/android/log/internal/domain/DatadogLogGenerator.kt b/features/dd-sdk-android-logs/src/main/kotlin/com/datadog/android/log/internal/domain/DatadogLogGenerator.kt index 050ba65ad3..a4a60590fb 100644 --- a/features/dd-sdk-android-logs/src/main/kotlin/com/datadog/android/log/internal/domain/DatadogLogGenerator.kt +++ b/features/dd-sdk-android-logs/src/main/kotlin/com/datadog/android/log/internal/domain/DatadogLogGenerator.kt @@ -194,6 +194,11 @@ internal class DatadogLogGenerator( buildId = datadogContext.appBuildId, error = error, logger = loggerInfo, + dd = LogEvent.Dd( + device = LogEvent.DdDevice( + architecture = deviceInfo.architecture + ) + ), usr = usr, account = account, network = network, @@ -210,7 +215,7 @@ internal class DatadogLogGenerator( versionMajor = deviceInfo.osMajorVersion ) - private fun resolveDeviceInfo(deviceInfo: DeviceInfo) = LogEvent.Device( + private fun resolveDeviceInfo(deviceInfo: DeviceInfo) = LogEvent.LogEventDevice( type = resolveDeviceType(deviceInfo.deviceType), name = deviceInfo.deviceName, model = deviceInfo.deviceModel, diff --git a/features/dd-sdk-android-logs/src/test/kotlin/com/datadog/android/utils/forge/LogEventForgeryFactory.kt b/features/dd-sdk-android-logs/src/test/kotlin/com/datadog/android/utils/forge/LogEventForgeryFactory.kt index dd0019fc6d..54ad0ebeee 100644 --- a/features/dd-sdk-android-logs/src/test/kotlin/com/datadog/android/utils/forge/LogEventForgeryFactory.kt +++ b/features/dd-sdk-android-logs/src/test/kotlin/com/datadog/android/utils/forge/LogEventForgeryFactory.kt @@ -87,13 +87,18 @@ internal class LogEventForgeryFactory : ForgeryFactory { version = forge.aStringMatching("[0-9]\\.[0-9]\\.[0-9]"), threadName = forge.aNullable { forge.anAlphabeticalString() } ), - device = LogEvent.Device( + device = LogEvent.LogEventDevice( type = resolveDeviceType(deviceInfo.deviceType), name = deviceInfo.deviceName, model = deviceInfo.deviceModel, brand = deviceInfo.deviceBrand, architecture = deviceInfo.architecture ), + dd = LogEvent.Dd( + device = LogEvent.DdDevice( + architecture = deviceInfo.architecture + ) + ), os = LogEvent.Os( name = deviceInfo.osName, version = deviceInfo.osVersion, diff --git a/features/dd-sdk-android-trace-api/api/apiSurface b/features/dd-sdk-android-trace-api/api/apiSurface index 95003209c0..0bb08ff565 100644 --- a/features/dd-sdk-android-trace-api/api/apiSurface +++ b/features/dd-sdk-android-trace-api/api/apiSurface @@ -30,6 +30,7 @@ object com.datadog.android.trace.api.DatadogTracingConstants const val PROPAGATION_STYLE_EXTRACT: String const val PROPAGATION_STYLE_INJECT: String const val SERVICE_NAME: String + const val SDK_V2_COMPATIBILITY_FLAG: String const val URL_AS_RESOURCE_NAME: String const val TAGS: String object LogAttributes diff --git a/features/dd-sdk-android-trace-api/api/dd-sdk-android-trace-api.api b/features/dd-sdk-android-trace-api/api/dd-sdk-android-trace-api.api index a5c75164d4..3d4112861a 100644 --- a/features/dd-sdk-android-trace-api/api/dd-sdk-android-trace-api.api +++ b/features/dd-sdk-android-trace-api/api/dd-sdk-android-trace-api.api @@ -53,6 +53,7 @@ public final class com/datadog/android/trace/api/DatadogTracingConstants$TracerC public static final field PARTIAL_FLUSH_MIN_SPANS Ljava/lang/String; public static final field PROPAGATION_STYLE_EXTRACT Ljava/lang/String; public static final field PROPAGATION_STYLE_INJECT Ljava/lang/String; + public static final field SDK_V2_COMPATIBILITY_FLAG Ljava/lang/String; public static final field SERVICE_NAME Ljava/lang/String; public static final field SPAN_TAGS Ljava/lang/String; public static final field TAGS Ljava/lang/String; diff --git a/features/dd-sdk-android-trace-api/src/main/kotlin/com/datadog/android/trace/api/DatadogTracingConstants.kt b/features/dd-sdk-android-trace-api/src/main/kotlin/com/datadog/android/trace/api/DatadogTracingConstants.kt index ebbcfde086..dd09a1bcc7 100644 --- a/features/dd-sdk-android-trace-api/src/main/kotlin/com/datadog/android/trace/api/DatadogTracingConstants.kt +++ b/features/dd-sdk-android-trace-api/src/main/kotlin/com/datadog/android/trace/api/DatadogTracingConstants.kt @@ -125,7 +125,8 @@ object DatadogTracingConstants { const val TRACE_RATE_LIMIT: String = "trace.rate.limit" /** - * A configuration key used to set the minimum number of spans required to trigger a partial flush of trace data. + * A configuration key used to set the minimum number of spans + * required to trigger a partial flush of trace data. */ const val PARTIAL_FLUSH_MIN_SPANS: String = "trace.partial.flush.min.spans" @@ -144,6 +145,16 @@ object DatadogTracingConstants { */ const val SERVICE_NAME: String = "service.name" + /** + * A constant flag used to toggle compatibility with SDK version 2 for the tracer. + * + * When this flag is enabled (set to "true"), the SDK adjusts its behavior of a sampler factory, + * making it same sampler as in SDK v2.*.*. + * + * This flag only being used by OTel tracer implementation and disabled by default. + */ + const val SDK_V2_COMPATIBILITY_FLAG: String = "v2.compatibility.enabled" + /** * A constant representing the configuration key for enabling or disabling the rule * that uses URLs as resource names in tracing. @@ -166,7 +177,8 @@ object DatadogTracingConstants { const val ERROR_KIND: String = "error.kind" /** - * The actual Throwable/Exception/Error object instance itself. E.g., a [UnsupportedOperationException] instance. + * The actual Throwable/Exception/Error object instance itself. + * E.g., a [UnsupportedOperationException] instance. */ const val ERROR_OBJECT: String = "error.object" diff --git a/features/dd-sdk-android-trace-internal/api/dd-sdk-android-trace-internal.api b/features/dd-sdk-android-trace-internal/api/dd-sdk-android-trace-internal.api index ee28a36b54..1baba1b470 100644 --- a/features/dd-sdk-android-trace-internal/api/dd-sdk-android-trace-internal.api +++ b/features/dd-sdk-android-trace-internal/api/dd-sdk-android-trace-internal.api @@ -107,6 +107,7 @@ public class com/datadog/trace/api/Config { public fun isTracePropagationExtractFirst ()Z public fun isTracePropagationStyleB3PaddingEnabled ()Z public fun isTraceStrictWritesEnabled ()Z + public fun isV2CompatibilityEnabled ()Z public static fun jmxFetchIntegrationEnabled (Ljava/util/SortedSet;Z)Z public fun toString ()Ljava/lang/String; public static fun traceAnalyticsIntegrationEnabled (Ljava/util/SortedSet;Z)Z @@ -867,6 +868,7 @@ public final class com/datadog/trace/api/config/TracerConfig { public static final field SCOPE_INHERIT_ASYNC_PROPAGATION Ljava/lang/String; public static final field SCOPE_ITERATION_KEEP_ALIVE Ljava/lang/String; public static final field SCOPE_STRICT_MODE Ljava/lang/String; + public static final field SDK_V2_COMPATIBILITY_FLAG Ljava/lang/String; public static final field SECURE_RANDOM Ljava/lang/String; public static final field SERVICE_MAPPING Ljava/lang/String; public static final field SPAN_SAMPLING_RULES Ljava/lang/String; @@ -996,12 +998,12 @@ public abstract interface class com/datadog/trace/api/interceptor/MutableSpan { public abstract fun getOperationName ()Ljava/lang/CharSequence; public abstract fun getResourceName ()Ljava/lang/CharSequence; public abstract fun getRootSpan ()Lcom/datadog/trace/api/interceptor/MutableSpan; - public abstract fun getSamplingPriority ()Ljava/lang/Integer; public abstract fun getServiceName ()Ljava/lang/String; public abstract fun getSpanType ()Ljava/lang/String; public abstract fun getStartTime ()J public fun getTag (Ljava/lang/String;)Ljava/lang/Object; public abstract fun getTags ()Ljava/util/Map; + public abstract fun getTraceSamplingPriority ()Ljava/lang/Integer; public abstract fun isError ()Z public abstract fun setError (Z)Lcom/datadog/trace/api/interceptor/MutableSpan; public abstract fun setMetric (Ljava/lang/CharSequence;D)Lcom/datadog/trace/api/interceptor/MutableSpan; @@ -1639,10 +1641,11 @@ public abstract interface class com/datadog/trace/bootstrap/instrumentation/api/ public abstract interface class com/datadog/trace/bootstrap/instrumentation/api/AgentSpan$Context { public abstract fun baggageItems ()Ljava/lang/Iterable; public abstract fun getPathwayContext ()Lcom/datadog/trace/bootstrap/instrumentation/api/PathwayContext; - public abstract fun getSamplingPriority ()I public abstract fun getSpanId ()J + public abstract fun getSpanSamplingPriority ()I public abstract fun getTrace ()Lcom/datadog/trace/bootstrap/instrumentation/api/AgentTrace; public abstract fun getTraceId ()Lcom/datadog/trace/api/DDTraceId; + public abstract fun getTraceSamplingPriority ()I public fun mergePathwayContext (Lcom/datadog/trace/bootstrap/instrumentation/api/PathwayContext;)V } @@ -1729,7 +1732,6 @@ public final class com/datadog/trace/bootstrap/instrumentation/api/AgentTracer$N public fun getResourceNamePriority ()B public synthetic fun getRootSpan ()Lcom/datadog/trace/api/interceptor/MutableSpan; public fun getRootSpan ()Lcom/datadog/trace/bootstrap/instrumentation/api/AgentSpan; - public fun getSamplingPriority ()Ljava/lang/Integer; public fun getServiceName ()Ljava/lang/String; public fun getSpanId ()J public synthetic fun getSpanName ()Ljava/lang/CharSequence; @@ -1739,6 +1741,7 @@ public final class com/datadog/trace/bootstrap/instrumentation/api/AgentTracer$N public fun getTag (Ljava/lang/String;)Ljava/lang/Object; public fun getTags ()Ljava/util/Map; public fun getTraceId ()Lcom/datadog/trace/api/DDTraceId; + public fun getTraceSamplingPriority ()Ljava/lang/Integer; public fun hasResourceName ()Z public fun isError ()Z public fun isSameTrace (Lcom/datadog/trace/bootstrap/instrumentation/api/AgentSpan;)Z @@ -1802,11 +1805,12 @@ public final class com/datadog/trace/bootstrap/instrumentation/api/AgentTracer$N public fun getForwarded ()Ljava/lang/String; public fun getForwardedFor ()Ljava/lang/String; public fun getPathwayContext ()Lcom/datadog/trace/bootstrap/instrumentation/api/PathwayContext; - public fun getSamplingPriority ()I public fun getSpanId ()J + public fun getSpanSamplingPriority ()I public fun getTerminatedContextLinks ()Ljava/util/List; public fun getTrace ()Lcom/datadog/trace/bootstrap/instrumentation/api/AgentTrace; public fun getTraceId ()Lcom/datadog/trace/api/DDTraceId; + public fun getTraceSamplingPriority ()I public fun getTrueClientIp ()Ljava/lang/String; public fun getUserAgent ()Ljava/lang/String; public fun getXClientIp ()Ljava/lang/String; @@ -2133,13 +2137,14 @@ public class com/datadog/trace/bootstrap/instrumentation/api/TagContext : com/da public fun getPropagationStyle ()Lcom/datadog/trace/api/TracePropagationStyle; public final fun getRequestContextDataAppSec ()Ljava/lang/Object; public final fun getRequestContextDataIast ()Ljava/lang/Object; - public final fun getSamplingPriority ()I public fun getSpanId ()J + public fun getSpanSamplingPriority ()I public final fun getTags ()Ljava/util/Map; public fun getTerminatedContextLinks ()Ljava/util/List; public final fun getTrace ()Lcom/datadog/trace/bootstrap/instrumentation/api/AgentTrace; public fun getTraceConfig ()Lcom/datadog/trace/api/TraceConfig; public fun getTraceId ()Lcom/datadog/trace/api/DDTraceId; + public final fun getTraceSamplingPriority ()I public fun getTrueClientIp ()Ljava/lang/String; public fun getUserAgent ()Ljava/lang/String; public fun getXClientIp ()Ljava/lang/String; @@ -2376,6 +2381,8 @@ public class com/datadog/trace/common/sampling/PrioritySampling { public class com/datadog/trace/common/sampling/RateByServiceTraceSampler : com/datadog/trace/common/sampling/PrioritySampler, com/datadog/trace/common/sampling/Sampler, com/datadog/trace/common/writer/RemoteResponseListener { public static final field SAMPLING_AGENT_RATE Ljava/lang/String; public fun ()V + public fun (Ljava/lang/Double;)V + public fun getSampleRate ()D public fun onResponse (Ljava/lang/String;Ljava/util/Map;)V public fun sample (Lcom/datadog/trace/core/CoreSpan;)Z public fun setSamplingPriority (Lcom/datadog/trace/core/CoreSpan;)V @@ -2577,6 +2584,7 @@ public abstract interface class com/datadog/trace/core/CoreSpan { public abstract fun getResourceName ()Ljava/lang/CharSequence; public abstract fun getServiceName ()Ljava/lang/String; public abstract fun getSpanId ()J + public abstract fun getSpanSamplingPriority ()I public abstract fun getStartTime ()J public abstract fun getTag (Ljava/lang/CharSequence;)Ljava/lang/Object; public abstract fun getTag (Ljava/lang/CharSequence;Ljava/lang/Object;)Ljava/lang/Object; @@ -2588,7 +2596,6 @@ public abstract interface class com/datadog/trace/core/CoreSpan { public abstract fun isTopLevel ()Z public abstract fun processTagsAndBaggage (Lcom/datadog/trace/core/MetadataConsumer;)V public abstract fun removeTag (Ljava/lang/String;)Lcom/datadog/trace/core/CoreSpan; - public abstract fun samplingPriority ()I public abstract fun setErrorMessage (Ljava/lang/String;)Lcom/datadog/trace/core/CoreSpan; public abstract fun setFlag (Ljava/lang/CharSequence;Z)Lcom/datadog/trace/core/CoreSpan; public abstract fun setMeasured (Z)Lcom/datadog/trace/core/CoreSpan; @@ -2735,10 +2742,10 @@ public class com/datadog/trace/core/DDSpan : com/datadog/trace/api/profiling/Tra public fun getResourceNamePriority ()B public synthetic fun getRootSpan ()Lcom/datadog/trace/api/interceptor/MutableSpan; public fun getRootSpan ()Lcom/datadog/trace/bootstrap/instrumentation/api/AgentSpan; - public fun getSamplingPriority ()Ljava/lang/Integer; public fun getServiceName ()Ljava/lang/String; public fun getSpanId ()J public fun getSpanName ()Ljava/lang/CharSequence; + public fun getSpanSamplingPriority ()I public fun getSpanType ()Ljava/lang/String; public fun getStartTime ()J public fun getStartTimeNano ()J @@ -2747,6 +2754,7 @@ public class com/datadog/trace/core/DDSpan : com/datadog/trace/api/profiling/Tra public fun getTag (Ljava/lang/String;)Ljava/lang/Object; public fun getTags ()Ljava/util/Map; public fun getTraceId ()Lcom/datadog/trace/api/DDTraceId; + public fun getTraceSamplingPriority ()Ljava/lang/Integer; public fun getType ()Ljava/lang/CharSequence; public fun getWrapper ()Ljava/lang/Object; public fun hasResourceName ()Z @@ -2764,7 +2772,6 @@ public class com/datadog/trace/core/DDSpan : com/datadog/trace/api/profiling/Tra public final fun publish ()V public synthetic fun removeTag (Ljava/lang/String;)Lcom/datadog/trace/core/CoreSpan; public fun removeTag (Ljava/lang/String;)Lcom/datadog/trace/core/DDSpan; - public fun samplingPriority ()I public synthetic fun setBaggageItem (Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/trace/bootstrap/instrumentation/api/AgentSpan; public final fun setBaggageItem (Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/trace/core/DDSpan; public fun setEndpointTracker (Lcom/datadog/trace/api/EndpointTracker;)V @@ -2884,14 +2891,15 @@ public class com/datadog/trace/core/DDSpanContext : com/datadog/trace/api/gatewa public fun getResourceName ()Ljava/lang/CharSequence; public fun getResourceNamePriority ()B public fun getRootSpanId ()J - public fun getSamplingPriority ()I public fun getServiceName ()Ljava/lang/String; public fun getSpanId ()J + public fun getSpanSamplingPriority ()I public fun getSpanType ()Ljava/lang/CharSequence; public fun getTags ()Ljava/util/Map; public synthetic fun getTrace ()Lcom/datadog/trace/bootstrap/instrumentation/api/AgentTrace; public fun getTrace ()Lcom/datadog/trace/core/PendingTrace; public fun getTraceId ()Lcom/datadog/trace/api/DDTraceId; + public fun getTraceSamplingPriority ()I public fun getTraceSegment ()Lcom/datadog/trace/api/internal/TraceSegment; public fun getTracer ()Lcom/datadog/trace/core/CoreTracer; public fun hasResourceName ()Z diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/Config.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/Config.java index f3b2632e1e..3fb302ba43 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/Config.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/Config.java @@ -1803,6 +1803,10 @@ public boolean isSamplingMechanismValidationDisabled() { return configProvider.getBoolean(TracerConfig.SAMPLING_MECHANISM_VALIDATION_DISABLED, false); } + public boolean isV2CompatibilityEnabled() { + return configProvider.getBoolean(TracerConfig.SDK_V2_COMPATIBILITY_FLAG, false); + } + /** * @param integrationNames * @param defaultEnabled diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/config/TracerConfig.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/config/TracerConfig.java index 6b30aa63ef..a219466f24 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/config/TracerConfig.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/config/TracerConfig.java @@ -50,6 +50,7 @@ public final class TracerConfig { public static final String TRACE_SAMPLING_OPERATION_RULES = "trace.sampling.operation.rules"; // JSON rules public static final String TRACE_SAMPLING_RULES = "trace.sampling.rules"; + public static final String SDK_V2_COMPATIBILITY_FLAG = "v2.compatibility.enabled"; public static final String SPAN_SAMPLING_RULES = "span.sampling.rules"; public static final String SPAN_SAMPLING_RULES_FILE = "span.sampling.rules.file"; // a global rate used for all services (that don’t have a dedicated rule defined). diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/interceptor/MutableSpan.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/interceptor/MutableSpan.java index e0ce878b47..cfe38cbb10 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/interceptor/MutableSpan.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/api/interceptor/MutableSpan.java @@ -27,7 +27,7 @@ public interface MutableSpan { MutableSpan setResourceName(final CharSequence resourceName); @Nullable - Integer getSamplingPriority(); + Integer getTraceSamplingPriority(); /** * @param newPriority diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java index fa4360f21f..aaa732a4d9 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java @@ -179,7 +179,21 @@ interface Context { * @return The trace sampling priority of the span's trace, or {@link PrioritySampling#UNSET} if * no priority has been set. */ - int getSamplingPriority(); + int getTraceSamplingPriority(); + + /** + * Gets the span's sampling priority. + * + *

Check {@link PrioritySampling} for possible values. + *

+ * + * Main difference between this and {@link #getTraceSamplingPriority()} is that this method + * does not take into account the root context sampling priority. + * + * @return The span sampling priority or {@link PrioritySampling#UNSET} if + * no priority has been set. + */ + int getSpanSamplingPriority(); Iterable> baggageItems(); diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java index 33bf8b7355..128be68f38 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java @@ -287,7 +287,7 @@ public AgentSpan setSamplingPriority(int newPriority, int samplingMechanism) { } @Override - public Integer getSamplingPriority() { + public Integer getTraceSamplingPriority() { return (int) PrioritySampling.UNSET; } @@ -521,7 +521,12 @@ public AgentTrace getTrace() { } @Override - public int getSamplingPriority() { + public int getTraceSamplingPriority() { + return PrioritySampling.UNSET; + } + + @Override + public int getSpanSamplingPriority() { return PrioritySampling.UNSET; } diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/SpanLink.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/SpanLink.java index 3eb94763ea..2f84ef2807 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/SpanLink.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/SpanLink.java @@ -44,7 +44,7 @@ public static SpanLink from(AgentSpan.Context context) { */ public static SpanLink from( AgentSpan.Context context, byte traceFlags, String traceState, Attributes attributes) { - if (context.getSamplingPriority() > 0) { + if (context.getTraceSamplingPriority() > 0) { traceFlags = (byte) (traceFlags | SAMPLED_FLAG); } return new SpanLink( diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/TagContext.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/TagContext.java index 18d490f16e..4e099547c6 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/TagContext.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/bootstrap/instrumentation/api/TagContext.java @@ -170,7 +170,12 @@ public final Map getTags() { } @Override - public final int getSamplingPriority() { + public final int getTraceSamplingPriority() { + return samplingPriority; + } + + @Override + public int getSpanSamplingPriority() { return samplingPriority; } diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/ForcePrioritySampler.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/ForcePrioritySampler.java index f104f4874e..0fa648ca04 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/ForcePrioritySampler.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/ForcePrioritySampler.java @@ -1,12 +1,17 @@ package com.datadog.trace.common.sampling; +import androidx.annotation.VisibleForTesting; + import com.datadog.trace.core.CoreSpan; /** A sampler which forces the sampling priority */ public class ForcePrioritySampler implements Sampler, PrioritySampler { - private final int prioritySampling; - private final int samplingMechanism; + @VisibleForTesting + final int prioritySampling; + + @VisibleForTesting + final int samplingMechanism; public ForcePrioritySampler(final int prioritySampling, final int samplingMechanism) { this.prioritySampling = prioritySampling; diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/RateByServiceTraceSampler.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/RateByServiceTraceSampler.java index 190cf0dc7e..f5ee229497 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/RateByServiceTraceSampler.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/RateByServiceTraceSampler.java @@ -1,5 +1,8 @@ package com.datadog.trace.common.sampling; +import androidx.annotation.VisibleForTesting; + +import com.datadog.android.trace.internal.compat.function.Function; import com.datadog.trace.api.cache.DDCache; import com.datadog.trace.api.cache.DDCaches; import com.datadog.trace.api.sampling.PrioritySampling; @@ -12,7 +15,6 @@ import java.util.HashMap; import java.util.Map; -import com.datadog.android.trace.internal.compat.function.Function; /** * A rate sampler which maintains different sample rates per service+env name. @@ -20,13 +22,19 @@ *

The configuration of (serviceName,env)->rate is configured by the core agent. */ public class RateByServiceTraceSampler implements Sampler, PrioritySampler, RemoteResponseListener { + private static final double DEFAULT_RATE = 1.0; + private volatile RateSamplersByEnvAndService serviceRates; private static final Logger log = LoggerFactory.getLogger(RateByServiceTraceSampler.class); public static final String SAMPLING_AGENT_RATE = "_dd.agent_psr"; - private static final double DEFAULT_RATE = 1.0; + public RateByServiceTraceSampler() { + this(DEFAULT_RATE); + } - private volatile RateSamplersByEnvAndService serviceRates = new RateSamplersByEnvAndService(); + public RateByServiceTraceSampler(Double defaultSampleRate) { + serviceRates = new RateSamplersByEnvAndService(defaultSampleRate); + } @Override public > boolean sample(final T span) { @@ -86,10 +94,15 @@ public void onResponse( RateByServiceTraceSampler.createRateSampler(entry.getValue().doubleValue())); } } - serviceRates = new RateSamplersByEnvAndService(updatedEnvServiceRates); + serviceRates = new RateSamplersByEnvAndService(updatedEnvServiceRates, serviceRates.getSampleRate()); } } + @VisibleForTesting + public double getSampleRate() { + return serviceRates.getSampleRate(); + } + private static RateSampler createRateSampler(final double sampleRate) { final double sanitizedRate; if (sampleRate < 0) { @@ -105,16 +118,19 @@ private static RateSampler createRateSampler(final double sampleRate) { } private static final class RateSamplersByEnvAndService { - private static final RateSampler DEFAULT = createRateSampler(DEFAULT_RATE); + private final double sampleRate; + private final RateSampler defaultSampler; private final Map> envServiceRates; - RateSamplersByEnvAndService() { - this(new HashMap<>(0)); + RateSamplersByEnvAndService(double defaultSampleRate) { + this(new HashMap<>(0), defaultSampleRate); } - RateSamplersByEnvAndService(Map> envServiceRates) { + RateSamplersByEnvAndService(Map> envServiceRates, double sampleRate) { + this.sampleRate = sampleRate; this.envServiceRates = envServiceRates; + this.defaultSampler = createRateSampler(sampleRate); } // used in tests only @@ -125,10 +141,14 @@ RateSampler getSampler(EnvAndService envAndService) { public RateSampler getSampler(String env, String service) { Map serviceRates = envServiceRates.get(env); if (serviceRates == null) { - return DEFAULT; + return defaultSampler; } RateSampler sampler = serviceRates.get(service); - return null == sampler ? DEFAULT : sampler; + return null == sampler ? defaultSampler : sampler; + } + + public double getSampleRate() { + return sampleRate; } } diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/Sampler.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/Sampler.java index 7c25cea467..2508a6f774 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/Sampler.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/common/sampling/Sampler.java @@ -42,6 +42,7 @@ public static Sampler forConfig(final Config config, final TraceConfig traceConf boolean serviceRulesDefined = serviceRules != null && !serviceRules.isEmpty(); boolean operationRulesDefined = operationRules != null && !operationRules.isEmpty(); boolean jsonTraceSamplingRulesDefined = !traceSamplingRules.isEmpty(); + boolean v2CompatibilityEnabled = config.isV2CompatibilityEnabled(); if ((serviceRulesDefined || operationRulesDefined) && jsonTraceSamplingRulesDefined) { log.warn( "Both {} and/or {} as well as {} are defined. Only {} will be used for rule-based sampling", @@ -52,22 +53,25 @@ public static Sampler forConfig(final Config config, final TraceConfig traceConf } Double traceSampleRate = null != traceConfig ? traceConfig.getTraceSampleRate() : config.getTraceSampleRate(); - if (serviceRulesDefined - || operationRulesDefined - || jsonTraceSamplingRulesDefined - || traceSampleRate != null) { + if (v2CompatibilityEnabled && (serviceRulesDefined + || operationRulesDefined + || jsonTraceSamplingRulesDefined + || traceSampleRate != null) + ) { try { - sampler = - RuleBasedTraceSampler.build( + sampler = RuleBasedTraceSampler.build( serviceRules, operationRules, traceSamplingRules, traceSampleRate, - config.getTraceRateLimit()); + config.getTraceRateLimit() + ); } catch (final IllegalArgumentException e) { log.error("Invalid sampler configuration. Using AllSampler", e); sampler = new AllSampler(); } + } else if (traceSampleRate != null) { + sampler = new RateByServiceTraceSampler(traceSampleRate); } else if (config.isPrioritySamplingEnabled()) { if (KEEP.equalsIgnoreCase(config.getPrioritySamplingForce())) { log.debug("Force Sampling Priority to: SAMPLER_KEEP."); diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreSpan.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreSpan.java index e834f7e53d..cac99db1c0 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreSpan.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreSpan.java @@ -86,5 +86,5 @@ T setSamplingPriority( T setFlag(CharSequence name, boolean value); - int samplingPriority(); + int getSpanSamplingPriority(); } diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreTracer.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreTracer.java index fb5601384c..622969ac8c 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreTracer.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/CoreTracer.java @@ -988,7 +988,7 @@ private DDSpanContext buildSpanContext() { final ExtractedContext extractedContext = (ExtractedContext) parentContext; traceId = extractedContext.getTraceId(); parentSpanId = extractedContext.getSpanId(); - samplingPriority = extractedContext.getSamplingPriority(); + samplingPriority = extractedContext.getTraceSamplingPriority(); endToEndStartTime = extractedContext.getEndToEndStartTime(); propagationTags = extractedContext.getPropagationTags(); } else if (parentContext != null) { @@ -997,7 +997,7 @@ private DDSpanContext buildSpanContext() { ? idGenerationStrategy.generateTraceId() : parentContext.getTraceId(); parentSpanId = parentContext.getSpanId(); - samplingPriority = parentContext.getSamplingPriority(); + samplingPriority = parentContext.getTraceSamplingPriority(); endToEndStartTime = 0; propagationTags = propagationTagsFactory.empty(); } else { diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpan.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpan.java index 6d4cfc2a9e..7c28121638 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpan.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpan.java @@ -552,7 +552,7 @@ public final DDSpan setResourceName(final CharSequence resourceName, byte priori @Override public boolean eligibleForDropping() { - int samplingPriority = context.getSamplingPriority(); + int samplingPriority = context.getTraceSamplingPriority(); return samplingPriority == USER_DROP || samplingPriority == SAMPLER_DROP; } @@ -569,7 +569,7 @@ public Integer forceSamplingDecision() { if (rootSpan == null) { return null; } - return rootSpan.getSamplingPriority(); + return rootSpan.getTraceSamplingPriority(); } @Deprecated @@ -674,8 +674,9 @@ public byte getResourceNamePriority() { } @Override - public Integer getSamplingPriority() { - final int samplingPriority = context.getSamplingPriority(); + @Nullable + public Integer getTraceSamplingPriority() { + final int samplingPriority = context.getTraceSamplingPriority(); if (samplingPriority == PrioritySampling.UNSET) { return null; } else { @@ -684,8 +685,8 @@ public Integer getSamplingPriority() { } @Override - public int samplingPriority() { - return context.getSamplingPriority(); + public int getSpanSamplingPriority() { + return context.getSpanSamplingPriority(); } @Override diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanContext.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanContext.java index 4166b94ed1..e6be5d6b15 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanContext.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanContext.java @@ -558,10 +558,15 @@ private boolean validateSamplingPriority(final int newPriority, final int newMec } @Override - public int getSamplingPriority() { + public int getTraceSamplingPriority() { return getRootSpanContextOrThis().samplingPriority; } + @Override + public int getSpanSamplingPriority() { + return samplingPriority; + } + public void setSpanSamplingPriority(double rate, int limit) { synchronized (unsafeTags) { unsafeSetTag(SPAN_SAMPLING_MECHANISM_TAG, SamplingMechanism.SPAN_SAMPLING_RATE); @@ -806,7 +811,7 @@ public void processTagsAndBaggage( threadName, tags, baggageItemsWithPropagationTags, - samplingPriority != PrioritySampling.UNSET ? samplingPriority : getSamplingPriority(), + samplingPriority != PrioritySampling.UNSET ? samplingPriority : getTraceSamplingPriority(), measured, topLevel, httpStatusCode == 0 ? null : HTTP_STATUSES.get(httpStatusCode), diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanLink.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanLink.java index fc1e778721..2727766025 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanLink.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/DDSpanLink.java @@ -50,7 +50,7 @@ public static SpanLink from(ExtractedContext context) { * @return A span link to the given context with custom attributes. */ public static SpanLink from(ExtractedContext context, Attributes attributes) { - byte traceFlags = context.getSamplingPriority() > 0 ? SAMPLED_FLAG : DEFAULT_FLAGS; + byte traceFlags = context.getTraceSamplingPriority() > 0 ? SAMPLED_FLAG : DEFAULT_FLAGS; String traceState = context.getPropagationTags() == null ? "" diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/PendingTrace.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/PendingTrace.java index 5108ae8334..84d1c2b15f 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/PendingTrace.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/PendingTrace.java @@ -247,7 +247,7 @@ public Integer evaluateSamplingPriority() { if (span == null) { return null; } - Integer prio = span.getSamplingPriority(); + Integer prio = span.getTraceSamplingPriority(); if (prio == null) { prio = span.forceSamplingDecision(); } @@ -331,7 +331,7 @@ private PublishState decrementRefAndMaybeWrite(boolean isRootSpan) { // Finished root with pending work ... delay write pendingTraceBuffer.enqueue(this); return PublishState.ROOT_BUFFERED; - } else if (partialFlushMinSpans > 0 && size() >= partialFlushMinSpans) { + } else if (partialFlushMinSpans > 0 && size() > partialFlushMinSpans) { // Trace is getting too big, write anything completed. partialFlush(); return PublishState.PARTIAL_FLUSH; @@ -524,7 +524,7 @@ public void setSamplingPriorityIfNecessary() { if (traceConfig.sampler instanceof PrioritySampler && rootSpan != null - && rootSpan.context().getSamplingPriority() == PrioritySampling.UNSET) { + && rootSpan.context().getTraceSamplingPriority() == PrioritySampling.UNSET) { ((PrioritySampler) traceConfig.sampler).setSamplingPriority(rootSpan); } } diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/B3HttpCodec.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/B3HttpCodec.java index 919537ba60..64c7d0376a 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/B3HttpCodec.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/B3HttpCodec.java @@ -120,7 +120,7 @@ public void inject( setter.set(carrier, SPAN_ID_KEY, injectedSpanId); if (context.lockSamplingPriority()) { final String injectedSamplingPriority = - convertSamplingPriority(context.getSamplingPriority()); + convertSamplingPriority(context.getTraceSamplingPriority()); setter.set(carrier, SAMPLING_PRIORITY_KEY, injectedSamplingPriority); } log.debug( @@ -146,7 +146,7 @@ public void inject( if (context.lockSamplingPriority()) { final String injectedSamplingPriority = - convertSamplingPriority(context.getSamplingPriority()); + convertSamplingPriority(context.getTraceSamplingPriority()); injectedB3IdBuilder.append('-').append(injectedSamplingPriority); } String injectedB3Id = injectedB3IdBuilder.toString(); diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/DatadogHttpCodec.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/DatadogHttpCodec.java index 820d8de60b..5b3e606dc4 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/DatadogHttpCodec.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/DatadogHttpCodec.java @@ -62,7 +62,7 @@ public void inject( setter.set(carrier, TRACE_ID_KEY, context.getTraceId().toString()); setter.set(carrier, SPAN_ID_KEY, DDSpanId.toString(context.getSpanId())); if (context.lockSamplingPriority()) { - setter.set(carrier, SAMPLING_PRIORITY_KEY, String.valueOf(context.getSamplingPriority())); + setter.set(carrier, SAMPLING_PRIORITY_KEY, String.valueOf(context.getTraceSamplingPriority())); } final CharSequence origin = context.getOrigin(); if (origin != null) { diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/ExtractedContext.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/ExtractedContext.java index 829c6f17ec..71ab991de9 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/ExtractedContext.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/ExtractedContext.java @@ -96,8 +96,8 @@ public String toString() { if (getBaggage() != null) { builder.append("baggage=").append(getBaggage()).append(", "); } - if (getSamplingPriority() != PrioritySampling.UNSET) { - builder.append("samplingPriority=").append(getSamplingPriority()).append(", "); + if (getTraceSamplingPriority() != PrioritySampling.UNSET) { + builder.append("samplingPriority=").append(getTraceSamplingPriority()).append(", "); } return builder.append('}').toString(); } diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/W3CHttpCodec.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/W3CHttpCodec.java index 46bb7c70af..7cd8e90bea 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/W3CHttpCodec.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/W3CHttpCodec.java @@ -81,7 +81,7 @@ private void injectTraceParent( sb.append(context.getTraceId().toHexString()); sb.append("-"); sb.append(DDSpanId.toHexStringPadded(context.getSpanId())); - sb.append(context.getSamplingPriority() > 0 ? "-01" : "-00"); + sb.append(context.getTraceSamplingPriority() > 0 ? "-01" : "-00"); setter.set(carrier, TRACE_PARENT_KEY, sb.toString()); } diff --git a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/XRayHttpCodec.java b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/XRayHttpCodec.java index 37220a56d7..5e0408d013 100644 --- a/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/XRayHttpCodec.java +++ b/features/dd-sdk-android-trace-internal/src/main/java/com/datadog/trace/core/propagation/XRayHttpCodec.java @@ -89,7 +89,7 @@ public void inject(DDSpanContext context, C carrier, AgentPropagation.Setter if (context.lockSamplingPriority()) { buf.append(';' + SAMPLED_PREFIX) - .append(convertSamplingPriority(context.getSamplingPriority())); + .append(convertSamplingPriority(context.getTraceSamplingPriority())); } int maxCapacity = buf.length() + MAX_ADDITIONAL_BYTES; diff --git a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/common/sampling/SamplerTest.kt b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/common/sampling/SamplerTest.kt new file mode 100644 index 0000000000..9d14aec345 --- /dev/null +++ b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/common/sampling/SamplerTest.kt @@ -0,0 +1,139 @@ +/* + * 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 2016-Present Datadog, Inc. + */ +package com.datadog.trace.common.sampling + +import com.datadog.trace.api.Config +import com.datadog.trace.api.sampling.PrioritySampling +import com.datadog.trace.api.sampling.SamplingMechanism +import com.datadog.trace.bootstrap.instrumentation.api.SamplerConstants +import com.datadog.utils.forge.Configurator +import fr.xgouchet.elmyr.annotation.DoubleForgery +import fr.xgouchet.elmyr.junit5.ForgeConfiguration +import fr.xgouchet.elmyr.junit5.ForgeExtension +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.api.extension.Extensions +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(value = Configurator::class) +class SamplerTest { + + private lateinit var mockConfig: Config + + @BeforeEach + fun `set up`() { + mockConfig = mock { + on { traceSampleRate } doReturn null + on { traceSamplingRules } doReturn null + on { traceSamplingServiceRules } doReturn null + on { isV2CompatibilityEnabled } doReturn false + on { isPrioritySamplingEnabled } doReturn false + on { traceSamplingOperationRules } doReturn null + } + } + + @Test + fun `M return RuleBasedTraceSampler W forConfig {v2 compatible, sampleRate provided}`( + @DoubleForgery(min = 0.1, max = 1.0) fakeSampleRate: Double + ) { + // Given + whenever(mockConfig.isV2CompatibilityEnabled).thenReturn(true) + whenever(mockConfig.traceSampleRate).thenReturn(fakeSampleRate) + + // When + val actual = Sampler.Builder.forConfig(mockConfig, null) + + // Then + assertThat(actual).isInstanceOf(RuleBasedTraceSampler::class.java) + } + + @Test + fun `M return RateByServiceTraceSampler W forConfig {v2 incompatible, sampleRate provided}`( + @DoubleForgery(min = 0.1, max = 1.0) fakeSampleRate: Double + ) { + // Given + whenever(mockConfig.traceSampleRate).thenReturn(fakeSampleRate) + + // When + val actual = Sampler.Builder.forConfig(mockConfig, null) + + // Then + assertThat(actual).isInstanceOf(RateByServiceTraceSampler::class.java) + assertThat((actual as RateByServiceTraceSampler).sampleRate).isEqualTo(fakeSampleRate) + } + + @Test + fun `M return AllSampler W forConfig {v2 incompatible, sampleRate not provided}`() { + // When + val actual = Sampler.Builder.forConfig(mockConfig, null) + + // Then + assertThat(actual).isInstanceOf(AllSampler::class.java) + } + + @Test + fun `M return ForcePrioritySampler W forConfig {priority sampling, prioritySamplingForce = KEEP}`() { + // Given + whenever(mockConfig.isPrioritySamplingEnabled).thenReturn(true) + whenever(mockConfig.prioritySamplingForce).thenReturn(SamplerConstants.KEEP) + + // When + val actual = Sampler.Builder.forConfig(mockConfig, null) + + // Then + assertThat(actual).isInstanceOf(ForcePrioritySampler::class.java) + assertThat((actual as ForcePrioritySampler).prioritySampling).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) + assertThat(actual.samplingMechanism).isEqualTo(SamplingMechanism.DEFAULT.toInt()) + } + + @Test + fun `M return ForcePrioritySampler W forConfig {priority sampling, prioritySamplingForce = DROP}`() { + // Given + whenever(mockConfig.isPrioritySamplingEnabled).thenReturn(true) + whenever(mockConfig.prioritySamplingForce).thenReturn(SamplerConstants.DROP) + + // When + val actual = Sampler.Builder.forConfig(mockConfig, null) + + // Then + assertThat(actual).isInstanceOf(ForcePrioritySampler::class.java) + assertThat((actual as ForcePrioritySampler).prioritySampling).isEqualTo(PrioritySampling.SAMPLER_DROP.toInt()) + assertThat(actual.samplingMechanism).isEqualTo(SamplingMechanism.DEFAULT.toInt()) + } + + @Test + fun `M return RateByServiceTraceSampler W forConfig {priority sampling, prioritySamplingForce is null}`() { + // Given + whenever(mockConfig.isPrioritySamplingEnabled).thenReturn(true) + + // When + val actual = Sampler.Builder.forConfig(mockConfig, null) + + // Then + assertThat(actual).isInstanceOf(RateByServiceTraceSampler::class.java) + } + + @Test + fun `M return AllSampler W forConfig {config is null}`() { + // When + val actual = Sampler.Builder.forConfig(null, null) + + // Then + assertThat(actual).isInstanceOf(AllSampler::class.java) + } +} diff --git a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreSpanBuilderTest.kt b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreSpanBuilderTest.kt index 6dc90fa6cf..00c4080759 100644 --- a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreSpanBuilderTest.kt +++ b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreSpanBuilderTest.kt @@ -327,7 +327,7 @@ internal class CoreSpanBuilderTest : DDCoreSpecification() { // Then assertThat(span.traceId).isEqualTo(extractedContext.traceId) assertThat(span.parentId).isEqualTo(extractedContext.spanId) - assertThat(span.samplingPriority).isEqualTo(extractedContext.samplingPriority) + assertThat(span.traceSamplingPriority).isEqualTo(extractedContext.traceSamplingPriority) assertThat(span.context().origin).isEqualTo(extractedContext.origin) assertThat(span.context().baggageItems).isEqualTo(extractedContext.baggage) // check the extracted context has been copied into the span tags. Intercepted tags will be skipped from @@ -353,7 +353,7 @@ internal class CoreSpanBuilderTest : DDCoreSpecification() { // Then assertThat(span.traceId).isNotEqualTo(DDTraceId.ZERO) assertThat(span.parentId).isEqualTo(DDSpanId.ZERO) - assertThat(span.samplingPriority).isNull() + assertThat(span.traceSamplingPriority).isNull() assertThat(span.context().origin).isEqualTo(tagContext.origin) assertThat(span.context().baggageItems).isEqualTo(emptyMap()) assertThat(span.context().tags).containsExactlyInAnyOrderEntriesOf( diff --git a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreTracerTest.kt b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreTracerTest.kt index 83a8a54964..70f32c1277 100644 --- a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreTracerTest.kt +++ b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/CoreTracerTest.kt @@ -150,7 +150,7 @@ internal class CoreTracerTest : DDCoreSpecification() { writer.waitForTraces(1) // Then - assertThat(span.samplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) + assertThat(span.traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) // Tear down tracer.close() @@ -168,15 +168,15 @@ internal class CoreTracerTest : DDCoreSpecification() { root.finish() // Then - assertThat(child.samplingPriority).isNull() + assertThat(child.traceSamplingPriority).isNull() // Tear down child.finish() writer.waitForTraces(1) // Then - assertThat(root.samplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) - assertThat(root.samplingPriority).isEqualTo(child.samplingPriority) + assertThat(root.traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) + assertThat(root.traceSamplingPriority).isEqualTo(child.traceSamplingPriority) // Tear down tracer.close() diff --git a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanContextTest.kt b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanContextTest.kt index 7b8ce441ea..967d6e387a 100644 --- a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanContextTest.kt +++ b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanContextTest.kt @@ -154,7 +154,7 @@ internal class DDSpanContextTest : DDCoreSpecification() { context.setSamplingPriority(PrioritySampling.SAMPLER_DROP.toInt(), SamplingMechanism.DEFAULT.toInt()) // Then: "priority should be set" - assertThat(context.samplingPriority).isEqualTo(PrioritySampling.SAMPLER_DROP.toInt()) + assertThat(context.traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_DROP.toInt()) // When: "sampling priority locked" context.lockSamplingPriority() @@ -164,13 +164,13 @@ internal class DDSpanContextTest : DDCoreSpecification() { context.setSamplingPriority(PrioritySampling.USER_DROP.toInt(), SamplingMechanism.MANUAL.toInt()) assertThat(samplingPriority) .isFalse() - assertThat(context.samplingPriority).isEqualTo(PrioritySampling.SAMPLER_DROP.toInt()) + assertThat(context.traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_DROP.toInt()) // When context.forceKeep() // Then: "lock is bypassed and priority set to USER_KEEP" - assertThat(context.samplingPriority).isEqualTo(PrioritySampling.USER_KEEP.toInt()) + assertThat(context.traceSamplingPriority).isEqualTo(PrioritySampling.USER_KEEP.toInt()) // Tear down span.finish() @@ -187,7 +187,7 @@ internal class DDSpanContextTest : DDCoreSpecification() { val context = span.context() as DDSpanContext // Then - assertThat(context.samplingPriority).isEqualTo(PrioritySampling.UNSET.toInt()) + assertThat(context.traceSamplingPriority).isEqualTo(PrioritySampling.UNSET.toInt()) // Given context.setSpanSamplingPriority(rate, limit) @@ -200,7 +200,7 @@ internal class DDSpanContextTest : DDCoreSpecification() { assertThat(context.getTag(DDSpanContext.SPAN_SAMPLING_MAX_PER_SECOND_TAG)) .isEqualTo(if (limit == Int.MAX_VALUE) null else limit) // single span sampling should not change the trace sampling priority - assertThat(context.samplingPriority).isEqualTo(PrioritySampling.UNSET.toInt()) + assertThat(context.traceSamplingPriority).isEqualTo(PrioritySampling.UNSET.toInt()) // make sure the `_dd.p.dm` tag has not been set by single span sampling assertThat(context.propagationTags.createTagMap().containsKey("_dd.p.dm")).isFalse() } diff --git a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanTest.kt b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanTest.kt index 6cc740891b..5bd609bc1c 100644 --- a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanTest.kt +++ b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/DDSpanTest.kt @@ -95,18 +95,18 @@ internal class DDSpanTest : DDCoreSpecification() { // When span.setSamplingPriority(PrioritySampling.UNSET.toInt()) // Then - assertThat(span.samplingPriority).isNull() + assertThat(span.traceSamplingPriority).isNull() // When span.setSamplingPriority(PrioritySampling.SAMPLER_KEEP.toInt()) // Then - assertThat(span.samplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) + assertThat(span.traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) // When (span.context() as DDSpanContext).lockSamplingPriority() span.setSamplingPriority(PrioritySampling.USER_KEEP.toInt()) // Then - assertThat(span.samplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) + assertThat(span.traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) } @Test @@ -301,10 +301,10 @@ internal class DDSpanTest : DDCoreSpecification() { parent.finish() // Then - assertThat(parent.context().samplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) - assertThat(parent.samplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) - assertThat(child1.samplingPriority).isEqualTo(parent.samplingPriority) - assertThat(child2.samplingPriority).isEqualTo(parent.samplingPriority) + assertThat(parent.context().traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) + assertThat(parent.traceSamplingPriority).isEqualTo(PrioritySampling.SAMPLER_KEEP.toInt()) + assertThat(child1.traceSamplingPriority).isEqualTo(parent.traceSamplingPriority) + assertThat(child2.traceSamplingPriority).isEqualTo(parent.traceSamplingPriority) } @ParameterizedTest @@ -499,7 +499,7 @@ internal class DDSpanTest : DDCoreSpecification() { // Then val expectedLimit = if (limit == Int.MAX_VALUE) null else limit - assertThat(span.samplingPriority()).isEqualTo(PrioritySampling.UNSET.toInt()) + assertThat(span.traceSamplingPriority).isNull() // When span.setSpanSamplingPriority(rate, limit) @@ -509,7 +509,7 @@ internal class DDSpanTest : DDCoreSpecification() { .isEqualTo(SamplingMechanism.SPAN_SAMPLING_RATE) assertThat(span.getTag(DDSpanContext.SPAN_SAMPLING_RULE_RATE_TAG)).isEqualTo(rate) assertThat(span.getTag(DDSpanContext.SPAN_SAMPLING_MAX_PER_SECOND_TAG)).isEqualTo(expectedLimit) - assertThat(span.samplingPriority()).isEqualTo(PrioritySampling.UNSET.toInt()) + assertThat(span.traceSamplingPriority).isNull() } @Test diff --git a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/PendingTraceTestBase.kt b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/PendingTraceTestBase.kt index 637aaedfad..ff18570dd6 100644 --- a/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/PendingTraceTestBase.kt +++ b/features/dd-sdk-android-trace-internal/src/test/kotlin/com/datadog/trace/core/PendingTraceTestBase.kt @@ -144,7 +144,7 @@ internal abstract class PendingTraceTestBase : DDCoreSpecification() { @Test fun `partial flush`() { // Given - val quickTracer = tracerBuilder().writer(writer).partialFlushMinSpans(2).build() + val quickTracer = tracerBuilder().writer(writer).partialFlushMinSpans(1).build() val rootSpan = quickTracer.buildSpan(instrumentationName, "root").start() as DDSpan val trace = rootSpan.context().trace as PendingTrace val child1 = quickTracer.buildSpan(instrumentationName, "child1") @@ -192,7 +192,7 @@ internal abstract class PendingTraceTestBase : DDCoreSpecification() { @Test fun `partial flush with root span closed last`() { // Given - val quickTracer = tracerBuilder().writer(writer).partialFlushMinSpans(2).build() as CoreTracer + val quickTracer = tracerBuilder().writer(writer).partialFlushMinSpans(1).build() as CoreTracer val rootSpan = quickTracer.buildSpan(instrumentationName, "root").start() as DDSpan val trace = rootSpan.context().trace val child1 = quickTracer diff --git a/features/dd-sdk-android-trace-otel/src/main/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerProvider.kt b/features/dd-sdk-android-trace-otel/src/main/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerProvider.kt index 597248df35..b4dda27ceb 100644 --- a/features/dd-sdk-android-trace-otel/src/main/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerProvider.kt +++ b/features/dd-sdk-android-trace-otel/src/main/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerProvider.kt @@ -17,6 +17,7 @@ import com.datadog.android.trace.DatadogTracing import com.datadog.android.trace.InternalCoreWriterProvider import com.datadog.android.trace.TracingHeaderType import com.datadog.android.trace.api.tracer.DatadogTracer +import com.datadog.android.trace.internal.DatadogTracingToolkit import com.datadog.android.trace.internal.DatadogTracingToolkit.setTraceId128BitGenerationEnabled import com.datadog.android.trace.opentelemetry.internal.DatadogContextStorageWrapper import com.datadog.android.trace.opentelemetry.internal.executeIfJavaFunctionPackageExists @@ -150,6 +151,7 @@ class OtelTracerProvider internal constructor( private fun createDatadogTracer(): DatadogTracer { val datadogTracer = builderDelegate .withServiceName(serviceName) + .also(DatadogTracingToolkit::setSdkV2Compatible) .build() return datadogTracer diff --git a/features/dd-sdk-android-trace-otel/src/test/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerBuilderProviderTest.kt b/features/dd-sdk-android-trace-otel/src/test/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerBuilderProviderTest.kt index 2d471e74a2..ee1a08b8e4 100644 --- a/features/dd-sdk-android-trace-otel/src/test/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerBuilderProviderTest.kt +++ b/features/dd-sdk-android-trace-otel/src/test/kotlin/com/datadog/android/trace/opentelemetry/OtelTracerBuilderProviderTest.kt @@ -369,7 +369,7 @@ internal class OtelTracerBuilderProviderTest { // Then val priority = delegateSpan.samplingPriority - assertThat(priority).isEqualTo(DatadogTracingConstants.PrioritySampling.USER_KEEP.toInt()) + assertThat(priority).isEqualTo(DatadogTracingConstants.PrioritySampling.USER_KEEP) } @Test @@ -423,9 +423,9 @@ internal class OtelTracerBuilderProviderTest { } spans.forEach { it.end() } val droppedSpans = - delegatedSpans.filter { it.samplingPriority == DatadogTracingConstants.PrioritySampling.USER_DROP.toInt() } + delegatedSpans.filter { it.samplingPriority == DatadogTracingConstants.PrioritySampling.USER_DROP } val keptSpans = - delegatedSpans.filter { it.samplingPriority == DatadogTracingConstants.PrioritySampling.USER_KEEP.toInt() } + delegatedSpans.filter { it.samplingPriority == DatadogTracingConstants.PrioritySampling.USER_KEEP } // Then assertThat(droppedSpans.size + keptSpans.size).isEqualTo(numberOfSpans) diff --git a/features/dd-sdk-android-trace/api/apiSurface b/features/dd-sdk-android-trace/api/apiSurface index 2fe67d85db..d1032344a0 100644 --- a/features/dd-sdk-android-trace/api/apiSurface +++ b/features/dd-sdk-android-trace/api/apiSurface @@ -30,28 +30,17 @@ object com.datadog.android.trace.internal.DatadogTracingToolkit var propagationHelper: DatadogPropagationHelper fun setTracingSamplingPriorityIfNecessary(com.datadog.android.trace.api.span.DatadogSpanContext) fun setTraceId128BitGenerationEnabled(com.datadog.android.trace.api.tracer.DatadogTracerBuilder): com.datadog.android.trace.api.tracer.DatadogTracerBuilder + fun setSdkV2Compatible(com.datadog.android.trace.api.tracer.DatadogTracerBuilder): com.datadog.android.trace.api.tracer.DatadogTracerBuilder object com.datadog.android.trace.internal.SpanAttributes const val DATADOG_INITIAL_CONTEXT: String fun android.database.sqlite.SQLiteDatabase.transactionTraced(String, Boolean = true, com.datadog.android.trace.api.span.DatadogSpan.(android.database.sqlite.SQLiteDatabase) -> T): T data class com.datadog.android.trace.model.SpanEvent - constructor(Device, Os, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.Long, kotlin.Long, kotlin.Long = 0L, Metrics, Meta) + constructor(kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.Long, kotlin.Long, kotlin.Long = 0L, Metrics, Meta) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): SpanEvent fun fromJsonObject(com.google.gson.JsonObject): SpanEvent - data class Device - constructor(Type? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.List? = null, kotlin.String? = null, kotlin.Number? = null, kotlin.Boolean? = null, kotlin.Number? = null) - fun toJson(): com.google.gson.JsonElement - companion object - fun fromJson(kotlin.String): Device - fun fromJsonObject(com.google.gson.JsonObject): Device - data class Os - constructor(kotlin.String, kotlin.String, kotlin.String? = null, kotlin.String) - fun toJson(): com.google.gson.JsonElement - companion object - fun fromJson(kotlin.String): Os - fun fromJsonObject(com.google.gson.JsonObject): Os data class Metrics constructor(kotlin.Long? = null, kotlin.collections.Map = mapOf()) fun toJson(): com.google.gson.JsonElement @@ -59,7 +48,7 @@ data class com.datadog.android.trace.model.SpanEvent fun fromJson(kotlin.String): Metrics fun fromJsonObject(com.google.gson.JsonObject): Metrics data class Meta - constructor(kotlin.String, Dd, Span, Tracer, Usr, Account? = null, Network? = null, kotlin.collections.Map = mapOf()) + constructor(kotlin.String, Dd, Span, Tracer, Usr, Account? = null, Network? = null, Device, Os, kotlin.collections.Map = mapOf()) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Meta @@ -100,6 +89,18 @@ data class com.datadog.android.trace.model.SpanEvent companion object fun fromJson(kotlin.String): Network fun fromJsonObject(com.google.gson.JsonObject): Network + data class Device + constructor(Type? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.List? = null, kotlin.String? = null, kotlin.Number? = null, kotlin.Boolean? = null, kotlin.Number? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Device + fun fromJsonObject(com.google.gson.JsonObject): Device + data class Os + constructor(kotlin.String, kotlin.String, kotlin.String? = null, kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Os + fun fromJsonObject(com.google.gson.JsonObject): Os data class Application constructor(kotlin.String? = null) fun toJson(): com.google.gson.JsonElement diff --git a/features/dd-sdk-android-trace/api/dd-sdk-android-trace.api b/features/dd-sdk-android-trace/api/dd-sdk-android-trace.api index 034296da94..d99dc33785 100644 --- a/features/dd-sdk-android-trace/api/dd-sdk-android-trace.api +++ b/features/dd-sdk-android-trace/api/dd-sdk-android-trace.api @@ -66,6 +66,7 @@ public final class com/datadog/android/trace/internal/DatadogTracingToolkit { public static final field INSTANCE Lcom/datadog/android/trace/internal/DatadogTracingToolkit; public static final field spanIdConverter Lcom/datadog/android/trace/internal/DatadogSpanIdConverter; public final fun getPropagationHelper ()Lcom/datadog/android/trace/internal/DatadogPropagationHelper; + public final fun setSdkV2Compatible (Lcom/datadog/android/trace/api/tracer/DatadogTracerBuilder;)Lcom/datadog/android/trace/api/tracer/DatadogTracerBuilder; public final fun setTraceId128BitGenerationEnabled (Lcom/datadog/android/trace/api/tracer/DatadogTracerBuilder;)Lcom/datadog/android/trace/api/tracer/DatadogTracerBuilder; public final fun setTracingSamplingPriorityIfNecessary (Lcom/datadog/android/trace/api/span/DatadogSpanContext;)V } @@ -77,33 +78,29 @@ public final class com/datadog/android/trace/internal/SpanAttributes { public final class com/datadog/android/trace/model/SpanEvent { public static final field Companion Lcom/datadog/android/trace/model/SpanEvent$Companion; - public fun (Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;)V - public synthetic fun (Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/datadog/android/trace/model/SpanEvent$Device; - public final fun component10 ()J - public final fun component11 ()J - public final fun component12 ()Lcom/datadog/android/trace/model/SpanEvent$Metrics; - public final fun component13 ()Lcom/datadog/android/trace/model/SpanEvent$Meta; - public final fun component2 ()Lcom/datadog/android/trace/model/SpanEvent$Os; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component10 ()Lcom/datadog/android/trace/model/SpanEvent$Metrics; + public final fun component11 ()Lcom/datadog/android/trace/model/SpanEvent$Meta; + public final fun component2 ()Ljava/lang/String; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; public final fun component6 ()Ljava/lang/String; - public final fun component7 ()Ljava/lang/String; - public final fun component8 ()Ljava/lang/String; + public final fun component7 ()J + public final fun component8 ()J public final fun component9 ()J - public final fun copy (Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;)Lcom/datadog/android/trace/model/SpanEvent; - public static synthetic fun copy$default (Lcom/datadog/android/trace/model/SpanEvent;Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;ILjava/lang/Object;)Lcom/datadog/android/trace/model/SpanEvent; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;)Lcom/datadog/android/trace/model/SpanEvent; + public static synthetic fun copy$default (Lcom/datadog/android/trace/model/SpanEvent;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJLcom/datadog/android/trace/model/SpanEvent$Metrics;Lcom/datadog/android/trace/model/SpanEvent$Meta;ILjava/lang/Object;)Lcom/datadog/android/trace/model/SpanEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/trace/model/SpanEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/trace/model/SpanEvent; - public final fun getDevice ()Lcom/datadog/android/trace/model/SpanEvent$Device; public final fun getDuration ()J public final fun getError ()J public final fun getMeta ()Lcom/datadog/android/trace/model/SpanEvent$Meta; public final fun getMetrics ()Lcom/datadog/android/trace/model/SpanEvent$Metrics; public final fun getName ()Ljava/lang/String; - public final fun getOs ()Lcom/datadog/android/trace/model/SpanEvent$Os; public final fun getParentId ()Ljava/lang/String; public final fun getResource ()Ljava/lang/String; public final fun getService ()Ljava/lang/String; @@ -273,25 +270,29 @@ public final class com/datadog/android/trace/model/SpanEvent$Device$Companion { public final class com/datadog/android/trace/model/SpanEvent$Meta { public static final field Companion Lcom/datadog/android/trace/model/SpanEvent$Meta$Companion; - public fun (Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Ljava/util/Map;)V - public synthetic fun (Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/util/Map;)V + public synthetic fun (Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; + public final fun component10 ()Ljava/util/Map; public final fun component2 ()Lcom/datadog/android/trace/model/SpanEvent$Dd; public final fun component3 ()Lcom/datadog/android/trace/model/SpanEvent$Span; public final fun component4 ()Lcom/datadog/android/trace/model/SpanEvent$Tracer; public final fun component5 ()Lcom/datadog/android/trace/model/SpanEvent$Usr; public final fun component6 ()Lcom/datadog/android/trace/model/SpanEvent$Account; public final fun component7 ()Lcom/datadog/android/trace/model/SpanEvent$Network; - public final fun component8 ()Ljava/util/Map; - public final fun copy (Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Ljava/util/Map;)Lcom/datadog/android/trace/model/SpanEvent$Meta; - public static synthetic fun copy$default (Lcom/datadog/android/trace/model/SpanEvent$Meta;Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/trace/model/SpanEvent$Meta; + public final fun component8 ()Lcom/datadog/android/trace/model/SpanEvent$Device; + public final fun component9 ()Lcom/datadog/android/trace/model/SpanEvent$Os; + public final fun copy (Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/util/Map;)Lcom/datadog/android/trace/model/SpanEvent$Meta; + public static synthetic fun copy$default (Lcom/datadog/android/trace/model/SpanEvent$Meta;Ljava/lang/String;Lcom/datadog/android/trace/model/SpanEvent$Dd;Lcom/datadog/android/trace/model/SpanEvent$Span;Lcom/datadog/android/trace/model/SpanEvent$Tracer;Lcom/datadog/android/trace/model/SpanEvent$Usr;Lcom/datadog/android/trace/model/SpanEvent$Account;Lcom/datadog/android/trace/model/SpanEvent$Network;Lcom/datadog/android/trace/model/SpanEvent$Device;Lcom/datadog/android/trace/model/SpanEvent$Os;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/trace/model/SpanEvent$Meta; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/trace/model/SpanEvent$Meta; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/trace/model/SpanEvent$Meta; public final fun getAccount ()Lcom/datadog/android/trace/model/SpanEvent$Account; public final fun getAdditionalProperties ()Ljava/util/Map; public final fun getDd ()Lcom/datadog/android/trace/model/SpanEvent$Dd; + public final fun getDevice ()Lcom/datadog/android/trace/model/SpanEvent$Device; public final fun getNetwork ()Lcom/datadog/android/trace/model/SpanEvent$Network; + public final fun getOs ()Lcom/datadog/android/trace/model/SpanEvent$Os; public final fun getSpan ()Lcom/datadog/android/trace/model/SpanEvent$Span; public final fun getTracer ()Lcom/datadog/android/trace/model/SpanEvent$Tracer; public final fun getUsr ()Lcom/datadog/android/trace/model/SpanEvent$Usr; diff --git a/features/dd-sdk-android-trace/src/main/json/trace/span-schema.json b/features/dd-sdk-android-trace/src/main/json/trace/span-schema.json index 1184e879b5..8701c68e21 100644 --- a/features/dd-sdk-android-trace/src/main/json/trace/span-schema.json +++ b/features/dd-sdk-android-trace/src/main/json/trace/span-schema.json @@ -16,17 +16,9 @@ "error", "type", "meta", - "metrics", - "device", - "os" + "metrics" ], "properties": { - "device": { - "$ref": "_common-schema.json#/properties/device" - }, - "os": { - "$ref": "_common-schema.json#/properties/os" - }, "trace_id": { "type": "string", "description": "The id of the trace this Span belongs to", @@ -260,6 +252,12 @@ } }, "readOnly": true + }, + "device": { + "$ref": "_common-schema.json#/properties/device" + }, + "os": { + "$ref": "_common-schema.json#/properties/os" } }, "required": [ diff --git a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapter.kt b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapter.kt index 2ea556fa06..57cf1734bf 100644 --- a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapter.kt +++ b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapter.kt @@ -21,7 +21,7 @@ internal class DatadogSpanAdapter( override val parentSpanId: Long? get() = (delegate as? DDSpan)?.parentId - override val samplingPriority: Int? get() = delegate.samplingPriority + override val samplingPriority: Int? get() = delegate.traceSamplingPriority override val durationNano: Long get() = delegate.durationNano diff --git a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapter.kt b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapter.kt index 1ca0fadd40..55ab6584e9 100644 --- a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapter.kt +++ b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapter.kt @@ -14,7 +14,7 @@ import com.datadog.trace.core.PendingTrace internal class DatadogSpanContextAdapter(internal val delegate: AgentSpan.Context) : DatadogSpanContext { override val spanId: Long get() = delegate.spanId - override val samplingPriority: Int get() = delegate.samplingPriority + override val samplingPriority: Int get() = delegate.traceSamplingPriority override val tags: Map get() = ddSpanContext?.tags.orEmpty() override val traceId: DatadogTraceId get() = DatadogTraceIdAdapter(delegate.traceId) diff --git a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapter.kt b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapter.kt index b130f8c54c..57b6797009 100644 --- a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapter.kt +++ b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapter.kt @@ -24,6 +24,7 @@ internal class DatadogTracerBuilderAdapter( private var sampleRate: Double? = null private var bundleWithRumEnabled: Boolean = true + private var sdkV2OTelCompatible: Boolean = false private var traceRateLimit = Int.MAX_VALUE private var partialFlushMinSpans = DEFAULT_PARTIAL_MIN_FLUSH private val globalTags: MutableMap = mutableMapOf() @@ -85,6 +86,10 @@ internal class DatadogTracerBuilderAdapter( delegate.idGenerationStrategy(IdGenerationStrategy.fromName("SECURE_RANDOM", traceId128BitGenerationEnabled)) } + internal fun setSdkV2Compatible() { + sdkV2OTelCompatible = true + } + @VisibleForTesting internal fun properties(): Properties { val properties = Properties() @@ -96,6 +101,7 @@ internal class DatadogTracerBuilderAdapter( properties.setProperty(TracerConfig.TRACE_RATE_LIMIT, traceRateLimit.toString()) properties.setProperty(TracerConfig.PARTIAL_FLUSH_MIN_SPANS, partialFlushMinSpans.toString()) properties.setProperty(TracerConfig.URL_AS_RESOURCE_NAME, DEFAULT_URL_AS_RESOURCE_NAME.toString()) + properties.setProperty(TracerConfig.SDK_V2_COMPATIBILITY_FLAG, sdkV2OTelCompatible.toString()) sampleRate?.let { properties.setProperty( TracerConfig.TRACE_SAMPLE_RATE, diff --git a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracingToolkit.kt b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracingToolkit.kt index 42e712174d..aec0b54314 100644 --- a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracingToolkit.kt +++ b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/DatadogTracingToolkit.kt @@ -49,4 +49,12 @@ object DatadogTracingToolkit { (builder as? DatadogTracerBuilderAdapter)?.setTraceId128BitGenerationEnabled(true) return builder } + + /** + * Enables compatibility mode with SDK v2 for sampling factory strategy. + */ + fun setSdkV2Compatible(builder: DatadogTracerBuilder): DatadogTracerBuilder { + (builder as? DatadogTracerBuilderAdapter)?.setSdkV2Compatible() + return builder + } } diff --git a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriter.kt b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriter.kt index d4514708b4..f1f7d8809d 100644 --- a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriter.kt +++ b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriter.kt @@ -46,7 +46,7 @@ internal class CoreTraceWriter( ?.withWriteContext { datadogContext, writeScope -> val writeSpans = trace .filter { - it.samplingPriority() !in DROP_SAMPLING_PRIORITIES + it.getTraceSamplingPriority() !in DROP_SAMPLING_PRIORITIES } .map { it.bundleWithRum() } // TODO RUM-4092 Add the capability in the serializer to handle multiple spans in one payload diff --git a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapper.kt b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapper.kt index 5a2735c8bd..a8996789a8 100644 --- a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapper.kt +++ b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapper.kt @@ -11,6 +11,7 @@ import com.datadog.android.log.LogAttributes import com.datadog.android.trace.model.SpanEvent import com.datadog.trace.api.DDSpanId import com.datadog.trace.api.internal.util.LongStringUtils +import com.datadog.trace.api.sampling.PrioritySampling import com.datadog.trace.bootstrap.instrumentation.api.AgentSpanLink import com.datadog.trace.core.DDSpan import com.datadog.trace.core.DDSpanContext @@ -28,8 +29,6 @@ internal class CoreTracerSpanToSpanEventMapper( val serverOffset = datadogContext.time.serverTimeOffsetNs val metrics = resolveMetrics(model) val metadata = resolveMeta(datadogContext, model) - val deviceInfo = resolveDeviceInfo(datadogContext.deviceInfo) - val osInfo = resolveOsInfo(datadogContext.deviceInfo) val lessSignificantTraceId = LongStringUtils.toHexStringPadded(model.traceId.toLong(), TRACE_ID_HEXA_SIZE) return SpanEvent( traceId = lessSignificantTraceId, @@ -42,9 +41,7 @@ internal class CoreTracerSpanToSpanEventMapper( start = model.startTime + serverOffset, error = model.error.toLong(), meta = metadata, - metrics = metrics, - device = deviceInfo, - os = osInfo + metrics = metrics ) } @@ -64,7 +61,12 @@ internal class CoreTracerSpanToSpanEventMapper( // TODO RUM-10805 - make it back private and re-create objects in tests internal fun resolveMetrics(event: DDSpan): SpanEvent.Metrics { val metrics = resolveMetricsFromSpanContext(event).apply { - this[DDSpanContext.PRIORITY_SAMPLING_KEY] = event.samplingPriority() + val spanSamplingPriority = event.spanSamplingPriority + if (spanSamplingPriority != PrioritySampling.UNSET.toInt()) { + // This required for backward compatibility with AndroidTracer that + // don't add the sampling priority if it not set for current span. + this[DDSpanContext.PRIORITY_SAMPLING_KEY] = spanSamplingPriority + } } return SpanEvent.Metrics( topLevel = if (event.parentId == 0L) 1 else null, @@ -74,6 +76,8 @@ internal class CoreTracerSpanToSpanEventMapper( // TODO RUM-10805 - make it back private and re-create objects in tests internal fun resolveMeta(datadogContext: DatadogContext, event: DDSpan): SpanEvent.Meta { + val deviceInfo = resolveDeviceInfo(datadogContext.deviceInfo) + val osInfo = resolveOsInfo(datadogContext.deviceInfo) val networkInfoMeta = if (networkInfoEnabled) resolveNetworkInfo(datadogContext.networkInfo) else null val userInfo = datadogContext.userInfo val accountInfo = datadogContext.accountInfo @@ -109,6 +113,8 @@ internal class CoreTracerSpanToSpanEventMapper( usr = usrMeta, account = accountMeta, network = networkInfoMeta, + device = deviceInfo, + os = osInfo, additionalProperties = meta ) } diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/assertj/SpanEventAssert.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/assertj/SpanEventAssert.kt index 0ddcd3576e..9813c5a406 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/assertj/SpanEventAssert.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/assertj/SpanEventAssert.kt @@ -359,64 +359,64 @@ internal class SpanEventAssert(actual: SpanEvent) : DeviceType.GAMING_CONSOLE -> SpanEvent.Type.GAMING_CONSOLE DeviceType.BOT -> SpanEvent.Type.BOT } - assertThat(actual.device.type) + assertThat(actual.meta.device.type) .overridingErrorMessage( "Expected SpanEvent to have device type: " + "$expectedType but " + - "instead was: ${actual.device.type}" + "instead was: ${actual.meta.device.type}" ) .isEqualTo(expectedType) - assertThat(actual.device.name) + assertThat(actual.meta.device.name) .overridingErrorMessage( "Expected SpanEvent to have device name: " + "${deviceInfo.deviceName} but " + - "instead was: ${actual.device.name}" + "instead was: ${actual.meta.device.name}" ) .isEqualTo(deviceInfo.deviceName) - assertThat(actual.device.model) + assertThat(actual.meta.device.model) .overridingErrorMessage( "Expected SpanEvent to have device model: " + "${deviceInfo.deviceModel} but " + - "instead was: ${actual.device.model}" + "instead was: ${actual.meta.device.model}" ) .isEqualTo(deviceInfo.deviceModel) - assertThat(actual.device.brand) + assertThat(actual.meta.device.brand) .overridingErrorMessage( "Expected SpanEvent to have device brand: " + "${deviceInfo.deviceBrand} but " + - "instead was: ${actual.device.brand}" + "instead was: ${actual.meta.device.brand}" ) .isEqualTo(deviceInfo.deviceBrand) - assertThat(actual.device.architecture) + assertThat(actual.meta.device.architecture) .overridingErrorMessage( "Expected SpanEvent to have device architecture: " + "${deviceInfo.architecture} but " + - "instead was: ${actual.device.architecture}" + "instead was: ${actual.meta.device.architecture}" ) .isEqualTo(deviceInfo.architecture) return this } fun hasOsInfo(deviceInfo: DeviceInfo): SpanEventAssert { - assertThat(actual.os.name) + assertThat(actual.meta.os.name) .overridingErrorMessage( "Expected SpanEvent to have os name: " + "${deviceInfo.osName} but " + - "instead was: ${actual.os.name}" + "instead was: ${actual.meta.os.name}" ) .isEqualTo(deviceInfo.osName) - assertThat(actual.os.versionMajor) + assertThat(actual.meta.os.versionMajor) .overridingErrorMessage( "Expected SpanEvent to have os major version: " + "${deviceInfo.osMajorVersion} but " + - "instead was: ${actual.os.versionMajor}" + "instead was: ${actual.meta.os.versionMajor}" ) .isEqualTo(deviceInfo.osMajorVersion) - assertThat(actual.os.version) + assertThat(actual.meta.os.version) .overridingErrorMessage( "Expected SpanEvent to have os version: " + "${deviceInfo.osVersion} but " + - "instead was: ${actual.os.version}" + "instead was: ${actual.meta.os.version}" ) .isEqualTo(deviceInfo.osVersion) return this diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapterTest.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapterTest.kt index 09fc53fd63..b85c3908a4 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapterTest.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanAdapterTest.kt @@ -253,7 +253,7 @@ internal class DatadogSpanAdapterTest { @Test fun `M return delegate#samplingPriority W samplingPriority is called`() { // Given - whenever(mockAgentSpan.samplingPriority).thenReturn(fakeInt) + whenever(mockAgentSpan.traceSamplingPriority).thenReturn(fakeInt) // When val actual = testedSpanAdapter.samplingPriority diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapterTest.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapterTest.kt index 8bff0fb418..61a83ea0f4 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapterTest.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogSpanContextAdapterTest.kt @@ -69,7 +69,7 @@ class DatadogSpanContextAdapterTest { @Test fun `M return delegate#samplingPriority W samplingPriority is called`() { // Given - whenever(mockAgentSpanContext.samplingPriority).thenReturn(fakeInt) + whenever(mockAgentSpanContext.traceSamplingPriority).thenReturn(fakeInt) // When val actual = testedAgentSpanContextAdapter.samplingPriority diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapterTest.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapterTest.kt index d2963520c9..a429c716f3 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapterTest.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/DatadogTracerBuilderAdapterTest.kt @@ -78,6 +78,7 @@ class DatadogTracerBuilderAdapterTest { DatadogTracerBuilderAdapter.DEFAULT_PARTIAL_MIN_FLUSH.toString() ) expected.setProperty(TracerConfig.URL_AS_RESOURCE_NAME, DEFAULT_URL_AS_RESOURCE_NAME.toString()) + expected.setProperty(TracerConfig.SDK_V2_COMPATIBILITY_FLAG, false.toString()) expected.setProperty(TracerConfig.TAGS, "") // When @@ -95,6 +96,7 @@ class DatadogTracerBuilderAdapterTest { val fakeTagValue = forge.aString() val fakeSampleRate = forge.aDouble(min = 0.0, max = 100.0) val fakeTraceLimit = forge.anInt() + val fakeV2Compatible = forge.aBool() val fakePartialFlushMinSpans = forge.anInt() val fakeHeaderType = forge.anElementFrom( TracingHeaderType.B3, @@ -111,6 +113,7 @@ class DatadogTracerBuilderAdapterTest { setProperty(TracerConfig.TRACE_SAMPLE_RATE, (fakeSampleRate / 100.0).toString()) setProperty(TracerConfig.PARTIAL_FLUSH_MIN_SPANS, fakePartialFlushMinSpans.toString()) setProperty(TracerConfig.URL_AS_RESOURCE_NAME, DEFAULT_URL_AS_RESOURCE_NAME.toString()) + setProperty(TracerConfig.SDK_V2_COMPATIBILITY_FLAG, fakeV2Compatible.toString()) setProperty(TracerConfig.TAGS, "$fakeTagKey:$fakeTagValue") } @@ -122,6 +125,7 @@ class DatadogTracerBuilderAdapterTest { .withServiceName(fakeServiceName) .withTracingHeadersTypes(setOf(fakeHeaderType)) .withPartialFlushMinSpans(fakePartialFlushMinSpans) + .also { if (fakeV2Compatible) it.setSdkV2Compatible() } .properties() // Then diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriterTest.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriterTest.kt index aa8795ddbb..67c7946a3c 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriterTest.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/data/CoreTraceWriterTest.kt @@ -505,9 +505,9 @@ internal class CoreTraceWriterTest { private fun createNonEmptyDdSpans(forge: Forge, includeDropSamplingPriority: Boolean): List { val predicate: (DDSpan) -> Boolean = if (includeDropSamplingPriority) { - { it.samplingPriority() in CoreTraceWriter.DROP_SAMPLING_PRIORITIES } + { it.getTraceSamplingPriority() in CoreTraceWriter.DROP_SAMPLING_PRIORITIES } } else { - { it.samplingPriority() !in CoreTraceWriter.DROP_SAMPLING_PRIORITIES } + { it.getTraceSamplingPriority() !in CoreTraceWriter.DROP_SAMPLING_PRIORITIES } } var spans = emptyList() diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapperTest.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapperTest.kt index 13a495d9a1..20e12490dc 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapperTest.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/domain/event/CoreTracerSpanToSpanEventMapperTest.kt @@ -194,7 +194,7 @@ internal class CoreTracerSpanToSpanEventMapperTest { private fun DDSpan.expectedMetrics(): Map { return tags.filterValues { it is Number }.mapValues { it.value as Number }.toMutableMap().apply { - this[DDSpanContext.PRIORITY_SAMPLING_KEY] = samplingPriority() + this[DDSpanContext.PRIORITY_SAMPLING_KEY] = spanSamplingPriority } } diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/CoreDDSpanForgeryFactory.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/CoreDDSpanForgeryFactory.kt index 30e6541e95..3bc70fd08d 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/CoreDDSpanForgeryFactory.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/CoreDDSpanForgeryFactory.kt @@ -60,7 +60,7 @@ internal class CoreDDSpanForgeryFactory : ForgeryFactory { whenever(it.parentId).thenReturn(parentId) whenever(it.baggage).thenReturn(baggageItems) whenever(it.tags).thenReturn(tagsAndMetrics) - whenever(it.samplingPriority()).thenReturn(samplingPriority) + whenever(it.traceSamplingPriority).thenReturn(samplingPriority) whenever(it.links).thenReturn(spanLinks) } return mockDDSpan diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/SpanEventForgeryFactory.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/SpanEventForgeryFactory.kt index 26f0d884dc..211fd6b8ab 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/SpanEventForgeryFactory.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/utils/forge/SpanEventForgeryFactory.kt @@ -47,18 +47,6 @@ internal class SpanEventForgeryFactory : ForgeryFactory { error = errorFlag, duration = duration, start = startTime, - device = SpanEvent.Device( - type = resolveDeviceType(deviceInfo.deviceType), - name = deviceInfo.deviceName, - model = deviceInfo.deviceModel, - brand = deviceInfo.deviceBrand, - architecture = deviceInfo.architecture - ), - os = SpanEvent.Os( - name = deviceInfo.osName, - version = deviceInfo.osVersion, - versionMajor = deviceInfo.osMajorVersion - ), meta = SpanEvent.Meta( version = appPackageVersion, dd = SpanEvent.Dd(source = forge.aNullable { anAlphabeticalString() }), @@ -85,6 +73,18 @@ internal class SpanEventForgeryFactory : ForgeryFactory { connectivity = networkInfo?.connectivity?.toString().orEmpty() ) ), + device = SpanEvent.Device( + type = resolveDeviceType(deviceInfo.deviceType), + name = deviceInfo.deviceName, + model = deviceInfo.deviceModel, + brand = deviceInfo.deviceBrand, + architecture = deviceInfo.architecture + ), + os = SpanEvent.Os( + name = deviceInfo.osName, + version = deviceInfo.osVersion, + versionMajor = deviceInfo.osMajorVersion + ), additionalProperties = meta ), metrics = SpanEvent.Metrics(topLevel = isTopLevel, additionalProperties = metrics) diff --git a/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/HeadBasedSamplingTest.kt b/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/HeadBasedSamplingTest.kt index c6e23a19ac..34aca4bedd 100644 --- a/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/HeadBasedSamplingTest.kt +++ b/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/HeadBasedSamplingTest.kt @@ -200,7 +200,7 @@ class HeadBasedSamplingTest { } @Test - fun `M respect parent sampling decision W call is made { parent context = OpenTracing Span, parent not sampled }`( + fun `M respect parent sampling decision W call is made {parent context DatadogTracing Span, parent not sampled}`( @StringForgery fakeSpanName: String ) { // Given @@ -294,7 +294,7 @@ class HeadBasedSamplingTest { } @Test - fun `M respect parent sampling decision W call is made { parent context = OpenTracing Span, parent sampled }`( + fun `M respect parent sampling decision W call is made { parent context = DatadogTracing Span, parent sampled }`( @StringForgery fakeSpanName: String ) { // Given @@ -329,7 +329,7 @@ class HeadBasedSamplingTest { // Then val requestSent = mockServer.takeRequest() - assertThat(requestSent.getHeader(DATADOG_SAMPLING_PRIORITY_HEADER)).isEqualTo("2") + assertThat(requestSent.getHeader(DATADOG_SAMPLING_PRIORITY_HEADER)).isEqualTo("1") val leastSignificantTraceId = requestSent.getHeader(DATADOG_TRACE_ID_HEADER) checkNotNull(leastSignificantTraceId) val spanId = requestSent.getHeader(DATADOG_SPAN_ID_HEADER) @@ -352,8 +352,8 @@ class HeadBasedSamplingTest { ) hasMostSignificant64BitsTraceId(mostSignificantTraceId) hasParentId("0000000000000000") - hasRulePsr(1.0) - hasSamplingPriority(DatadogTracingConstants.PrioritySampling.USER_KEEP) + hasAgentPsr(1.0) + hasSamplingPriority(DatadogTracingConstants.PrioritySampling.SAMPLER_KEEP) hasGenericMetricValue("_top_level", 1) } @@ -376,7 +376,7 @@ class HeadBasedSamplingTest { hasName("okhttp.request") hasResource("http://${mockServer.hostName}:${mockServer.port}/") hasNoAgentPsr() - hasSamplingPriority(2) + hasNoSamplingPriority() hasNoGenericMetric("_top_level") hasSpanKind("client") hasHttpMethod("GET") @@ -574,7 +574,7 @@ class HeadBasedSamplingTest { // Then val requestSent = mockServer.takeRequest() - assertThat(requestSent.getHeader(DATADOG_SAMPLING_PRIORITY_HEADER)).isEqualTo("2") + assertThat(requestSent.getHeader(DATADOG_SAMPLING_PRIORITY_HEADER)).isEqualTo("1") val leastSignificantTraceId = requestSent.getHeader(DATADOG_TRACE_ID_HEADER) checkNotNull(leastSignificantTraceId) val spanId = requestSent.getHeader(DATADOG_SPAN_ID_HEADER) @@ -597,8 +597,8 @@ class HeadBasedSamplingTest { ) hasMostSignificant64BitsTraceId(mostSignificantTraceId) hasParentId("0000000000000000") - hasRulePsr(1.0) - hasSamplingPriority(DatadogTracingConstants.PrioritySampling.USER_KEEP) + hasAgentPsr(1.0) + hasSamplingPriority(DatadogTracingConstants.PrioritySampling.SAMPLER_KEEP) hasGenericMetricValue("_top_level", 1) } @@ -623,7 +623,7 @@ class HeadBasedSamplingTest { hasNoAgentPsr() // this one will have sampling priority unlike in case of propagation with tagged Span directly, // because there sampling priority is not yet set at the parent during child creation - hasSamplingPriority(2) + hasSamplingPriority(1) hasNoGenericMetric("_top_level") hasSpanKind("client") hasHttpMethod("GET") diff --git a/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/SpanExtIntegrationTest.kt b/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/SpanExtIntegrationTest.kt new file mode 100644 index 0000000000..92913c65f3 --- /dev/null +++ b/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/SpanExtIntegrationTest.kt @@ -0,0 +1,273 @@ +/* + * 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 2016-Present Datadog, Inc. + */ +package com.datadog.android.okhttp + +import com.datadog.android.Datadog +import com.datadog.android.api.SdkCore +import com.datadog.android.api.feature.Feature +import com.datadog.android.core.stub.StubEvent +import com.datadog.android.core.stub.StubSDKCore +import com.datadog.android.internal.utils.toHexString +import com.datadog.android.okhttp.tests.assertj.SpansPayloadAssert +import com.datadog.android.okhttp.tests.elmyr.OkHttpConfigurator +import com.datadog.android.trace.DatadogTracing +import com.datadog.android.trace.GlobalDatadogTracer +import com.datadog.android.trace.Trace +import com.datadog.android.trace.TraceConfiguration +import com.datadog.android.trace.api.span.DatadogSpan +import com.datadog.android.trace.withinSpan +import com.datadog.tools.unit.extensions.TestConfigurationExtension +import com.datadog.tools.unit.getFieldValue +import com.datadog.tools.unit.getStaticValue +import com.google.gson.JsonArray +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.junit5.ForgeConfiguration +import fr.xgouchet.elmyr.junit5.ForgeExtension +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.api.extension.Extensions +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.quality.Strictness + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class), + ExtendWith(TestConfigurationExtension::class) +) +@ForgeConfiguration(OkHttpConfigurator::class) +@MockitoSettings(strictness = Strictness.LENIENT) +class SpanExtIntegrationTest { + private lateinit var stubSdkCore: StubSDKCore + private lateinit var mockServer: MockWebServer + + private val expectedEnv: String get() = stubSdkCore.getDatadogContext().env + + private val JsonObject.spanId: String + get() = get("span_id").asString + + private val JsonObject.spans: JsonArray + get() = getAsJsonArray("spans") + + private fun JsonArray.getObject(index: Int) = get(index).asJsonObject + private fun StubEvent.asJson(): JsonObject = JsonParser.parseString(eventData).asJsonObject + private fun DatadogSpan.getSpanId(): String = context().spanId.toHexString() + private fun registerTracer( + sampleRate: Double? = null, + partialFlushMinSpans: Int? = null + ) = GlobalDatadogTracer.registerIfAbsent( + DatadogTracing.newTracerBuilder(stubSdkCore) + .also { + if (sampleRate != null) it.withSampleRate(sampleRate) + if (partialFlushMinSpans != null) it.withPartialFlushMinSpans(partialFlushMinSpans) + } + .build() + ) + + @BeforeEach + fun `set up`(forge: Forge) { + stubSdkCore = StubSDKCore(forge) + val registry: Any = Datadog::class.java.getStaticValue("registry") + val instances: MutableMap = registry.getFieldValue("instances") + instances += stubSdkCore.name to stubSdkCore + mockServer = MockWebServer() + + val fakeTraceConfiguration = TraceConfiguration.Builder().build() + Trace.enable(fakeTraceConfiguration, stubSdkCore) + + mockServer.enqueue(MockResponse()) + mockServer.start() + } + + @AfterEach + fun `tear down`() { + GlobalDatadogTracer.clear() + Datadog.stopInstance(stubSdkCore.name) + mockServer.shutdown() + } + + @Test + fun `M return expected events W withinSpan {two composite spans}`() { + registerTracer(partialFlushMinSpans = 1) + var isCalled = false + var rootSpanId = "" + var childSpanId = "" + withinSpan("rootSpanOperation") { + rootSpanId = getSpanId() + withinSpan("childSpanOperation") { + childSpanId = getSpanId() + isCalled = true + } + } + + val eventsWritten = stubSdkCore.eventsWritten(Feature.TRACING_FEATURE_NAME) + val rootSpanJson = eventsWritten[0].asJson() + val childSpanJson = eventsWritten[1].asJson() + + assertThat(isCalled).isTrue + SpansPayloadAssert.assertThat(rootSpanJson) + .hasEnv(expectedEnv) + .hasSpanAtIndexWith(0) { + hasSamplingPriority(1) + hasSpanId(rootSpanId) + hasResource("rootSpanOperation") + hasName("rootSpanOperation") + hasType("custom") + hasAgentPsr(1.0) + hasSamplingPriority(1) + hasValidMostSignificant64BitsTraceId() + hasValidLeastSignificant64BitsTraceId() + } + + SpansPayloadAssert.assertThat(childSpanJson) + .hasEnv(expectedEnv) + .hasSpanAtIndexWith(0) { + hasSpanId(childSpanId) + hasNoSamplingPriority() + hasParentId(rootSpanId) + hasResource("childSpanOperation") + hasName("childSpanOperation") + hasType("custom") + hasSpanKind("client") + hasNoAgentPsr() + hasNoSamplingPriority() + hasValidMostSignificant64BitsTraceId() + hasValidLeastSignificant64BitsTraceId() + } + } + + @Test + fun `M return expected events W withinSpan {three composite spans}`() { + registerTracer(partialFlushMinSpans = 1) + var isCalled = false + var rootSpanId = "" + var level1ChildSpanId = "" + var level2ChildSpanId = "" + withinSpan("rootSpanOperation") { + rootSpanId = getSpanId() + withinSpan("level1ChildSpanOperation") { + level1ChildSpanId = getSpanId() + withinSpan("level2ChildSpanOperation") { + isCalled = true + level2ChildSpanId = getSpanId() + } + } + } + + val eventsWritten = stubSdkCore.eventsWritten(Feature.TRACING_FEATURE_NAME) + val eventsJson = eventsWritten + .map { it.asJson() } + .associateBy { it.spans.getObject(0).spanId } + + val rootSpanJson = checkNotNull(eventsJson[rootSpanId]) + val child1Json = checkNotNull(eventsJson[level1ChildSpanId]) + val child2Json = checkNotNull(eventsJson[level2ChildSpanId]) + + assertThat(isCalled).isTrue + SpansPayloadAssert.assertThat(rootSpanJson) + .hasEnv(expectedEnv) + .hasSpanAtIndexWith(0) { + hasSamplingPriority(1) + hasSpanId(rootSpanId) + hasResource("rootSpanOperation") + hasName("rootSpanOperation") + hasType("custom") + hasAgentPsr(1.0) + hasSamplingPriority(1) + hasValidMostSignificant64BitsTraceId() + hasValidLeastSignificant64BitsTraceId() + } + + SpansPayloadAssert.assertThat(child1Json) + .hasEnv(expectedEnv) + .hasSpanAtIndexWith(0) { + hasSpanId(level1ChildSpanId) + hasNoSamplingPriority() + hasParentId(rootSpanId) + hasResource("level1ChildSpanOperation") + hasName("level1ChildSpanOperation") + hasType("custom") + hasSpanKind("client") + hasNoAgentPsr() + hasNoSamplingPriority() + hasValidMostSignificant64BitsTraceId() + hasValidLeastSignificant64BitsTraceId() + } + + SpansPayloadAssert.assertThat(child2Json) + .hasEnv(expectedEnv) + .hasSpanAtIndexWith(0) { + hasSpanId(level2ChildSpanId) + hasNoSamplingPriority() + hasParentId(level1ChildSpanId) + hasResource("level2ChildSpanOperation") + hasName("level2ChildSpanOperation") + hasType("custom") + hasSpanKind("client") + hasNoAgentPsr() + hasNoSamplingPriority() + hasValidMostSignificant64BitsTraceId() + hasValidLeastSignificant64BitsTraceId() + } + } + + @Test + fun `M return expected events W withinSpan {composite spans, explicit sample rate = 100}`() { + registerTracer(sampleRate = 100.0, partialFlushMinSpans = 1) + var isCalled = false + var rootSpanId = "" + var childSpanId = "" + withinSpan("rootSpanOperation") { + rootSpanId = getSpanId() + withinSpan("childSpanOperation") { + childSpanId = getSpanId() + isCalled = true + } + } + + val eventsWritten = stubSdkCore.eventsWritten(Feature.TRACING_FEATURE_NAME) + val rootSpanJson = eventsWritten[0].asJson() + val childSpanJson = eventsWritten[1].asJson() + + assertThat(isCalled).isTrue + SpansPayloadAssert.assertThat(rootSpanJson) + .hasEnv(expectedEnv) + .hasSpanAtIndexWith(0) { + hasSamplingPriority(1) + hasSpanId(rootSpanId) + hasResource("rootSpanOperation") + hasName("rootSpanOperation") + hasType("custom") + hasAgentPsr(1.0) + hasSamplingPriority(1) + hasValidMostSignificant64BitsTraceId() + hasValidLeastSignificant64BitsTraceId() + } + + SpansPayloadAssert.assertThat(childSpanJson) + .hasEnv(expectedEnv) + .hasSpanAtIndexWith(0) { + hasSpanId(childSpanId) + hasNoSamplingPriority() + hasParentId(rootSpanId) + hasResource("childSpanOperation") + hasName("childSpanOperation") + hasType("custom") + hasSpanKind("client") + hasNoAgentPsr() + hasNoSamplingPriority() + hasValidMostSignificant64BitsTraceId() + hasValidLeastSignificant64BitsTraceId() + } + } +} diff --git a/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/tests/assertj/SpansPayloadAssert.kt b/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/tests/assertj/SpansPayloadAssert.kt index fd71289a99..3490f093b2 100644 --- a/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/tests/assertj/SpansPayloadAssert.kt +++ b/reliability/single-fit/okhttp/src/test/kotlin/com/datadog/android/okhttp/tests/assertj/SpansPayloadAssert.kt @@ -108,6 +108,14 @@ internal class SpansPayloadAssert(actual: JsonObject) : return this } + fun hasType(type: String): SpanAssert { + val actualType = actualSpan.getString(TYPE_KEY) + assertThat(actualType).overridingErrorMessage( + "Expected type to be $type but was $actualType for index $index" + ).isEqualTo(type) + return this + } + fun hasResource(resource: String): SpanAssert { val actualResource = actualSpan.getString(RESOURCE_KEY) assertThat(actualResource).overridingErrorMessage( @@ -437,6 +445,7 @@ internal class SpansPayloadAssert(actual: JsonObject) : private const val SERVICE_KEY = "service" private const val ERROR_KEY = "error" private const val NAME_KEY = "name" + private const val TYPE_KEY = "type" private const val RESOURCE_KEY = "resource" private const val USR_KEY = "meta.usr" private const val USR_ID_KEY = "meta.usr.id"