From 0cb89abd4551fac85d9576360913f432e24211c5 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 22 May 2024 09:10:39 -0700 Subject: [PATCH 001/133] [docs] Tweak ToC (#5644) --- .../README.md | 23 +++++++++++-------- docs/trace/getting-started-jaeger/README.md | 19 +++++++++------ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/metrics/getting-started-prometheus-grafana/README.md b/docs/metrics/getting-started-prometheus-grafana/README.md index 7f39b121a72..dfc3e09c1a3 100644 --- a/docs/metrics/getting-started-prometheus-grafana/README.md +++ b/docs/metrics/getting-started-prometheus-grafana/README.md @@ -1,11 +1,16 @@ # Getting Started with Prometheus and Grafana -- [Export metrics from the application](#export-metrics-from-the-application) -- [Collect metrics using Prometheus](#collect-metrics-using-prometheus) - - [Install and run Prometheus](#install-and-run-prometheus) - - [View results in Prometheus](#view-results-in-prometheus) -- [Explore metrics using Grafana](#explore-metrics-using-grafana) -- [Learn more](#learn-more) +
+Table of Contents + +* [Export metrics from the application](#export-metrics-from-the-application) +* [Collect metrics using Prometheus](#collect-metrics-using-prometheus) + * [Install and run Prometheus](#install-and-run-prometheus) + * [View results in Prometheus](#view-results-in-prometheus) +* [Explore metrics using Grafana](#explore-metrics-using-grafana) +* [Learn more](#learn-more) + +
## Export metrics from the application @@ -140,8 +145,8 @@ UI](https://user-images.githubusercontent.com/17327289/151636769-138ecb4f-b44f-4 ## Learn more -- [What is Prometheus?](https://prometheus.io/docs/introduction/overview/) -- [Prometheus now supports OpenTelemetry +* [What is Prometheus?](https://prometheus.io/docs/introduction/overview/) +* [Prometheus now supports OpenTelemetry Metrics](https://horovits.medium.com/prometheus-now-supports-opentelemetry-metrics-83f85878e46a) -- [Grafana support for +* [Grafana support for Prometheus](https://prometheus.io/docs/visualization/grafana/#creating-a-prometheus-graph) diff --git a/docs/trace/getting-started-jaeger/README.md b/docs/trace/getting-started-jaeger/README.md index 4f8e36c387d..b291933df00 100644 --- a/docs/trace/getting-started-jaeger/README.md +++ b/docs/trace/getting-started-jaeger/README.md @@ -1,10 +1,15 @@ # Getting Started with Jaeger -- [Export traces from the application](#export-traces-from-the-application) - - [Check results in the console](#check-results-in-the-console) -- [Collect and visualize traces using Jaeger](#collect-and-visualize-traces-using-jaeger) -- [Final cleanup](#final-cleanup) -- [Learn more](#learn-more) +
+Table of Contents + +* [Export traces from the application](#export-traces-from-the-application) + * [Check results in the console](#check-results-in-the-console) +* [Collect and visualize traces using Jaeger](#collect-and-visualize-traces-using-jaeger) +* [Final cleanup](#final-cleanup) +* [Learn more](#learn-more) + +
## Export traces from the application @@ -178,6 +183,6 @@ BatchExportProcessor --> | Batch | OtlpExporter ## Learn more -- [Jaeger Tracing](https://www.jaegertracing.io/) -- [OTLP Exporter for OpenTelemetry +* [Jaeger Tracing](https://www.jaegertracing.io/) +* [OTLP Exporter for OpenTelemetry .NET](../../../src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md) From 574c71612b6c24ef0cef0ecf4b344a4f5f0f544e Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 22 May 2024 15:42:38 -0500 Subject: [PATCH 002/133] [repo] Fix variable usage in test-aot-compatibility script (#5645) --- build/scripts/test-aot-compatibility.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/test-aot-compatibility.ps1 b/build/scripts/test-aot-compatibility.ps1 index c7fc3acf7d8..895055a1b48 100644 --- a/build/scripts/test-aot-compatibility.ps1 +++ b/build/scripts/test-aot-compatibility.ps1 @@ -44,7 +44,7 @@ $testPassed = 0 if ($actualWarningCount -ne $expectedWarningCount) { $testPassed = 1 - Write-Host "Actual warning count:", actualWarningCount, "is not as expected. Expected warning count is:", $expectedWarningCount + Write-Host "Actual warning count:", $actualWarningCount, "is not as expected. Expected warning count is:", $expectedWarningCount } Exit $testPassed From 361a4b9bd8d73879194b860ea01e6a62978d9aa1 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Thu, 23 May 2024 12:40:23 -0700 Subject: [PATCH 003/133] [docs] Move docker related files to examples folder (#5640) Co-authored-by: Mikel Blanchard Co-authored-by: Cijo Thomas --- .../metrics/exemplars => examples/AspNetCore}/docker-compose.yaml | 0 .../exemplars => examples/AspNetCore}/grafana-datasources.yaml | 0 .../metrics/exemplars => examples/AspNetCore}/otel-collector.yaml | 0 {docs/metrics/exemplars => examples/AspNetCore}/prometheus.yaml | 0 {docs/metrics/exemplars => examples/AspNetCore}/tempo.yaml | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {docs/metrics/exemplars => examples/AspNetCore}/docker-compose.yaml (100%) rename {docs/metrics/exemplars => examples/AspNetCore}/grafana-datasources.yaml (100%) rename {docs/metrics/exemplars => examples/AspNetCore}/otel-collector.yaml (100%) rename {docs/metrics/exemplars => examples/AspNetCore}/prometheus.yaml (100%) rename {docs/metrics/exemplars => examples/AspNetCore}/tempo.yaml (100%) diff --git a/docs/metrics/exemplars/docker-compose.yaml b/examples/AspNetCore/docker-compose.yaml similarity index 100% rename from docs/metrics/exemplars/docker-compose.yaml rename to examples/AspNetCore/docker-compose.yaml diff --git a/docs/metrics/exemplars/grafana-datasources.yaml b/examples/AspNetCore/grafana-datasources.yaml similarity index 100% rename from docs/metrics/exemplars/grafana-datasources.yaml rename to examples/AspNetCore/grafana-datasources.yaml diff --git a/docs/metrics/exemplars/otel-collector.yaml b/examples/AspNetCore/otel-collector.yaml similarity index 100% rename from docs/metrics/exemplars/otel-collector.yaml rename to examples/AspNetCore/otel-collector.yaml diff --git a/docs/metrics/exemplars/prometheus.yaml b/examples/AspNetCore/prometheus.yaml similarity index 100% rename from docs/metrics/exemplars/prometheus.yaml rename to examples/AspNetCore/prometheus.yaml diff --git a/docs/metrics/exemplars/tempo.yaml b/examples/AspNetCore/tempo.yaml similarity index 100% rename from docs/metrics/exemplars/tempo.yaml rename to examples/AspNetCore/tempo.yaml From 625f32f33ea3c0bad11d1cd6b756294dd44e46bd Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 24 May 2024 13:04:08 -0700 Subject: [PATCH 004/133] [docs] Add exemplar project to solution (#5650) --- OpenTelemetry.sln | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 5150016a129..86455353f31 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -336,6 +336,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{4498 build\scripts\update-changelogs.ps1 = build\scripts\update-changelogs.ps1 EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "exemplars", "docs\metrics\exemplars\exemplars.csproj", "{79C12C80-B27B-41FB-AE79-A3BB74CFA782}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -590,6 +592,10 @@ Global {19545B37-8518-4BDD-AD49-00C031FB3C2A}.Debug|Any CPU.Build.0 = Debug|Any CPU {19545B37-8518-4BDD-AD49-00C031FB3C2A}.Release|Any CPU.ActiveCfg = Release|Any CPU {19545B37-8518-4BDD-AD49-00C031FB3C2A}.Release|Any CPU.Build.0 = Release|Any CPU + {79C12C80-B27B-41FB-AE79-A3BB74CFA782}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79C12C80-B27B-41FB-AE79-A3BB74CFA782}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79C12C80-B27B-41FB-AE79-A3BB74CFA782}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79C12C80-B27B-41FB-AE79-A3BB74CFA782}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -647,6 +653,7 @@ Global {87A20A76-D524-4AAC-AF92-8725BFED0415} = {A49299FB-C5CD-4E0E-B7E1-B7867BBD67CC} {993E65E5-E71B-40FD-871C-60A9EBD59724} = {A49299FB-C5CD-4E0E-B7E1-B7867BBD67CC} {44982E0D-C8C6-42DC-9F8F-714981F27CE6} = {7CB2F02E-03FA-4FFF-89A5-C51F107623FD} + {79C12C80-B27B-41FB-AE79-A3BB74CFA782} = {3277B1C0-BDFE-4460-9B0D-D9A661FB48DB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521} From 81244d61368cb9ce79c5cfcb63963034540e2dec Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 27 May 2024 23:37:19 -0700 Subject: [PATCH 005/133] [repo] CI tweaks and improvements (#5651) --- .github/codecov.yml | 8 ++--- .github/workflows/Component.BuildTest.yml | 2 +- .github/workflows/ci.yml | 31 +++++++++++++------ .github/workflows/codeql-analysis.yml | 4 +-- .github/workflows/dotnet-format.yml | 8 ++--- .github/workflows/package-validation.yml | 8 ++--- .github/workflows/publish-packages-1.0.yml | 6 ++-- OpenTelemetry.sln | 2 +- .../OpenTelemetry.proj | 18 ++++++----- build/UnstableCoreLibraries.proj | 16 ++++++---- 10 files changed, 61 insertions(+), 42 deletions(-) rename OpenTelemetry.proj => build/OpenTelemetry.proj (61%) diff --git a/.github/codecov.yml b/.github/codecov.yml index b20bf1b2972..c381869ce70 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -33,22 +33,22 @@ ignore: - "test" flags: - unittests-Solution-Stable: + unittests-Solution: carryforward: true paths: - src - unittests-Solution-Experimental: + unittests-Project-Stable: carryforward: true paths: - src - unittests-Instrumentation-Stable: + unittests-Project-Experimental: carryforward: true paths: - src - unittests-Instrumentation-Experimental: + unittests-UnstableCoreLibraries-Experimental: carryforward: true paths: - src diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index f97c8b94f9b..f5ef85e0dc3 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -65,7 +65,7 @@ jobs: run: dotnet tool install -g dotnet-coverage - name: Merging test results - run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage + run: dotnet-coverage merge -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/**/*.coverage - name: Upload code coverage ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} uses: codecov/codecov-action@v4 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1a0d80bac4..7f222b07cc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,7 @@ jobs: build: ['build/**', '.github/**/*.yml', '**/*.targets', '**/*.props'] shared: ['src/Shared/**'] code: ['**.cs', '**.csproj', '.editorconfig'] + solution: ['OpenTelemetry.sln'] packaged-code: ['src/**', '!**/*.md'] api-code: ['*/OpenTelemetry.Api*/**', '!**/*.md'] api-packages: ['src/OpenTelemetry.Api*/**', '!**/*.md'] @@ -50,19 +51,30 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'build') uses: ./.github/workflows/dotnet-format.yml - build-test-solution-stable: + build-test-solution: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'code') + contains(needs.detect-changes.outputs.changes, 'solution') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: project-name: 'OpenTelemetry.sln' + code-cov-name: 'Solution' + + build-test-project-stable: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'code') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: './build/OpenTelemetry.proj' project-build-commands: '-p:ExposeExperimentalFeatures=false' - code-cov-name: 'Solution-Stable' + code-cov-name: 'Project-Stable' - build-test-solution-experimental: + build-test-project-experimental: needs: detect-changes if: | contains(needs.detect-changes.outputs.changes, 'code') @@ -70,9 +82,9 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: 'OpenTelemetry.sln' + project-name: './build/OpenTelemetry.proj' project-build-commands: '-p:ExposeExperimentalFeatures=true' - code-cov-name: 'Solution-Experimental' + code-cov-name: 'Project-Experimental' # Build unstable core libraries using stable packages released to NuGet build-test-unstable-core: @@ -85,7 +97,7 @@ jobs: with: project-name: './build/UnstableCoreLibraries.proj' project-build-commands: '-p:RunningDotNetPack=true -p:ExposeExperimentalFeatures=true' - code-cov-name: 'Unstable-Core' + code-cov-name: 'UnstableCoreLibraries-Experimental' otlp-integration-test: needs: detect-changes @@ -163,8 +175,9 @@ jobs: detect-changes, lint-md, lint-dotnet-format, - build-test-solution-stable, - build-test-solution-experimental, + build-test-solution, + build-test-project-stable, + build-test-project-experimental, build-test-unstable-core, otlp-integration-test, w3c-trace-context-integration-test, diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c091dc85184..3cdd6a57b6d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,8 +39,8 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 - - name: dotnet pack OpenTelemetry.proj - run: dotnet pack OpenTelemetry.proj --configuration Release + - name: dotnet pack + run: dotnet pack ./build/OpenTelemetry.proj --configuration Release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index b6baf18aab0..2ea4834570f 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -17,10 +17,10 @@ jobs: uses: actions/setup-dotnet@v4 - name: dotnet restore - run: dotnet restore + run: dotnet restore OpenTelemetry.sln - name: dotnet format - run: dotnet format OpenTelemetry.sln --no-restore --verify-no-changes + run: dotnet format OpenTelemetry.sln --no-restore --verify-no-changes # Note: .proj files are currently not supported by dotnet format env: ExposeExperimentalFeatures: false @@ -35,9 +35,9 @@ jobs: uses: actions/setup-dotnet@v4 - name: dotnet restore - run: dotnet restore + run: dotnet restore OpenTelemetry.sln - name: dotnet format - run: dotnet format OpenTelemetry.sln --no-restore --verify-no-changes + run: dotnet format OpenTelemetry.sln --no-restore --verify-no-changes # Note: .proj files are currently not supported by dotnet format env: ExposeExperimentalFeatures: true diff --git a/.github/workflows/package-validation.yml b/.github/workflows/package-validation.yml index 757b38c18a5..d1f7658ee2d 100644 --- a/.github/workflows/package-validation.yml +++ b/.github/workflows/package-validation.yml @@ -20,8 +20,8 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 - - name: Pack - run: dotnet pack OpenTelemetry.proj --configuration Release /p:EnablePackageValidation=true /p:ExposeExperimentalFeatures=false /p:RunningDotNetPack=true + - name: dotnet pack + run: dotnet pack ./build/OpenTelemetry.proj --configuration Release /p:EnablePackageValidation=true /p:ExposeExperimentalFeatures=false /p:RunningDotNetPack=true run-package-validation-experimental: runs-on: windows-latest @@ -37,5 +37,5 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 - - name: Pack - run: dotnet pack OpenTelemetry.proj --configuration Release /p:EnablePackageValidation=true /p:ExposeExperimentalFeatures=true /p:RunningDotNetPack=true + - name: dotnet pack + run: dotnet pack ./build/OpenTelemetry.proj --configuration Release /p:EnablePackageValidation=true /p:ExposeExperimentalFeatures=true /p:RunningDotNetPack=true diff --git a/.github/workflows/publish-packages-1.0.yml b/.github/workflows/publish-packages-1.0.yml index dd2e568f2d5..1391382e3ca 100644 --- a/.github/workflows/publish-packages-1.0.yml +++ b/.github/workflows/publish-packages-1.0.yml @@ -51,13 +51,13 @@ jobs: uses: actions/setup-dotnet@v4 - name: dotnet restore - run: dotnet restore OpenTelemetry.proj -p:RunningDotNetPack=true + run: dotnet restore ./build/OpenTelemetry.proj -p:RunningDotNetPack=true - name: dotnet build - run: dotnet build OpenTelemetry.proj --configuration Release --no-restore -p:Deterministic=true -p:BuildNumber=${{ github.run_number }} -p:RunningDotNetPack=true + run: dotnet build ./build/OpenTelemetry.proj --configuration Release --no-restore -p:Deterministic=true -p:BuildNumber=${{ github.run_number }} -p:RunningDotNetPack=true - name: dotnet pack - run: dotnet pack OpenTelemetry.proj --configuration Release --no-restore --no-build -p:PackTag=${{ github.ref_type == 'tag' && github.ref_name || inputs.tag || '' }} + run: dotnet pack ./build/OpenTelemetry.proj --configuration Release --no-restore --no-build -p:PackTag=${{ github.ref_type == 'tag' && github.ref_name || inputs.tag || '' }} - name: Publish Artifacts id: upload-artifacts diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 86455353f31..5f26ccbedf3 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -17,7 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json LICENSE.TXT = LICENSE.TXT NuGet.config = NuGet.config - OpenTelemetry.proj = OpenTelemetry.proj README.md = README.md THIRD-PARTY-NOTICES.TXT = THIRD-PARTY-NOTICES.TXT VERSIONING.md = VERSIONING.md @@ -38,6 +37,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetry.prod.loose.ruleset = build\OpenTelemetry.prod.loose.ruleset build\OpenTelemetry.prod.ruleset = build\OpenTelemetry.prod.ruleset + build\OpenTelemetry.proj = build\OpenTelemetry.proj build\OpenTelemetry.test.ruleset = build\OpenTelemetry.test.ruleset build\RELEASING.md = build\RELEASING.md build\stylecop.json = build\stylecop.json diff --git a/OpenTelemetry.proj b/build/OpenTelemetry.proj similarity index 61% rename from OpenTelemetry.proj rename to build/OpenTelemetry.proj index b55859fe017..86987bbbe2a 100644 --- a/OpenTelemetry.proj +++ b/build/OpenTelemetry.proj @@ -1,16 +1,18 @@ + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName) + + - - - + + + - - - + + + diff --git a/build/UnstableCoreLibraries.proj b/build/UnstableCoreLibraries.proj index 8d333db2d94..7686376563a 100644 --- a/build/UnstableCoreLibraries.proj +++ b/build/UnstableCoreLibraries.proj @@ -1,12 +1,16 @@ + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName) + + - - - + + + - - - + + + From b9d56aa64ecbad7a56c61941a760abd210051590 Mon Sep 17 00:00:00 2001 From: Robert Coltheart <13191652+robertcoltheart@users.noreply.github.com> Date: Wed, 29 May 2024 03:47:02 +1000 Subject: [PATCH 006/133] [prometheus] Fix OpenMetrics format suffixes (#5646) Co-authored-by: Cijo Thomas Co-authored-by: Mikel Blanchard Co-authored-by: Reiley Yang --- .../CHANGELOG.md | 3 + .../CHANGELOG.md | 3 + .../Internal/PrometheusMetric.cs | 43 ++++++++--- .../Internal/PrometheusSerializer.cs | 35 ++++++--- .../Internal/PrometheusSerializerExt.cs | 14 ++-- .../PrometheusExporterMiddlewareTests.cs | 14 ++-- .../PrometheusHttpListenerTests.cs | 12 ++-- .../PrometheusMetricTests.cs | 72 ++++++++++++++++--- 8 files changed, 151 insertions(+), 45 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 703074b0be6..e673dbfb822 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fixed issue with OpenMetrics suffixes for Prometheus + ([#5646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5646)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index abb4d7287fc..717e61290b8 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fixed issue with OpenMetrics suffixes for Prometheus + ([#5646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5646)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index a39a426136a..6f18f06a536 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -27,6 +27,7 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa // consecutive `_` characters MUST be replaced with a single `_` character. // https://github.com/open-telemetry/opentelemetry-specification/blob/b2f923fb1650dde1f061507908b834035506a796/specification/compatibility/prometheus_and_openmetrics.md#L230-L233 var sanitizedName = SanitizeMetricName(name); + var openMetricsName = SanitizeOpenMetricsName(sanitizedName); string sanitizedUnit = null; if (!string.IsNullOrEmpty(unit)) @@ -35,38 +36,50 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa // The resulting unit SHOULD be added to the metric as // [OpenMetrics UNIT metadata](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#metricfamily) - // and as a suffix to the metric name unless the metric name already contains the - // unit, or the unit MUST be omitted. The unit suffix comes before any - // type-specific suffixes. - // https://github.com/open-telemetry/opentelemetry-specification/blob/b2f923fb1650dde1f061507908b834035506a796/specification/compatibility/prometheus_and_openmetrics.md#L242-L246 - if (!sanitizedName.Contains(sanitizedUnit)) + // and as a suffix to the metric name. The unit suffix comes before any type-specific suffixes. + // https://github.com/open-telemetry/opentelemetry-specification/blob/3dfb383fe583e3b74a2365c5a1d90256b273ee76/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 + if (!sanitizedName.EndsWith(sanitizedUnit)) { - sanitizedName = sanitizedName + "_" + sanitizedUnit; + sanitizedName += $"_{sanitizedUnit}"; + openMetricsName += $"_{sanitizedUnit}"; } } // If the metric name for monotonic Sum metric points does not end in a suffix of `_total` a suffix of `_total` MUST be added by default, otherwise the name MUST remain unchanged. // Exporters SHOULD provide a configuration option to disable the addition of `_total` suffixes. // https://github.com/open-telemetry/opentelemetry-specification/blob/b2f923fb1650dde1f061507908b834035506a796/specification/compatibility/prometheus_and_openmetrics.md#L286 + // Note that we no longer append '_ratio' for units that are '1', see: https://github.com/open-telemetry/opentelemetry-specification/issues/4058 if (type == PrometheusType.Counter && !sanitizedName.EndsWith("_total") && !disableTotalNameSuffixForCounters) { sanitizedName += "_total"; } - // Special case: Converting "1" to "ratio". - // https://github.com/open-telemetry/opentelemetry-specification/blob/b2f923fb1650dde1f061507908b834035506a796/specification/compatibility/prometheus_and_openmetrics.md#L239 - if (type == PrometheusType.Gauge && unit == "1" && !sanitizedName.Contains("ratio")) + // For counters requested using OpenMetrics format, the MetricFamily name MUST be suffixed with '_total', regardless of the setting to disable the 'total' suffix. + // https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1 + if (type == PrometheusType.Counter && !openMetricsName.EndsWith("_total")) { - sanitizedName += "_ratio"; + openMetricsName += "_total"; } + // In OpenMetrics format, the UNIT, TYPE and HELP metadata must be suffixed with the unit (handled above), and not the '_total' suffix, as in the case for counters. + // https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#unit + var openMetricsMetadataName = type == PrometheusType.Counter + ? SanitizeOpenMetricsName(openMetricsName) + : sanitizedName; + this.Name = sanitizedName; + this.OpenMetricsName = openMetricsName; + this.OpenMetricsMetadataName = openMetricsMetadataName; this.Unit = sanitizedUnit; this.Type = type; } public string Name { get; } + public string OpenMetricsName { get; } + + public string OpenMetricsMetadataName { get; } + public string Unit { get; } public PrometheusType Type { get; } @@ -159,6 +172,16 @@ internal static string RemoveAnnotations(string unit) return sb.ToString(); } + private static string SanitizeOpenMetricsName(string metricName) + { + if (metricName.EndsWith("_total")) + { + return metricName.Substring(0, metricName.Length - 6); + } + + return metricName; + } + private static string GetUnit(string unit) { // Dropping the portions of the Unit within brackets (e.g. {packet}). Brackets MUST NOT be included in the resulting unit. A "count of foo" is considered unitless in Prometheus. diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs index 719f21a0c61..3c142d91233 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs @@ -230,12 +230,29 @@ static string GetLabelValueString(object labelValue) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteMetricName(byte[] buffer, int cursor, PrometheusMetric metric) + public static int WriteMetricName(byte[] buffer, int cursor, PrometheusMetric metric, bool openMetricsRequested) { // Metric name has already been escaped. - for (int i = 0; i < metric.Name.Length; i++) + var name = openMetricsRequested ? metric.OpenMetricsName : metric.Name; + + for (int i = 0; i < name.Length; i++) + { + var ordinal = (ushort)name[i]; + buffer[cursor++] = unchecked((byte)ordinal); + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteMetricMetadataName(byte[] buffer, int cursor, PrometheusMetric metric, bool openMetricsRequested) + { + // Metric name has already been escaped. + var name = openMetricsRequested ? metric.OpenMetricsMetadataName : metric.Name; + + for (int i = 0; i < name.Length; i++) { - var ordinal = (ushort)metric.Name[i]; + var ordinal = (ushort)name[i]; buffer[cursor++] = unchecked((byte)ordinal); } @@ -252,7 +269,7 @@ public static int WriteEof(byte[] buffer, int cursor) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteHelpMetadata(byte[] buffer, int cursor, PrometheusMetric metric, string metricDescription) + public static int WriteHelpMetadata(byte[] buffer, int cursor, PrometheusMetric metric, string metricDescription, bool openMetricsRequested) { if (string.IsNullOrEmpty(metricDescription)) { @@ -260,7 +277,7 @@ public static int WriteHelpMetadata(byte[] buffer, int cursor, PrometheusMetric } cursor = WriteAsciiStringNoEscape(buffer, cursor, "# HELP "); - cursor = WriteMetricName(buffer, cursor, metric); + cursor = WriteMetricMetadataName(buffer, cursor, metric, openMetricsRequested); if (!string.IsNullOrEmpty(metricDescription)) { @@ -274,14 +291,14 @@ public static int WriteHelpMetadata(byte[] buffer, int cursor, PrometheusMetric } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteTypeMetadata(byte[] buffer, int cursor, PrometheusMetric metric) + public static int WriteTypeMetadata(byte[] buffer, int cursor, PrometheusMetric metric, bool openMetricsRequested) { var metricType = MapPrometheusType(metric.Type); Debug.Assert(!string.IsNullOrEmpty(metricType), $"{nameof(metricType)} should not be null or empty."); cursor = WriteAsciiStringNoEscape(buffer, cursor, "# TYPE "); - cursor = WriteMetricName(buffer, cursor, metric); + cursor = WriteMetricMetadataName(buffer, cursor, metric, openMetricsRequested); buffer[cursor++] = unchecked((byte)' '); cursor = WriteAsciiStringNoEscape(buffer, cursor, metricType); @@ -291,7 +308,7 @@ public static int WriteTypeMetadata(byte[] buffer, int cursor, PrometheusMetric } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteUnitMetadata(byte[] buffer, int cursor, PrometheusMetric metric) + public static int WriteUnitMetadata(byte[] buffer, int cursor, PrometheusMetric metric, bool openMetricsRequested) { if (string.IsNullOrEmpty(metric.Unit)) { @@ -299,7 +316,7 @@ public static int WriteUnitMetadata(byte[] buffer, int cursor, PrometheusMetric } cursor = WriteAsciiStringNoEscape(buffer, cursor, "# UNIT "); - cursor = WriteMetricName(buffer, cursor, metric); + cursor = WriteMetricMetadataName(buffer, cursor, metric, openMetricsRequested); buffer[cursor++] = unchecked((byte)' '); diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs index 1523ef7c160..70d67f468bf 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs @@ -24,9 +24,9 @@ public static bool CanWriteMetric(Metric metric) public static int WriteMetric(byte[] buffer, int cursor, Metric metric, PrometheusMetric prometheusMetric, bool openMetricsRequested = false) { - cursor = WriteTypeMetadata(buffer, cursor, prometheusMetric); - cursor = WriteUnitMetadata(buffer, cursor, prometheusMetric); - cursor = WriteHelpMetadata(buffer, cursor, prometheusMetric, metric.Description); + cursor = WriteTypeMetadata(buffer, cursor, prometheusMetric, openMetricsRequested); + cursor = WriteUnitMetadata(buffer, cursor, prometheusMetric, openMetricsRequested); + cursor = WriteHelpMetadata(buffer, cursor, prometheusMetric, metric.Description, openMetricsRequested); if (!metric.MetricType.IsHistogram()) { @@ -35,7 +35,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe var timestamp = metricPoint.EndTime.ToUnixTimeMilliseconds(); // Counter and Gauge - cursor = WriteMetricName(buffer, cursor, prometheusMetric); + cursor = WriteMetricName(buffer, cursor, prometheusMetric, openMetricsRequested); cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags); buffer[cursor++] = unchecked((byte)' '); @@ -85,7 +85,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe { totalCount += histogramMeasurement.BucketCount; - cursor = WriteMetricName(buffer, cursor, prometheusMetric); + cursor = WriteMetricName(buffer, cursor, prometheusMetric, openMetricsRequested); cursor = WriteAsciiStringNoEscape(buffer, cursor, "_bucket{"); cursor = WriteTags(buffer, cursor, metric, tags, writeEnclosingBraces: false); @@ -111,7 +111,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe } // Histogram sum - cursor = WriteMetricName(buffer, cursor, prometheusMetric); + cursor = WriteMetricName(buffer, cursor, prometheusMetric, openMetricsRequested); cursor = WriteAsciiStringNoEscape(buffer, cursor, "_sum"); cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags); @@ -125,7 +125,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe buffer[cursor++] = ASCII_LINEFEED; // Histogram count - cursor = WriteMetricName(buffer, cursor, prometheusMetric); + cursor = WriteMetricName(buffer, cursor, prometheusMetric, openMetricsRequested); cursor = WriteAsciiStringNoEscape(buffer, cursor, "_count"); cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags); diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs index 7386a5a9729..19b22e47be5 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs @@ -264,7 +264,7 @@ public async Task PrometheusExporterMiddlewareIntegration_CanServeOpenMetricsAnd var beginTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); - var counter = meter.CreateCounter("counter_double"); + var counter = meter.CreateCounter("counter_double", unit: "By"); counter.Add(100.18D, tags); counter.Add(0.99D, tags); @@ -312,7 +312,7 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( var beginTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); - var counter = meter.CreateCounter("counter_double"); + var counter = meter.CreateCounter("counter_double", unit: "By"); if (!skipMetrics) { counter.Add(100.18D, tags); @@ -368,14 +368,16 @@ private static async Task VerifyAsync(long beginTimestamp, long endTimestamp, Ht # TYPE otel_scope_info info # HELP otel_scope_info Scope metadata otel_scope_info{otel_scope_name="{{MeterName}}"} 1 - # TYPE counter_double_total counter - counter_double_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",key1="value1",key2="value2"} 101.17 (\d+\.\d{3}) + # TYPE counter_double_bytes counter + # UNIT counter_double_bytes bytes + counter_double_bytes_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",key1="value1",key2="value2"} 101.17 (\d+\.\d{3}) # EOF """.ReplaceLineEndings() : $$""" - # TYPE counter_double_total counter - counter_double_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",key1="value1",key2="value2"} 101.17 (\d+) + # TYPE counter_double_bytes_total counter + # UNIT counter_double_bytes_total bytes + counter_double_bytes_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",key1="value1",key2="value2"} 101.17 (\d+) # EOF """.ReplaceLineEndings(); diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs index 3a4ca1c4153..9ef62de196f 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs @@ -202,7 +202,7 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri new KeyValuePair("key2", "value2"), }; - var counter = meter.CreateCounter("counter_double"); + var counter = meter.CreateCounter("counter_double", unit: "By"); if (!skipMetrics) { counter.Add(100.18D, tags); @@ -241,11 +241,13 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri + "# TYPE otel_scope_info info\n" + "# HELP otel_scope_info Scope metadata\n" + $"otel_scope_info{{otel_scope_name='{MeterName}'}} 1\n" - + "# TYPE counter_double_total counter\n" - + $"counter_double_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+\\.\\d{{3}})\n" + + "# TYPE counter_double_bytes counter\n" + + "# UNIT counter_double_bytes bytes\n" + + $"counter_double_bytes_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+\\.\\d{{3}})\n" + "# EOF\n" - : "# TYPE counter_double_total counter\n" - + $"counter_double_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+)\n" + : "# TYPE counter_double_bytes_total counter\n" + + "# UNIT counter_double_bytes_total bytes\n" + + $"counter_double_bytes_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+)\n" + "# EOF\n"; Assert.Matches(("^" + expected + "$").Replace('\'', '"'), content); diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs index 81ce3e1f7da..a1350f03ec9 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs @@ -26,7 +26,7 @@ public void SanitizeMetricName_SupportLeadingAndTrailingUnderscores() } [Fact] - public void SanitizeMetricName_RemoveUnsupportedChracters() + public void SanitizeMetricName_RemoveUnsupportedCharacters() { AssertSanitizeMetricName("metric_unit_$1000", "metric_unit_1000"); } @@ -116,13 +116,7 @@ public void Unit_AnnotationMismatch_Close() } [Fact] - public void Name_SpecialCaseGuage_AppendRatio() - { - AssertName("sample", "1", PrometheusType.Gauge, false, "sample_ratio"); - } - - [Fact] - public void Name_GuageWithUnit_NoAppendRatio() + public void Name_GaugeWithUnit_NoAppendRatio() { AssertName("sample", "unit", PrometheusType.Gauge, false, "sample_unit"); } @@ -205,6 +199,54 @@ public void Name_StartWithNumber_UnderscoreStart() AssertName("2_metric_name", "By", PrometheusType.Summary, false, "_metric_name_bytes"); } + [Fact] + public void OpenMetricsName_UnitAlreadyPresentInName_Appended() + { + AssertOpenMetricsName("db_bytes_written", "By", PrometheusType.Gauge, false, "db_bytes_written_bytes"); + } + + [Fact] + public void OpenMetricsName_SuffixedWithUnit_NotAppended() + { + AssertOpenMetricsName("db_written_bytes", "By", PrometheusType.Gauge, false, "db_written_bytes"); + } + + [Fact] + public void OpenMetricsName_Counter_AppendTotal() + { + AssertOpenMetricsName("db_bytes_written", "By", PrometheusType.Counter, false, "db_bytes_written_bytes_total"); + } + + [Fact] + public void OpenMetricsName_Counter_DisableSuffixTotal_AppendTotal() + { + AssertOpenMetricsName("db_bytes_written", "By", PrometheusType.Counter, true, "db_bytes_written_bytes_total"); + } + + [Fact] + public void OpenMetricsName_CounterSuffixedWithTotal_AppendUnitAndTotal() + { + AssertOpenMetricsName("db_bytes_written_total", "By", PrometheusType.Counter, false, "db_bytes_written_bytes_total"); + } + + [Fact] + public void OpenMetricsName_CounterSuffixedWithTotal_DisableSuffixTotal_AppendTotal() + { + AssertOpenMetricsName("db_bytes_written_total", "By", PrometheusType.Counter, false, "db_bytes_written_bytes_total"); + } + + [Fact] + public void OpenMetricsMetadataName_Counter_NotAppendTotal() + { + AssertOpenMetricsMetadataName("db_bytes_written", "By", PrometheusType.Counter, false, "db_bytes_written_bytes"); + } + + [Fact] + public void OpenMetricsMetadataName_Counter_DisableSuffixTotal_NotAppendTotal() + { + AssertOpenMetricsMetadataName("db_bytes_written", "By", PrometheusType.Counter, true, "db_bytes_written_bytes"); + } + private static void AssertName( string name, string unit, PrometheusType type, bool disableTotalNameSuffixForCounters, string expected) { @@ -217,4 +259,18 @@ private static void AssertSanitizeMetricName(string name, string expected) var sanatizedName = PrometheusMetric.SanitizeMetricName(name); Assert.Equal(expected, sanatizedName); } + + private static void AssertOpenMetricsName( + string name, string unit, PrometheusType type, bool disableTotalNameSuffixForCounters, string expected) + { + var prometheusMetric = new PrometheusMetric(name, unit, type, disableTotalNameSuffixForCounters); + Assert.Equal(expected, prometheusMetric.OpenMetricsName); + } + + private static void AssertOpenMetricsMetadataName( + string name, string unit, PrometheusType type, bool disableTotalNameSuffixForCounters, string expected) + { + var prometheusMetric = new PrometheusMetric(name, unit, type, disableTotalNameSuffixForCounters); + Assert.Equal(expected, prometheusMetric.OpenMetricsMetadataName); + } } From 3ffa9160d9ee531e33533eeb7374e4accd2e2a6a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 29 May 2024 10:41:04 -0700 Subject: [PATCH 007/133] [repo] Release automation improvements (#5657) --- .github/workflows/automation.yml | 34 ++++++ .github/workflows/post-release.yml | 51 +++++++++ .github/workflows/prepare-release.yml | 98 ++++++++-------- .github/workflows/publish-packages-1.0.yml | 65 ++++++----- OpenTelemetry.sln | 2 + build/scripts/post-release.psm1 | 125 ++++++++++++++++----- build/scripts/prepare-release.psm1 | 90 ++++++--------- 7 files changed, 296 insertions(+), 169 deletions(-) create mode 100644 .github/workflows/automation.yml create mode 100644 .github/workflows/post-release.yml diff --git a/.github/workflows/automation.yml b/.github/workflows/automation.yml new file mode 100644 index 00000000000..e85a3720aba --- /dev/null +++ b/.github/workflows/automation.yml @@ -0,0 +1,34 @@ +name: Resolve automation settings + +on: + workflow_call: + outputs: + enabled: + value: ${{ jobs.resolve-automation.outputs.enabled == 'true' }} + token-secret-name: + value: ${{ jobs.resolve-automation.outputs.token-secret-name }} + username: + value: ${{ vars.AUTOMATION_USERNAME }} + email: + value: ${{ vars.AUTOMATION_EMAIL }} + secrets: + OPENTELEMETRYBOT_GITHUB_TOKEN: + required: true + +jobs: + resolve-automation: + + runs-on: ubuntu-latest + + outputs: + enabled: ${{ steps.evaluate.outputs.enabled }} + token-secret-name: ${{ steps.evaluate.outputs.token-secret-name }} + + env: + OPENTELEMETRYBOT_GITHUB_TOKEN_EXISTS: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN != '' }} + + steps: + - id: evaluate + run: | + echo "enabled=${{ env.OPENTELEMETRYBOT_GITHUB_TOKEN_EXISTS == 'true' }}" >> "$GITHUB_OUTPUT" + echo "token-secret-name=OPENTELEMETRYBOT_GITHUB_TOKEN" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml new file mode 100644 index 00000000000..162e17f10a5 --- /dev/null +++ b/.github/workflows/post-release.yml @@ -0,0 +1,51 @@ +name: Complete release + +on: + workflow_dispatch: + inputs: + tag: + required: true + description: 'Release tag' + type: string + release: + types: [published] + +jobs: + automation: + uses: ./.github/workflows/automation.yml + secrets: inherit + + post-release: + runs-on: ubuntu-latest + + needs: + - automation + + if: | + needs.automation.outputs.enabled + && + ( + (github.ref_type == 'tag' && startsWith(github.ref_name, 'core-') && !contains(github.ref_name, '-alpha') && !contains(github.ref_name, '-beta') && !contains(github.ref_name, '-rc')) + || (inputs.tag && startsWith(inputs.tag, 'core-') && !contains(inputs.tag, '-alpha') && !contains(inputs.tag, '-beta') && !contains(inputs.tag, '-rc')) + ) + + env: + GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.repository.default_branch }} + token: ${{ secrets[needs.automation.outputs.token-secret-name] }} + + - name: Create GitHub Pull Request to update stable build version in props + shell: pwsh + run: | + Import-Module .\build\scripts\post-release.psm1 + + CreateStableVersionUpdatePullRequest ` + -gitRepository '${{ github.repository }}' ` + -tag '${{ inputs.tag || github.ref_name }}' ` + -targetBranch '${{ github.event.repository.default_branch }}' ` + -gitUserName '${{ needs.automation.outputs.username }}' ` + -gitUserEmail '${{ needs.automation.outputs.email }}' diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index fb54dfd04f5..087081efbb1 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -23,19 +23,26 @@ on: types: - created -permissions: - contents: write - pull-requests: write - jobs: + automation: + uses: ./.github/workflows/automation.yml + secrets: inherit + prepare-release-pr: - if: github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + + needs: automation - runs-on: windows-latest + if: github.event_name == 'workflow_dispatch' && needs.automation.outputs.enabled + + env: + GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} steps: - name: check out code uses: actions/checkout@v4 + with: + token: ${{ secrets[needs.automation.outputs.token-secret-name] }} - name: Create GitHub Pull Request to prepare release shell: pwsh @@ -43,25 +50,34 @@ jobs: Import-Module .\build\scripts\prepare-release.psm1 CreatePullRequestToUpdateChangelogsAndPublicApis ` + -gitRepository '${{ github.repository }}' ` -minVerTagPrefix '${{ inputs.tag-prefix }}' ` -version '${{ inputs.version }}' ` - -targetBranch '${{ github.ref_name }}' - env: - GH_TOKEN: ${{ github.token }} + -targetBranch '${{ github.ref_name }}' ` + -gitUserName '${{ needs.automation.outputs.username }}' ` + -gitUserEmail '${{ needs.automation.outputs.email }}' lock-pr-and-post-notice-to-create-release-tag: + runs-on: ubuntu-latest + + needs: automation + if: | github.event_name == 'pull_request' && github.event.action == 'closed' - && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.user.login == needs.automation.outputs.username && github.event.pull_request.merged == true && startsWith(github.event.pull_request.title, '[repo] Prepare release ') + && needs.automation.outputs.enabled - runs-on: windows-latest + env: + GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} steps: - name: check out code uses: actions/checkout@v4 + with: + token: ${{ secrets[needs.automation.outputs.token-secret-name] }} - name: Lock GitHub Pull Request to prepare release shell: pwsh @@ -69,23 +85,27 @@ jobs: Import-Module .\build\scripts\prepare-release.psm1 LockPullRequestAndPostNoticeToCreateReleaseTag ` - -pullRequestNumber '${{ github.event.pull_request.number }}' - env: - GH_TOKEN: ${{ github.token }} + -gitRepository '${{ github.repository }}' ` + -pullRequestNumber '${{ github.event.pull_request.number }}' ` + -botUserName '${{ needs.automation.outputs.username }}' create-release-tag-unlock-pr-post-notice: + runs-on: ubuntu-latest + + needs: automation + if: | github.event_name == 'issue_comment' && github.event.issue.pull_request && github.event.issue.locked == true + && github.event.comment.user.login != needs.automation.outputs.username && contains(github.event.comment.body, '/CreateReleaseTag') && startsWith(github.event.issue.title, '[repo] Prepare release ') && github.event.issue.pull_request.merged_at + && needs.automation.outputs.enabled - runs-on: windows-latest - - outputs: - tag: ${{ steps.create-tag.outputs.tag }} + env: + GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} steps: - name: check out code @@ -93,6 +113,7 @@ jobs: with: # Note: By default GitHub only fetches 1 commit which fails the git tag operation below fetch-depth: 0 + token: ${{ secrets[needs.automation.outputs.token-secret-name] }} - name: Create release tag id: create-tag @@ -100,40 +121,9 @@ jobs: run: | Import-Module .\build\scripts\prepare-release.psm1 - $tag = '' - - CreateReleaseTag ` - -pullRequestNumber '${{ github.event.issue.number }}' ` - -actionRunId '${{ github.run_id }}' ` - -tag ([ref]$tag) - - echo "tag=$tag" >> $env:GITHUB_OUTPUT - env: - GH_TOKEN: ${{ github.token }} - - invoke-package-workflow: - needs: create-release-tag-unlock-pr-post-notice - uses: ./.github/workflows/publish-packages-1.0.yml - with: - tag: ${{ needs.create-release-tag-unlock-pr-post-notice.outputs.tag }} - - post-packages-ready-notice: - needs: - - create-release-tag-unlock-pr-post-notice - - invoke-package-workflow - runs-on: windows-latest - steps: - - name: check out code - uses: actions/checkout@v4 - - - name: Post notice when packages are ready - shell: pwsh - run: | - Import-Module .\build\scripts\prepare-release.psm1 - - PostPackagesReadyNotice ` + CreateReleaseTagAndPostNoticeOnPullRequest ` + -gitRepository '${{ github.repository }}' ` -pullRequestNumber '${{ github.event.issue.number }}' ` - -tag '${{ needs.create-release-tag-unlock-pr-post-notice.outputs.tag }}' ` - -packagesUrl '${{ needs.invoke-package-workflow.outputs.artifact-url }}' - env: - GH_TOKEN: ${{ github.token }} + -botUserName '${{ needs.automation.outputs.username }}' ` + -gitUserName '${{ needs.automation.outputs.username }}' ` + -gitUserEmail '${{ needs.automation.outputs.email }}' diff --git a/.github/workflows/publish-packages-1.0.yml b/.github/workflows/publish-packages-1.0.yml index 1391382e3ca..7f78116bab4 100644 --- a/.github/workflows/publish-packages-1.0.yml +++ b/.github/workflows/publish-packages-1.0.yml @@ -13,29 +13,18 @@ on: tags: - 'core-*' - 'coreunstable-*' - workflow_call: - inputs: - tag: - required: true - type: string - outputs: - artifact-id: - value: ${{ jobs.build-pack-publish.outputs.artifact-id }} - artifact-url: - value: ${{ jobs.build-pack-publish.outputs.artifact-url }} schedule: - cron: '0 0 * * *' # once in a day at 00:00 -permissions: - contents: write - pull-requests: write - jobs: + automation: + uses: ./.github/workflows/automation.yml + secrets: inherit + build-pack-publish: runs-on: windows-latest outputs: - artifact-id: ${{ steps.upload-artifacts.outputs.artifact-id }} artifact-url: ${{ steps.upload-artifacts.outputs.artifact-url }} steps: @@ -45,7 +34,6 @@ jobs: # the version tag which is typically NOT on the first commit so we # retrieve them all. fetch-depth: 0 - ref: ${{ inputs.tag || github.ref || 'main' }} - name: Setup dotnet uses: actions/setup-dotnet@v4 @@ -57,13 +45,13 @@ jobs: run: dotnet build ./build/OpenTelemetry.proj --configuration Release --no-restore -p:Deterministic=true -p:BuildNumber=${{ github.run_number }} -p:RunningDotNetPack=true - name: dotnet pack - run: dotnet pack ./build/OpenTelemetry.proj --configuration Release --no-restore --no-build -p:PackTag=${{ github.ref_type == 'tag' && github.ref_name || inputs.tag || '' }} + run: dotnet pack ./build/OpenTelemetry.proj --configuration Release --no-restore --no-build -p:PackTag=${{ github.ref_type == 'tag' && github.ref_name || '' }} - name: Publish Artifacts id: upload-artifacts uses: actions/upload-artifact@v4 with: - name: ${{ inputs.tag || github.ref_name }}-packages + name: ${{ github.ref_name }}-packages path: '**/bin/**/*.*nupkg' - name: Publish MyGet @@ -74,26 +62,43 @@ jobs: nuget setApiKey ${{ secrets.MYGET_TOKEN }} -Source https://www.myget.org/F/opentelemetry/api/v2/package nuget push **/bin/**/*.nupkg -Source https://www.myget.org/F/opentelemetry/api/v2/package + post-build: + runs-on: ubuntu-latest + + needs: + - automation + - build-pack-publish + + if: needs.automation.outputs.enabled && github.event_name == 'push' + + env: + GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} + + steps: + - name: check out code + uses: actions/checkout@v4 + with: + token: ${{ secrets[needs.automation.outputs.token-secret-name] }} + - name: Create GitHub Release draft - if: github.ref_type == 'tag' || inputs.tag shell: pwsh run: | Import-Module .\build\scripts\post-release.psm1 CreateDraftRelease ` - -tag '${{ inputs.tag || github.ref_name }}' - env: - GH_TOKEN: ${{ github.token }} + -gitRepository '${{ github.repository }}' ` + -tag '${{ github.ref_name }}' - - name: Create GitHub draft Pull Request to update stable build version in props - if: | - (github.ref_type == 'tag' && startsWith(github.ref_name, 'core-') && !contains(github.ref_name, '-alpha') && !contains(github.ref_name, '-beta') && !contains(github.ref_name, '-rc')) - || (inputs.tag && startsWith(inputs.tag, 'core-') && !contains(inputs.tag, '-alpha') && !contains(inputs.tag, '-beta') && !contains(inputs.tag, '-rc')) + - name: Post notice when packages are ready shell: pwsh run: | Import-Module .\build\scripts\post-release.psm1 - CreateStableVersionUpdatePullRequest ` - -tag '${{ inputs.tag || github.ref_name }}' - env: - GH_TOKEN: ${{ github.token }} + TryPostPackagesReadyNoticeOnPrepareReleasePullRequest ` + -gitRepository '${{ github.repository }}' ` + -tag '${{ github.ref_name }}' ` + -tagSha '${{ github.sha }}' ` + -packagesUrl '${{ needs.build-pack-publish.outputs.artifact-url }}' ` + -botUserName '${{ needs.automation.outputs.username }}' + + diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 5f26ccbedf3..d7d059b58cb 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -86,6 +86,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{E69578EB-B456-4062-A645-877CD964528B}" ProjectSection(SolutionItems) = preProject .github\workflows\add-labels.yml = .github\workflows\add-labels.yml + .github\workflows\automation.yml = .github\workflows\automation.yml .github\workflows\ci.yml = .github\workflows\ci.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\Component.BuildTest.yml = .github\workflows\Component.BuildTest.yml @@ -94,6 +95,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-validation.yml = .github\workflows\package-validation.yml + .github\workflows\post-release.yml = .github\workflows\post-release.yml .github\workflows\prepare-release.yml = .github\workflows\prepare-release.yml .github\workflows\publish-packages-1.0.yml = .github\workflows\publish-packages-1.0.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index 39250d38d18..369d4366fb3 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -1,39 +1,39 @@ -$gitHubBotUserName="github-actions[bot]" -$gitHubBotEmail="41898282+github-actions[bot]@users.noreply.github.com" - -$repoViewResponse = gh repo view --json nameWithOwner | ConvertFrom-Json - -$gitRepository = $repoViewResponse.nameWithOwner - function CreateDraftRelease { param( + [Parameter(Mandatory=$true)][string]$gitRepository, [Parameter(Mandatory=$true)][string]$tag ) - $packages = (Get-ChildItem -Path src/*/bin/Release/*.nupkg).Name + $match = [regex]::Match($tag, '^(.*?-)(.*)$') + if ($match.Success -eq $false) + { + throw 'Could not parse prefix or version from tag' + } - $notes = '' - $firstPackageVersion = '' + $tagPrefix = $match.Groups[1].Value + $version = $match.Groups[2].Value + + $projects = @(Get-ChildItem -Path src/**/*.csproj | Select-String "$tagPrefix" -List | Select Path) - foreach ($package in $packages) + if ($projects.Length -eq 0) { - $match = [regex]::Match($package, '(.*)\.(\d+\.\d+\.\d+.*?)\.nupkg') - $packageName = $match.Groups[1].Value - $packageVersion = $match.Groups[2].Value + throw 'No projects found with MinVerTagPrefix matching prefix from tag' + } - if ($firstPackageVersion -eq '') - { - $firstPackageVersion = $packageVersion - } + $notes = '' + + foreach ($project in $projects) + { + $projectName = [System.IO.Path]::GetFileNameWithoutExtension($project.Path) - $changelogContent = Get-Content -Path "src/$packageName/CHANGELOG.md" + $changelogContent = Get-Content -Path "src/$projectName/CHANGELOG.md" $started = $false $content = "" foreach ($line in $changelogContent) { - if ($line -like "## $packageVersion" -and $started -ne $true) + if ($line -like "## $version" -and $started -ne $true) { $started = $true } @@ -63,16 +63,16 @@ function CreateDraftRelease { $notes += @" -* NuGet: [$packageName v$packageVersion](https://www.nuget.org/packages/$packageName/$packageVersion) +* NuGet: [$projectName v$version](https://www.nuget.org/packages/$projectName/$version) $content - See [CHANGELOG](https://github.com/$gitRepository/blob/$tag/src/$packageName/CHANGELOG.md) for details. + See [CHANGELOG](https://github.com/$gitRepository/blob/$tag/src/$projectName/CHANGELOG.md) for details. "@ } - if ($firstPackageVersion -match '-alpha' -or $firstPackageVersion -match '-beta' -or $firstPackageVersion -match '-rc') + if ($version -match '-alpha' -or $version -match '-beta' -or $version -match '-rc') { gh release create $tag ` --title $tag ` @@ -94,12 +94,70 @@ $content Export-ModuleMember -Function CreateDraftRelease +function TryPostPackagesReadyNoticeOnPrepareReleasePullRequest { + param( + [Parameter(Mandatory=$true)][string]$gitRepository, + [Parameter(Mandatory=$true)][string]$tag, + [Parameter(Mandatory=$true)][string]$tagSha, + [Parameter(Mandatory=$true)][string]$packagesUrl, + [Parameter(Mandatory=$true)][string]$botUserName + ) + + $prListResponse = gh pr list --search $tagSha --state merged --json number,author,title,comments | ConvertFrom-Json + + if ($prListResponse.Length -eq 0) + { + Write-Host 'No prepare release PR found for tag & commit skipping post notice' + return + } + + foreach ($pr in $prListResponse) + { + if ($pr.author.login -ne $botUserName -or $pr.title -ne "[repo] Prepare release $tag") + { + continue + } + + $foundComment = $false + foreach ($comment in $pr.comments) + { + if ($comment.author.login -eq $botUserName -and $comment.body.StartsWith("I just pushed the [$tag]")) + { + $foundComment = $true + break + } + } + + if ($foundComment -eq $false) + { + continue + } + + $body = +@" +The packages for [$tag](https://github.com/$gitRepository/releases/tag/$tag) are now available: $packagesUrl. + +Have a nice day! +"@ + + $pullRequestNumber = $pr.number + + gh pr comment $pullRequestNumber --body $body + return + } + + Write-Host 'No prepare release PR found matched author and title with a valid comment' +} + +Export-ModuleMember -Function TryPostPackagesReadyNoticeOnPrepareReleasePullRequest + function CreateStableVersionUpdatePullRequest { param( + [Parameter(Mandatory=$true)][string]$gitRepository, [Parameter(Mandatory=$true)][string]$tag, - [Parameter()][string]$gitUserName=$gitHubBotUserName, - [Parameter()][string]$gitUserEmail=$gitHubBotEmail, - [Parameter()][string]$targetBranch="main" + [Parameter()][string]$targetBranch="main", + [Parameter()][string]$gitUserName, + [Parameter()][string]$gitUserEmail ) $match = [regex]::Match($tag, '.*?-(.*)') @@ -112,8 +170,14 @@ function CreateStableVersionUpdatePullRequest { $branch="release/post-stable-${tag}-update" - git config user.name $gitUserName - git config user.email $gitUserEmail + if ([string]::IsNullOrEmpty($gitUserName) -eq $false) + { + git config user.name $gitUserName + } + if ([string]::IsNullOrEmpty($gitUserEmail) -eq $false) + { + git config user.email $gitUserEmail + } git switch --create $branch origin/$targetBranch --no-track 2>&1 | % ToString if ($LASTEXITCODE -gt 0) @@ -145,7 +209,7 @@ function CreateStableVersionUpdatePullRequest { $body = @" -Note: This PR was opened automatically by the [package workflow](https://github.com/$gitRepository/actions/workflows/publish-packages-1.0.yml). +Note: This PR was opened automatically by the [post-release workflow](https://github.com/$gitRepository/actions/workflows/post-release.yml). Merge once packages are available on NuGet and the build passes. @@ -159,8 +223,7 @@ Merge once packages are available on NuGet and the build passes. --body $body ` --base $targetBranch ` --head $branch ` - --label infra ` - --draft + --label infra } Export-ModuleMember -Function CreateStableVersionUpdatePullRequest diff --git a/build/scripts/prepare-release.psm1 b/build/scripts/prepare-release.psm1 index ad2b0b53e77..78a87549808 100644 --- a/build/scripts/prepare-release.psm1 +++ b/build/scripts/prepare-release.psm1 @@ -1,24 +1,24 @@ -$gitHubBotUserName="github-actions[bot]" -$gitHubBotEmail="41898282+github-actions[bot]@users.noreply.github.com" - -$repoViewResponse = gh repo view --json nameWithOwner | ConvertFrom-Json - -$gitRepository = $repoViewResponse.nameWithOwner - function CreatePullRequestToUpdateChangelogsAndPublicApis { param( + [Parameter(Mandatory=$true)][string]$gitRepository, [Parameter(Mandatory=$true)][string]$minVerTagPrefix, [Parameter(Mandatory=$true)][string]$version, - [Parameter()][string]$gitUserName=$gitHubBotUserName, - [Parameter()][string]$gitUserEmail=$gitHubBotEmail, - [Parameter()][string]$targetBranch="main" + [Parameter()][string]$targetBranch="main", + [Parameter()][string]$gitUserName, + [Parameter()][string]$gitUserEmail ) $tag="${minVerTagPrefix}${version}" $branch="release/prepare-${tag}-release" - git config user.name $gitUserName - git config user.email $gitUserEmail + if ([string]::IsNullOrEmpty($gitUserName) -eq $false) + { + git config user.name $gitUserName + } + if ([string]::IsNullOrEmpty($gitUserEmail) -eq $false) + { + git config user.email $gitUserEmail + } git switch --create $branch 2>&1 | % ToString if ($LASTEXITCODE -gt 0) @@ -70,17 +70,14 @@ Export-ModuleMember -Function CreatePullRequestToUpdateChangelogsAndPublicApis function LockPullRequestAndPostNoticeToCreateReleaseTag { param( + [Parameter(Mandatory=$true)][string]$gitRepository, [Parameter(Mandatory=$true)][string]$pullRequestNumber, - [Parameter()][string]$gitUserName=$gitHubBotUserName, - [Parameter()][string]$gitUserEmail=$gitHubBotEmail + [Parameter(Mandatory=$true)][string]$botUserName ) - git config user.name $gitUserName - git config user.email $gitUserEmail - $prViewResponse = gh pr view $pullRequestNumber --json mergeCommit,author,title | ConvertFrom-Json - if ($prViewResponse.author.is_bot -eq $false -or $prViewResponse.author.login -ne 'app/github-actions') + if ($prViewResponse.author.login -ne $botUserName) { throw 'PR author was unexpected' } @@ -113,21 +110,18 @@ Post a comment with "/CreateReleaseTag" in the body if you would like me to crea Export-ModuleMember -Function LockPullRequestAndPostNoticeToCreateReleaseTag -function CreateReleaseTag { +function CreateReleaseTagAndPostNoticeOnPullRequest { param( + [Parameter(Mandatory=$true)][string]$gitRepository, [Parameter(Mandatory=$true)][string]$pullRequestNumber, - [Parameter(Mandatory=$true)][string]$actionRunId, - [Parameter()][string]$gitUserName=$gitHubBotUserName, - [Parameter()][string]$gitUserEmail=$gitHubBotEmail, - [Parameter()][ref]$tag + [Parameter(Mandatory=$true)][string]$botUserName, + [Parameter()][string]$gitUserName, + [Parameter()][string]$gitUserEmail ) - git config user.name $gitUserName - git config user.email $gitUserEmail - $prViewResponse = gh pr view $pullRequestNumber --json mergeCommit,author,title | ConvertFrom-Json - if ($prViewResponse.author.is_bot -eq $false -or $prViewResponse.author.login -ne 'app/github-actions') + if ($prViewResponse.author.login -ne $botUserName) { throw 'PR author was unexpected' } @@ -138,7 +132,7 @@ function CreateReleaseTag { throw 'Could not parse tag from PR title' } - $tagValue = $match.Groups[1].Value + $tag = $match.Groups[1].Value $commit = $prViewResponse.mergeCommit.oid if ([string]::IsNullOrEmpty($commit) -eq $true) @@ -146,13 +140,22 @@ function CreateReleaseTag { throw 'Could not find merge commit' } - git tag -a $tagValue -m "$tagValue" $commit 2>&1 | % ToString + if ([string]::IsNullOrEmpty($gitUserName) -eq $false) + { + git config user.name $gitUserName + } + if ([string]::IsNullOrEmpty($gitUserEmail) -eq $false) + { + git config user.email $gitUserEmail + } + + git tag -a $tag -m "$tag" $commit 2>&1 | % ToString if ($LASTEXITCODE -gt 0) { throw 'git tag failure' } - git push origin $tagValue 2>&1 | % ToString + git push origin $tag 2>&1 | % ToString if ($LASTEXITCODE -gt 0) { throw 'git push failure' @@ -162,33 +165,12 @@ function CreateReleaseTag { $body = @" -I just pushed the [$tagValue](https://github.com/$gitRepository/releases/tag/$tagValue) tag. - -The [package workflow](https://github.com/$gitRepository/actions/runs/$actionRunId) should begin momentarily. -"@ - - gh pr comment $pullRequestNumber --body $body - - $tag.value = $tagValue -} - -Export-ModuleMember -Function CreateReleaseTag - -function PostPackagesReadyNotice { - param( - [Parameter(Mandatory=$true)][string]$pullRequestNumber, - [Parameter(Mandatory=$true)][string]$tag, - [Parameter(Mandatory=$true)][string]$packagesUrl - ) - - $body = -@" -The packages for [$tag](https://github.com/$gitRepository/releases/tag/$tag) are now available: $packagesUrl. +I just pushed the [$tag](https://github.com/$gitRepository/releases/tag/$tag) tag. -Have a nice day! +The [package workflow](https://github.com/$gitRepository/actions/workflows/publish-packages-1.0.yml) should begin momentarily. "@ gh pr comment $pullRequestNumber --body $body } -Export-ModuleMember -Function PostPackagesReadyNotice +Export-ModuleMember -Function CreateReleaseTagAndPostNoticeOnPullRequest From 61eee46af8a46e2ad4203a9fb52f491f8eaa7d48 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 29 May 2024 19:52:07 +0200 Subject: [PATCH 008/133] [repo] Prepare release coreunstable-1.9.0-alpha.2 (#5662) --- src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index e673dbfb822..fa76f44a318 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-alpha.2 + +Released 2024-May-29 + * Fixed issue with OpenMetrics suffixes for Prometheus ([#5646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5646)) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 717e61290b8..07ac849c6d7 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-alpha.2 + +Released 2024-May-29 + * Fixed issue with OpenMetrics suffixes for Prometheus ([#5646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5646)) diff --git a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md index b0cb58b6b50..1dbb969e79c 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md +++ b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-alpha.2 + +Released 2024-May-29 + ## 1.9.0-alpha.1 Released 2024-May-20 From c38cc273bcd03949897d1585e9bc083962cb5f22 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Fri, 31 May 2024 08:46:25 +1000 Subject: [PATCH 009/133] [repo] Reduce explicit package references on newer TFM's (#5659) --- src/Directory.Build.targets | 2 +- .../OpenTelemetry.Exporter.Console.csproj | 2 +- .../OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj | 2 +- .../OpenTelemetry.Exporter.Zipkin.csproj | 2 +- test/Directory.Build.targets | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index ef4301eb074..3ee054532a9 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -14,7 +14,7 @@ - + + + + + + + + $(DefineConstants);@(CompilerConstantsForDependenciesWithExposedExperimentalFeatures) + + diff --git a/build/Common.prod.props b/build/Common.prod.props index 011f7d9b313..2f7b7cc900f 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -39,6 +39,10 @@ + @@ -82,6 +86,15 @@ $(DefineConstants);EXPOSE_EXPERIMENTAL_FEATURES + + + diff --git a/docs/diagnostics/experimental-apis/OTEL1000.md b/docs/diagnostics/experimental-apis/OTEL1000.md index 1ea4be023a3..28b8147293c 100644 --- a/docs/diagnostics/experimental-apis/OTEL1000.md +++ b/docs/diagnostics/experimental-apis/OTEL1000.md @@ -4,11 +4,17 @@ This is an Experimental API diagnostic covering the following APIs: +* `ILoggingBuilder.UseOpenTelemetry` + +Experimental APIs may be changed or removed in the future. + +The following portions of `OTEL1000` were released stable in `1.9.0` and are no +longer considered experimental: + * `LoggerProviderBuilder` * `LoggerProvider` * `IDeferredLoggerProviderBuilder` - -Experimental APIs may be changed or removed in the future. +* `OpenTelemetryBuilder.WithLogging` ## Details diff --git a/docs/diagnostics/experimental-apis/OTEL1001.md b/docs/diagnostics/experimental-apis/OTEL1001.md index 5386726e644..aeb8952630c 100644 --- a/docs/diagnostics/experimental-apis/OTEL1001.md +++ b/docs/diagnostics/experimental-apis/OTEL1001.md @@ -9,6 +9,7 @@ This is an Experimental API diagnostic covering the following APIs: * `LogRecordAttributeList` * `LogRecordData` * `LogRecordSeverity` +* `Sdk.CreateLoggerProviderBuilder` Experimental APIs may be changed or removed in the future. diff --git a/docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs b/docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs index 538f23b5cb4..c9343185e21 100644 --- a/docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs +++ b/docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs @@ -11,20 +11,25 @@ public static class DedicatedLoggingServiceCollectionExtensions public static IServiceCollection AddDedicatedLogging( this IServiceCollection services, IConfiguration configuration, - Action configureOpenTelemetry) + Action configureOpenTelemetry) { ArgumentNullException.ThrowIfNull(configureOpenTelemetry); - services.TryAddSingleton(sp => + services.TryAddSingleton(_ => { - var loggerFactory = LoggerFactory.Create(builder => + var services = new ServiceCollection(); + services.AddLogging(builder => { builder.AddConfiguration(configuration); - builder.AddOpenTelemetry(configureOpenTelemetry); + builder.AddOpenTelemetry(); }); - return new DedicatedLoggerFactory(loggerFactory); + services.ConfigureOpenTelemetryLoggerProvider(configureOpenTelemetry); + + var sp = services.BuildServiceProvider(); + + return new DedicatedLoggerFactory(sp); }); services.TryAdd(ServiceDescriptor.Singleton(typeof(IDedicatedLogger<>), typeof(DedicatedLogger<>))); @@ -54,11 +59,13 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except private sealed class DedicatedLoggerFactory : ILoggerFactory { + private readonly ServiceProvider serviceProvider; private readonly ILoggerFactory innerLoggerFactory; - public DedicatedLoggerFactory(ILoggerFactory loggerFactory) + public DedicatedLoggerFactory(ServiceProvider serviceProvider) { - this.innerLoggerFactory = loggerFactory; + this.serviceProvider = serviceProvider; + this.innerLoggerFactory = serviceProvider.GetRequiredService(); } public void AddProvider(ILoggerProvider provider) @@ -68,6 +75,6 @@ public ILogger CreateLogger(string categoryName) => this.innerLoggerFactory.CreateLogger(categoryName); public void Dispose() - => this.innerLoggerFactory.Dispose(); + => this.serviceProvider.Dispose(); } } diff --git a/docs/logs/dedicated-pipeline/Program.cs b/docs/logs/dedicated-pipeline/Program.cs index ad671445cde..c465c77d0d3 100644 --- a/docs/logs/dedicated-pipeline/Program.cs +++ b/docs/logs/dedicated-pipeline/Program.cs @@ -8,18 +8,19 @@ builder.Logging.ClearProviders(); -builder.Logging.AddOpenTelemetry(options => -{ - // Set up primary pipeline for common app logs - options.AddConsoleExporter(); -}); +builder.Services.AddOpenTelemetry() + .WithLogging(logging => + { + // Set up primary pipeline for common app logs + logging.AddConsoleExporter(); + }); builder.Services.AddDedicatedLogging( builder.Configuration.GetSection("DedicatedLogging"), // Bind configuration for dedicated logging pipeline - options => + logging => { // Set up secondary pipeline for dedicated logs - options.AddConsoleExporter(); + logging.AddConsoleExporter(); }); var app = builder.Build(); diff --git a/docs/logs/getting-started-aspnetcore/Program.cs b/docs/logs/getting-started-aspnetcore/Program.cs index 179d9d2237a..123bf54a2c9 100644 --- a/docs/logs/getting-started-aspnetcore/Program.cs +++ b/docs/logs/getting-started-aspnetcore/Program.cs @@ -6,25 +6,21 @@ var builder = WebApplication.CreateBuilder(args); -// Remove default providers and add OpenTelemetry logging provider. -// For instructional purposes only, disable the default .NET console logging provider to -// use the verbose OpenTelemetry console exporter instead. For most development -// and production scenarios the default console provider works well and there is no need to +// For instructional purposes only, disable the default .NET logging providers. +// We remove the console logging provider in this demo to use the verbose +// OpenTelemetry console exporter instead. For most development and production +// scenarios the default console provider works well and there is no need to // clear these providers. builder.Logging.ClearProviders(); -builder.Logging.AddOpenTelemetry(logging => -{ - var resourceBuilder = ResourceBuilder - .CreateDefault() - .AddService(builder.Environment.ApplicationName); - - logging.SetResourceBuilder(resourceBuilder) - - // ConsoleExporter is used for demo purpose only. - // In production environment, ConsoleExporter should be replaced with other exporters (e.g. OTLP Exporter). - .AddConsoleExporter(); -}); +// Add OpenTelemetry logging provider by calling the WithLogging extension. +builder.Services.AddOpenTelemetry() + .ConfigureResource(r => r.AddService(builder.Environment.ApplicationName)) + .WithLogging(logging => logging + /* Note: ConsoleExporter is used for demo purpose only. In production + environment, ConsoleExporter should be replaced with other exporters + (e.g. OTLP Exporter). */ + .AddConsoleExporter()); var app = builder.Build(); diff --git a/examples/AspNetCore/Program.cs b/examples/AspNetCore/Program.cs index 89ac46932dc..809534f5c76 100644 --- a/examples/AspNetCore/Program.cs +++ b/examples/AspNetCore/Program.cs @@ -24,20 +24,21 @@ // Note: Switch between Explicit/Exponential by setting HistogramAggregation in appsettings.json var histogramAggregation = appBuilder.Configuration.GetValue("HistogramAggregation", defaultValue: "explicit")!.ToLowerInvariant(); -// Build a resource configuration action to set service information. -Action configureResource = r => r.AddService( - serviceName: appBuilder.Configuration.GetValue("ServiceName", defaultValue: "otel-test")!, - serviceVersion: typeof(Program).Assembly.GetName().Version?.ToString() ?? "unknown", - serviceInstanceId: Environment.MachineName); - // Create a service to expose ActivitySource, and Metric Instruments // for manual instrumentation appBuilder.Services.AddSingleton(); -// Configure OpenTelemetry tracing & metrics with auto-start using the +// Clear default logging providers used by WebApplication host. +appBuilder.Logging.ClearProviders(); + +// Configure OpenTelemetry logging, metrics, & tracing with auto-start using the // AddOpenTelemetry extension from OpenTelemetry.Extensions.Hosting. appBuilder.Services.AddOpenTelemetry() - .ConfigureResource(configureResource) + .ConfigureResource(r => r + .AddService( + serviceName: appBuilder.Configuration.GetValue("ServiceName", defaultValue: "otel-test")!, + serviceVersion: typeof(Program).Assembly.GetName().Version?.ToString() ?? "unknown", + serviceInstanceId: Environment.MachineName)) .WithTracing(builder => { // Tracing @@ -121,34 +122,25 @@ builder.AddConsoleExporter(); break; } - }); - -// Clear default logging providers used by WebApplication host. -appBuilder.Logging.ClearProviders(); - -// Configure OpenTelemetry Logging. -appBuilder.Logging.AddOpenTelemetry(options => -{ - // Note: See appsettings.json Logging:OpenTelemetry section for configuration. - - var resourceBuilder = ResourceBuilder.CreateDefault(); - configureResource(resourceBuilder); - options.SetResourceBuilder(resourceBuilder); - - switch (logExporter) + }) + .WithLogging(builder => { - case "otlp": - options.AddOtlpExporter(otlpOptions => - { - // Use IConfiguration directly for Otlp exporter endpoint option. - otlpOptions.Endpoint = new Uri(appBuilder.Configuration.GetValue("Otlp:Endpoint", defaultValue: "http://localhost:4317")!); - }); - break; - default: - options.AddConsoleExporter(); - break; - } -}); + // Note: See appsettings.json Logging:OpenTelemetry section for configuration. + + switch (logExporter) + { + case "otlp": + builder.AddOtlpExporter(otlpOptions => + { + // Use IConfiguration directly for Otlp exporter endpoint option. + otlpOptions.Endpoint = new Uri(appBuilder.Configuration.GetValue("Otlp:Endpoint", defaultValue: "http://localhost:4317")!); + }); + break; + default: + builder.AddConsoleExporter(); + break; + } + }); appBuilder.Services.AddControllers(); diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Experimental/PublicAPI.Unshipped.txt index a0f2e472dd6..e69de29bb2d 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -1,9 +0,0 @@ -OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions -OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, T! instrumentation) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..a0f2e472dd6 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,9 @@ +OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions +OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, T! instrumentation) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md index 1f2a27b7f38..9d22648cde4 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* The experimental APIs previously covered by `OTEL1000` + (`LoggerProviderBuilder` `AddInstrumentation` & `ConfigureServices` extensions + and `IServiceCollection.ConfigureOpenTelemetryLoggerProvider` extension) will + now be part of the public API and supported in stable builds. + ([#5648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5648)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs index 257b7332bec..c3105bc4c08 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs @@ -13,40 +13,18 @@ namespace OpenTelemetry.Logs; /// /// Contains extension methods for the class. /// -#if EXPOSE_EXPERIMENTAL_FEATURES -#if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif -public -#else -internal -#endif -static class OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions +public static class OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions { -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds instrumentation to the provider. /// /// - /// /// Note: The type specified by will be /// registered as a singleton service into application services. /// /// Instrumentation type. /// . /// The supplied for chaining. -#else - /// - /// Adds instrumentation to the provider. - /// - /// - /// Note: The type specified by will be - /// registered as a singleton service into application services. - /// - /// Instrumentation type. - /// . - /// The supplied for chaining. -#endif public static LoggerProviderBuilder AddInstrumentation< #if NET6_0_OR_GREATER [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] @@ -64,24 +42,13 @@ public static LoggerProviderBuilder AddInstrumentation< return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds instrumentation to the provider. /// /// Instrumentation type. - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// . /// Instrumentation instance. /// The supplied for chaining. -#else - /// - /// Adds instrumentation to the provider. - /// - /// Instrumentation type. - /// . - /// Instrumentation instance. - /// The supplied for chaining. -#endif public static LoggerProviderBuilder AddInstrumentation(this LoggerProviderBuilder loggerProviderBuilder, T instrumentation) where T : class { @@ -95,24 +62,13 @@ public static LoggerProviderBuilder AddInstrumentation(this LoggerProviderBui return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds instrumentation to the provider. /// /// Instrumentation type. - /// /// . /// Instrumentation factory. /// The supplied for chaining. -#else - /// - /// Adds instrumentation to the provider. - /// - /// Instrumentation type. - /// . - /// Instrumentation factory. - /// The supplied for chaining. -#endif public static LoggerProviderBuilder AddInstrumentation( this LoggerProviderBuilder loggerProviderBuilder, Func instrumentationFactory) @@ -128,16 +84,6 @@ public static LoggerProviderBuilder AddInstrumentation( return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Adds instrumentation to the provider. - /// - /// Instrumentation type. - /// - /// . - /// Instrumentation factory. - /// The supplied for chaining. -#else /// /// Adds instrumentation to the provider. /// @@ -145,7 +91,6 @@ public static LoggerProviderBuilder AddInstrumentation( /// . /// Instrumentation factory. /// The supplied for chaining. -#endif public static LoggerProviderBuilder AddInstrumentation( this LoggerProviderBuilder loggerProviderBuilder, Func instrumentationFactory) @@ -165,32 +110,17 @@ public static LoggerProviderBuilder AddInstrumentation( return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Register a callback action to configure the where logging services are configured. /// /// - /// /// Note: Logging services are only available during the application /// configuration phase. /// /// . /// Configuration callback. /// The supplied for chaining. -#else - /// - /// Register a callback action to configure the where logging services are configured. - /// - /// - /// Note: Logging services are only available during the application - /// configuration phase. - /// - /// . - /// Configuration callback. - /// The supplied for chaining. -#endif public static LoggerProviderBuilder ConfigureServices( this LoggerProviderBuilder loggerProviderBuilder, Action configure) diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs index 8e6f899b24e..8d33a420a61 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Internal; @@ -12,23 +9,13 @@ namespace OpenTelemetry.Logs; /// /// Extension methods for setting up OpenTelemetry logging services in an . /// -#if EXPOSE_EXPERIMENTAL_FEATURES -#if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif -public -#else -internal -#endif -static class OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions +public static class OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions { -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Registers an action used to configure the OpenTelemetry . /// /// - /// /// Notes: /// /// This is safe to be called multiple times and by library authors. @@ -45,29 +32,6 @@ static class OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions /// cref="LoggerProviderBuilder"/>. /// The so that additional calls /// can be chained. -#else - /// - /// Registers an action used to configure the OpenTelemetry . - /// - /// - /// Notes: - /// - /// This is safe to be called multiple times and by library authors. - /// Each registered configuration action will be applied - /// sequentially. - /// A will NOT be created automatically - /// using this method. To begin collecting logs use the - /// IServiceCollection.AddOpenTelemetry extension in the - /// OpenTelemetry.Extensions.Hosting package. - /// - /// - /// . - /// Callback action to configure the . - /// The so that additional calls - /// can be chained. -#endif public static IServiceCollection ConfigureOpenTelemetryLoggerProvider( this IServiceCollection services, Action configure) @@ -80,40 +44,6 @@ public static IServiceCollection ConfigureOpenTelemetryLoggerProvider( return services; } -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Registers an action used to configure the OpenTelemetry once the - /// is available. - /// - /// - /// - /// Notes: - /// - /// This is safe to be called multiple times and by library authors. - /// Each registered configuration action will be applied - /// sequentially. - /// A will NOT be created automatically - /// using this method. To begin collecting logs use the - /// IServiceCollection.AddOpenTelemetry extension in the - /// OpenTelemetry.Extensions.Hosting package. - /// The supplied configuration delegate is called once the is available. Services may NOT be added to a - /// once the has been created. Many helper extensions - /// register services and may throw if invoked inside the configuration - /// delegate. If you don't need access to the - /// call instead which is safe to be used with - /// helper extensions. - /// - /// - /// . - /// Callback action to configure the . - /// The so that additional calls - /// can be chained. -#else /// /// Registers an action used to configure the OpenTelemetry once the @@ -145,7 +75,6 @@ public static IServiceCollection ConfigureOpenTelemetryLoggerProvider( /// cref="LoggerProviderBuilder"/>. /// The so that additional calls /// can be chained. -#endif public static IServiceCollection ConfigureOpenTelemetryLoggerProvider( this IServiceCollection services, Action configure) diff --git a/src/OpenTelemetry.Api/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api/.publicApi/Experimental/PublicAPI.Unshipped.txt index 2c2dcbb59e2..4cb12fd2969 100644 --- a/src/OpenTelemetry.Api/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -1,19 +1,12 @@ abstract OpenTelemetry.Logs.Logger.EmitLog(in OpenTelemetry.Logs.LogRecordData data, in OpenTelemetry.Logs.LogRecordAttributeList attributes) -> void -abstract OpenTelemetry.Logs.LoggerProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -OpenTelemetry.Logs.IDeferredLoggerProviderBuilder -OpenTelemetry.Logs.IDeferredLoggerProviderBuilder.Configure(System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! OpenTelemetry.Logs.Logger OpenTelemetry.Logs.Logger.EmitLog(in OpenTelemetry.Logs.LogRecordData data) -> void OpenTelemetry.Logs.Logger.Logger(string? name) -> void OpenTelemetry.Logs.Logger.Name.get -> string! OpenTelemetry.Logs.Logger.Version.get -> string? -OpenTelemetry.Logs.LoggerProvider OpenTelemetry.Logs.LoggerProvider.GetLogger() -> OpenTelemetry.Logs.Logger! OpenTelemetry.Logs.LoggerProvider.GetLogger(string? name) -> OpenTelemetry.Logs.Logger! OpenTelemetry.Logs.LoggerProvider.GetLogger(string? name, string? version) -> OpenTelemetry.Logs.Logger! -OpenTelemetry.Logs.LoggerProvider.LoggerProvider() -> void -OpenTelemetry.Logs.LoggerProviderBuilder -OpenTelemetry.Logs.LoggerProviderBuilder.LoggerProviderBuilder() -> void OpenTelemetry.Logs.LogRecordAttributeList OpenTelemetry.Logs.LogRecordAttributeList.Add(string! key, object? value) -> void OpenTelemetry.Logs.LogRecordAttributeList.Add(System.Collections.Generic.KeyValuePair attribute) -> void diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..d50e30cadb4 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,7 @@ +abstract OpenTelemetry.Logs.LoggerProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! +OpenTelemetry.Logs.IDeferredLoggerProviderBuilder +OpenTelemetry.Logs.IDeferredLoggerProviderBuilder.Configure(System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +OpenTelemetry.Logs.LoggerProvider +OpenTelemetry.Logs.LoggerProvider.LoggerProvider() -> void +OpenTelemetry.Logs.LoggerProviderBuilder +OpenTelemetry.Logs.LoggerProviderBuilder.LoggerProviderBuilder() -> void diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 9bdc9bf5d16..e340f5d5b22 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The experimental APIs previously covered by `OTEL1000` (`LoggerProvider`, + `LoggerProviderBuilder`, & `IDeferredLoggerProviderBuilder`) will now be part + of the public API and supported in stable builds. + ([#5648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5648)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs b/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs index 70528fe6cb7..7421a9df268 100644 --- a/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs @@ -3,33 +3,14 @@ #nullable enable -#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES -using System.Diagnostics.CodeAnalysis; -using OpenTelemetry.Internal; -#endif - namespace OpenTelemetry.Logs; -#if EXPOSE_EXPERIMENTAL_FEATURES -/// -/// Describes a logger provider builder that supports deferred -/// initialization using an to perform -/// dependency injection. -/// -/// -#if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif -public -#else /// /// Describes a logger provider builder that supports deferred /// initialization using an to perform /// dependency injection. /// -internal -#endif -interface IDeferredLoggerProviderBuilder +public interface IDeferredLoggerProviderBuilder { /// /// Register a callback action to configure the /// LoggerProvider is the entry point of the OpenTelemetry API. It provides access to . /// -/// -#if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif -public -#else -/// -/// LoggerProvider is the entry point of the OpenTelemetry API. It provides access to . -/// -internal -#endif - class LoggerProvider : BaseProvider +public class LoggerProvider : BaseProvider { private static readonly NoopLogger NoopLogger = new(); @@ -38,37 +26,55 @@ protected LoggerProvider() { } +#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Gets a logger. /// + /// /// instance. #if NET8_0_OR_GREATER [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif - public Logger GetLogger() + public +#else + internal +#endif + Logger GetLogger() => this.GetLogger(name: null, version: null); +#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Gets a logger with the given name. /// + /// /// Optional name identifying the instrumentation library. /// instance. #if NET8_0_OR_GREATER [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif - public Logger GetLogger(string? name) + public +#else + internal +#endif + Logger GetLogger(string? name) => this.GetLogger(name, version: null); +#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Gets a logger with the given name and version. /// + /// /// Optional name identifying the instrumentation library. /// Optional version of the instrumentation library. /// instance. #if NET8_0_OR_GREATER [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif - public Logger GetLogger(string? name, string? version) + public +#else + internal +#endif + Logger GetLogger(string? name, string? version) { if (!this.TryCreateLogger(name, out var logger)) { @@ -80,16 +86,22 @@ public Logger GetLogger(string? name, string? version) return logger; } +#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Try to create a logger with the given name. /// + /// /// Optional name identifying the instrumentation library. /// . /// if the logger was created. #if NET8_0_OR_GREATER [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif - protected virtual bool TryCreateLogger( + protected +#else + internal +#endif + virtual bool TryCreateLogger( string? name, #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER [NotNullWhen(true)] diff --git a/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs b/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs index 3fa9c6fc743..b0aec6bfca7 100644 --- a/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs @@ -3,29 +3,12 @@ #nullable enable -#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES -using System.Diagnostics.CodeAnalysis; -using OpenTelemetry.Internal; -#endif - namespace OpenTelemetry.Logs; -#if EXPOSE_EXPERIMENTAL_FEATURES -/// -/// LoggerProviderBuilder base class. -/// -/// -#if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif -public -#else /// /// LoggerProviderBuilder base class. /// -internal -#endif - abstract class LoggerProviderBuilder +public abstract class LoggerProviderBuilder { /// /// Initializes a new instance of the class. diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/Experimental/PublicAPI.Unshipped.txt index be114835ccd..e69de29bb2d 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -1,3 +0,0 @@ -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, string name, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..be114835ccd 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, string name, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index 6605e9d684f..f6a7ebb48b8 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The experimental APIs previously covered by `OTEL1000` + (`LoggerProviderBuilder.AddConsoleExporter` extension) will now be part of the + public API and supported in stable builds. + ([#5648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5648)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs index 6b024498cb7..80c767343b7 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; @@ -18,7 +15,7 @@ public static class ConsoleExporterLoggingExtensions /// /// options to use. /// The instance of to chain the calls. - /// todo: [Obsolete("Call LoggerProviderBuilder.AddConsoleExporter instead this method will be removed in a future version.")] + // TODO: [Obsolete("Call LoggerProviderBuilder.AddConsoleExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions) => AddConsoleExporter(loggerOptions, configure: null); @@ -28,7 +25,7 @@ public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLo /// options to use. /// Callback action for configuring . /// The instance of to chain the calls. - /// todo: [Obsolete("Call LoggerProviderBuilder.AddConsoleExporter instead this method will be removed in a future version.")] + // TODO: [Obsolete("Call LoggerProviderBuilder.AddConsoleExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions, Action configure) { Guard.ThrowIfNull(loggerOptions); @@ -38,69 +35,26 @@ public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLo return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(new ConsoleLogRecordExporter(options))); } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds Console exporter with LoggerProviderBuilder. /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// . /// The supplied instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds Console exporter with LoggerProviderBuilder. - /// - /// . - /// The supplied instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddConsoleExporter( + public static LoggerProviderBuilder AddConsoleExporter( this LoggerProviderBuilder loggerProviderBuilder) => AddConsoleExporter(loggerProviderBuilder, name: null, configure: null); -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Adds Console exporter with LoggerProviderBuilder. - /// - /// - /// . - /// Callback action for configuring . - /// The supplied instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else /// /// Adds Console exporter with LoggerProviderBuilder. /// /// . /// Callback action for configuring . /// The supplied instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddConsoleExporter( + public static LoggerProviderBuilder AddConsoleExporter( this LoggerProviderBuilder loggerProviderBuilder, Action configure) => AddConsoleExporter(loggerProviderBuilder, name: null, configure); -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Adds Console exporter with LoggerProviderBuilder. - /// - /// - /// . - /// Name which is used when retrieving options. - /// Callback action for configuring . - /// The supplied instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else /// /// Adds Console exporter with LoggerProviderBuilder. /// @@ -108,9 +62,7 @@ static LoggerProviderBuilder AddConsoleExporter( /// Name which is used when retrieving options. /// Callback action for configuring . /// The supplied instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddConsoleExporter( + public static LoggerProviderBuilder AddConsoleExporter( this LoggerProviderBuilder loggerProviderBuilder, string name, Action configure) diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Experimental/PublicAPI.Unshipped.txt index f7378ee36cc..e69de29bb2d 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -1 +0,0 @@ -static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Logs.LoggerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..f7378ee36cc 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Logs.LoggerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md index d4aa853c675..8b932042281 100644 --- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The experimental APIs previously covered by `OTEL1000` + (`LoggerProviderBuilder.AddInMemoryExporter` extension) will now be part of + the public API and supported in stable builds. + ([#5648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5648)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs index 982595f8824..19b2079921e 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -17,7 +14,7 @@ public static class InMemoryExporterLoggingExtensions /// options to use. /// Collection which will be populated with the exported . /// The supplied instance of to chain the calls. - /// todo: [Obsolete("Call LoggerProviderBuilder.AddInMemoryExporter instead this method will be removed in a future version.")] + // TODO: [Obsolete("Call LoggerProviderBuilder.AddInMemoryExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddInMemoryExporter( this OpenTelemetryLoggerOptions loggerOptions, ICollection exportedItems) @@ -31,28 +28,13 @@ public static OpenTelemetryLoggerOptions AddInMemoryExporter( new SimpleLogRecordExportProcessor(logExporter)); } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds InMemory exporter to the LoggerProviderBuilder. /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// . /// Collection which will be populated with the exported . /// The supplied instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds InMemory exporter to the LoggerProviderBuilder. - /// - /// . - /// Collection which will be populated with the exported . - /// The supplied instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddInMemoryExporter( + public static LoggerProviderBuilder AddInMemoryExporter( this LoggerProviderBuilder loggerProviderBuilder, ICollection exportedItems) { diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Experimental/PublicAPI.Unshipped.txt index e6bd747c9de..e69de29bb2d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -1,5 +0,0 @@ -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..e6bd747c9de 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 08310125087..4c2d56a7243 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The experimental APIs previously covered by `OTEL1000` + (`LoggerProviderBuilder.AddOtlpExporter` extension) will now be part of the + public API and supported in stable builds. + ([#5648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5648)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs index ca5a759caf4..3a994c8e772 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs @@ -4,9 +4,6 @@ #nullable enable using System.Diagnostics; -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -28,6 +25,7 @@ public static class OtlpLogExporterHelperExtensions /// /// options to use. /// The instance of to chain the calls. + // TODO: [Obsolete("Call LoggerProviderBuilder.AddOtlpExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLoggerOptions loggerOptions) => AddOtlpExporter(loggerOptions, name: null, configure: null); @@ -37,6 +35,7 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLogge /// options to use. /// Callback action for configuring . /// The instance of to chain the calls. + // TODO: [Obsolete("Call LoggerProviderBuilder.AddOtlpExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddOtlpExporter( this OpenTelemetryLoggerOptions loggerOptions, Action configure) @@ -49,6 +48,7 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter( /// Optional name which is used when retrieving options. /// Optional callback action for configuring . /// The instance of to chain the calls. + // TODO: [Obsolete("Call LoggerProviderBuilder.AddOtlpExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddOtlpExporter( this OpenTelemetryLoggerOptions loggerOptions, string? name, @@ -81,6 +81,7 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter( /// options to use. /// Callback action for configuring and . /// The instance of to chain the calls. + // TODO: [Obsolete("Call LoggerProviderBuilder.AddOtlpExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddOtlpExporter( this OpenTelemetryLoggerOptions loggerOptions, Action configureExporterAndProcessor) @@ -93,6 +94,7 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter( /// Optional name which is used when retrieving options. /// Optional callback action for configuring and . /// The instance of to chain the calls. + // TODO: [Obsolete("Call LoggerProviderBuilder.AddOtlpExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddOtlpExporter( this OpenTelemetryLoggerOptions loggerOptions, string? name, @@ -119,96 +121,42 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter( }); } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds an OTLP exporter to the LoggerProvider. /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// builder to use. /// The instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds an OTLP exporter to the LoggerProvider. - /// - /// builder to use. - /// The instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddOtlpExporter(this LoggerProviderBuilder builder) + public static LoggerProviderBuilder AddOtlpExporter(this LoggerProviderBuilder builder) => AddOtlpExporter(builder, name: null, configureExporter: null); -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Adds an OTLP exporter to the LoggerProvider. - /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. - /// builder to use. - /// Callback action for configuring . - /// The instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else /// /// Adds an OTLP exporter to the LoggerProvider. /// /// builder to use. /// Callback action for configuring . /// The instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddOtlpExporter(this LoggerProviderBuilder builder, Action configureExporter) + public static LoggerProviderBuilder AddOtlpExporter(this LoggerProviderBuilder builder, Action configureExporter) => AddOtlpExporter(builder, name: null, configureExporter); -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds an OTLP exporter to the LoggerProvider. /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// builder to use. /// Callback action for /// configuring and . /// The instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - internal -#endif - static LoggerProviderBuilder AddOtlpExporter(this LoggerProviderBuilder builder, Action configureExporterAndProcessor) + public static LoggerProviderBuilder AddOtlpExporter(this LoggerProviderBuilder builder, Action configureExporterAndProcessor) => AddOtlpExporter(builder, name: null, configureExporterAndProcessor); -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds OpenTelemetry Protocol (OTLP) exporter to the LoggerProvider. /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// builder to use. /// Optional name which is used when retrieving options. /// Optional callback action for configuring . /// The instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds OpenTelemetry Protocol (OTLP) exporter to the LoggerProvider. - /// - /// builder to use. - /// Optional name which is used when retrieving options. - /// Optional callback action for configuring . - /// The instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddOtlpExporter( + public static LoggerProviderBuilder AddOtlpExporter( this LoggerProviderBuilder builder, string? name, Action? configureExporter) @@ -265,22 +213,6 @@ static LoggerProviderBuilder AddOtlpExporter( }); } -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Adds an OTLP exporter to the LoggerProvider. - /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. - /// builder to use. - /// Optional name which is used when retrieving options. - /// Optional callback action for - /// configuring and . - /// The instance of to chain the calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else /// /// Adds an OTLP exporter to the LoggerProvider. /// @@ -290,9 +222,7 @@ static LoggerProviderBuilder AddOtlpExporter( /// configuring and . /// The instance of to chain the calls. - internal -#endif - static LoggerProviderBuilder AddOtlpExporter( + public static LoggerProviderBuilder AddOtlpExporter( this LoggerProviderBuilder builder, string? name, Action? configureExporterAndProcessor) diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Experimental/PublicAPI.Unshipped.txt index f83d7ca4a0f..e69de29bb2d 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -1,3 +0,0 @@ -OpenTelemetry.OpenTelemetryBuilder.WithLogging() -> OpenTelemetry.OpenTelemetryBuilder! -OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action! configure) -> OpenTelemetry.OpenTelemetryBuilder! -OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.OpenTelemetryBuilder! diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..f83d7ca4a0f 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.OpenTelemetryBuilder.WithLogging() -> OpenTelemetry.OpenTelemetryBuilder! +OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action! configure) -> OpenTelemetry.OpenTelemetryBuilder! +OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.OpenTelemetryBuilder! diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index a5921a6dd90..3bcc96de580 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The experimental APIs previously covered by `OTEL1000` + (`OpenTelemetryBuilder.WithLogging` method) will now be part of the public API + and supported in stable builds. + ([#5648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5648)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs index 042a211e76b..5512befb59e 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.Logging; @@ -112,13 +109,10 @@ public OpenTelemetryBuilder WithTracing(Action configure) return this; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds logging services into the builder. /// /// - /// WARNING: This is an experimental API which might change or - /// be removed in the future. Use at your own risk. /// Notes: /// /// This is safe to be called multiple times and by library authors. @@ -131,33 +125,9 @@ public OpenTelemetryBuilder WithTracing(Action configure) /// /// The supplied for chaining /// calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds logging services into the builder. - /// - /// - /// Notes: - /// - /// This is safe to be called multiple times and by library authors. - /// Only a single will be created for a given - /// . - /// This method automatically registers an named 'OpenTelemetry' into the . - /// - /// - /// The supplied for chaining - /// calls. - internal -#endif - OpenTelemetryBuilder WithLogging() + public OpenTelemetryBuilder WithLogging() => this.WithLogging(configureBuilder: null, configureOptions: null); -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds logging services into the builder. /// @@ -166,44 +136,13 @@ OpenTelemetryBuilder WithLogging() /// configuration callback. /// The supplied for chaining /// calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds logging services into the builder. - /// - /// - /// - /// configuration callback. - /// The supplied for chaining - /// calls. - internal -#endif - OpenTelemetryBuilder WithLogging(Action configure) + public OpenTelemetryBuilder WithLogging(Action configure) { Guard.ThrowIfNull(configure); return this.WithLogging(configureBuilder: configure, configureOptions: null); } -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Adds logging services into the builder. - /// - /// - /// Optional configuration callback. - /// Optional configuration callback. - /// The supplied for chaining - /// calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else /// /// Adds logging services into the builder. /// @@ -211,14 +150,15 @@ OpenTelemetryBuilder WithLogging(Action configure) /// Optional configuration callback. /// Optional configuration callback. + /// cref="OpenTelemetryLoggerOptions"/> configuration callback. are used by the named 'OpenTelemetry' automatically registered + /// by this method. /// The supplied for chaining /// calls. - internal -#endif - OpenTelemetryBuilder WithLogging( - Action? configureBuilder, - Action? configureOptions) + public OpenTelemetryBuilder WithLogging( + Action? configureBuilder, + Action? configureOptions) { OpenTelemetryBuilderSdkExtensions.WithLogging(this, configureBuilder, configureOptions); diff --git a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt index 22a73f5d6bb..a6594de1a9c 100644 --- a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -1,8 +1,6 @@ abstract OpenTelemetry.Metrics.ExemplarReservoir.Collect() -> OpenTelemetry.Metrics.ReadOnlyExemplarCollection abstract OpenTelemetry.Metrics.ExemplarReservoir.Offer(in OpenTelemetry.Metrics.ExemplarMeasurement measurement) -> void abstract OpenTelemetry.Metrics.ExemplarReservoir.Offer(in OpenTelemetry.Metrics.ExemplarMeasurement measurement) -> void -OpenTelemetry.Logs.LoggerProviderBuilderExtensions -OpenTelemetry.Logs.LoggerProviderExtensions OpenTelemetry.Logs.LogRecord.Logger.get -> OpenTelemetry.Logs.Logger! OpenTelemetry.Logs.LogRecord.Severity.get -> OpenTelemetry.Logs.LogRecordSeverity? OpenTelemetry.Logs.LogRecord.Severity.set -> void @@ -24,20 +22,8 @@ OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.set -> void OpenTelemetry.Metrics.MetricStreamConfiguration.ExemplarReservoirFactory.get -> System.Func? OpenTelemetry.Metrics.MetricStreamConfiguration.ExemplarReservoirFactory.set -> void override sealed OpenTelemetry.Metrics.FixedSizeExemplarReservoir.Collect() -> OpenTelemetry.Metrics.ReadOnlyExemplarCollection -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func!>! implementationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.Build(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProvider! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProvider! provider, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProvider! -static OpenTelemetry.Logs.LoggerProviderExtensions.ForceFlush(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool -static OpenTelemetry.Logs.LoggerProviderExtensions.Shutdown(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.LoggerProviderBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.UseOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.UseOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action! configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.UseOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configureBuilder, System.Action? configureOptions) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.LoggerProviderBuilder! virtual OpenTelemetry.Metrics.FixedSizeExemplarReservoir.OnCollected() -> void diff --git a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt index a9a6c031d7a..4ebd84b69d9 100644 --- a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,3 +1,5 @@ +OpenTelemetry.Logs.LoggerProviderBuilderExtensions +OpenTelemetry.Logs.LoggerProviderExtensions OpenTelemetry.Metrics.Exemplar OpenTelemetry.Metrics.Exemplar.DoubleValue.get -> double OpenTelemetry.Metrics.Exemplar.Exemplar() -> void @@ -25,4 +27,16 @@ OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.Enumerator() -> void OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.MoveNext() -> bool OpenTelemetry.ReadOnlyFilteredTagCollection.GetEnumerator() -> OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator OpenTelemetry.ReadOnlyFilteredTagCollection.ReadOnlyFilteredTagCollection() -> void +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func!>! implementationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.Build(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProvider! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProvider! provider, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProvider! +static OpenTelemetry.Logs.LoggerProviderExtensions.ForceFlush(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool +static OpenTelemetry.Logs.LoggerProviderExtensions.Shutdown(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetExemplarFilter(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.ExemplarFilterType exemplarFilter) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry/BatchExportProcessor.cs b/src/OpenTelemetry/BatchExportProcessor.cs index 8e1e2ed0e58..b377d5e89e5 100644 --- a/src/OpenTelemetry/BatchExportProcessor.cs +++ b/src/OpenTelemetry/BatchExportProcessor.cs @@ -20,10 +20,10 @@ public abstract class BatchExportProcessor : BaseExportProcessor internal const int DefaultMaxExportBatchSize = 512; internal readonly int MaxExportBatchSize; + internal readonly int ScheduledDelayMilliseconds; + internal readonly int ExporterTimeoutMilliseconds; private readonly CircularBuffer circularBuffer; - private readonly int scheduledDelayMilliseconds; - private readonly int exporterTimeoutMilliseconds; private readonly Thread exporterThread; private readonly AutoResetEvent exportTrigger = new(false); private readonly ManualResetEvent dataExportedNotification = new(false); @@ -54,8 +54,8 @@ protected BatchExportProcessor( Guard.ThrowIfOutOfRange(exporterTimeoutMilliseconds, min: 0); this.circularBuffer = new CircularBuffer(maxQueueSize); - this.scheduledDelayMilliseconds = scheduledDelayMilliseconds; - this.exporterTimeoutMilliseconds = exporterTimeoutMilliseconds; + this.ScheduledDelayMilliseconds = scheduledDelayMilliseconds; + this.ExporterTimeoutMilliseconds = exporterTimeoutMilliseconds; this.MaxExportBatchSize = maxExportBatchSize; this.exporterThread = new Thread(this.ExporterProc) { @@ -252,7 +252,7 @@ private void ExporterProc() { try { - WaitHandle.WaitAny(triggers, this.scheduledDelayMilliseconds); + WaitHandle.WaitAny(triggers, this.ScheduledDelayMilliseconds); } catch (ObjectDisposedException) { diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 763f3f370a0..5f11580af07 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* The experimental APIs previously covered by `OTEL1000` + (`LoggerProviderBuilder` `AddProcessor` & `ConfigureResource` extensions, and + `LoggerProvider` `ForceFlush` & `Shutdown` extensions) will now be part of the + public API and supported in stable builds. + ([#5648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5648)) + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs b/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs index 3fad4d173dc..36ac8ac8e6e 100644 --- a/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs @@ -14,30 +14,8 @@ namespace OpenTelemetry.Logs; /// /// Contains extension methods for the class. /// -#if EXPOSE_EXPERIMENTAL_FEATURES -#if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif -public -#else -internal -#endif - static class LoggerProviderBuilderExtensions +public static class LoggerProviderBuilderExtensions { -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Sets the from which the associated with - /// this provider is built from. - /// - /// - /// - /// Note: Calling will override the currently set . - /// To modify the current call instead. - /// - /// . - /// from which Resource will be built. - /// Returns for chaining. -#else /// /// Sets the from which the associated with /// this provider is built from. @@ -49,7 +27,6 @@ static class LoggerProviderBuilderExtensions /// . /// from which Resource will be built. /// Returns for chaining. -#endif public static LoggerProviderBuilder SetResourceBuilder(this LoggerProviderBuilder loggerProviderBuilder, ResourceBuilder resourceBuilder) { Guard.ThrowIfNull(resourceBuilder); @@ -65,24 +42,13 @@ public static LoggerProviderBuilder SetResourceBuilder(this LoggerProviderBuilde return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Modify in-place the from which the associated with /// this provider is built from. /// - /// /// . /// An action which modifies the provided in-place. /// Returns for chaining. -#else - /// - /// Modify in-place the from which the associated with - /// this provider is built from. - /// - /// . - /// An action which modifies the provided in-place. - /// Returns for chaining. -#endif public static LoggerProviderBuilder ConfigureResource(this LoggerProviderBuilder loggerProviderBuilder, Action configure) { Guard.ThrowIfNull(configure); @@ -98,22 +64,12 @@ public static LoggerProviderBuilder ConfigureResource(this LoggerProviderBuilder return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds a processor to the provider. /// - /// /// . /// LogRecord processor to add. /// Returns for chaining. -#else - /// - /// Adds a processor to the provider. - /// - /// . - /// LogRecord processor to add. - /// Returns for chaining. -#endif public static LoggerProviderBuilder AddProcessor(this LoggerProviderBuilder loggerProviderBuilder, BaseProcessor processor) { Guard.ThrowIfNull(processor); @@ -129,30 +85,16 @@ public static LoggerProviderBuilder AddProcessor(this LoggerProviderBuilder logg return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds a processor to the provider which will be retrieved using dependency injection. /// /// - /// /// Note: The type specified by will be /// registered as a singleton service into application services. /// /// Processor type. /// . /// The supplied for chaining. -#else - /// - /// Adds a processor to the provider which will be retrieved using dependency injection. - /// - /// - /// Note: The type specified by will be - /// registered as a singleton service into application services. - /// - /// Processor type. - /// . - /// The supplied for chaining. -#endif public static LoggerProviderBuilder AddProcessor< #if NET6_0_OR_GREATER [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] @@ -173,22 +115,12 @@ public static LoggerProviderBuilder AddProcessor< return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds a processor to the provider which will be retrieved using dependency injection. /// - /// /// . /// The factory that creates the service. /// The supplied for chaining. -#else - /// - /// Adds a processor to the provider which will be retrieved using dependency injection. - /// - /// . - /// The factory that creates the service. - /// The supplied for chaining. -#endif public static LoggerProviderBuilder AddProcessor( this LoggerProviderBuilder loggerProviderBuilder, Func> implementationFactory) @@ -206,20 +138,11 @@ public static LoggerProviderBuilder AddProcessor( return loggerProviderBuilder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Run the given actions to initialize the . /// - /// /// . /// . -#else - /// - /// Run the given actions to initialize the . - /// - /// . - /// . -#endif public static LoggerProvider Build(this LoggerProviderBuilder loggerProviderBuilder) { if (loggerProviderBuilder is LoggerProviderBuilderBase loggerProviderBuilderBase) diff --git a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggerOptions.cs index 06b3478e548..921fd948ce0 100644 --- a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggerOptions.cs @@ -82,6 +82,7 @@ public class OpenTelemetryLoggerOptions /// /// Log processor to add. /// Returns for chaining. + // TODO: [Obsolete("Use LoggerProviderBuilder.AddProcessor instead this method will be removed in a future version.")] public OpenTelemetryLoggerOptions AddProcessor(BaseProcessor processor) { Guard.ThrowIfNull(processor); @@ -96,6 +97,7 @@ public OpenTelemetryLoggerOptions AddProcessor(BaseProcessor processo /// /// The factory that creates the service. /// Returns for chaining. + // TODO: [Obsolete("Use LoggerProviderBuilder.AddProcessor instead this method will be removed in a future version.")] public OpenTelemetryLoggerOptions AddProcessor( Func> implementationFactory) { @@ -112,6 +114,7 @@ public OpenTelemetryLoggerOptions AddProcessor( /// /// from which Resource will be built. /// Returns for chaining. + // TODO: [Obsolete("Use LoggerProviderBuilder.SetResourceBuilder instead this method will be removed in a future version.")] public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBuilder) { Guard.ThrowIfNull(resourceBuilder); diff --git a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs index 6fdf9244170..ba488b00df3 100644 --- a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs @@ -1,13 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; #if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; #endif -#if EXPOSE_EXPERIMENTAL_FEATURES -using System.ComponentModel; -#endif -using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; @@ -39,11 +36,10 @@ public static class OpenTelemetryLoggingExtensions /// /// The to use. /// The supplied for call chaining. -#if EXPOSE_EXPERIMENTAL_FEATURES - // todo: [Obsolete("Call UseOpenTelemetry instead this method will be removed in a future version.")] + /* TODO: // Note: We hide AddOpenTelemetry from IDEs using EditorBrowsable when UseOpenTelemetry is present to reduce confusion. [EditorBrowsable(EditorBrowsableState.Never)] -#endif + [Obsolete("Call UseOpenTelemetry instead this method will be removed in a future version.")] */ public static ILoggingBuilder AddOpenTelemetry( this ILoggingBuilder builder) => AddOpenTelemetryInternal(builder, configureBuilder: null, configureOptions: null); @@ -55,11 +51,10 @@ public static ILoggingBuilder AddOpenTelemetry( /// The to use. /// Optional configuration action. /// The supplied for call chaining. -#if EXPOSE_EXPERIMENTAL_FEATURES - // todo: [Obsolete("Call UseOpenTelemetry instead this method will be removed in a future version.")] + /* TODO: // Note: We hide AddOpenTelemetry from IDEs using EditorBrowsable when UseOpenTelemetry is present to reduce confusion. [EditorBrowsable(EditorBrowsableState.Never)] -#endif + [Obsolete("Call UseOpenTelemetry instead this method will be removed in a future version.")]*/ public static ILoggingBuilder AddOpenTelemetry( this ILoggingBuilder builder, Action? configure) @@ -70,7 +65,6 @@ public static ILoggingBuilder AddOpenTelemetry( /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the . /// /// - /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// Note: This is safe to be called multiple times and by library authors. /// Only a single will be created /// for a given . @@ -82,19 +76,9 @@ public static ILoggingBuilder AddOpenTelemetry( #endif public #else - /// - /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the . - /// - /// - /// Note: This is safe to be called multiple times and by library authors. - /// Only a single will be created - /// for a given . - /// - /// The to use. - /// The supplied for call chaining. internal #endif - static ILoggingBuilder UseOpenTelemetry( + static ILoggingBuilder UseOpenTelemetry( this ILoggingBuilder builder) => AddOpenTelemetryInternal(builder, configureBuilder: null, configureOptions: null); @@ -104,23 +88,16 @@ static ILoggingBuilder UseOpenTelemetry( /// /// /// The to use. - /// Optional configuration action. + /// configuration action. /// The supplied for call chaining. #if NET8_0_OR_GREATER [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public #else - /// - /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the . - /// - /// - /// The to use. - /// configuration action. - /// The supplied for call chaining. internal #endif - static ILoggingBuilder UseOpenTelemetry( + static ILoggingBuilder UseOpenTelemetry( this ILoggingBuilder builder, Action configure) { @@ -143,17 +120,9 @@ static ILoggingBuilder UseOpenTelemetry( #endif public #else - /// - /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the . - /// - /// - /// The to use. - /// Optional configuration action. - /// Optional configuration action. - /// The supplied for call chaining. internal #endif - static ILoggingBuilder UseOpenTelemetry( + static ILoggingBuilder UseOpenTelemetry( this ILoggingBuilder builder, Action? configureBuilder, Action? configureOptions) diff --git a/src/OpenTelemetry/Logs/LoggerProviderExtensions.cs b/src/OpenTelemetry/Logs/LoggerProviderExtensions.cs index 66dbac5ad42..f5d795fba2b 100644 --- a/src/OpenTelemetry/Logs/LoggerProviderExtensions.cs +++ b/src/OpenTelemetry/Logs/LoggerProviderExtensions.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using OpenTelemetry.Internal; namespace OpenTelemetry.Logs; @@ -11,22 +8,12 @@ namespace OpenTelemetry.Logs; /// /// Contains extension methods for the class. /// -#if EXPOSE_EXPERIMENTAL_FEATURES -#if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif -public -#else -internal -#endif - static class LoggerProviderExtensions +public static class LoggerProviderExtensions { -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Add a processor to the . /// /// - /// /// Note: The supplied will be /// automatically disposed when then the is disposed. @@ -34,19 +21,6 @@ static class LoggerProviderExtensions /// instance on which ForceFlush will be called. /// Log processor to add. /// The supplied for chaining. -#else - /// - /// Add a processor to the . - /// - /// - /// Note: The supplied will be - /// automatically disposed when then the is disposed. - /// - /// instance on which ForceFlush will be called. - /// Log processor to add. - /// The supplied for chaining. -#endif public static LoggerProvider AddProcessor(this LoggerProvider provider, BaseProcessor processor) { Guard.ThrowIfNull(provider); @@ -60,27 +34,6 @@ public static LoggerProvider AddProcessor(this LoggerProvider provider, BaseProc return provider; } -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Flushes all the processors registered under , blocks the current thread - /// until flush completed, shutdown signaled or timed out. - /// - /// instance on which ForceFlush will be called. - /// - /// The number (non-negative) of milliseconds to wait, or - /// Timeout.Infinite to wait indefinitely. - /// - /// - /// Returns true when force flush succeeded; otherwise, false. - /// - /// - /// Thrown when the timeoutMilliseconds is smaller than -1. - /// - /// - /// - /// This function guarantees thread-safety. - /// -#else /// /// Flushes all the processors registered under , blocks the current thread /// until flush completed, shutdown signaled or timed out. @@ -99,7 +52,6 @@ public static LoggerProvider AddProcessor(this LoggerProvider provider, BaseProc /// /// This function guarantees thread-safety. /// -#endif public static bool ForceFlush(this LoggerProvider provider, int timeoutMilliseconds = Timeout.Infinite) { Guard.ThrowIfNull(provider); @@ -113,28 +65,6 @@ public static bool ForceFlush(this LoggerProvider provider, int timeoutMilliseco return true; } -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Attempts to shutdown the , blocks the current thread until - /// shutdown completed or timed out. - /// - /// instance on which Shutdown will be called. - /// - /// The number (non-negative) of milliseconds to wait, or - /// Timeout.Infinite to wait indefinitely. - /// - /// - /// Returns true when shutdown succeeded; otherwise, false. - /// - /// - /// Thrown when the timeoutMilliseconds is smaller than -1. - /// - /// - /// - /// This function guarantees thread-safety. Only the first call will - /// win, subsequent calls will be no-op. - /// -#else /// /// Attempts to shutdown the , blocks the current thread until /// shutdown completed or timed out. @@ -154,7 +84,6 @@ public static bool ForceFlush(this LoggerProvider provider, int timeoutMilliseco /// This function guarantees thread-safety. Only the first call will /// win, subsequent calls will be no-op. /// -#endif public static bool Shutdown(this LoggerProvider provider, int timeoutMilliseconds = Timeout.Infinite) { Guard.ThrowIfNull(provider); diff --git a/src/OpenTelemetry/Logs/LoggerProviderSdk.cs b/src/OpenTelemetry/Logs/LoggerProviderSdk.cs index f3fc00fe8a1..9dd7297dfa8 100644 --- a/src/OpenTelemetry/Logs/LoggerProviderSdk.cs +++ b/src/OpenTelemetry/Logs/LoggerProviderSdk.cs @@ -194,7 +194,12 @@ public bool ContainsBatchProcessor(BaseProcessor processor) } /// - protected override bool TryCreateLogger( +#if EXPOSE_EXPERIMENTAL_FEATURES + protected +#else + internal +#endif + override bool TryCreateLogger( string? name, #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER [NotNullWhen(true)] diff --git a/src/OpenTelemetry/OpenTelemetryBuilderSdkExtensions.cs b/src/OpenTelemetry/OpenTelemetryBuilderSdkExtensions.cs index 4ae87d34078..c499ef02631 100644 --- a/src/OpenTelemetry/OpenTelemetryBuilderSdkExtensions.cs +++ b/src/OpenTelemetry/OpenTelemetryBuilderSdkExtensions.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.Logging; @@ -129,14 +126,11 @@ public static IOpenTelemetryBuilder WithTracing( return builder; } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds logging services into the builder. /// /// . /// - /// WARNING: This is an experimental API which might change or - /// be removed in the future. Use at your own risk. /// Notes: /// /// This is safe to be called multiple times and by library authors. @@ -149,48 +143,9 @@ public static IOpenTelemetryBuilder WithTracing( /// /// The supplied for chaining /// calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds logging services into the builder. - /// - /// . - /// - /// Notes: - /// - /// This is safe to be called multiple times and by library authors. - /// Only a single will be created for a given - /// . - /// This method automatically registers an named 'OpenTelemetry' into the . - /// - /// - /// The supplied for chaining - /// calls. - internal -#endif - static IOpenTelemetryBuilder WithLogging(this IOpenTelemetryBuilder builder) + public static IOpenTelemetryBuilder WithLogging(this IOpenTelemetryBuilder builder) => WithLogging(builder, configureBuilder: null, configureOptions: null); -#if EXPOSE_EXPERIMENTAL_FEATURES - /// - /// Adds logging services into the builder. - /// - /// - /// . - /// - /// configuration callback. - /// The supplied for chaining - /// calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else /// /// Adds logging services into the builder. /// @@ -200,18 +155,15 @@ static IOpenTelemetryBuilder WithLogging(this IOpenTelemetryBuilder builder) /// configuration callback. /// The supplied for chaining /// calls. - internal -#endif - static IOpenTelemetryBuilder WithLogging( - this IOpenTelemetryBuilder builder, - Action configure) + public static IOpenTelemetryBuilder WithLogging( + this IOpenTelemetryBuilder builder, + Action configure) { Guard.ThrowIfNull(configure); return WithLogging(builder, configureBuilder: configure, configureOptions: null); } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Adds logging services into the builder. /// @@ -220,31 +172,16 @@ static IOpenTelemetryBuilder WithLogging( /// Optional configuration callback. /// Optional configuration callback. + /// cref="OpenTelemetryLoggerOptions"/> configuration callback. are used by the named 'OpenTelemetry' automatically registered + /// by this method. /// The supplied for chaining /// calls. -#if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - /// - /// Adds logging services into the builder. - /// - /// - /// . - /// Optional configuration callback. - /// Optional configuration callback. - /// The supplied for chaining - /// calls. - internal -#endif - static IOpenTelemetryBuilder WithLogging( - this IOpenTelemetryBuilder builder, - Action? configureBuilder, - Action? configureOptions) + public static IOpenTelemetryBuilder WithLogging( + this IOpenTelemetryBuilder builder, + Action? configureBuilder, + Action? configureOptions) { builder.Services.AddLogging( logging => logging.UseOpenTelemetry(configureBuilder, configureOptions)); diff --git a/src/OpenTelemetry/Sdk.cs b/src/OpenTelemetry/Sdk.cs index 9dd0f2776e0..3a95120e3ef 100644 --- a/src/OpenTelemetry/Sdk.cs +++ b/src/OpenTelemetry/Sdk.cs @@ -90,7 +90,7 @@ public static TracerProviderBuilder CreateTracerProviderBuilder() /// instance, which is used /// to build a . #if NET8_0_OR_GREATER - [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] + [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public #else diff --git a/test/Benchmarks/Helper/LogRecordHelper.cs b/test/Benchmarks/Helper/LogRecordHelper.cs index 0cfd5efde25..f08e62527f5 100644 --- a/test/Benchmarks/Helper/LogRecordHelper.cs +++ b/test/Benchmarks/Helper/LogRecordHelper.cs @@ -12,9 +12,9 @@ internal static LogRecord CreateTestLogRecord() { var items = new List(1); using var factory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(loggerOptions => + .UseOpenTelemetry(logging => { - loggerOptions.AddInMemoryExporter(items); + logging.AddInMemoryExporter(items); })); var logger = factory.CreateLogger("TestLogger"); diff --git a/test/Benchmarks/Logs/LogBenchmarks.cs b/test/Benchmarks/Logs/LogBenchmarks.cs index ed1d637e7b8..1854eb26f2a 100644 --- a/test/Benchmarks/Logs/LogBenchmarks.cs +++ b/test/Benchmarks/Logs/LogBenchmarks.cs @@ -50,14 +50,14 @@ public LogBenchmarks() this.loggerFactoryWithOneProcessor = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => options + builder.UseOpenTelemetry(logging => logging .AddProcessor(new DummyLogProcessor())); }); this.loggerWithOneProcessor = this.loggerFactoryWithOneProcessor.CreateLogger(); this.loggerFactoryWithTwoProcessor = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => options + builder.UseOpenTelemetry(logging => logging .AddProcessor(new DummyLogProcessor()) .AddProcessor(new DummyLogProcessor())); }); @@ -65,7 +65,7 @@ public LogBenchmarks() this.loggerFactoryWithThreeProcessor = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => options + builder.UseOpenTelemetry(logging => logging .AddProcessor(new DummyLogProcessor()) .AddProcessor(new DummyLogProcessor()) .AddProcessor(new DummyLogProcessor())); diff --git a/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs b/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs index e26443707d2..24d343d98bd 100644 --- a/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs +++ b/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs @@ -62,7 +62,11 @@ private sealed class NoopLoggerProvider : LoggerProvider private sealed class TestLoggerProvider : LoggerProvider { +#if OPENTELEMETRY_API_EXPERIMENTAL_FEATURES_EXPOSED protected override bool TryCreateLogger( +#else + internal override bool TryCreateLogger( +#endif string? name, #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER [NotNullWhen(true)] diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs index 9fbe4b5703a..14b73571e35 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Diagnostics.Metrics; using System.Diagnostics.Tracing; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; using OpenTelemetry.Logs; @@ -235,7 +234,7 @@ public void LogExportResultIsSuccess(OtlpExportProtocol protocol, string endpoin using var loggerFactory = LoggerFactory.Create(builder => { builder - .AddOpenTelemetry(options => options + .UseOpenTelemetry(logging => logging .AddProcessor(sp => OtlpLogExporterHelperExtensions.BuildOtlpLogExporter( sp, diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index fd0ea958c28..f494a2683c6 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -3,7 +3,6 @@ using System.Collections.ObjectModel; using System.Diagnostics; -using System.Reflection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -111,46 +110,32 @@ public void UserHttpFactoryCalledWhenUsingHttpProtobuf() [Fact] public void AddOtlpExporterSetsDefaultBatchExportProcessor() { - var loggerProvider = Sdk.CreateLoggerProviderBuilder() + using var loggerProvider = Sdk.CreateLoggerProviderBuilder() .AddOtlpExporter() .Build(); - CheckProcessorDefaults(); - - loggerProvider.Dispose(); - - void CheckProcessorDefaults() - { - var bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic; - - var processor = typeof(BaseProcessor) - .Assembly - .GetType("OpenTelemetry.Logs.LoggerProviderSdk") - .GetProperty("Processor", bindingFlags) - .GetValue(loggerProvider) as BatchExportProcessor; + var loggerProviderSdk = loggerProvider as LoggerProviderSdk; + Assert.NotNull(loggerProviderSdk); - Assert.NotNull(processor); + var batchProcessor = loggerProviderSdk.Processor as BatchLogRecordExportProcessor; + Assert.NotNull(batchProcessor); - var scheduledDelayMilliseconds = typeof(BatchExportProcessor) - .GetField("scheduledDelayMilliseconds", bindingFlags) - .GetValue(processor); - - Assert.Equal(5000, scheduledDelayMilliseconds); - } + Assert.Equal(BatchLogRecordExportProcessor.DefaultScheduledDelayMilliseconds, batchProcessor.ScheduledDelayMilliseconds); + Assert.Equal(BatchLogRecordExportProcessor.DefaultExporterTimeoutMilliseconds, batchProcessor.ExporterTimeoutMilliseconds); + Assert.Equal(BatchLogRecordExportProcessor.DefaultMaxExportBatchSize, batchProcessor.MaxExportBatchSize); } - [Fact] - public void AddOtlpLogExporterReceivesAttributesWithParseStateValueSetToFalse() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void AddOtlpLogExporterReceivesAttributesWithParseStateValueSetToFalse(bool callUseOpenTelemetry) { bool optionsValidated = false; var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder - .AddOpenTelemetry(options => options - .AddInMemoryExporter(logRecords) - .AddOtlpExporter()); + ConfigureOtlpExporter(builder, callUseOpenTelemetry, logRecords: logRecords); builder.Services.Configure(o => { @@ -172,21 +157,20 @@ public void AddOtlpLogExporterReceivesAttributesWithParseStateValueSetToFalse() } [Theory] - [InlineData(true)] - [InlineData(false)] - public void AddOtlpLogExporterParseStateValueCanBeTurnedOff(bool parseState) + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(true, true)] + [InlineData(false, true)] + public void AddOtlpLogExporterParseStateValueCanBeTurnedOff(bool parseState, bool callUseOpenTelemetry) { var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder - .AddOpenTelemetry(options => - { - options.ParseStateValues = parseState; - options - .AddInMemoryExporter(logRecords) - .AddOtlpExporter(); - }); + ConfigureOtlpExporter( + builder, + callUseOpenTelemetry, + configureOptions: o => o.ParseStateValues = parseState, + logRecords: logRecords); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -215,17 +199,19 @@ public void AddOtlpLogExporterParseStateValueCanBeTurnedOff(bool parseState) } [Theory] - [InlineData(true)] - [InlineData(false)] - public void AddOtlpLogExporterParseStateValueCanBeTurnedOffHosting(bool parseState) + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(true, true)] + [InlineData(false, true)] + public void AddOtlpLogExporterParseStateValueCanBeTurnedOffHosting(bool parseState, bool callUseOpenTelemetry) { var logRecords = new List(); var hostBuilder = new HostBuilder(); - hostBuilder.ConfigureLogging(logging => logging - .AddOpenTelemetry(options => options - .AddInMemoryExporter(logRecords) - .AddOtlpExporter())); + hostBuilder.ConfigureLogging(logging => + { + ConfigureOtlpExporter(logging, callUseOpenTelemetry, logRecords: logRecords); + }); hostBuilder.ConfigureServices(services => services.Configure(options => options.ParseStateValues = parseState)); @@ -263,12 +249,13 @@ public void OtlpLogRecordTestWhenStateValuesArePopulated() var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeFormattedMessage = true; - options.ParseStateValues = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => + { + options.IncludeFormattedMessage = true; + options.ParseStateValues = true; + }); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -308,12 +295,13 @@ public void CheckToOtlpLogRecordEventId(string emitLogEventAttributes) var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeFormattedMessage = true; - options.ParseStateValues = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => + { + options.IncludeFormattedMessage = true; + options.ParseStateValues = true; + }); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -377,10 +365,7 @@ public void CheckToOtlpLogRecordTimestamps() var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry(logging => logging.AddInMemoryExporter(logRecords)); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -400,10 +385,7 @@ public void CheckToOtlpLogRecordTraceIdSpanIdFlagWithNoActivity() var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry(logging => logging.AddInMemoryExporter(logRecords)); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -426,10 +408,7 @@ public void CheckToOtlpLogRecordSpanIdTraceIdAndFlag() var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry(logging => logging.AddInMemoryExporter(logRecords)); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -466,12 +445,11 @@ public void CheckToOtlpLogRecordSeverityLevelAndText(LogLevel logLevel) var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.AddInMemoryExporter(logRecords); - options.IncludeFormattedMessage = true; - }) - .AddFilter("CheckToOtlpLogRecordSeverityLevelAndText", LogLevel.Trace); + builder + .UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeFormattedMessage = true) + .AddFilter("CheckToOtlpLogRecordSeverityLevelAndText", LogLevel.Trace); }); var logger = loggerFactory.CreateLogger("CheckToOtlpLogRecordSeverityLevelAndText"); @@ -519,12 +497,13 @@ public void CheckToOtlpLogRecordBodyIsPopulated(bool includeFormattedMessage) var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.AddInMemoryExporter(logRecords); - options.IncludeFormattedMessage = includeFormattedMessage; - options.ParseStateValues = true; - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => + { + options.IncludeFormattedMessage = includeFormattedMessage; + options.ParseStateValues = true; + }); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -642,10 +621,7 @@ public void CheckToOtlpLogRecordExceptionAttributes() var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry(logging => logging.AddInMemoryExporter(logRecords)); }); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); @@ -683,11 +659,9 @@ public void CheckToOtlpLogRecordRespectsAttributeLimits() var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.ParseStateValues = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.ParseStateValues = true); }); var logger = loggerFactory.CreateLogger(string.Empty); @@ -789,11 +763,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsFalse_DoesNotContainScopeAttribu var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = false; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = false); }); var logger = loggerFactory.CreateLogger("Some category"); @@ -826,11 +798,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeStrin var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -866,11 +836,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeBoolV var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -918,11 +886,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeIntVa var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -958,11 +924,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeDoubl var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -998,11 +962,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeDoubl var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1035,11 +997,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfTypeString var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1071,11 +1031,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfPrimitiveT var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1102,11 +1060,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfDictionary var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1141,11 +1097,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfEnumerable var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1180,11 +1134,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndMultipleScopesAreAdded_C var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1223,11 +1175,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndMultipleScopeLevelsAreAd var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1265,11 +1215,9 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeIsUsedInLogMethod_C var logRecords = new List(1); using var loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddInMemoryExporter(logRecords); - }); + builder.UseOpenTelemetry( + logging => logging.AddInMemoryExporter(logRecords), + options => options.IncludeScopes = true); }); var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); @@ -1303,56 +1251,66 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeIsUsedInLogMethod_C Assert.Contains(scopeValue2, allScopeValues); } - [Fact] - public void AddOtlpLogExporterDefaultOptionsTest() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void AddOtlpLogExporterDefaultOptionsTest(bool callUseOpenTelemetry) { - var options = new OpenTelemetryLoggerOptions(); - - options.AddOtlpExporter(); - - var provider = new OpenTelemetryLoggerProvider(new TestOptionsMonitor(options)); + var services = new ServiceCollection(); + services.AddLogging(builder => + { + ConfigureOtlpExporter(builder, callUseOpenTelemetry); + }); - var processor = GetProcessor(provider); + using var sp = services.BuildServiceProvider(); - Assert.NotNull(processor); + sp.GetRequiredService(); - var batchProcesor = processor as BatchLogRecordExportProcessor; + var provider = sp.GetRequiredService() as LoggerProviderSdk; + Assert.NotNull(provider); + var batchProcesor = provider.Processor as BatchLogRecordExportProcessor; Assert.NotNull(batchProcesor); - var batchProcessorType = typeof(BatchExportProcessor); - - Assert.Equal(5000, batchProcessorType.GetField("scheduledDelayMilliseconds", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(batchProcesor)); + Assert.Equal(BatchLogRecordExportProcessor.DefaultScheduledDelayMilliseconds, batchProcesor.ScheduledDelayMilliseconds); } [Theory] - [InlineData(ExportProcessorType.Simple)] - [InlineData(ExportProcessorType.Batch)] - public void AddOtlpLogExporterLogRecordProcessorOptionsTest(ExportProcessorType processorType) + [InlineData(ExportProcessorType.Simple, false)] + [InlineData(ExportProcessorType.Batch, false)] + [InlineData(ExportProcessorType.Simple, true)] + [InlineData(ExportProcessorType.Batch, true)] + public void AddOtlpLogExporterLogRecordProcessorOptionsTest(ExportProcessorType processorType, bool callUseOpenTelemetry) { - var options = new OpenTelemetryLoggerOptions(); - - options.AddOtlpExporter((o, l) => + var services = new ServiceCollection(); + services.AddLogging(builder => { - l.ExportProcessorType = processorType; - l.BatchExportProcessorOptions = new BatchExportLogRecordProcessorOptions() { ScheduledDelayMilliseconds = 1000 }; + ConfigureOtlpExporter( + builder, + callUseOpenTelemetry, + configureExporterAndProcessor: (e, p) => + { + p.ExportProcessorType = processorType; + p.BatchExportProcessorOptions = new BatchExportLogRecordProcessorOptions() { ScheduledDelayMilliseconds = 1000 }; + }); }); - var provider = new OpenTelemetryLoggerProvider(new TestOptionsMonitor(options)); + using var sp = services.BuildServiceProvider(); + + sp.GetRequiredService(); - var processor = GetProcessor(provider); + var provider = sp.GetRequiredService() as LoggerProviderSdk; + Assert.NotNull(provider); + var processor = provider.Processor; Assert.NotNull(processor); if (processorType == ExportProcessorType.Batch) { var batchProcesor = processor as BatchLogRecordExportProcessor; - Assert.NotNull(batchProcesor); - var batchProcessorType = typeof(BatchExportProcessor); - - Assert.Equal(1000, batchProcessorType.GetField("scheduledDelayMilliseconds", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(batchProcesor)); + Assert.Equal(1000, batchProcesor.ScheduledDelayMilliseconds); } else { @@ -1368,9 +1326,7 @@ public void ValidateInstrumentationScope() var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { - builder - .AddOpenTelemetry(options => options - .AddInMemoryExporter(logRecords)); + builder.UseOpenTelemetry(logging => logging.AddInMemoryExporter(logRecords)); }); var logger1 = loggerFactory.CreateLogger("OtlpLogExporterTests-A"); @@ -1421,9 +1377,11 @@ public void ValidateInstrumentationScope() } [Theory] - [InlineData(null)] - [InlineData("logging")] - public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFactoryCreate(string optionsName) + [InlineData(null, false)] + [InlineData("logging", false)] + [InlineData(null, true)] + [InlineData("logging", true)] + public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFactoryCreate(string optionsName, bool callUseOpenTelemetry) { RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( optionsName, @@ -1433,7 +1391,10 @@ public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFact { configure(logging.Services); - logging.AddOpenTelemetry(o => o.AddOtlpExporter(optionsName, configure: null)); + ConfigureOtlpExporter( + logging, + callUseOpenTelemetry, + name: optionsName); }); return (factory, factory); @@ -1441,9 +1402,11 @@ public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFact } [Theory] - [InlineData(null)] - [InlineData("logging")] - public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBuilder(string optionsName) + [InlineData(null, false)] + [InlineData("logging", false)] + [InlineData(null, true)] + [InlineData("logging", true)] + public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBuilder(string optionsName, bool callUseOpenTelemetry) { RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( optionsName, @@ -1454,8 +1417,10 @@ public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBui configure(services); services.AddLogging( - logging => logging.AddOpenTelemetry(o => - o.AddOtlpExporter(optionsName, configure: null))); + logging => ConfigureOtlpExporter( + logging, + callUseOpenTelemetry, + name: optionsName)); var sp = services.BuildServiceProvider(); @@ -1582,11 +1547,62 @@ private static OtlpCommon.KeyValue TryGetAttribute(OtlpLogs.LogRecord record, st return record.Attributes.FirstOrDefault(att => att.Key == key); } - private static BaseProcessor GetProcessor(OpenTelemetryLoggerProvider provider) + private static void ConfigureOtlpExporter( + ILoggingBuilder builder, + bool callUseOpenTelemetry, + string name = null, + Action configureExporter = null, + Action configureExporterAndProcessor = null, + Action configureOptions = null, + List logRecords = null) { - var sdkProvider = typeof(OpenTelemetryLoggerProvider).GetField("Provider", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(provider); + if (callUseOpenTelemetry) + { + builder.UseOpenTelemetry( + logging => + { + if (configureExporterAndProcessor != null) + { + logging.AddOtlpExporter(name, configureExporterAndProcessor); + } + else + { + logging.AddOtlpExporter(name, configureExporter); + } + + if (logRecords != null) + { + logging.AddInMemoryExporter(logRecords); + } + }, + options => + { + configureOptions?.Invoke(options); + }); + } + else + { +#pragma warning disable CS0618 // Type or member is obsolete + builder.AddOpenTelemetry(options => + { + configureOptions?.Invoke(options); + + if (configureExporterAndProcessor != null) + { + options.AddOtlpExporter(name, configureExporterAndProcessor); + } + else + { + options.AddOtlpExporter(name, configureExporter); + } - return (BaseProcessor)sdkProvider.GetType().GetProperty("Processor", BindingFlags.Instance | BindingFlags.Public).GetMethod.Invoke(sdkProvider, null); + if (logRecords != null) + { + options.AddInMemoryExporter(logRecords); + } + }); +#pragma warning restore CS0618 // Type or member is obsolete + } } private sealed class TestOptionsMonitor : IOptionsMonitor diff --git a/test/OpenTelemetry.Tests.Stress.Logs/Program.cs b/test/OpenTelemetry.Tests.Stress.Logs/Program.cs index dececdacb51..c8b640aea37 100644 --- a/test/OpenTelemetry.Tests.Stress.Logs/Program.cs +++ b/test/OpenTelemetry.Tests.Stress.Logs/Program.cs @@ -23,9 +23,9 @@ public LogsStressTest(StressTestOptions options) { this.loggerFactory = LoggerFactory.Create(builder => { - builder.AddOpenTelemetry(options => + builder.AddOpenTelemetry(logging => { - options.AddProcessor(new DummyProcessor()); + logging.AddProcessor(new DummyProcessor()); }); }); From 90871e01cbef2303dddccd990c12ef280ae6457e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 6 Jun 2024 15:02:20 -0700 Subject: [PATCH 013/133] [repo] Add packages to releases when created by automation (#5674) --- .github/workflows/publish-packages-1.0.yml | 14 +++++++++++++- build/scripts/post-release.psm1 | 7 ++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-packages-1.0.yml b/.github/workflows/publish-packages-1.0.yml index 7f78116bab4..553b8bbfc62 100644 --- a/.github/workflows/publish-packages-1.0.yml +++ b/.github/workflows/publish-packages-1.0.yml @@ -26,6 +26,7 @@ jobs: outputs: artifact-url: ${{ steps.upload-artifacts.outputs.artifact-url }} + artifact-id: ${{ steps.upload-artifacts.outputs.artifact-id }} steps: - uses: actions/checkout@v4 @@ -80,6 +81,16 @@ jobs: with: token: ${{ secrets[needs.automation.outputs.token-secret-name] }} + - name: Download Artifacts + run: | + curl \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: token ${{ github.token }}" \ + -L \ + -o '${{ github.workspace }}/artifacts/${{ github.ref_name }}-packages.zip' \ + --create-dirs \ + "https://api.github.com/repos/${{ github.repository }}/actions/artifacts/${{ needs.build-pack-publish.outputs.artifact-id }}/zip" + - name: Create GitHub Release draft shell: pwsh run: | @@ -87,7 +98,8 @@ jobs: CreateDraftRelease ` -gitRepository '${{ github.repository }}' ` - -tag '${{ github.ref_name }}' + -tag '${{ github.ref_name }}' ` + -releaseFiles '${{ github.workspace }}/artifacts/${{ github.ref_name }}-packages.zip#Packages' - name: Post notice when packages are ready shell: pwsh diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index ca6ea1cc158..51010213cd5 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -1,7 +1,8 @@ function CreateDraftRelease { param( [Parameter(Mandatory=$true)][string]$gitRepository, - [Parameter(Mandatory=$true)][string]$tag + [Parameter(Mandatory=$true)][string]$tag, + [Parameter()][string]$releaseFiles ) $match = [regex]::Match($tag, '^(.*?-)(.*)$') @@ -74,7 +75,7 @@ $content if ($version -match '-alpha' -or $version -match '-beta' -or $version -match '-rc') { - gh release create $tag ` + gh release create $tag $releaseFiles ` --title $tag ` --verify-tag ` --notes $notes ` @@ -83,7 +84,7 @@ $content } else { - gh release create $tag ` + gh release create $tag $releaseFiles ` --title $tag ` --verify-tag ` --notes $notes ` From 84cd83ad5334435f004260798d7d78c3aa3c9661 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 7 Jun 2024 11:12:22 -0700 Subject: [PATCH 014/133] [repo] NuGet push release automation (#5675) --- .github/workflows/post-release.yml | 54 ++++++++++- .github/workflows/prepare-release.yml | 3 +- .github/workflows/publish-packages-1.0.yml | 4 +- build/RELEASING.md | 107 +++++++++++++-------- build/scripts/post-release.psm1 | 84 ++++++++++++++++ build/scripts/prepare-release.psm1 | 4 +- 6 files changed, 205 insertions(+), 51 deletions(-) diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml index 6f26e1058a3..42c2ce11db7 100644 --- a/.github/workflows/post-release.yml +++ b/.github/workflows/post-release.yml @@ -7,21 +7,69 @@ on: required: true description: 'Release tag' type: string + release: - types: [published] + types: + - published + + issue_comment: + types: + - created jobs: automation: uses: ./.github/workflows/automation.yml secrets: inherit - post-release: + push-packages-and-publish-release: + runs-on: ubuntu-latest + + needs: automation + + if: | + github.event_name == 'issue_comment' + && github.event.issue.pull_request + && github.event.issue.locked == true + && github.event.comment.user.login != needs.automation.outputs.username + && contains(github.event.comment.body, '/PushPackages') + && startsWith(github.event.issue.title, '[repo] Prepare release ') + && github.event.issue.pull_request.merged_at + && needs.automation.outputs.enabled + + env: + GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} + + steps: + - name: check out code + uses: actions/checkout@v4 + with: + token: ${{ secrets[needs.automation.outputs.token-secret-name] }} + ref: ${{ github.event.repository.default_branch }} + + - name: Push packages and publish release + shell: pwsh + env: + NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} + run: | + Import-Module .\build\scripts\post-release.psm1 + + PushPackagesPublishReleaseUnlockAndPostNoticeOnPrepareReleasePullRequest ` + -gitRepository '${{ github.repository }}' ` + -pullRequestNumber '${{ github.event.issue.number }}' ` + -botUserName '${{ needs.automation.outputs.username }}' ` + -commentUserName '${{ github.event.comment.user.login }}' ` + -artifactDownloadPath '${{ github.workspace }}/artifacts' ` + -pushToNuget '${{ secrets.NUGET_TOKEN != '' }}' + + post-release-published: runs-on: ubuntu-latest needs: - automation - if: needs.automation.outputs.enabled + if: | + needs.automation.outputs.enabled + && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') env: GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 087081efbb1..1225f098e96 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -89,7 +89,7 @@ jobs: -pullRequestNumber '${{ github.event.pull_request.number }}' ` -botUserName '${{ needs.automation.outputs.username }}' - create-release-tag-unlock-pr-post-notice: + create-release-tag-pr-post-notice: runs-on: ubuntu-latest needs: automation @@ -127,3 +127,4 @@ jobs: -botUserName '${{ needs.automation.outputs.username }}' ` -gitUserName '${{ needs.automation.outputs.username }}' ` -gitUserEmail '${{ needs.automation.outputs.email }}' + diff --git a/.github/workflows/publish-packages-1.0.yml b/.github/workflows/publish-packages-1.0.yml index 553b8bbfc62..7553bd66627 100644 --- a/.github/workflows/publish-packages-1.0.yml +++ b/.github/workflows/publish-packages-1.0.yml @@ -53,7 +53,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: ${{ github.ref_name }}-packages - path: '**/bin/**/*.*nupkg' + path: 'src/**/*.*nupkg' - name: Publish MyGet env: @@ -61,7 +61,7 @@ jobs: if: env.MYGET_TOKEN_EXISTS == 'true' # Skip MyGet publish if run on a fork without the secret run: | nuget setApiKey ${{ secrets.MYGET_TOKEN }} -Source https://www.myget.org/F/opentelemetry/api/v2/package - nuget push **/bin/**/*.nupkg -Source https://www.myget.org/F/opentelemetry/api/v2/package + nuget push src/**/*.nupkg -Source https://www.myget.org/F/opentelemetry/api/v2/package post-build: runs-on: ubuntu-latest diff --git a/build/RELEASING.md b/build/RELEASING.md index d25f13b1355..f9075727bd6 100644 --- a/build/RELEASING.md +++ b/build/RELEASING.md @@ -1,6 +1,7 @@ # Release process -**Only for Maintainers.** +**Note: Approvers (collaborators) can perform much of the release process but +Maintainers (admins) are needed to merge PRs and for the push to NuGet.** 1. Decide the component(s) and tag name (version name) to be released. We use [MinVer](https://github.com/adamralph/minver) to do versioning, which @@ -40,15 +41,13 @@ * `OpenTelemetry.Shims.OpenTracing` - Defined by spec (stable but incomplete implementation) - * As of the `1.9.0` release cycle instrumentation packages and core - unstable packages always depend on the stable versions of core - packages. Before releasing a non-core component ensure the - `OTelLatestStableVer` property in `Directory.Packages.props` has been - updated to the latest stable core version. + * As of the `1.9.0` release cycle core unstable packages always depend on + the stable versions of core packages. Before releasing a non-core + component ensure the `OTelLatestStableVer` property in + `Directory.Packages.props` has been updated to the latest stable core + version. - 2. Prepare for release - - Run the [Prepare for a + 2. Run the [Prepare for a release](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/prepare-release.yml) workflow. Specify the `tag-prefix` and the `version` for the release. Make sure to run the workflow on the branch being released. This is typically @@ -91,11 +90,10 @@ comment and lock the PR. Post a comment with "/CreateReleaseTag" in the body. This will tell the [Prepare for a release](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/prepare-release.yml) - workflow to push the tag for the merge commit of the PR and to call the - [Build, pack, and publish to + workflow to push the tag for the merge commit of the PR which will trigger + the [Build, pack, and publish to MyGet](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/publish-packages-1.0.yml) - workflow. Once packages are available a comment will be posted on the PR - opened in step 2 with a link to the artifacts. + workflow.
Instructions for pushing tags manually @@ -127,51 +125,76 @@ 5. :stop_sign: Wait for the [Build, pack, and publish to MyGet](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/publish-packages-1.0.yml) - workflow to complete. + workflow to complete. When complete a trigger will automatically add a + comment on the PR opened by [Prepare for a + release](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/prepare-release.yml) + workflow in step 2. Use MyGet or download the packages using the provided + link to validate locally everything works. After validation has been + performed have a maintainer post a comment with "/PushPackages" in the body. + This will trigger the [Complete + release](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/prepare-release.yml) + workflow to push the packages to NuGet and publish the draft release created + by the [Build, pack, and publish to + MyGet](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/publish-packages-1.0.yml) + workflow. Comments will automatically be added on the PR opened by [Prepare + for a + release](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/prepare-release.yml) + workflow in step 2 as the process is run and the PR will be unlocked. - 6. Validate locally everything works using the MyGet packages pushed from the - release. Basic sanity checks :) +
+ Instructions for pushing packages to NuGet manually - 7. Download the artifacts from the drop attached to the workflow run. The - artifacts archive (`.zip`) contains all the NuGet packages (`.nupkg`) and - symbols (`.snupkg`) from the build which were pushed to MyGet. + 1. The [Build, pack, and publish to + MyGet](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/publish-packages-1.0.yml) + workflow pushes the packages to MyGet and attaches them as artifacts on + the workflow run. - 8. Extract the artifacts from the archive (`.zip`) into a local folder. + 2. Validate locally everything works using the packages pushed to MyGet or + downloaded from the drop attached to the workflow run. Basic sanity + checks :) - 9. Download latest [nuget.exe](https://www.nuget.org/downloads) into the same - folder from Step 8. + 3. Download the artifacts from the drop attached to the workflow run. The + artifacts archive (`.zip`) contains all the NuGet packages (`.nupkg`) and + symbols (`.snupkg`) from the build which were pushed to MyGet. -10. Create or regenerate an API key from nuget.org (only maintainers have - access). When creating API keys make sure it is set to expire in 1 day or - less. + 4. Extract the artifacts from the archive (`.zip`) into a local folder. -11. Run the following commands from PowerShell from local folder used in Step 8: + 5. Download latest [nuget.exe](https://www.nuget.org/downloads) into the + same folder from step 4. - ```powershell - .\nuget.exe setApiKey + 6. Create or regenerate an API key from nuget.org (only maintainers have + access). When creating API keys make sure it is set to expire in 1 day or + less. - get-childitem -Recurse | where {$_.extension -eq ".nupkg"} | foreach ($_) {.\nuget.exe push $_.fullname -Source https://api.nuget.org/v3/index.json} - ``` + 7. Run the following commands from PowerShell from local folder used in step + 4: -12. Validate that the package(s) are uploaded. Packages are available - immediately to maintainers on nuget.org but aren't publicly visible until - scanning completes. This process usually takes a few minutes. + ```powershell + .\nuget.exe setApiKey -13. Open the - [Releases](https://github.com/open-telemetry/opentelemetry-dotnet/releases) - page on the GitHub repository. The [Build, pack, and publish to - MyGet](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/publish-packages-1.0.yml) - workflow creates a draft release for the tag which was pushed. Edit the - draft Release and click `Publish release`. + get-childitem -Recurse | where {$_.extension -eq ".nupkg"} | foreach ($_) {.\nuget.exe push $_.fullname -Source https://api.nuget.org/v3/index.json} + ``` + + 8. Validate that the package(s) are uploaded. Packages are available + immediately to maintainers on nuget.org but aren't publicly visible until + scanning completes. This process usually takes a few minutes. + + 9. Open the + [Releases](https://github.com/open-telemetry/opentelemetry-dotnet/releases) + page on the GitHub repository. The [Build, pack, and publish to + MyGet](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/publish-packages-1.0.yml) + workflow creates a draft release for the tag which was pushed. Edit the + draft Release and click `Publish release`. +
-14. If a new stable version of the core packages was released, a PR should have + 6. If a new stable version of the core packages was released, a PR should have been automatically created by the [Complete release](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/post-release.yml) workflow to update the `OTelLatestStableVer` property in `Directory.Packages.props` to the just released stable version. Merge that PR once the build passes (this requires the packages be available on NuGet). -15. The [Complete + 7. The [Complete release](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/post-release.yml) workflow should have invoked the [Core version update](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/core-version-update.yml) @@ -180,6 +203,6 @@ repository which opens a PR to update dependencies. Verify this PR was opened successfully. -16. Post an announcement in the [Slack + 8. Post an announcement in the [Slack channel](https://cloud-native.slack.com/archives/C01N3BC2W7Q). Note any big or interesting new features as part of the announcement. diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index 51010213cd5..fc72bc208a9 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -137,6 +137,8 @@ function TryPostPackagesReadyNoticeOnPrepareReleasePullRequest { $body = @" The packages for [$tag](https://github.com/$gitRepository/releases/tag/$tag) are now available: $packagesUrl. + +Once these packages have been validated have a maintainer post a comment with "/PushPackages" in the body if you would like me to push to NuGet. "@ $pullRequestNumber = $pr.number @@ -150,6 +152,88 @@ The packages for [$tag](https://github.com/$gitRepository/releases/tag/$tag) are Export-ModuleMember -Function TryPostPackagesReadyNoticeOnPrepareReleasePullRequest +function PushPackagesPublishReleaseUnlockAndPostNoticeOnPrepareReleasePullRequest { + param( + [Parameter(Mandatory=$true)][string]$gitRepository, + [Parameter(Mandatory=$true)][string]$pullRequestNumber, + [Parameter(Mandatory=$true)][string]$botUserName, + [Parameter(Mandatory=$true)][string]$commentUserName, + [Parameter(Mandatory=$true)][string]$artifactDownloadPath, + [Parameter(Mandatory=$true)][string]$pushToNuget + ) + + $prViewResponse = gh pr view $pullRequestNumber --json author,title,comments | ConvertFrom-Json + + if ($prViewResponse.author.login -ne $botUserName) + { + throw 'PR author was unexpected' + } + + $match = [regex]::Match($prViewResponse.title, '^\[repo\] Prepare release (.*)$') + if ($match.Success -eq $false) + { + throw 'Could not parse tag from PR title' + } + + $tag = $match.Groups[1].Value + + $commentUserPermission = gh api "repos/$gitRepository/collaborators/$commentUserName/permission" | ConvertFrom-Json + if ($commentUserPermission.permission -ne 'admin') + { + gh pr comment $pullRequestNumber ` + --body "I'm sorry @$commentUserName but you don't have permission to push packages. Only maintainers can push to NuGet." + return + } + + $foundComment = $false + $packagesUrl = '' + foreach ($comment in $prViewResponse.comments) + { + if ($comment.author.login -eq $botUserName -and $comment.body.StartsWith("The packages for [$tag](https://github.com/$gitRepository/releases/tag/$tag) are now available:")) + { + $foundComment = $true + break + } + } + + if ($foundComment -eq $false) + { + throw 'Could not find package push comment on pr' + } + + gh release download $tag ` + -p "$tag-packages.zip" ` + -D "$artifactDownloadPath" + + Expand-Archive -LiteralPath "$artifactDownloadPath/$tag-packages.zip" -DestinationPath "$artifactDownloadPath\" + + if ($pushToNuget -eq 'true') + { + gh pr comment $pullRequestNumber ` + --body "I am uploading the packages for ``$tag`` to NuGet and then I will publish the release." + + nuget push "$artifactDownloadPath/**/*.nupkg" -Source https://api.nuget.org/v3/index.json -ApiKey "$env.NUGET_TOKEN" -SymbolApiKey "$env.NUGET_TOKEN" + + if ($LASTEXITCODE -gt 0) + { + gh pr comment $pullRequestNumber ` + --body "Something went wrong uploading the packages for ``$tag`` to NuGet." + + throw 'nuget push failure' + } + } + else { + gh pr comment $pullRequestNumber ` + --body "I am publishing the release without uploading the packages to NuGet because a token wasn't configured." + } + + gh release edit $tag --draft=false + + gh pr unlock $pullRequestNumber +} + +Export-ModuleMember -Function PushPackagesPublishReleaseUnlockAndPostNoticeOnPrepareReleasePullRequest + function CreateStableVersionUpdatePullRequest { param( [Parameter(Mandatory=$true)][string]$gitRepository, diff --git a/build/scripts/prepare-release.psm1 b/build/scripts/prepare-release.psm1 index 78a87549808..bc7809eb9e7 100644 --- a/build/scripts/prepare-release.psm1 +++ b/build/scripts/prepare-release.psm1 @@ -100,7 +100,7 @@ function LockPullRequestAndPostNoticeToCreateReleaseTag { @" I noticed this PR was merged. -Post a comment with "/CreateReleaseTag" in the body if you would like me to create the release tag ``$tag`` for [the merge commit](https://github.com/$gitRepository/commit/$commit) and then trigger the package workflow. +Post a comment with "/CreateReleaseTag" in the body if you would like me to create the release tag ``$tag`` for [the merge commit](https://github.com/$gitRepository/commit/$commit) which will trigger the package workflow. "@ gh pr comment $pullRequestNumber --body $body @@ -161,8 +161,6 @@ function CreateReleaseTagAndPostNoticeOnPullRequest { throw 'git push failure' } - gh pr unlock $pullRequestNumber - $body = @" I just pushed the [$tag](https://github.com/$gitRepository/releases/tag/$tag) tag. From 357f0a2d79e71b0b2c76a2790ff54ba04484d440 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:03:04 +0200 Subject: [PATCH 015/133] [repo] Prepare release core-1.9.0-rc.1 (#5679) --- src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Api/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.Console/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md | 4 ++++ src/OpenTelemetry/CHANGELOG.md | 4 ++++ 9 files changed, 36 insertions(+) diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md index 9d22648cde4..47b77fc0db0 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + * The experimental APIs previously covered by `OTEL1000` (`LoggerProviderBuilder` `AddInstrumentation` & `ConfigureServices` extensions and `IServiceCollection.ConfigureOpenTelemetryLoggerProvider` extension) will diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index e340f5d5b22..3139700ac14 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + * The experimental APIs previously covered by `OTEL1000` (`LoggerProvider`, `LoggerProviderBuilder`, & `IDeferredLoggerProviderBuilder`) will now be part of the public API and supported in stable builds. diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index f6a7ebb48b8..44d0bb78a77 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + * The experimental APIs previously covered by `OTEL1000` (`LoggerProviderBuilder.AddConsoleExporter` extension) will now be part of the public API and supported in stable builds. diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md index 8b932042281..15094116015 100644 --- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + * The experimental APIs previously covered by `OTEL1000` (`LoggerProviderBuilder.AddInMemoryExporter` extension) will now be part of the public API and supported in stable builds. diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 4c2d56a7243..bc54ca54de9 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + * The experimental APIs previously covered by `OTEL1000` (`LoggerProviderBuilder.AddOtlpExporter` extension) will now be part of the public API and supported in stable builds. diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index 15dcc2f3396..97999e013e0 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index 3bcc96de580..013bc9014d5 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + * The experimental APIs previously covered by `OTEL1000` (`OpenTelemetryBuilder.WithLogging` method) will now be part of the public API and supported in stable builds. diff --git a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md index 68d9cd7747f..345fd621fec 100644 --- a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + ## 1.9.0-alpha.1 Released 2024-May-20 diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 5f11580af07..a5a637f8236 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-07 + * The experimental APIs previously covered by `OTEL1000` (`LoggerProviderBuilder` `AddProcessor` & `ConfigureResource` extensions, and `LoggerProvider` `ForceFlush` & `Shutdown` extensions) will now be part of the From fd18bb134c7933f90648d904dec9796936875e0c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 7 Jun 2024 13:28:44 -0700 Subject: [PATCH 016/133] [repo] Fix a couple issues in automation workflows/scripts (#5680) --- .github/workflows/automation.yml | 2 +- build/scripts/post-release.psm1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/automation.yml b/.github/workflows/automation.yml index e85a3720aba..1385474892a 100644 --- a/.github/workflows/automation.yml +++ b/.github/workflows/automation.yml @@ -13,7 +13,7 @@ on: value: ${{ vars.AUTOMATION_EMAIL }} secrets: OPENTELEMETRYBOT_GITHUB_TOKEN: - required: true + required: false jobs: resolve-automation: diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index fc72bc208a9..fa141ba0d80 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -212,7 +212,7 @@ function PushPackagesPublishReleaseUnlockAndPostNoticeOnPrepareReleasePullReques gh pr comment $pullRequestNumber ` --body "I am uploading the packages for ``$tag`` to NuGet and then I will publish the release." - nuget push "$artifactDownloadPath/**/*.nupkg" -Source https://api.nuget.org/v3/index.json -ApiKey "$env.NUGET_TOKEN" -SymbolApiKey "$env.NUGET_TOKEN" + nuget push "$artifactDownloadPath/**/*.nupkg" -Source https://api.nuget.org/v3/index.json -ApiKey "$env:NUGET_TOKEN" -SymbolApiKey "$env:NUGET_TOKEN" if ($LASTEXITCODE -gt 0) { From a763c0dbfc8b21319a6b3e644b74856c6772a0ee Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 10 Jun 2024 09:02:41 -0700 Subject: [PATCH 017/133] [repo] Auto label pull requests (#5681) --- .github/workflows/add-labels.yml | 42 ++++++-- .github/workflows/post-release.yml | 2 +- .github/workflows/prepare-release.yml | 4 +- OpenTelemetry.sln | 2 +- build/scripts/add-labels.ps1 | 12 --- build/scripts/add-labels.psm1 | 148 ++++++++++++++++++++++++++ build/scripts/post-release.psm1 | 10 +- build/scripts/prepare-release.psm1 | 8 +- 8 files changed, 196 insertions(+), 32 deletions(-) delete mode 100644 build/scripts/add-labels.ps1 create mode 100644 build/scripts/add-labels.psm1 diff --git a/.github/workflows/add-labels.yml b/.github/workflows/add-labels.yml index 3566af9ec83..e0452a5631c 100644 --- a/.github/workflows/add-labels.yml +++ b/.github/workflows/add-labels.yml @@ -1,25 +1,53 @@ -name: 'Add labels for area found in bug issue descriptions' +name: 'Add labels to issues and pull requests' on: issues: - types: [opened] + types: [ opened ] + + pull_request: + branches: [ 'main*' ] permissions: issues: write + pull-requests: write jobs: - add-labels: - if: ${{ !github.event.issue.pull_request }} + add-labels-on-issues: + if: github.event_name == 'issues' && !github.event.issue.pull_request runs-on: ubuntu-latest + steps: - name: check out code uses: actions/checkout@v4 - - name: Add labels for areas found in bug issue descriptions + - name: Add labels for package found in bug issue descriptions shell: pwsh run: | - .\build\scripts\add-labels.ps1 -issueNumber $env:ISSUE_NUMBER -issueBody $env:ISSUE_BODY + Import-Module .\build\scripts\add-labels.psm1 + + AddLabelsOnIssuesForPackageFoundInBody ` + -issueNumber ${{ github.event.issue.number }} ` + -issueBody $env:ISSUE_BODY env: GH_TOKEN: ${{ github.token }} - ISSUE_NUMBER: ${{ github.event.issue.number }} ISSUE_BODY: ${{ github.event.issue.body }} + + add-labels-on-pull-requests: + if: github.event_name == 'pull_request' + + runs-on: ubuntu-latest + + steps: + - name: check out code + uses: actions/checkout@v4 + + - name: Add labels for files changed on pull requests + shell: pwsh + run: | + Import-Module .\build\scripts\add-labels.psm1 + + AddLabelsOnPullRequestsBasedOnFilesChanged ` + -pullRequestNumber ${{ github.event.pull_request.number }} ` + -labelPackagePrefix 'pkg:' + env: + GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml index 42c2ce11db7..e824e87d724 100644 --- a/.github/workflows/post-release.yml +++ b/.github/workflows/post-release.yml @@ -32,7 +32,7 @@ jobs: && github.event.issue.locked == true && github.event.comment.user.login != needs.automation.outputs.username && contains(github.event.comment.body, '/PushPackages') - && startsWith(github.event.issue.title, '[repo] Prepare release ') + && startsWith(github.event.issue.title, '[release] Prepare release ') && github.event.issue.pull_request.merged_at && needs.automation.outputs.enabled diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 1225f098e96..bd8211e645e 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -67,7 +67,7 @@ jobs: && github.event.action == 'closed' && github.event.pull_request.user.login == needs.automation.outputs.username && github.event.pull_request.merged == true - && startsWith(github.event.pull_request.title, '[repo] Prepare release ') + && startsWith(github.event.pull_request.title, '[release] Prepare release ') && needs.automation.outputs.enabled env: @@ -100,7 +100,7 @@ jobs: && github.event.issue.locked == true && github.event.comment.user.login != needs.automation.outputs.username && contains(github.event.comment.body, '/CreateReleaseTag') - && startsWith(github.event.issue.title, '[repo] Prepare release ') + && startsWith(github.event.issue.title, '[release] Prepare release ') && github.event.issue.pull_request.merged_at && needs.automation.outputs.enabled diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index d7d059b58cb..61963889e01 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -328,7 +328,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TagWriter", "TagWriter", "{ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{44982E0D-C8C6-42DC-9F8F-714981F27CE6}" ProjectSection(SolutionItems) = preProject - build\scripts\add-labels.ps1 = build\scripts\add-labels.ps1 + build\scripts\add-labels.psm1 = build\scripts\add-labels.psm1 build\scripts\finalize-publicapi.ps1 = build\scripts\finalize-publicapi.ps1 build\scripts\post-release.psm1 = build\scripts\post-release.psm1 build\scripts\prepare-release.psm1 = build\scripts\prepare-release.psm1 diff --git a/build/scripts/add-labels.ps1 b/build/scripts/add-labels.ps1 deleted file mode 100644 index 9b91ad9df87..00000000000 --- a/build/scripts/add-labels.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -param( - [Parameter(Mandatory=$true)][int]$issueNumber, - [Parameter(Mandatory=$true)][string]$issueBody -) - -$match = [regex]::Match($issueBody, '^[#]+ Package\s*(OpenTelemetry(?:\.\w+)*)') -if ($match.Success -eq $false) -{ - Return -} - -gh issue edit $issueNumber --add-label $("pkg:" + $match.Groups[1].Value) diff --git a/build/scripts/add-labels.psm1 b/build/scripts/add-labels.psm1 new file mode 100644 index 00000000000..ee82ae2ebf1 --- /dev/null +++ b/build/scripts/add-labels.psm1 @@ -0,0 +1,148 @@ +function AddLabelsOnIssuesForPackageFoundInBody { + param( + [Parameter(Mandatory=$true)][int]$issueNumber, + [Parameter(Mandatory=$true)][string]$issueBody + ) + + $match = [regex]::Match($issueBody, '^[#]+ Package\s*(OpenTelemetry(?:\.\w+)*)') + if ($match.Success -eq $false) + { + Return + } + + gh issue edit $issueNumber --add-label $("pkg:" + $match.Groups[1].Value) +} + +Export-ModuleMember -Function AddLabelsOnIssuesForPackageFoundInBody + +function AddLabelsOnPullRequestsBasedOnFilesChanged { + param( + [Parameter(Mandatory=$true)][int]$pullRequestNumber, + [Parameter(Mandatory=$true)][string]$labelPackagePrefix # 'pkg:' on main repo, 'comp:' on contrib repo + ) + + # Note: This function is intended to work on main repo and on contrib. Please + # keep them in sync. + + $repoLabels = gh label list --json name,id | ConvertFrom-Json + + $filesChangedOnPullRequest = gh pr diff $pullRequestNumber --name-only + + $labelsOnPullRequest = (gh pr view $pullRequestNumber --json labels | ConvertFrom-Json).labels + + $visitedProjects = New-Object System.Collections.Generic.HashSet[string] + $labelsToAdd = New-Object System.Collections.Generic.HashSet[string] + $labelsToRemove = New-Object System.Collections.Generic.HashSet[string] + + # Note: perf label may be added but it is kind of a guess so we don't remove + # it automatically in order to also allow manual inclusion after reviewing files + $managedLabels = 'infra', 'documentation', 'dependencies' + $rootInfraFiles = 'global.json', 'NuGet.config', 'codeowners' + $documentationFiles = 'readme.md', 'contributing.md', 'releasing.md', 'versioning.md' + + foreach ($fileChanged in $filesChangedOnPullRequest) + { + $fileChanged = $fileChanged.ToLower() + $fullFileName = [System.IO.Path]::GetFileName($fileChanged) + $fileName = [System.IO.Path]::GetFileNameWithoutExtension($fileChanged) + $fileExtension = [System.IO.Path]::GetExtension($fileChanged) + + if ($fileChanged.StartsWith('src/') -or $fileChanged.StartsWith('test/')) + { + $match = [regex]::Match($fileChanged, '^(?:(?:src)|(?:test))\/(.*?)\/.+$') + if ($match.Success -eq $false) + { + continue + } + $rawProjectName = $match.Groups[1].Value + if ($rawProjectName.Contains(".benchmarks") -or $rawProjectName.Contains(".stress")) + { + $added = $labelsToAdd.Add("perf") + } + + $projectName = $rawProjectName.Replace(".tests", "").Replace(".benchmarks", "").Replace(".stress", "") + if ($visitedProjects.Contains($projectName)) + { + continue + } + + $added = $visitedProjects.Add($projectName); + + foreach ($repoLabel in $repoLabels) + { + if ($repoLabel.name.StartsWith($labelPackagePrefix)) + { + $package = $repoLabel.name.Substring($labelPackagePrefix.Length).ToLower() + if ($package.StartsWith('opentelemetry') -eq $false) + { + # Note: On contrib labels don't have "OpenTelemetry." prefix + $package = 'opentelemetry.' + $package + } + if ($package -eq $projectName) + { + $added = $labelsToAdd.Add($repoLabel.name) + break + } + } + } + } + + if ($documentationFiles.Contains($fullFileName) -or + $fileChanged.StartsWith('docs/') -or + $fileChanged.StartsWith('examples/')) + { + $added = $labelsToAdd.Add("documentation") + } + + if ($fileChanged.StartsWith('build/') -or + $fileChanged.StartsWith('.github/') -or + $rootInfraFiles.Contains($fullFileName) -or + $fileExtension -eq ".props" -or + $fileExtension -eq ".targets" -or + $fileChanged.StartsWith('test\openTelemetry.aotcompatibility')) + { + $added = $labelsToAdd.Add("infra") + } + + if ($fileChanged.StartsWith('test\benchmarks')) + { + $added = $labelsToAdd.Add("perf") + } + + if ($fullFileName -eq 'directory.packages.props') + { + $added = $labelsToAdd.Add("dependencies") + } + } + + foreach ($labelOnPullRequest in $labelsOnPullRequest) + { + if ($labelsToAdd.Contains($labelOnPullRequest.name)) + { + $removed = $labelsToAdd.Remove($labelOnPullRequest.name) + } + elseif ($labelOnPullRequest.name.StartsWith($labelPackagePrefix) -or + $managedLabels.Contains($labelOnPullRequest.name)) + { + $added = $labelsToRemove.Add($labelOnPullRequest.name) + } + } + + if ($labelsToAdd.Count -gt 0) + { + foreach ($label in $labelsToAdd) + { + gh pr edit $pullRequestNumber --add-label $label + } + } + + if ($labelsToRemove.Count -gt 0) + { + foreach ($label in $labelsToRemove) + { + gh pr edit $pullRequestNumber --remove-label $label + } + } +} + +Export-ModuleMember -Function AddLabelsOnPullRequestsBasedOnFilesChanged diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index fa141ba0d80..57f0f341c8f 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -114,7 +114,7 @@ function TryPostPackagesReadyNoticeOnPrepareReleasePullRequest { foreach ($pr in $prListResponse) { - if ($pr.author.login -ne $botUserName -or $pr.title -ne "[repo] Prepare release $tag") + if ($pr.author.login -ne $botUserName -or $pr.title -ne "[release] Prepare release $tag") { continue } @@ -169,7 +169,7 @@ function PushPackagesPublishReleaseUnlockAndPostNoticeOnPrepareReleasePullReques throw 'PR author was unexpected' } - $match = [regex]::Match($prViewResponse.title, '^\[repo\] Prepare release (.*)$') + $match = [regex]::Match($prViewResponse.title, '^\[release\] Prepare release (.*)$') if ($match.Success -eq $false) { throw 'Could not parse tag from PR title' @@ -302,11 +302,11 @@ Merge once packages are available on NuGet and the build passes. "@ gh pr create ` - --title "[repo] Core stable release $packageVersion updates" ` + --title "[release] Core stable release $packageVersion updates" ` --body $body ` --base $targetBranch ` --head $branch ` - --label infra + --label release } Export-ModuleMember -Function CreateStableVersionUpdatePullRequest @@ -355,7 +355,7 @@ function TryPostReleasePublishedNoticeOnPrepareReleasePullRequest { foreach ($pr in $prListResponse) { - if ($pr.author.login -ne $botUserName -or $pr.title -ne "[repo] Prepare release $tag") + if ($pr.author.login -ne $botUserName -or $pr.title -ne "[release] Prepare release $tag") { continue } diff --git a/build/scripts/prepare-release.psm1 b/build/scripts/prepare-release.psm1 index bc7809eb9e7..88e6f7ad11f 100644 --- a/build/scripts/prepare-release.psm1 +++ b/build/scripts/prepare-release.psm1 @@ -59,11 +59,11 @@ Note: This PR was opened automatically by the [prepare release workflow](https:/ } gh pr create ` - --title "[repo] Prepare release $tag" ` + --title "[release] Prepare release $tag" ` --body $body ` --base $targetBranch ` --head $branch ` - --label infra + --label release } Export-ModuleMember -Function CreatePullRequestToUpdateChangelogsAndPublicApis @@ -82,7 +82,7 @@ function LockPullRequestAndPostNoticeToCreateReleaseTag { throw 'PR author was unexpected' } - $match = [regex]::Match($prViewResponse.title, '^\[repo\] Prepare release (.*)$') + $match = [regex]::Match($prViewResponse.title, '^\[release\] Prepare release (.*)$') if ($match.Success -eq $false) { throw 'Could not parse tag from PR title' @@ -126,7 +126,7 @@ function CreateReleaseTagAndPostNoticeOnPullRequest { throw 'PR author was unexpected' } - $match = [regex]::Match($prViewResponse.title, '^\[repo\] Prepare release (.*)$') + $match = [regex]::Match($prViewResponse.title, '^\[release\] Prepare release (.*)$') if ($match.Success -eq $false) { throw 'Could not parse tag from PR title' From 23fb65112926e56e3b37bdedc097da418e807c56 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:17:16 +0000 Subject: [PATCH 018/133] [repo] Replace Logging Exporter with Debug Exporter in otel-collector configs (#5685) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- examples/AspNetCore/otel-collector.yaml | 10 +++++----- examples/Console/otlp-collector-example/config.yaml | 8 ++++---- .../IntegrationTest/otel-collector-config.yaml | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/AspNetCore/otel-collector.yaml b/examples/AspNetCore/otel-collector.yaml index bcf0cb5d6d2..15df605c542 100644 --- a/examples/AspNetCore/otel-collector.yaml +++ b/examples/AspNetCore/otel-collector.yaml @@ -5,8 +5,8 @@ receivers: http: exporters: - logging: - loglevel: debug + debug: + verbosity: detailed prometheus: endpoint: ":9201" send_timestamps: true @@ -21,10 +21,10 @@ service: pipelines: traces: receivers: [otlp] - exporters: [logging,otlp] + exporters: [debug, otlp] metrics: receivers: [otlp] - exporters: [logging,prometheus] + exporters: [debug, prometheus] logs: receivers: [otlp] - exporters: [logging] + exporters: [debug] diff --git a/examples/Console/otlp-collector-example/config.yaml b/examples/Console/otlp-collector-example/config.yaml index 932f24a193d..8d0584b61fa 100644 --- a/examples/Console/otlp-collector-example/config.yaml +++ b/examples/Console/otlp-collector-example/config.yaml @@ -11,17 +11,17 @@ receivers: http: exporters: - logging: + debug: verbosity: detailed service: pipelines: traces: receivers: [otlp] - exporters: [logging] + exporters: [debug] metrics: receivers: [otlp] - exporters: [logging] + exporters: [debug] logs: receivers: [otlp] - exporters: [logging] + exporters: [debug] diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/otel-collector-config.yaml b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/otel-collector-config.yaml index 477de40fe74..f479ebe4ad8 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/otel-collector-config.yaml +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/otel-collector-config.yaml @@ -25,17 +25,17 @@ receivers: key_file: /cfg/otel-collector.key exporters: - logging: + debug: verbosity: detailed service: pipelines: traces: receivers: [otlp, otlp/tls] - exporters: [logging] + exporters: [debug] metrics: receivers: [otlp, otlp/tls] - exporters: [logging] + exporters: [debug] logs: receivers: [otlp, otlp/tls] - exporters: [logging] + exporters: [debug] From 48ce500ae58711217735c248bf45659aeb12dd4d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 11 Jun 2024 10:28:12 -0700 Subject: [PATCH 019/133] [repo] Auto label PR workflow permissions fix (#5684) --- .github/workflows/add-labels.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/add-labels.yml b/.github/workflows/add-labels.yml index e0452a5631c..cae26b876b4 100644 --- a/.github/workflows/add-labels.yml +++ b/.github/workflows/add-labels.yml @@ -3,7 +3,7 @@ on: issues: types: [ opened ] - pull_request: + pull_request_target: branches: [ 'main*' ] permissions: @@ -33,13 +33,15 @@ jobs: ISSUE_BODY: ${{ github.event.issue.body }} add-labels-on-pull-requests: - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - name: check out code uses: actions/checkout@v4 + with: + ref: ${{ github.event.repository.default_branch }} # Note: Do not run on the PR branch we want to execute add-labels.psm1 from main on the base repo only because pull_request_target can see secrets - name: Add labels for files changed on pull requests shell: pwsh From 28824f805c92d79b0ed6d0b6cdc7cfaf47cb276f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 12 Jun 2024 18:44:29 +0200 Subject: [PATCH 020/133] [repo] Bump tests and examples dependencies (#5688) --- Directory.Packages.props | 28 ++++++++----------- .../SuppressInstrumentationTest.cs | 2 +- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 6469f47b892..032d5eb04a2 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -70,7 +70,7 @@ --> - + @@ -81,35 +81,29 @@ - + - + - - + + - - - + + + - - - + - - - + - - - + diff --git a/test/OpenTelemetry.Tests/SuppressInstrumentationTest.cs b/test/OpenTelemetry.Tests/SuppressInstrumentationTest.cs index d562699fec8..d6ccb414ddf 100644 --- a/test/OpenTelemetry.Tests/SuppressInstrumentationTest.cs +++ b/test/OpenTelemetry.Tests/SuppressInstrumentationTest.cs @@ -51,7 +51,7 @@ public void SuppressInstrumentationBeginTest(bool? shouldBegin) } [Fact] - public async void SuppressInstrumentationScopeEnterIsLocalToAsyncFlow() + public async Task SuppressInstrumentationScopeEnterIsLocalToAsyncFlow() { Assert.False(Sdk.SuppressInstrumentation); From dc390a6a7d14dd8ba9a97ee43884566de19b1010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ach?= Date: Wed, 12 Jun 2024 19:01:04 +0200 Subject: [PATCH 021/133] [api-baggage] revert space encoding change (#5687) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Api/CHANGELOG.md | 4 ++++ .../Context/Propagation/BaggagePropagator.cs | 7 ++++--- .../Trace/Propagation/BaggagePropagatorTest.cs | 17 ++++------------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 3139700ac14..5394fdf705e 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* **Breaking change:** Revert space character encoding change from `+` to `%20` + for baggage item values from [#5303](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5303) + ([#5687](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5687)) + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs index e9dc29d950d..57bdb453b8f 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Net; using System.Text; using OpenTelemetry.Internal; @@ -93,7 +94,7 @@ public override void Inject(PropagationContext context, T carrier, Action> { new KeyValuePair(BaggagePropagator.BaggageHeaderName, initialBaggage), @@ -144,11 +142,11 @@ public void ValidateSpecialCharsBaggageExtraction() Assert.False(propagationContext == default); Assert.True(propagationContext.ActivityContext == default); - Assert.Equal(4, propagationContext.Baggage.Count); + Assert.Equal(3, propagationContext.Baggage.Count); var actualBaggage = propagationContext.Baggage.GetBaggage(); - Assert.Equal(4, actualBaggage.Count); + Assert.Equal(3, actualBaggage.Count); Assert.True(actualBaggage.ContainsKey("key 1")); Assert.Equal("value 1", actualBaggage["key 1"]); @@ -158,10 +156,6 @@ public void ValidateSpecialCharsBaggageExtraction() Assert.True(actualBaggage.ContainsKey("key()3")); Assert.Equal("value()!&;:", actualBaggage["key()3"]); - - // x20-x7E range - Assert.True(actualBaggage.ContainsKey("key4")); - Assert.Equal(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", actualBaggage["key4"]); } [Fact] @@ -201,14 +195,11 @@ public void ValidateSpecialCharsBaggageInjection() { { "key 1", "value 1" }, { "key2", "!x_x,x-x&x(x\");:" }, - - // x20-x7E range - { "key3", " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" }, })); this.baggage.Inject(propagationContext, carrier, Setter); Assert.Single(carrier); - Assert.Equal("key%201=value%201,key2=%21x_x%2Cx-x%26x%28x%22%29%3B%3A,key3=%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~", carrier[BaggagePropagator.BaggageHeaderName]); + Assert.Equal("key+1=value+1,key2=!x_x%2Cx-x%26x(x%22)%3B%3A", carrier[BaggagePropagator.BaggageHeaderName]); } } From 26a4414a21266ccb07f83a3e29fcb07798124e43 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 14 Jun 2024 12:23:43 -0700 Subject: [PATCH 022/133] [repo] Auto-label PR workflow improvements (#5693) --- build/scripts/add-labels.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/add-labels.psm1 b/build/scripts/add-labels.psm1 index ee82ae2ebf1..60c07bc4637 100644 --- a/build/scripts/add-labels.psm1 +++ b/build/scripts/add-labels.psm1 @@ -24,7 +24,7 @@ function AddLabelsOnPullRequestsBasedOnFilesChanged { # Note: This function is intended to work on main repo and on contrib. Please # keep them in sync. - $repoLabels = gh label list --json name,id | ConvertFrom-Json + $repoLabels = gh label list --json name,id -L 200 | ConvertFrom-Json $filesChangedOnPullRequest = gh pr diff $pullRequestNumber --name-only From df260790f0a9bc35c7c4842fbc44d93e9a6d182c Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 14 Jun 2024 21:43:54 +0200 Subject: [PATCH 023/133] [release] Prepare release core-1.9.0 (#5694) --- .../.publicApi/Stable/PublicAPI.Shipped.txt | 13 ++++- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 9 ---- .../CHANGELOG.md | 4 ++ .../.publicApi/Stable/PublicAPI.Shipped.txt | 15 ++++-- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 7 --- src/OpenTelemetry.Api/CHANGELOG.md | 4 ++ .../.publicApi/Stable/PublicAPI.Shipped.txt | 9 ++-- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 3 -- .../CHANGELOG.md | 4 ++ .../.publicApi/Stable/PublicAPI.Shipped.txt | 5 +- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 1 - .../CHANGELOG.md | 4 ++ .../.publicApi/Stable/PublicAPI.Shipped.txt | 13 +++-- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 5 -- .../CHANGELOG.md | 4 ++ .../.publicApi/PublicAPI.Shipped.txt | 2 +- .../CHANGELOG.md | 4 ++ .../.publicApi/Stable/PublicAPI.Shipped.txt | 3 ++ .../.publicApi/Stable/PublicAPI.Unshipped.txt | 3 -- .../CHANGELOG.md | 4 ++ .../CHANGELOG.md | 4 ++ .../.publicApi/Stable/PublicAPI.Shipped.txt | 54 ++++++++++++++++--- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 42 --------------- src/OpenTelemetry/CHANGELOG.md | 4 ++ 24 files changed, 128 insertions(+), 92 deletions(-) diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Shipped.txt index ca48e185f6d..8c11dafee83 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Shipped.txt @@ -1,21 +1,30 @@ #nullable enable OpenTelemetry.IOpenTelemetryBuilder OpenTelemetry.IOpenTelemetryBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions +OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMetricsServiceCollectionExtensions OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracingServiceCollectionExtensions -static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, T! instrumentation) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, T! instrumentation) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMetricsServiceCollectionExtensions.ConfigureOpenTelemetryMeterProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static OpenTelemetry.Metrics.OpenTelemetryDependencyInjectionMetricsServiceCollectionExtensions.ConfigureOpenTelemetryMeterProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, T! instrumentation) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracingServiceCollectionExtensions.ConfigureOpenTelemetryTracerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracingServiceCollectionExtensions.ConfigureOpenTelemetryTracerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt index a0f2e472dd6..e69de29bb2d 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,9 +0,0 @@ -OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions -OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, T! instrumentation) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Logs.OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.ConfigureOpenTelemetryLoggerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md index 47b77fc0db0..fecd873f3a7 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt index a87bb701214..7b02ca885de 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt @@ -52,6 +52,7 @@ ~static OpenTelemetry.Context.RuntimeContext.SetValue(string slotName, T value) -> void abstract OpenTelemetry.Context.RuntimeContextSlot.Get() -> T abstract OpenTelemetry.Context.RuntimeContextSlot.Set(T value) -> void +abstract OpenTelemetry.Logs.LoggerProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! abstract OpenTelemetry.Metrics.MeterProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! abstract OpenTelemetry.Metrics.MeterProviderBuilder.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! abstract OpenTelemetry.Trace.TracerProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! @@ -90,6 +91,12 @@ OpenTelemetry.Context.RuntimeContext OpenTelemetry.Context.RuntimeContextSlot OpenTelemetry.Context.RuntimeContextSlot.Dispose() -> void OpenTelemetry.Context.ThreadLocalRuntimeContextSlot +OpenTelemetry.Logs.IDeferredLoggerProviderBuilder +OpenTelemetry.Logs.IDeferredLoggerProviderBuilder.Configure(System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +OpenTelemetry.Logs.LoggerProvider +OpenTelemetry.Logs.LoggerProvider.LoggerProvider() -> void +OpenTelemetry.Logs.LoggerProviderBuilder +OpenTelemetry.Logs.LoggerProviderBuilder.LoggerProviderBuilder() -> void OpenTelemetry.Metrics.IDeferredMeterProviderBuilder OpenTelemetry.Metrics.IDeferredMeterProviderBuilder.Configure(System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! OpenTelemetry.Metrics.MeterProvider @@ -104,8 +111,8 @@ OpenTelemetry.Trace.Link.Attributes.get -> System.Collections.Generic.IEnumerabl OpenTelemetry.Trace.Link.Context.get -> OpenTelemetry.Trace.SpanContext OpenTelemetry.Trace.Link.Equals(OpenTelemetry.Trace.Link other) -> bool OpenTelemetry.Trace.Link.Link() -> void -OpenTelemetry.Trace.Link.Link(in OpenTelemetry.Trace.SpanContext spanContext) -> void OpenTelemetry.Trace.Link.Link(in OpenTelemetry.Trace.SpanContext spanContext, OpenTelemetry.Trace.SpanAttributes? attributes) -> void +OpenTelemetry.Trace.Link.Link(in OpenTelemetry.Trace.SpanContext spanContext) -> void OpenTelemetry.Trace.SpanAttributes OpenTelemetry.Trace.SpanAttributes.Add(string! key, bool value) -> void OpenTelemetry.Trace.SpanAttributes.Add(string! key, bool[]? values) -> void @@ -145,10 +152,10 @@ OpenTelemetry.Trace.StatusCode.Error = 2 -> OpenTelemetry.Trace.StatusCode OpenTelemetry.Trace.StatusCode.Ok = 1 -> OpenTelemetry.Trace.StatusCode OpenTelemetry.Trace.StatusCode.Unset = 0 -> OpenTelemetry.Trace.StatusCode OpenTelemetry.Trace.TelemetrySpan -OpenTelemetry.Trace.TelemetrySpan.AddEvent(string! name) -> OpenTelemetry.Trace.TelemetrySpan! OpenTelemetry.Trace.TelemetrySpan.AddEvent(string! name, OpenTelemetry.Trace.SpanAttributes? attributes) -> OpenTelemetry.Trace.TelemetrySpan! -OpenTelemetry.Trace.TelemetrySpan.AddEvent(string! name, System.DateTimeOffset timestamp) -> OpenTelemetry.Trace.TelemetrySpan! OpenTelemetry.Trace.TelemetrySpan.AddEvent(string! name, System.DateTimeOffset timestamp, OpenTelemetry.Trace.SpanAttributes? attributes) -> OpenTelemetry.Trace.TelemetrySpan! +OpenTelemetry.Trace.TelemetrySpan.AddEvent(string! name, System.DateTimeOffset timestamp) -> OpenTelemetry.Trace.TelemetrySpan! +OpenTelemetry.Trace.TelemetrySpan.AddEvent(string! name) -> OpenTelemetry.Trace.TelemetrySpan! OpenTelemetry.Trace.TelemetrySpan.Context.get -> OpenTelemetry.Trace.SpanContext OpenTelemetry.Trace.TelemetrySpan.Dispose() -> void OpenTelemetry.Trace.TelemetrySpan.End() -> void @@ -202,8 +209,8 @@ static OpenTelemetry.Baggage.operator ==(OpenTelemetry.Baggage left, OpenTelemet static OpenTelemetry.Context.Propagation.PropagationContext.operator !=(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator ==(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool static OpenTelemetry.Trace.ActivityExtensions.GetStatus(this System.Diagnostics.Activity! activity) -> OpenTelemetry.Trace.Status -static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity! activity, System.Exception? ex) -> void static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity! activity, System.Exception? ex, in System.Diagnostics.TagList tags) -> void +static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity! activity, System.Exception? ex) -> void static OpenTelemetry.Trace.ActivityExtensions.SetStatus(this System.Diagnostics.Activity! activity, OpenTelemetry.Trace.Status status) -> void static OpenTelemetry.Trace.Link.operator !=(OpenTelemetry.Trace.Link link1, OpenTelemetry.Trace.Link link2) -> bool static OpenTelemetry.Trace.Link.operator ==(OpenTelemetry.Trace.Link link1, OpenTelemetry.Trace.Link link2) -> bool diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt index d50e30cadb4..e69de29bb2d 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,7 +0,0 @@ -abstract OpenTelemetry.Logs.LoggerProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -OpenTelemetry.Logs.IDeferredLoggerProviderBuilder -OpenTelemetry.Logs.IDeferredLoggerProviderBuilder.Configure(System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -OpenTelemetry.Logs.LoggerProvider -OpenTelemetry.Logs.LoggerProvider.LoggerProvider() -> void -OpenTelemetry.Logs.LoggerProviderBuilder -OpenTelemetry.Logs.LoggerProviderBuilder.LoggerProviderBuilder() -> void diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 5394fdf705e..f39d81b108e 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + * **Breaking change:** Revert space character encoding change from `+` to `%20` for baggage item values from [#5303](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5303) ([#5687](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5687)) diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt index 6f900a1f6f6..0e45009bac8 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt @@ -21,13 +21,16 @@ override OpenTelemetry.Exporter.ConsoleActivityExporter.Export(in OpenTelemetry. override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Dispose(bool disposing) -> void override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.ConsoleMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, string name, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt index be114835ccd..e69de29bb2d 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,3 +0,0 @@ -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, string name, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index 44d0bb78a77..9e94df266e8 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt index 499065e2d09..a79ca4f2cf5 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt @@ -14,11 +14,12 @@ OpenTelemetry.Metrics.MetricSnapshot.Unit.get -> string OpenTelemetry.Trace.InMemoryExporterHelperExtensions override OpenTelemetry.Exporter.InMemoryExporter.Dispose(bool disposing) -> void override OpenTelemetry.Exporter.InMemoryExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Logs.LoggerProviderBuilder static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Trace.InMemoryExporterHelperExtensions.AddInMemoryExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt index f7378ee36cc..e69de29bb2d 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1 +0,0 @@ -static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Logs.LoggerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md index 15094116015..fc2a00afb3c 100644 --- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Shipped.txt index 2fd5a429424..94c328771df 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Shipped.txt @@ -33,18 +33,23 @@ OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions override OpenTelemetry.Exporter.OtlpLogExporter.Export(in OpenTelemetry.Batch logRecordBatch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.OtlpMetricExporter.OnShutdown(int timeoutMilliseconds) -> bool override OpenTelemetry.Exporter.OtlpTraceExporter.OnShutdown(int timeoutMilliseconds) -> bool -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, string? name, System.Action? configureExporterAndProcessor) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action! configureExporterAndProcessor) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.OpenTelemetryBuilderOtlpExporterExtensions.UseOtlpExporter(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.OpenTelemetryBuilderOtlpExporterExtensions.UseOtlpExporter(this OpenTelemetry.IOpenTelemetryBuilder! builder, OpenTelemetry.Exporter.OtlpExportProtocol protocol, System.Uri! baseUrl) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.OpenTelemetryBuilderOtlpExporterExtensions.UseOtlpExporter(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt index e6bd747c9de..e69de29bb2d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,5 +0,0 @@ -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporterAndProcessor) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index bc54ca54de9..e8866580e55 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt index 9e2e613e196..5d94b912d2d 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt @@ -16,6 +16,6 @@ OpenTelemetry.Exporter.ZipkinExporterOptions.UseShortTraceIds.set -> void OpenTelemetry.Exporter.ZipkinExporterOptions.ZipkinExporterOptions() -> void OpenTelemetry.Trace.ZipkinExporterHelperExtensions override OpenTelemetry.Exporter.ZipkinExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index 97999e013e0..28869770365 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Shipped.txt index b0f847bf1ea..57bce9162b8 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Shipped.txt @@ -3,6 +3,9 @@ Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions OpenTelemetry.OpenTelemetryBuilder OpenTelemetry.OpenTelemetryBuilder.ConfigureResource(System.Action! configure) -> OpenTelemetry.OpenTelemetryBuilder! OpenTelemetry.OpenTelemetryBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +OpenTelemetry.OpenTelemetryBuilder.WithLogging() -> OpenTelemetry.OpenTelemetryBuilder! +OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action! configure) -> OpenTelemetry.OpenTelemetryBuilder! +OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.OpenTelemetryBuilder! OpenTelemetry.OpenTelemetryBuilder.WithMetrics() -> OpenTelemetry.OpenTelemetryBuilder! OpenTelemetry.OpenTelemetryBuilder.WithMetrics(System.Action! configure) -> OpenTelemetry.OpenTelemetryBuilder! OpenTelemetry.OpenTelemetryBuilder.WithTracing() -> OpenTelemetry.OpenTelemetryBuilder! diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt index f83d7ca4a0f..e69de29bb2d 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,3 +0,0 @@ -OpenTelemetry.OpenTelemetryBuilder.WithLogging() -> OpenTelemetry.OpenTelemetryBuilder! -OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action! configure) -> OpenTelemetry.OpenTelemetryBuilder! -OpenTelemetry.OpenTelemetryBuilder.WithLogging(System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.OpenTelemetryBuilder! diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index 013bc9014d5..0b9b1a1c9fe 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md index 345fd621fec..10b287b0dc3 100644 --- a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 diff --git a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Shipped.txt index 6a4426d4ce6..43e084ad586 100644 --- a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Shipped.txt @@ -56,6 +56,8 @@ OpenTelemetry.ExportResult.Failure = 1 -> OpenTelemetry.ExportResult OpenTelemetry.ExportResult.Success = 0 -> OpenTelemetry.ExportResult OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void +OpenTelemetry.Logs.LoggerProviderBuilderExtensions +OpenTelemetry.Logs.LoggerProviderExtensions OpenTelemetry.Logs.LogRecord OpenTelemetry.Logs.LogRecord.Attributes.get -> System.Collections.Generic.IReadOnlyList>? OpenTelemetry.Logs.LogRecord.Attributes.set -> void @@ -129,6 +131,18 @@ OpenTelemetry.Metrics.Base2ExponentialBucketHistogramConfiguration.MaxSize.set - OpenTelemetry.Metrics.BaseExportingMetricReader OpenTelemetry.Metrics.BaseExportingMetricReader.BaseExportingMetricReader(OpenTelemetry.BaseExporter! exporter) -> void OpenTelemetry.Metrics.BaseExportingMetricReader.SupportedExportModes.get -> OpenTelemetry.Metrics.ExportModes +OpenTelemetry.Metrics.Exemplar +OpenTelemetry.Metrics.Exemplar.DoubleValue.get -> double +OpenTelemetry.Metrics.Exemplar.Exemplar() -> void +OpenTelemetry.Metrics.Exemplar.FilteredTags.get -> OpenTelemetry.ReadOnlyFilteredTagCollection +OpenTelemetry.Metrics.Exemplar.LongValue.get -> long +OpenTelemetry.Metrics.Exemplar.SpanId.get -> System.Diagnostics.ActivitySpanId +OpenTelemetry.Metrics.Exemplar.Timestamp.get -> System.DateTimeOffset +OpenTelemetry.Metrics.Exemplar.TraceId.get -> System.Diagnostics.ActivityTraceId +OpenTelemetry.Metrics.ExemplarFilterType +OpenTelemetry.Metrics.ExemplarFilterType.AlwaysOff = 0 -> OpenTelemetry.Metrics.ExemplarFilterType +OpenTelemetry.Metrics.ExemplarFilterType.AlwaysOn = 1 -> OpenTelemetry.Metrics.ExemplarFilterType +OpenTelemetry.Metrics.ExemplarFilterType.TraceBased = 2 -> OpenTelemetry.Metrics.ExemplarFilterType OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.get -> double[]? OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void @@ -195,6 +209,7 @@ OpenTelemetry.Metrics.MetricPoint.GetSumLong() -> long OpenTelemetry.Metrics.MetricPoint.MetricPoint() -> void OpenTelemetry.Metrics.MetricPoint.StartTime.get -> System.DateTimeOffset OpenTelemetry.Metrics.MetricPoint.Tags.get -> OpenTelemetry.ReadOnlyTagCollection +OpenTelemetry.Metrics.MetricPoint.TryGetExemplars(out OpenTelemetry.Metrics.ReadOnlyExemplarCollection exemplars) -> bool OpenTelemetry.Metrics.MetricPoint.TryGetHistogramMinMaxValues(out double min, out double max) -> bool OpenTelemetry.Metrics.MetricPointsAccessor OpenTelemetry.Metrics.MetricPointsAccessor.Enumerator @@ -245,8 +260,22 @@ OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportIntervalMillise OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportTimeoutMilliseconds.get -> int? OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.ExportTimeoutMilliseconds.set -> void OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions.PeriodicExportingMetricReaderOptions() -> void +OpenTelemetry.Metrics.ReadOnlyExemplarCollection +OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator +OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator.Current.get -> OpenTelemetry.Metrics.Exemplar +OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator.Enumerator() -> void +OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator.MoveNext() -> bool +OpenTelemetry.Metrics.ReadOnlyExemplarCollection.GetEnumerator() -> OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator +OpenTelemetry.Metrics.ReadOnlyExemplarCollection.ReadOnlyExemplarCollection() -> void OpenTelemetry.OpenTelemetryBuilderSdkExtensions OpenTelemetry.ProviderExtensions +OpenTelemetry.ReadOnlyFilteredTagCollection +OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator +OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair +OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.Enumerator() -> void +OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.MoveNext() -> bool +OpenTelemetry.ReadOnlyFilteredTagCollection.GetEnumerator() -> OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator +OpenTelemetry.ReadOnlyFilteredTagCollection.ReadOnlyFilteredTagCollection() -> void OpenTelemetry.ReadOnlyTagCollection OpenTelemetry.ReadOnlyTagCollection.Count.get -> int OpenTelemetry.ReadOnlyTagCollection.Enumerator @@ -289,8 +318,8 @@ OpenTelemetry.Trace.AlwaysOnSampler.AlwaysOnSampler() -> void OpenTelemetry.Trace.BatchExportActivityProcessorOptions OpenTelemetry.Trace.BatchExportActivityProcessorOptions.BatchExportActivityProcessorOptions() -> void OpenTelemetry.Trace.ParentBasedSampler -OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler! rootSampler) -> void OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler! rootSampler, OpenTelemetry.Trace.Sampler? remoteParentSampled = null, OpenTelemetry.Trace.Sampler? remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler? localParentSampled = null, OpenTelemetry.Trace.Sampler? localParentNotSampled = null) -> void +OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler! rootSampler) -> void OpenTelemetry.Trace.Sampler OpenTelemetry.Trace.Sampler.Description.get -> string! OpenTelemetry.Trace.Sampler.Description.set -> void @@ -314,10 +343,10 @@ OpenTelemetry.Trace.SamplingResult.Decision.get -> OpenTelemetry.Trace.SamplingD OpenTelemetry.Trace.SamplingResult.Equals(OpenTelemetry.Trace.SamplingResult other) -> bool OpenTelemetry.Trace.SamplingResult.SamplingResult() -> void OpenTelemetry.Trace.SamplingResult.SamplingResult(bool isSampled) -> void -OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision) -> void OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string? traceStateString) -> void -OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable>? attributes) -> void OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable>? attributes, string? traceStateString) -> void +OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable>? attributes) -> void +OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision) -> void OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string? OpenTelemetry.Trace.TraceIdRatioBasedSampler OpenTelemetry.Trace.TraceIdRatioBasedSampler.TraceIdRatioBasedSampler(double probability) -> void @@ -366,8 +395,17 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter! -static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func!>! implementationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.Build(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProvider! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.LoggerProviderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProvider! provider, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProvider! +static OpenTelemetry.Logs.LoggerProviderExtensions.ForceFlush(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool +static OpenTelemetry.Logs.LoggerProviderExtensions.Shutdown(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! implementationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! @@ -376,6 +414,7 @@ static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTel static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetExemplarFilter(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.ExemplarFilterType exemplarFilter) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! @@ -388,10 +427,13 @@ static OpenTelemetry.Metrics.MetricTypeExtensions.IsHistogram(this OpenTelemetry static OpenTelemetry.Metrics.MetricTypeExtensions.IsLong(this OpenTelemetry.Metrics.MetricType self) -> bool static OpenTelemetry.Metrics.MetricTypeExtensions.IsSum(this OpenTelemetry.Metrics.MetricType self) -> bool static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.ConfigureResource(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithMetrics(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithMetrics(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithTracing(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithMetrics(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithTracing(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithTracing(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! static OpenTelemetry.ProviderExtensions.GetDefaultResource(this OpenTelemetry.BaseProvider! baseProvider) -> OpenTelemetry.Resources.Resource! static OpenTelemetry.ProviderExtensions.GetResource(this OpenTelemetry.BaseProvider! baseProvider) -> OpenTelemetry.Resources.Resource! static OpenTelemetry.Resources.Resource.Empty.get -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt index 4ebd84b69d9..e69de29bb2d 100644 --- a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,42 +0,0 @@ -OpenTelemetry.Logs.LoggerProviderBuilderExtensions -OpenTelemetry.Logs.LoggerProviderExtensions -OpenTelemetry.Metrics.Exemplar -OpenTelemetry.Metrics.Exemplar.DoubleValue.get -> double -OpenTelemetry.Metrics.Exemplar.Exemplar() -> void -OpenTelemetry.Metrics.Exemplar.FilteredTags.get -> OpenTelemetry.ReadOnlyFilteredTagCollection -OpenTelemetry.Metrics.Exemplar.LongValue.get -> long -OpenTelemetry.Metrics.Exemplar.SpanId.get -> System.Diagnostics.ActivitySpanId -OpenTelemetry.Metrics.Exemplar.Timestamp.get -> System.DateTimeOffset -OpenTelemetry.Metrics.Exemplar.TraceId.get -> System.Diagnostics.ActivityTraceId -OpenTelemetry.Metrics.ExemplarFilterType -OpenTelemetry.Metrics.ExemplarFilterType.AlwaysOff = 0 -> OpenTelemetry.Metrics.ExemplarFilterType -OpenTelemetry.Metrics.ExemplarFilterType.AlwaysOn = 1 -> OpenTelemetry.Metrics.ExemplarFilterType -OpenTelemetry.Metrics.ExemplarFilterType.TraceBased = 2 -> OpenTelemetry.Metrics.ExemplarFilterType -OpenTelemetry.Metrics.MetricPoint.TryGetExemplars(out OpenTelemetry.Metrics.ReadOnlyExemplarCollection exemplars) -> bool -OpenTelemetry.Metrics.ReadOnlyExemplarCollection -OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator -OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator.Current.get -> OpenTelemetry.Metrics.Exemplar -OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator.Enumerator() -> void -OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator.MoveNext() -> bool -OpenTelemetry.Metrics.ReadOnlyExemplarCollection.GetEnumerator() -> OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator -OpenTelemetry.Metrics.ReadOnlyExemplarCollection.ReadOnlyExemplarCollection() -> void -OpenTelemetry.ReadOnlyFilteredTagCollection -OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator -OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair -OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.Enumerator() -> void -OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator.MoveNext() -> bool -OpenTelemetry.ReadOnlyFilteredTagCollection.GetEnumerator() -> OpenTelemetry.ReadOnlyFilteredTagCollection.Enumerator -OpenTelemetry.ReadOnlyFilteredTagCollection.ReadOnlyFilteredTagCollection() -> void -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.IOpenTelemetryBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Func!>! implementationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.Build(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProvider! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.LoggerProviderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProvider! provider, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProvider! -static OpenTelemetry.Logs.LoggerProviderExtensions.ForceFlush(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool -static OpenTelemetry.Logs.LoggerProviderExtensions.Shutdown(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetExemplarFilter(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.ExemplarFilterType exemplarFilter) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index a5a637f8236..ca4d195698d 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-14 + ## 1.9.0-rc.1 Released 2024-Jun-07 From 908b46ca2dafa1ed93ced7d7a921e9c4afa7a1a1 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 14 Jun 2024 15:34:34 -0700 Subject: [PATCH 024/133] [repo] Bump OTelLatestStableVer to 1.9.0 and fix coreunstable test issues (#5696) --- Directory.Packages.props | 2 +- build/Common.prod.props | 3 +++ build/Common.props | 4 ++++ ...lemetry.Exporter.Prometheus.AspNetCore.Tests.csproj | 10 +++++++++- ...metry.Exporter.Prometheus.HttpListener.Tests.csproj | 7 +++++++ .../OpenTelemetry.Shims.OpenTracing.Tests.csproj | 10 ++++++++-- 6 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 032d5eb04a2..14d04b08b29 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@ true - 1.8.1 + 1.9.0 + + false + + net462 diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj index e3603d4bc50..97e6f15e108 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj @@ -18,9 +18,17 @@ + + + + - + + + + + diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj index 7ab05160d72..f4901706361 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj @@ -18,9 +18,16 @@ + + + + + + + diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj index 7e08df554f3..07fe011a082 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj @@ -15,8 +15,14 @@ - - + + + + + + + + From 237de185a706c0ae81bd68133ec26a6e5e17837b Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sat, 15 Jun 2024 00:40:23 +0200 Subject: [PATCH 025/133] [release] Prepare release coreunstable-1.9.0-beta.1 (#5697) --- src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index fa76f44a318..9364cb454c1 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jun-14 + ## 1.9.0-alpha.2 Released 2024-May-29 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 07ac849c6d7..80d67e0b45e 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jun-14 + ## 1.9.0-alpha.2 Released 2024-May-29 diff --git a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md index 1dbb969e79c..31ebdc599ec 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md +++ b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jun-14 + ## 1.9.0-alpha.2 Released 2024-May-29 From b1a21cc0dc3a5dafd6266444f1442aefee332910 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 18 Jun 2024 09:58:29 -0700 Subject: [PATCH 026/133] [repo] Stable version update automation tweaks (#5698) --- .github/workflows/post-release.yml | 3 + Directory.Packages.props | 12 +- build/scripts/post-release.psm1 | 192 ++++++++++++++++++++++++++++- 3 files changed, 195 insertions(+), 12 deletions(-) diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml index e824e87d724..249fd360da9 100644 --- a/.github/workflows/post-release.yml +++ b/.github/workflows/post-release.yml @@ -83,6 +83,9 @@ jobs: ref: ${{ github.event.repository.default_branch }} token: ${{ secrets[needs.automation.outputs.token-secret-name] }} + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + - name: Create GitHub Pull Request to update stable build version in props if: | (github.ref_type == 'tag' && startsWith(github.ref_name, 'core-') && !contains(github.ref_name, '-alpha') && !contains(github.ref_name, '-beta') && !contains(github.ref_name, '-rc')) diff --git a/Directory.Packages.props b/Directory.Packages.props index 14d04b08b29..d7180a1c1ae 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -35,12 +35,12 @@ - - - - - - + + + + + + - disable BUILDING_INTERNAL_PERSISTENT_STORAGE;$(DefineConstants) true diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 7c14310d17f..59088ce0877 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; #if NETFRAMEWORK using System.Net.Http; diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 17c89b01c0e..b755e15880b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -233,13 +233,13 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio { options.HttpClientFactory = () => { - Type httpClientFactoryType = Type.GetType("System.Net.Http.IHttpClientFactory, Microsoft.Extensions.Http", throwOnError: false); + Type? httpClientFactoryType = Type.GetType("System.Net.Http.IHttpClientFactory, Microsoft.Extensions.Http", throwOnError: false); if (httpClientFactoryType != null) { - object httpClientFactory = serviceProvider.GetService(httpClientFactoryType); + object? httpClientFactory = serviceProvider.GetService(httpClientFactoryType); if (httpClientFactory != null) { - MethodInfo createClientMethod = httpClientFactoryType.GetMethod( + MethodInfo? createClientMethod = httpClientFactoryType.GetMethod( "CreateClient", BindingFlags.Public | BindingFlags.Instance, binder: null, @@ -247,11 +247,14 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio modifiers: null); if (createClientMethod != null) { - HttpClient client = (HttpClient)createClientMethod.Invoke(httpClientFactory, new object[] { httpClientName }); + HttpClient? client = (HttpClient?)createClientMethod.Invoke(httpClientFactory, new object[] { httpClientName }); - client.Timeout = TimeSpan.FromMilliseconds(options.TimeoutMilliseconds); + if (client != null) + { + client.Timeout = TimeSpan.FromMilliseconds(options.TimeoutMilliseconds); - return client; + return client; + } } } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs index b3781c4c346..dec5e8cc3e9 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; @@ -49,7 +47,7 @@ internal OtlpLogExporter( Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null"); Debug.Assert(experimentalOptions != null, "experimentalOptions was null"); - this.transmissionHandler = transmissionHandler ?? exporterOptions.GetLogsExportTransmissionHandler(experimentalOptions!); + this.transmissionHandler = transmissionHandler ?? exporterOptions!.GetLogsExportTransmissionHandler(experimentalOptions!); this.otlpLogRecordTransformer = new OtlpLogRecordTransformer(sdkLimitOptions!, experimentalOptions!); } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs index 3a994c8e772..42faf425356 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -288,7 +286,7 @@ internal static BaseProcessor BuildOtlpLogExporter( if (!skipUseOtlpExporterRegistrationCheck) { - serviceProvider.EnsureNoUseOtlpExporterRegistrations(); + serviceProvider!.EnsureNoUseOtlpExporterRegistrations(); } /* diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs index b2b0c3e5766..aef2bdc4fe3 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs @@ -18,7 +18,7 @@ public class OtlpMetricExporter : BaseExporter { private readonly OtlpExporterTransmissionHandler transmissionHandler; - private OtlpResource.Resource processResource; + private OtlpResource.Resource? processResource; /// /// Initializes a new instance of the class. @@ -38,12 +38,12 @@ public OtlpMetricExporter(OtlpExporterOptions options) internal OtlpMetricExporter( OtlpExporterOptions exporterOptions, ExperimentalOptions experimentalOptions, - OtlpExporterTransmissionHandler transmissionHandler = null) + OtlpExporterTransmissionHandler? transmissionHandler = null) { Debug.Assert(exporterOptions != null, "exporterOptions was null"); Debug.Assert(experimentalOptions != null, "experimentalOptions was null"); - this.transmissionHandler = transmissionHandler ?? exporterOptions.GetMetricsExportTransmissionHandler(experimentalOptions); + this.transmissionHandler = transmissionHandler ?? exporterOptions!.GetMetricsExportTransmissionHandler(experimentalOptions!); } internal OtlpResource.Resource ProcessResource => this.processResource ??= this.ParentProvider.GetResource().ToOtlpResource(); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs index 57ad3dd47ec..1a8ef2f1b42 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -172,12 +170,12 @@ internal static MetricReader BuildOtlpExporterMetricReader( if (!skipUseOtlpExporterRegistrationCheck) { - serviceProvider.EnsureNoUseOtlpExporterRegistrations(); + serviceProvider!.EnsureNoUseOtlpExporterRegistrations(); } - exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpMetricExporter"); + exporterOptions!.TryEnableIHttpClientFactoryIntegration(serviceProvider!, "OtlpMetricExporter"); - BaseExporter metricExporter = new OtlpMetricExporter(exporterOptions, experimentalOptions); + BaseExporter metricExporter = new OtlpMetricExporter(exporterOptions!, experimentalOptions!); if (configureExporterInstance != null) { diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs index b02d348bd8a..da92667e033 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs @@ -18,7 +18,7 @@ public class OtlpTraceExporter : BaseExporter private readonly SdkLimitOptions sdkLimitOptions; private readonly OtlpExporterTransmissionHandler transmissionHandler; - private OtlpResource.Resource processResource; + private OtlpResource.Resource? processResource; /// /// Initializes a new instance of the class. @@ -40,14 +40,14 @@ internal OtlpTraceExporter( OtlpExporterOptions exporterOptions, SdkLimitOptions sdkLimitOptions, ExperimentalOptions experimentalOptions, - OtlpExporterTransmissionHandler transmissionHandler = null) + OtlpExporterTransmissionHandler? transmissionHandler = null) { Debug.Assert(exporterOptions != null, "exporterOptions was null"); Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null"); - this.sdkLimitOptions = sdkLimitOptions; + this.sdkLimitOptions = sdkLimitOptions!; - this.transmissionHandler = transmissionHandler ?? exporterOptions.GetTraceExportTransmissionHandler(experimentalOptions); + this.transmissionHandler = transmissionHandler ?? exporterOptions!.GetTraceExportTransmissionHandler(experimentalOptions); } internal OtlpResource.Resource ProcessResource => this.processResource ??= this.ParentProvider.GetResource().ToOtlpResource(); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs index 036e9a90dd3..3a18b3da423 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -133,12 +131,12 @@ internal static BaseProcessor BuildOtlpExporterProcessor( if (!skipUseOtlpExporterRegistrationCheck) { - serviceProvider.EnsureNoUseOtlpExporterRegistrations(); + serviceProvider!.EnsureNoUseOtlpExporterRegistrations(); } - exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpTraceExporter"); + exporterOptions!.TryEnableIHttpClientFactoryIntegration(serviceProvider!, "OtlpTraceExporter"); - BaseExporter otlpExporter = new OtlpTraceExporter(exporterOptions, sdkLimitOptions, experimentalOptions); + BaseExporter otlpExporter = new OtlpTraceExporter(exporterOptions!, sdkLimitOptions!, experimentalOptions!); if (configureExporterInstance != null) { diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs index a60715d185b..2bbc352817d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.PersistentStorage.FileSystem; /// diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlob.cs index 337c3226243..cfb1c395d08 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlob.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; using OpenTelemetry.PersistentStorage.Abstractions; diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlobProvider.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlobProvider.cs index c9afdf34ce8..4d790469958 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlobProvider.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/FileBlobProvider.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; using System.Timers; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlob.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlob.cs index 2f0912feb75..aca1491ba29 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlob.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlob.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; namespace OpenTelemetry.PersistentStorage.Abstractions; diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlobProvider.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlobProvider.cs index 5d4895f8d46..29d3dee8a02 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentBlobProvider.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; namespace OpenTelemetry.PersistentStorage.Abstractions; diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentStorageHelper.cs index 538597dc18f..63005646fc7 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/PersistentStorageHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Globalization; using System.Runtime.CompilerServices; diff --git a/src/Shared/Shims/NullableAttributes.cs b/src/Shared/Shims/NullableAttributes.cs index 72d877e3dae..3126b557623 100644 --- a/src/Shared/Shims/NullableAttributes.cs +++ b/src/Shared/Shims/NullableAttributes.cs @@ -6,9 +6,10 @@ #pragma warning disable SA1649 // File name should match first type name #pragma warning disable SA1402 // File may only contain a single type -#if NETFRAMEWORK || NETSTANDARD2_0 +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER namespace System.Diagnostics.CodeAnalysis { +#if NETFRAMEWORK || NETSTANDARD2_0 /// Specifies that null is allowed as an input even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] internal sealed class AllowNullAttribute : Attribute @@ -42,5 +43,26 @@ internal sealed class NotNullIfNotNullAttribute : Attribute public string ParameterName { get; } } +#endif + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] + internal sealed class MemberNotNullWhenAttribute : Attribute + { + public MemberNotNullWhenAttribute(bool returnValue, string member) + { + ReturnValue = returnValue; + Members = new[] { member }; + } + + public MemberNotNullWhenAttribute(bool returnValue, params string[] members) + { + ReturnValue = returnValue; + Members = members; + } + + public bool ReturnValue { get; } + + public string[] Members { get; } + } } #endif diff --git a/src/Shared/TagWriter/TagWriter.cs b/src/Shared/TagWriter/TagWriter.cs index 9594382df6f..473090f6dcc 100644 --- a/src/Shared/TagWriter/TagWriter.cs +++ b/src/Shared/TagWriter/TagWriter.cs @@ -27,24 +27,33 @@ public bool TryWriteTag( KeyValuePair tag, int? tagValueMaxLength = null) { - if (tag.Value == null) + return this.TryWriteTag(ref state, tag.Key, tag.Value, tagValueMaxLength); + } + + public bool TryWriteTag( + ref TTagState state, + string key, + object? value, + int? tagValueMaxLength = null) + { + if (value == null) { return false; } - switch (tag.Value) + switch (value) { case char c: - this.WriteCharTag(ref state, tag.Key, c); + this.WriteCharTag(ref state, key, c); break; case string s: this.WriteStringTag( ref state, - tag.Key, + key, TruncateString(s.AsSpan(), tagValueMaxLength)); break; case bool b: - this.WriteBooleanTag(ref state, tag.Key, b); + this.WriteBooleanTag(ref state, key, b); break; case byte: case sbyte: @@ -53,23 +62,23 @@ public bool TryWriteTag( case int: case uint: case long: - this.WriteIntegralTag(ref state, tag.Key, Convert.ToInt64(tag.Value)); + this.WriteIntegralTag(ref state, key, Convert.ToInt64(value)); break; case float: case double: - this.WriteFloatingPointTag(ref state, tag.Key, Convert.ToDouble(tag.Value)); + this.WriteFloatingPointTag(ref state, key, Convert.ToDouble(value)); break; case Array array: try { - this.WriteArrayTagInternal(ref state, tag.Key, array, tagValueMaxLength); + this.WriteArrayTagInternal(ref state, key, array, tagValueMaxLength); } catch { // If an exception is thrown when calling ToString // on any element of the array, then the entire array value // is ignored. - return this.LogUnsupportedTagTypeAndReturnFalse(tag.Key, tag.Value); + return this.LogUnsupportedTagTypeAndReturnFalse(key, value); } break; @@ -83,21 +92,21 @@ public bool TryWriteTag( default: try { - var stringValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + var stringValue = Convert.ToString(value, CultureInfo.InvariantCulture); if (stringValue == null) { - return this.LogUnsupportedTagTypeAndReturnFalse(tag.Key, tag.Value); + return this.LogUnsupportedTagTypeAndReturnFalse(key, value); } this.WriteStringTag( ref state, - tag.Key, + key, TruncateString(stringValue.AsSpan(), tagValueMaxLength)); } catch { // If ToString throws an exception then the tag is ignored. - return this.LogUnsupportedTagTypeAndReturnFalse(tag.Key, tag.Value); + return this.LogUnsupportedTagTypeAndReturnFalse(key, value); } break; From 8cc51b8bca1e26c23a6aff3aae93ec8080a68b8d Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 24 Jun 2024 21:57:02 +0200 Subject: [PATCH 033/133] [release] Prepare release coreunstable-1.9.0-beta.2 (#5716) --- src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 17c6d731761..89392443dac 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.2 + +Released 2024-Jun-24 + * Fixed a bug which lead to empty responses when the internal buffer is resized processing a collection request ([#5676](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5676)) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 4c8b6db142e..d04d8d825b2 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.2 + +Released 2024-Jun-24 + * Fixed a bug which lead to empty responses when the internal buffer is resized processing a collection request ([#5676](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5676)) diff --git a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md index 31ebdc599ec..2d1f86d48d9 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md +++ b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.2 + +Released 2024-Jun-24 + ## 1.9.0-beta.1 Released 2024-Jun-14 From 4d254eb2783aa7f1c44053e64dc1d4e261f7eb5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 25 Jun 2024 19:12:30 +0200 Subject: [PATCH 034/133] [Exporter.OTLP - Tests] Nullable (#5720) --- .../OtlpExporterOptions.cs | 2 +- .../BaseOtlpHttpExportClientTests.cs | 2 +- .../OtlpHttpTraceExportClientTests.cs | 8 +- .../IntegrationTest/IntegrationTests.cs | 12 +- .../MockCollectorIntegrationTests.cs | 27 +++-- ...xporter.OpenTelemetryProtocol.Tests.csproj | 2 - .../OtlpAttributeTests.cs | 46 ++++---- .../OtlpExporterOptionsExtensionsTests.cs | 10 +- .../OtlpExporterOptionsTests.cs | 8 +- .../OtlpLogExporterTests.cs | 83 +++++++------- .../OtlpMetricsExporterTests.cs | 66 +++++------ .../OtlpTestHelpers.cs | 5 +- .../OtlpTraceExporterTests.cs | 108 +++++++++++------- .../SdkLimitOptionsTests.cs | 2 +- .../TestExportClient.cs | 2 +- .../TestHttpMessageHandler.cs | 6 +- .../Shared/EventSourceTestHelper.cs | 15 ++- .../SkipUnlessEnvVarFoundFactAttribute.cs | 6 +- .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 6 +- .../Shared/TestActivityProcessor.cs | 6 +- .../Shared/TestEventListener.cs | 6 +- 21 files changed, 237 insertions(+), 191 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 59088ce0877..355ab376743 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -30,7 +30,7 @@ public class OtlpExporterOptions : IOtlpExporterOptions internal static readonly KeyValuePair[] StandardHeaders = new KeyValuePair[] { - new KeyValuePair("User-Agent", GetUserAgentString()), + new("User-Agent", GetUserAgentString()), }; internal readonly Func DefaultHttpClientFactory; diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs index a846af33a4e..36d534df9a1 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs @@ -17,7 +17,7 @@ public class BaseOtlpHttpExportClientTests [InlineData("https://custom.host", null, "https://custom.host")] [InlineData("http://custom.host:44318/custom/path", null, "http://custom.host:44318/custom/path")] [InlineData("https://custom.host", "http://from.otel.exporter.env.var", "https://custom.host")] - public void ValidateOtlpHttpExportClientEndpoint(string optionEndpoint, string endpointEnvVar, string expectedExporterEndpoint) + public void ValidateOtlpHttpExportClientEndpoint(string? optionEndpoint, string? endpointEnvVar, string expectedExporterEndpoint) { try { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/ExportClient/OtlpHttpTraceExportClientTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/ExportClient/OtlpHttpTraceExportClientTests.cs index d796e36ef5a..0b932f87d39 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/ExportClient/OtlpHttpTraceExportClientTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/ExportClient/OtlpHttpTraceExportClientTests.cs @@ -63,8 +63,8 @@ public void NewOtlpHttpTraceExportClient_OtlpExporterOptions_ExporterHasCorrectP public void SendExportRequest_ExportTraceServiceRequest_SendsCorrectHttpRequest(bool includeServiceNameInResource) { // Arrange - var evenTags = new[] { new KeyValuePair("k0", "v0") }; - var oddTags = new[] { new KeyValuePair("k1", "v1") }; + var evenTags = new[] { new KeyValuePair("k0", "v0") }; + var oddTags = new[] { new KeyValuePair("k1", "v1") }; var sources = new[] { new ActivitySource("even", "2.4.6"), @@ -116,7 +116,8 @@ public void SendExportRequest_ExportTraceServiceRequest_SendsCorrectHttpRequest( var activityKind = isEven ? ActivityKind.Client : ActivityKind.Server; var activityTags = isEven ? evenTags : oddTags; - using Activity activity = source.StartActivity($"span-{i}", activityKind, parentContext: default, activityTags); + using Activity? activity = source.StartActivity($"span-{i}", activityKind, parentContext: default, activityTags); + Assert.NotNull(activity); processor.OnEnd(activity); } @@ -141,6 +142,7 @@ void RunTest(Batch batch) Assert.True(result.Success); Assert.NotNull(httpRequest); Assert.Equal(HttpMethod.Post, httpRequest.Method); + Assert.NotNull(httpRequest.RequestUri); Assert.Equal("http://localhost:4317/", httpRequest.RequestUri.AbsoluteUri); Assert.Equal(OtlpExporterOptions.StandardHeaders.Length + 2, httpRequest.Headers.Count()); Assert.Contains(httpRequest.Headers, h => h.Key == header1.Name && h.Value.First() == header1.Value); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs index 14b73571e35..3e40b9c6d9f 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs @@ -21,7 +21,7 @@ public sealed class IntegrationTests : IDisposable private const int ExportIntervalMilliseconds = 10000; private static readonly SdkLimitOptions DefaultSdkLimitOptions = new(); private static readonly ExperimentalOptions DefaultExperimentalOptions = new(); - private static readonly string CollectorHostname = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(CollectorHostnameEnvVarName); + private static readonly string? CollectorHostname = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(CollectorHostnameEnvVarName); private readonly OpenTelemetryEventListener openTelemetryEventListener; public IntegrationTests(ITestOutputHelper outputHelper) @@ -61,7 +61,7 @@ public void TraceExportResultIsSuccess(OtlpExportProtocol protocol, string endpo }, }; - DelegatingExporter delegatingExporter = null; + DelegatingExporter? delegatingExporter = null; var exportResults = new List(); var activitySourceName = "otlp.collector.test"; @@ -140,7 +140,7 @@ public void MetricExportResultIsSuccess(OtlpExportProtocol protocol, string endp Protocol = protocol, }; - DelegatingExporter delegatingExporter = null; + DelegatingExporter? delegatingExporter = null; var exportResults = new List(); var meterName = "otlp.collector.test"; @@ -220,7 +220,7 @@ public void LogExportResultIsSuccess(OtlpExportProtocol protocol, string endpoin Protocol = protocol, }; - DelegatingExporter delegatingExporter = null; + DelegatingExporter delegatingExporter; var exportResults = new List(); var processorOptions = new LogRecordExportProcessorOptions { @@ -298,8 +298,8 @@ protected override void OnEventSourceCreated(EventSource eventSource) protected override void OnEventWritten(EventWrittenEventArgs eventData) { - string message; - if (eventData.Message != null && (eventData.Payload?.Count ?? 0) > 0) + string? message; + if (eventData.Message != null && eventData.Payload != null && eventData.Payload.Count > 0) { message = string.Format(eventData.Message, eventData.Payload.ToArray()); } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs index a5ce7a0a279..e72a6773b81 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs @@ -3,6 +3,7 @@ #if !NETFRAMEWORK using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Net; using Google.Protobuf; using Grpc.Core; @@ -94,12 +95,12 @@ public async Task TestRecoveryAfterFailedExport() using var source = new ActivitySource(activitySourceName); - source.StartActivity().Stop(); + source.StartActivity()?.Stop(); Assert.Single(exportResults); Assert.Equal(ExportResult.Failure, exportResults[0]); - source.StartActivity().Stop(); + source.StartActivity()?.Stop(); Assert.Equal(2, exportResults.Count); Assert.Equal(ExportResult.Success, exportResults[1]); @@ -179,7 +180,7 @@ public async Task GrpcRetryTests(bool useRetryTransmissionHandler, ExportResult var exporterOptions = new OtlpExporterOptions() { Endpoint = endpoint, TimeoutMilliseconds = 20000, Protocol = OtlpExportProtocol.Grpc }; var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.OtlpRetryEnvVar] = useRetryTransmissionHandler ? "in_memory" : null }) + .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.OtlpRetryEnvVar] = useRetryTransmissionHandler ? "in_memory" : null }) .Build(); var otlpExporter = new OtlpTraceExporter(exporterOptions, new SdkLimitOptions(), new ExperimentalOptions(configuration)); @@ -192,6 +193,7 @@ public async Task GrpcRetryTests(bool useRetryTransmissionHandler, ExportResult .Build(); using var activity = source.StartActivity("GrpcRetryTest"); + Assert.NotNull(activity); activity.Stop(); using var batch = new Batch([activity], 1); @@ -263,7 +265,7 @@ public async Task HttpRetryTests(bool useRetryTransmissionHandler, ExportResult var exporterOptions = new OtlpExporterOptions() { Endpoint = endpoint, TimeoutMilliseconds = 20000, Protocol = OtlpExportProtocol.HttpProtobuf }; var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.OtlpRetryEnvVar] = useRetryTransmissionHandler ? "in_memory" : null }) + .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.OtlpRetryEnvVar] = useRetryTransmissionHandler ? "in_memory" : null }) .Build(); var otlpExporter = new OtlpTraceExporter(exporterOptions, new SdkLimitOptions(), new ExperimentalOptions(configuration)); @@ -276,6 +278,7 @@ public async Task HttpRetryTests(bool useRetryTransmissionHandler, ExportResult .Build(); using var activity = source.StartActivity("HttpRetryTest"); + Assert.NotNull(activity); activity.Stop(); using var batch = new Batch([activity], 1); @@ -348,7 +351,7 @@ public async Task HttpPersistentStorageRetryTests(bool usePersistentStorageTrans // TODO: update this to configure via experimental environment variable. OtlpExporterTransmissionHandler transmissionHandler; - MockFileProvider mockProvider = null; + MockFileProvider? mockProvider = null; if (usePersistentStorageTransmissionHandler) { mockProvider = new MockFileProvider(); @@ -378,6 +381,7 @@ public async Task HttpPersistentStorageRetryTests(bool usePersistentStorageTrans .Build(); using var activity = source.StartActivity("HttpPersistentStorageRetryTest"); + Assert.NotNull(activity); activity.Stop(); using var batch = new Batch([activity], 1); @@ -387,12 +391,13 @@ public async Task HttpPersistentStorageRetryTests(bool usePersistentStorageTrans if (usePersistentStorageTransmissionHandler) { + Assert.NotNull(mockProvider); if (exportResult == ExportResult.Success) { - Assert.Single(mockProvider.TryGetBlobs()); + Assert.Single(mockProvider!.TryGetBlobs()); // Force Retry - Assert.True((transmissionHandler as OtlpExporterPersistentStorageTransmissionHandler).InitiateAndWaitForRetryProcess(-1)); + Assert.True((transmissionHandler as OtlpExporterPersistentStorageTransmissionHandler)!.InitiateAndWaitForRetryProcess(-1)); Assert.False(mockProvider.TryGetBlob(out _)); } @@ -485,7 +490,7 @@ public async Task GrpcPersistentStorageRetryTests(bool usePersistentStorageTrans // TODO: update this to configure via experimental environment variable. OtlpExporterTransmissionHandler transmissionHandler; - MockFileProvider mockProvider = null; + MockFileProvider? mockProvider = null; if (usePersistentStorageTransmissionHandler) { mockProvider = new MockFileProvider(); @@ -515,6 +520,7 @@ public async Task GrpcPersistentStorageRetryTests(bool usePersistentStorageTrans .Build(); using var activity = source.StartActivity("GrpcPersistentStorageRetryTest"); + Assert.NotNull(activity); activity.Stop(); using var batch = new Batch([activity], 1); @@ -524,12 +530,13 @@ public async Task GrpcPersistentStorageRetryTests(bool usePersistentStorageTrans if (usePersistentStorageTransmissionHandler) { + Assert.NotNull(mockProvider); if (exportResult == ExportResult.Success) { Assert.Single(mockProvider.TryGetBlobs()); // Force Retry - Assert.True((transmissionHandler as OtlpExporterPersistentStorageTransmissionHandler).InitiateAndWaitForRetryProcess(-1)); + Assert.True((transmissionHandler as OtlpExporterPersistentStorageTransmissionHandler)!.InitiateAndWaitForRetryProcess(-1)); Assert.False(mockProvider.TryGetBlob(out _)); } @@ -630,7 +637,7 @@ protected override bool OnTryCreateBlob(byte[] buffer, out PersistentBlob blob) return blob.TryWrite(buffer); } - protected override bool OnTryGetBlob(out PersistentBlob blob) + protected override bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) { blob = this.GetBlobs().FirstOrDefault(); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj index ad60a2385a2..21b320de546 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj @@ -2,8 +2,6 @@ $(TargetFrameworksForTests) - - disable diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpAttributeTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpAttributeTests.cs index af31f32c795..a325874fb30 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpAttributeTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpAttributeTests.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics.CodeAnalysis; using Google.Protobuf.Collections; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; using Xunit; @@ -13,19 +14,19 @@ public class OtlpAttributeTests [Fact] public void NullValueAttribute() { - var kvp = new KeyValuePair("key", null); - Assert.False(TryTransformTag(kvp, out var _)); + var kvp = new KeyValuePair("key", null); + Assert.False(TryTransformTag(kvp, out _)); } [Fact] public void EmptyArrays() { - var kvp = new KeyValuePair("key", Array.Empty()); + var kvp = new KeyValuePair("key", Array.Empty()); Assert.True(TryTransformTag(kvp, out var attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.ArrayValue, attribute.Value.ValueCase); Assert.Empty(attribute.Value.ArrayValue.Values); - kvp = new KeyValuePair("key", Array.Empty()); + kvp = new KeyValuePair("key", Array.Empty()); Assert.True(TryTransformTag(kvp, out attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.ArrayValue, attribute.Value.ValueCase); Assert.Empty(attribute.Value.ArrayValue.Values); @@ -48,7 +49,7 @@ public void EmptyArrays() [InlineData(new long[] { 1, 2, 3 })] public void IntegralTypesSupported(object value) { - var kvp = new KeyValuePair("key", value); + var kvp = new KeyValuePair("key", value); Assert.True(TryTransformTag(kvp, out var attribute)); switch (value) @@ -77,7 +78,7 @@ public void IntegralTypesSupported(object value) [InlineData(new double[] { 1, 2, 3 })] public void FloatingPointTypesSupported(object value) { - var kvp = new KeyValuePair("key", value); + var kvp = new KeyValuePair("key", value); Assert.True(TryTransformTag(kvp, out var attribute)); switch (value) @@ -104,7 +105,7 @@ public void FloatingPointTypesSupported(object value) [InlineData(new bool[] { true, false, true })] public void BooleanTypeSupported(object value) { - var kvp = new KeyValuePair("key", value); + var kvp = new KeyValuePair("key", value); Assert.True(TryTransformTag(kvp, out var attribute)); switch (value) @@ -131,7 +132,7 @@ public void BooleanTypeSupported(object value) [InlineData("string")] public void StringTypesSupported(object value) { - var kvp = new KeyValuePair("key", value); + var kvp = new KeyValuePair("key", value); Assert.True(TryTransformTag(kvp, out var attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.StringValue, attribute.Value.ValueCase); Assert.Equal(Convert.ToString(value), attribute.Value.StringValue); @@ -141,9 +142,9 @@ public void StringTypesSupported(object value) public void ObjectArrayTypesSupported() { var obj = new object(); - var objectArray = new object[] { null, "a", 'b', true, int.MaxValue, long.MaxValue, float.MaxValue, double.MaxValue, obj }; + var objectArray = new object?[] { null, "a", 'b', true, int.MaxValue, long.MaxValue, float.MaxValue, double.MaxValue, obj }; - var kvp = new KeyValuePair("key", objectArray); + var kvp = new KeyValuePair("key", objectArray); Assert.True(TryTransformTag(kvp, out var attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.ArrayValue, attribute.Value.ValueCase); @@ -179,14 +180,14 @@ public void ObjectArrayTypesSupported() public void StringArrayTypesSupported() { var charArray = new char[] { 'a', 'b', 'c' }; - var stringArray = new string[] { "a", "b", "c", string.Empty, null }; + var stringArray = new string?[] { "a", "b", "c", string.Empty, null }; - var kvp = new KeyValuePair("key", charArray); + var kvp = new KeyValuePair("key", charArray); Assert.True(TryTransformTag(kvp, out var attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.ArrayValue, attribute.Value.ValueCase); Assert.Equal(charArray.Select(x => x.ToString()), attribute.Value.ArrayValue.Values.Select(x => x.StringValue)); - kvp = new KeyValuePair("key", stringArray); + kvp = new KeyValuePair("key", stringArray); Assert.True(TryTransformTag(kvp, out attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.ArrayValue, attribute.Value.ValueCase); @@ -221,12 +222,12 @@ public void ToStringIsCalledForAllOtherTypes() new nint[] { 1, 2, 3 }, new nuint[] { 1, 2, 3 }, new decimal[] { 1, 2, 3 }, - new object[] { new object[3], new object(), null }, + new object?[] { new object[3], new object(), null }, }; foreach (var value in testValues) { - var kvp = new KeyValuePair("key", value); + var kvp = new KeyValuePair("key", value); Assert.True(TryTransformTag(kvp, out var attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.StringValue, attribute.Value.ValueCase); Assert.Equal(value.ToString(), attribute.Value.StringValue); @@ -234,11 +235,12 @@ public void ToStringIsCalledForAllOtherTypes() foreach (var value in testArrayValues) { - var kvp = new KeyValuePair("key", value); + var kvp = new KeyValuePair("key", value); Assert.True(TryTransformTag(kvp, out var attribute)); Assert.Equal(OtlpCommon.AnyValue.ValueOneofCase.ArrayValue, attribute.Value.ValueCase); var array = value as Array; + Assert.NotNull(array); for (var i = 0; i < attribute.Value.ArrayValue.Values.Count; ++i) { var expectedValue = array.GetValue(i)?.ToString(); @@ -249,7 +251,7 @@ public void ToStringIsCalledForAllOtherTypes() Assert.Equal(expectedValueCase, attribute.Value.ArrayValue.Values[i].ValueCase); if (expectedValueCase != OtlpCommon.AnyValue.ValueOneofCase.None) { - Assert.Equal(array.GetValue(i).ToString(), attribute.Value.ArrayValue.Values[i].StringValue); + Assert.Equal(array.GetValue(i)!.ToString(), attribute.Value.ArrayValue.Values[i].StringValue); } } } @@ -258,14 +260,14 @@ public void ToStringIsCalledForAllOtherTypes() [Fact] public void ExceptionInToStringIsCaught() { - var kvp = new KeyValuePair("key", new MyToStringMethodThrowsAnException()); - Assert.False(TryTransformTag(kvp, out var _)); + var kvp = new KeyValuePair("key", new MyToStringMethodThrowsAnException()); + Assert.False(TryTransformTag(kvp, out _)); - kvp = new KeyValuePair("key", new object[] { 1, false, new MyToStringMethodThrowsAnException() }); - Assert.False(TryTransformTag(kvp, out var _)); + kvp = new KeyValuePair("key", new object[] { 1, false, new MyToStringMethodThrowsAnException() }); + Assert.False(TryTransformTag(kvp, out _)); } - private static bool TryTransformTag(KeyValuePair tag, out OtlpCommon.KeyValue attribute) + private static bool TryTransformTag(KeyValuePair tag, [NotNullWhen(true)] out OtlpCommon.KeyValue? attribute) { var destination = new RepeatedField(); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs index 2b7810dfadf..4018998b890 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs @@ -73,7 +73,7 @@ public void GetMetadataFromHeadersThrowsExceptionOnInvalidFormat(string headers) [Theory] [InlineData("")] [InlineData(null)] - public void GetHeaders_NoOptionHeaders_ReturnsStandardHeaders(string optionHeaders) + public void GetHeaders_NoOptionHeaders_ReturnsStandardHeaders(string? optionHeaders) { var options = new OtlpExporterOptions { @@ -158,19 +158,19 @@ public void AppendPathIfNotPresent_TracesPath_AppendsCorrectly(string inputUri, [InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcLogExportClient), false, 10000, "disk")] [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpLogExportClient), false, 10000, "disk")] [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpLogExportClient), true, 8000, "disk")] - public void GetTransmissionHandler_InitializesCorrectHandlerExportClientAndTimeoutValue(OtlpExportProtocol protocol, Type exportClientType, bool customHttpClient, int expectedTimeoutMilliseconds, string retryStrategy) + public void GetTransmissionHandler_InitializesCorrectHandlerExportClientAndTimeoutValue(OtlpExportProtocol protocol, Type exportClientType, bool customHttpClient, int expectedTimeoutMilliseconds, string? retryStrategy) { var exporterOptions = new OtlpExporterOptions() { Protocol = protocol }; if (customHttpClient) { exporterOptions.HttpClientFactory = () => { - return new HttpClient() { Timeout = TimeSpan.FromMilliseconds(expectedTimeoutMilliseconds) }; + return new HttpClient { Timeout = TimeSpan.FromMilliseconds(expectedTimeoutMilliseconds) }; }; } var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.OtlpRetryEnvVar] = retryStrategy }) + .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.OtlpRetryEnvVar] = retryStrategy }) .Build(); if (exportClientType == typeof(OtlpGrpcTraceExportClient) || exportClientType == typeof(OtlpHttpTraceExportClient)) @@ -193,7 +193,7 @@ public void GetTransmissionHandler_InitializesCorrectHandlerExportClientAndTimeo } } - private static void AssertTransmissionHandler(OtlpExporterTransmissionHandler transmissionHandler, Type exportClientType, int expectedTimeoutMilliseconds, string retryStrategy) + private static void AssertTransmissionHandler(OtlpExporterTransmissionHandler transmissionHandler, Type exportClientType, int expectedTimeoutMilliseconds, string? retryStrategy) { if (retryStrategy == "in_memory") { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs index dc79c95c07b..c22f0e14863 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs @@ -74,7 +74,7 @@ public void OtlpExporterOptions_UsingIConfiguration(object testDataObject) [Fact] public void OtlpExporterOptions_InvalidEnvironmentVariableOverride() { - var values = new Dictionary() + var values = new Dictionary { ["EndpointWithInvalidValue"] = "invalid", ["TimeoutWithInvalidValue"] = "invalid", @@ -104,7 +104,7 @@ public void OtlpExporterOptions_InvalidEnvironmentVariableOverride() [Fact] public void OtlpExporterOptions_SetterOverridesEnvironmentVariable() { - var values = new Dictionary() + var values = new Dictionary { ["Endpoint"] = "http://test:8888", ["Timeout"] = "2000", @@ -169,7 +169,7 @@ public void OtlpExporterOptions_SettingEndpointToNullResetsAppendSignalPathToEnd { var options = new OtlpExporterOptions(OtlpExporterOptionsConfigurationType.Default); - Assert.Throws(() => options.Endpoint = null); + Assert.Throws(() => options.Endpoint = null!); } [Fact] @@ -177,7 +177,7 @@ public void OtlpExporterOptions_HttpClientFactoryThrowsWhenSetToNull() { var options = new OtlpExporterOptions(OtlpExporterOptionsConfigurationType.Default); - Assert.Throws(() => options.HttpClientFactory = null); + Assert.Throws(() => options.HttpClientFactory = null!); } [Fact] diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index f494a2683c6..c47fa7b5a5d 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -7,7 +7,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using OpenTelemetry.Internal; @@ -100,7 +99,7 @@ public void UserHttpFactoryCalledWhenUsingHttpProtobuf() Assert.Equal(2, invocations); } - options.HttpClientFactory = () => null; + options.HttpClientFactory = () => null!; Assert.Throws(() => { using var exporter = new OtlpLogExporter(options); @@ -218,6 +217,7 @@ public void AddOtlpLogExporterParseStateValueCanBeTurnedOffHosting(bool parseSta var host = hostBuilder.Build(); var loggerFactory = host.Services.GetService(); + Assert.NotNull(loggerFactory); var logger = loggerFactory.CreateLogger("OtlpLogExporterTests"); logger.Log(LogLevel.Information, default, new { propertyA = "valueA" }, null, (s, e) => "Custom state log message"); Assert.Single(logRecords); @@ -290,7 +290,7 @@ public void OtlpLogRecordTestWhenStateValuesArePopulated() [InlineData("true")] [InlineData("false")] [InlineData(null)] - public void CheckToOtlpLogRecordEventId(string emitLogEventAttributes) + public void CheckToOtlpLogRecordEventId(string? emitLogEventAttributes) { var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => @@ -309,7 +309,7 @@ public void CheckToOtlpLogRecordEventId(string emitLogEventAttributes) Assert.Single(logRecords); var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.EmitLogEventEnvVar] = emitLogEventAttributes }) + .AddInMemoryCollection(new Dictionary { [ExperimentalOptions.EmitLogEventEnvVar] = emitLogEventAttributes }) .Build(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new(configuration)); @@ -375,6 +375,7 @@ public void CheckToOtlpLogRecordTimestamps() var logRecord = logRecords[0]; var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.True(otlpLogRecord.TimeUnixNano > 0); Assert.True(otlpLogRecord.ObservedTimeUnixNano > 0); } @@ -397,9 +398,10 @@ public void CheckToOtlpLogRecordTraceIdSpanIdFlagWithNoActivity() var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); Assert.Null(Activity.Current); + Assert.NotNull(otlpLogRecord); Assert.True(otlpLogRecord.TraceId.IsEmpty); Assert.True(otlpLogRecord.SpanId.IsEmpty); - Assert.True(otlpLogRecord.Flags == 0); + Assert.Equal(0u, otlpLogRecord.Flags); } [Fact] @@ -428,6 +430,7 @@ public void CheckToOtlpLogRecordSpanIdTraceIdAndFlag() var logRecord = logRecords[0]; var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Equal(expectedTraceId.ToString(), ActivityTraceId.CreateFromBytes(otlpLogRecord.TraceId.ToByteArray()).ToString()); Assert.Equal(expectedSpanId.ToString(), ActivitySpanId.CreateFromBytes(otlpLogRecord.SpanId.ToByteArray()).ToString()); Assert.Equal((uint)logRecord.TraceFlags, otlpLogRecord.Flags); @@ -465,6 +468,7 @@ public void CheckToOtlpLogRecordSeverityLevelAndText(LogLevel logLevel) #pragma warning disable CS0618 // Type or member is obsolete Assert.Equal(logRecord.LogLevel.ToString(), otlpLogRecord.SeverityText); #pragma warning restore CS0618 // Type or member is obsolete + Assert.NotNull(logRecord.Severity); Assert.Equal((int)logRecord.Severity, (int)otlpLogRecord.SeverityNumber); switch (logLevel) { @@ -546,7 +550,7 @@ public void CheckToOtlpLogRecordBodyIsPopulated(bool includeFormattedMessage) // Scenario 3 - Using the raw ILogger.Log Method, but with null // formatter. - logger.Log(LogLevel.Information, default, "state", exception: null, formatter: null); + logger.Log(LogLevel.Information, default, "state", exception: null, formatter: null!); Assert.Single(logRecords); logRecord = logRecords[0]; @@ -590,6 +594,7 @@ public void LogRecordBodyIsExportedWhenUsingBridgeApi(bool isBodySet) var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecords[0]); + Assert.NotNull(otlpLogRecord); if (isBodySet) { Assert.Equal("Hello world", otlpLogRecord.Body?.StringValue); @@ -601,6 +606,7 @@ public void LogRecordBodyIsExportedWhenUsingBridgeApi(bool isBodySet) otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecords[1]); + Assert.NotNull(otlpLogRecord); Assert.Equal(2, otlpLogRecord.Attributes.Count); var index = 0; @@ -638,6 +644,7 @@ public void CheckToOtlpLogRecordExceptionAttributes() var otlpLogRecordAttributes = otlpLogRecord.Attributes.ToString(); Assert.Contains(SemanticConventions.AttributeExceptionType, otlpLogRecordAttributes); + Assert.NotNull(logRecord.Exception); Assert.Contains(logRecord.Exception.GetType().Name, otlpLogRecordAttributes); Assert.Contains(SemanticConventions.AttributeExceptionMessage, otlpLogRecordAttributes); @@ -785,6 +792,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsFalse_DoesNotContainScopeAttribu var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); var actualScope = TryGetAttribute(otlpLogRecord, expectedScopeKey); Assert.Null(actualScope); } @@ -819,6 +827,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeStrin var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Single(otlpLogRecord.Attributes); var actualScope = TryGetAttribute(otlpLogRecord, scopeKey); Assert.NotNull(actualScope); @@ -857,6 +866,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeBoolV var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Single(otlpLogRecord.Attributes); var actualScope = TryGetAttribute(otlpLogRecord, scopeKey); Assert.NotNull(actualScope); @@ -907,6 +917,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeIntVa var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Single(otlpLogRecord.Attributes); var actualScope = TryGetAttribute(otlpLogRecord, scopeKey); Assert.NotNull(actualScope); @@ -935,7 +946,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeDoubl // Act. using (logger.BeginScope(new List> { - new KeyValuePair(scopeKey, scopeValue), + new(scopeKey, scopeValue), })) { logger.LogInformation("Some log information message."); @@ -945,6 +956,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeDoubl var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Single(otlpLogRecord.Attributes); var actualScope = TryGetAttribute(otlpLogRecord, scopeKey); Assert.NotNull(actualScope); @@ -973,7 +985,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeDoubl // Act. using (logger.BeginScope(new List> { - new KeyValuePair(scopeKey, scopeValue), + new(scopeKey, scopeValue), })) { logger.LogInformation("Some log information message."); @@ -983,6 +995,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeDoubl var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Single(otlpLogRecord.Attributes); var actualScope = TryGetAttribute(otlpLogRecord, scopeKey); Assert.NotNull(actualScope); @@ -1038,6 +1051,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfPrimitiveT var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests)); var scopeState = Activator.CreateInstance(typeOfScopeState); + Assert.NotNull(scopeState); // Act. using (logger.BeginScope(scopeState)) @@ -1080,6 +1094,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfDictionary var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Single(otlpLogRecord.Attributes); var actualScope = TryGetAttribute(otlpLogRecord, scopeKey); Assert.NotNull(actualScope); @@ -1105,10 +1120,11 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfEnumerable const string scopeKey = "Some scope key"; const string scopeValue = "Some scope value"; - var scopeValues = new List> { new KeyValuePair(scopeKey, scopeValue) }; + var scopeValues = new List> { new(scopeKey, scopeValue) }; var scopeState = Activator.CreateInstance(typeOfScopeState, scopeValues) as ICollection>; // Act. + Assert.NotNull(scopeState); using (logger.BeginScope(scopeState)) { logger.LogInformation("Some log information message."); @@ -1118,6 +1134,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfEnumerable var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); Assert.Single(otlpLogRecord.Attributes); var actualScope = TryGetAttribute(otlpLogRecord, scopeKey); Assert.NotNull(actualScope); @@ -1157,6 +1174,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndMultipleScopesAreAdded_C var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); var allScopeValues = otlpLogRecord.Attributes .Where(_ => _.Key == scopeKey1 || _.Key == scopeKey2) .Select(_ => _.Value.StringValue); @@ -1197,6 +1215,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndMultipleScopeLevelsAreAd var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); var allScopeValues = otlpLogRecord.Attributes .Where(_ => _.Key == scopeKey1 || _.Key == scopeKey2) .Select(_ => _.Value.StringValue); @@ -1242,6 +1261,7 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeIsUsedInLogMethod_C var logRecord = logRecords.Single(); var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecord); + Assert.NotNull(otlpLogRecord); var allScopeValues = otlpLogRecord.Attributes .Where(_ => _.Key == scopeKey1 || _.Key == scopeKey2) .Select(_ => _.Value.StringValue); @@ -1314,9 +1334,9 @@ public void AddOtlpLogExporterLogRecordProcessorOptionsTest(ExportProcessorType } else { - var simpleProcesor = processor as SimpleLogRecordExportProcessor; + var simpleProcessor = processor as SimpleLogRecordExportProcessor; - Assert.NotNull(simpleProcesor); + Assert.NotNull(simpleProcessor); } } @@ -1381,7 +1401,7 @@ public void ValidateInstrumentationScope() [InlineData("logging", false)] [InlineData(null, true)] [InlineData("logging", true)] - public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFactoryCreate(string optionsName, bool callUseOpenTelemetry) + public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFactoryCreate(string? optionsName, bool callUseOpenTelemetry) { RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( optionsName, @@ -1406,7 +1426,7 @@ public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFact [InlineData("logging", false)] [InlineData(null, true)] [InlineData("logging", true)] - public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBuilder(string optionsName, bool callUseOpenTelemetry) + public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBuilder(string? optionsName, bool callUseOpenTelemetry) { RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( optionsName, @@ -1433,7 +1453,7 @@ public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBui [Theory] [InlineData("my_instrumentation_scope_name", "my_instrumentation_scope_name")] [InlineData(null, "")] - public void LogRecordLoggerNameIsExportedWhenUsingBridgeApi(string loggerName, string expectedScopeName) + public void LogRecordLoggerNameIsExportedWhenUsingBridgeApi(string? loggerName, string expectedScopeName) { LogRecordAttributeList attributes = default; attributes.Add("name", "tomato"); @@ -1469,10 +1489,10 @@ public void LogRecordLoggerNameIsExportedWhenUsingBridgeApi(string loggerName, s } private static void RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( - string optionsName, + string? optionsName, Func, (IDisposable Container, ILoggerFactory LoggerFactory)> createLoggerFactoryFunc) { - var values = new Dictionary() + var values = new Dictionary { [OtlpSpecConfigDefinitions.DefaultEndpointEnvVarName] = "http://test:8888", }; @@ -1542,7 +1562,7 @@ private static void RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( Assert.True(allConfigureDelegateCalled); } - private static OtlpCommon.KeyValue TryGetAttribute(OtlpLogs.LogRecord record, string key) + private static OtlpCommon.KeyValue? TryGetAttribute(OtlpLogs.LogRecord record, string key) { return record.Attributes.FirstOrDefault(att => att.Key == key); } @@ -1550,11 +1570,11 @@ private static OtlpCommon.KeyValue TryGetAttribute(OtlpLogs.LogRecord record, st private static void ConfigureOtlpExporter( ILoggingBuilder builder, bool callUseOpenTelemetry, - string name = null, - Action configureExporter = null, - Action configureExporterAndProcessor = null, - Action configureOptions = null, - List logRecords = null) + string? name = null, + Action? configureExporter = null, + Action? configureExporterAndProcessor = null, + Action? configureOptions = null, + List? logRecords = null) { if (callUseOpenTelemetry) { @@ -1604,23 +1624,4 @@ private static void ConfigureOtlpExporter( #pragma warning restore CS0618 // Type or member is obsolete } } - - private sealed class TestOptionsMonitor : IOptionsMonitor - { - private readonly T instance; - - public TestOptionsMonitor(T instance) - { - this.instance = instance; - } - - public T CurrentValue => this.instance; - - public T Get(string name) => this.instance; - - public IDisposable OnChange(Action listener) - { - throw new NotImplementedException(); - } - } } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs index 07124e63a85..d92f33ee6a9 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs @@ -21,10 +21,10 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; [Collection("EnvVars")] public class OtlpMetricsExporterTests : IDisposable { - private static readonly KeyValuePair[] KeyValues = new KeyValuePair[] + private static readonly KeyValuePair[] KeyValues = new KeyValuePair[] { - new KeyValuePair("key1", "value1"), - new KeyValuePair("key2", 123), + new("key1", "value1"), + new("key2", 123), }; public OtlpMetricsExporterTests() @@ -57,14 +57,14 @@ void CheckMetricReaderDefaults() var metricReader = typeof(MetricReader) .Assembly - .GetType("OpenTelemetry.Metrics.MeterProviderSdk") - .GetField("reader", bindingFlags) + .GetType("OpenTelemetry.Metrics.MeterProviderSdk")? + .GetField("reader", bindingFlags)? .GetValue(meterProvider) as PeriodicExportingMetricReader; Assert.NotNull(metricReader); - var exportIntervalMilliseconds = (int)typeof(PeriodicExportingMetricReader) - .GetField("ExportIntervalMilliseconds", bindingFlags) + var exportIntervalMilliseconds = (int?)typeof(PeriodicExportingMetricReader)? + .GetField("ExportIntervalMilliseconds", bindingFlags)? .GetValue(metricReader); Assert.Equal(60000, exportIntervalMilliseconds); @@ -129,8 +129,8 @@ public void UserHttpFactoryCalled() Assert.Equal(2, invocations); } - options.HttpClientFactory = () => null; - Assert.Throws(() => + options.HttpClientFactory = () => throw new NotSupportedException(); + Assert.Throws(() => { using var exporter = new OtlpMetricExporter(options); }); @@ -219,7 +219,7 @@ public void ToOtlpResourceMetricsTest(bool includeServiceNameInResource) [InlineData("test_gauge", null, null, 123L, null, true)] [InlineData("test_gauge", null, null, null, 123.45, true)] [InlineData("test_gauge", "description", "unit", 123L, null)] - public void TestGaugeToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, bool enableExemplars = false) + public void TestGaugeToOtlpMetric(string name, string? description, string? unit, long? longValue, double? doubleValue, bool enableExemplars = false) { var metrics = new List(); @@ -236,7 +236,7 @@ public void TestGaugeToOtlpMetric(string name, string description, string unit, } else { - meter.CreateObservableGauge(name, () => doubleValue.Value, unit, description); + meter.CreateObservableGauge(name, () => doubleValue!.Value, unit, description); } provider.ForceFlush(); @@ -294,7 +294,7 @@ public void TestGaugeToOtlpMetric(string name, string description, string unit, [InlineData("test_counter", null, null, null, 123.45, MetricReaderTemporalityPreference.Delta, false, true)] [InlineData("test_counter", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)] [InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, true)] - public void TestCounterToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) + public void TestCounterToOtlpMetric(string name, string? description, string? unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) { var metrics = new List(); @@ -308,7 +308,7 @@ public void TestCounterToOtlpMetric(string name, string description, string unit }) .Build(); - var attributes = enableKeyValues ? KeyValues : Array.Empty>(); + var attributes = enableKeyValues ? KeyValues : Array.Empty>(); if (longValue.HasValue) { var counter = meter.CreateCounter(name, unit, description); @@ -317,7 +317,7 @@ public void TestCounterToOtlpMetric(string name, string description, string unit else { var counter = meter.CreateCounter(name, unit, description); - counter.Add(doubleValue.Value, attributes); + counter.Add(doubleValue!.Value, attributes); } provider.ForceFlush(); @@ -391,7 +391,7 @@ public void TestCounterToOtlpMetric(string name, string description, string unit [InlineData("test_counter", null, null, null, -123.45, MetricReaderTemporalityPreference.Delta, false, true)] [InlineData("test_counter", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)] [InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, true)] - public void TestUpDownCounterToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) + public void TestUpDownCounterToOtlpMetric(string name, string? description, string? unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) { var metrics = new List(); @@ -405,7 +405,7 @@ public void TestUpDownCounterToOtlpMetric(string name, string description, strin }) .Build(); - var attributes = enableKeyValues ? KeyValues : Array.Empty>(); + var attributes = enableKeyValues ? KeyValues : Array.Empty>(); if (longValue.HasValue) { var counter = meter.CreateUpDownCounter(name, unit, description); @@ -414,7 +414,7 @@ public void TestUpDownCounterToOtlpMetric(string name, string description, strin else { var counter = meter.CreateUpDownCounter(name, unit, description); - counter.Add(doubleValue.Value, attributes); + counter.Add(doubleValue!.Value, attributes); } provider.ForceFlush(); @@ -488,7 +488,7 @@ public void TestUpDownCounterToOtlpMetric(string name, string description, strin [InlineData("test_histogram", null, null, null, 123.45, MetricReaderTemporalityPreference.Delta, false, true)] [InlineData("test_histogram", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)] [InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, true)] - public void TestExponentialHistogramToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) + public void TestExponentialHistogramToOtlpMetric(string name, string? description, string? unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) { var metrics = new List(); @@ -506,7 +506,7 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description }) .Build(); - var attributes = enableKeyValues ? KeyValues : Array.Empty>(); + var attributes = enableKeyValues ? KeyValues : Array.Empty>(); if (longValue.HasValue) { var histogram = meter.CreateHistogram(name, unit, description); @@ -516,7 +516,7 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description else { var histogram = meter.CreateHistogram(name, unit, description); - histogram.Record(doubleValue.Value, attributes); + histogram.Record(doubleValue!.Value, attributes); histogram.Record(0, attributes); } @@ -577,7 +577,7 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description { Assert.Equal(0, dataPoint.Sum); Assert.Null(dataPoint.Negative); - Assert.True(dataPoint.Positive.Offset == 0); + Assert.Equal(0, dataPoint.Positive.Offset); Assert.Empty(dataPoint.Positive.BucketCounts); } } @@ -594,7 +594,7 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description { Assert.Equal(0, dataPoint.Sum); Assert.Null(dataPoint.Negative); - Assert.True(dataPoint.Positive.Offset == 0); + Assert.Equal(0, dataPoint.Positive.Offset); Assert.Empty(dataPoint.Positive.BucketCounts); } } @@ -628,7 +628,7 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description [InlineData("test_histogram", null, null, null, 123.45, MetricReaderTemporalityPreference.Delta, false, true)] [InlineData("test_histogram", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)] [InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, true)] - public void TestHistogramToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) + public void TestHistogramToOtlpMetric(string name, string? description, string? unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool enableKeyValues = false, bool enableExemplars = false) { var metrics = new List(); @@ -642,7 +642,7 @@ public void TestHistogramToOtlpMetric(string name, string description, string un }) .Build(); - var attributes = enableKeyValues ? KeyValues : Array.Empty>(); + var attributes = enableKeyValues ? KeyValues : Array.Empty>(); if (longValue.HasValue) { var histogram = meter.CreateHistogram(name, unit, description); @@ -651,7 +651,7 @@ public void TestHistogramToOtlpMetric(string name, string description, string un else { var histogram = meter.CreateHistogram(name, unit, description); - histogram.Record(doubleValue.Value, attributes); + histogram.Record(doubleValue!.Value, attributes); } provider.ForceFlush(); @@ -732,7 +732,7 @@ public void TestTemporalityPreferenceUsingConfiguration(string configValue, Metr { var testExecuted = false; - var configData = new Dictionary { [OtlpSpecConfigDefinitionTests.MetricsData.TemporalityKeyName] = configValue }; + var configData = new Dictionary { [OtlpSpecConfigDefinitionTests.MetricsData.TemporalityKeyName] = configValue }; var configuration = new ConfigurationBuilder() .AddInMemoryCollection(configData) .Build(); @@ -786,9 +786,9 @@ public void TestTemporalityPreferenceUsingEnvVar(string configValue, MetricReade [InlineData(true, true)] public void ToOtlpExemplarTests(bool enableTagFiltering, bool enableTracing) { - ActivitySource activitySource = null; - Activity activity = null; - TracerProvider tracerProvider = null; + ActivitySource? activitySource = null; + Activity? activity = null; + TracerProvider? tracerProvider = null; using var meter = new Meter(Utils.GetCurrentMethodName()); @@ -823,8 +823,8 @@ public void ToOtlpExemplarTests(bool enableTagFiltering, bool enableTracing) var counterDouble = meter.CreateCounter("testCounterDouble"); var counterLong = meter.CreateCounter("testCounterLong"); - counterDouble.Add(1.18D, new KeyValuePair("key1", "value1")); - counterLong.Add(18L, new KeyValuePair("key1", "value1")); + counterDouble.Add(1.18D, new KeyValuePair("key1", "value1")); + counterLong.Add(18L, new KeyValuePair("key1", "value1")); meterProvider.ForceFlush(); @@ -869,6 +869,7 @@ void AssertExemplars(T value, Metric metric) else { byte[] traceIdBytes = new byte[16]; + Assert.NotNull(activity); activity.TraceId.CopyTo(traceIdBytes); byte[] spanIdBytes = new byte[8]; @@ -914,7 +915,7 @@ public void Dispose() GC.SuppressFinalize(this); } - private static void VerifyExemplars(long? longValue, double? doubleValue, bool enableExemplars, Func getExemplarFunc, T state) + private static void VerifyExemplars(long? longValue, double? doubleValue, bool enableExemplars, Func getExemplarFunc, T state) { var exemplar = getExemplarFunc(state); @@ -928,6 +929,7 @@ private static void VerifyExemplars(long? longValue, double? doubleValue, boo } else { + Assert.NotNull(doubleValue); Assert.Equal(doubleValue.Value, exemplar.AsDouble); } } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTestHelpers.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTestHelpers.cs index ec9dbbe4312..7cc6b10336e 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTestHelpers.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTestHelpers.cs @@ -11,7 +11,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; internal static class OtlpTestHelpers { public static void AssertOtlpAttributes( - IEnumerable> expected, + IEnumerable> expected, RepeatedField actual) { var expectedAttributes = expected.ToList(); @@ -20,6 +20,7 @@ public static void AssertOtlpAttributes( { var current = expectedAttributes[i].Value; Assert.Equal(expectedAttributes[i].Key, actual[i].Key); + Assert.NotNull(current); if (current.GetType().IsArray) { @@ -91,7 +92,7 @@ public static void AssertOtlpAttributes( Assert.Equal(expectedSize, actual.Count); } - private static void AssertOtlpAttributeValue(object expected, OtlpCommon.AnyValue actual) + private static void AssertOtlpAttributeValue(object? expected, OtlpCommon.AnyValue actual) { switch (expected) { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index 18434043bc7..84d3076500a 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -63,8 +63,8 @@ public void AddOtlpTraceExporterNamedOptionsSupported() [Fact] public void OtlpExporter_BadArgs() { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddOtlpExporter()); + TracerProviderBuilder? builder = null; + Assert.Throws(() => builder!.AddOtlpExporter()); } [Fact] @@ -98,7 +98,7 @@ public void UserHttpFactoryCalled() Assert.Equal(2, invocations); } - options.HttpClientFactory = () => null; + options.HttpClientFactory = () => null!; Assert.Throws(() => { using var exporter = new OtlpTraceExporter(options); @@ -131,8 +131,8 @@ public void ServiceProviderHttpClientFactoryInvoked() [InlineData(false)] public void ToOtlpResourceSpansTest(bool includeServiceNameInResource) { - var evenTags = new[] { new KeyValuePair("k0", "v0") }; - var oddTags = new[] { new KeyValuePair("k1", "v1") }; + var evenTags = new[] { new KeyValuePair("k0", "v0") }; + var oddTags = new[] { new KeyValuePair("k1", "v1") }; var sources = new[] { new ActivitySource("even", "2.4.6"), @@ -163,7 +163,7 @@ public void ToOtlpResourceSpansTest(bool includeServiceNameInResource) var activityKind = isEven ? ActivityKind.Client : ActivityKind.Server; var activityTags = isEven ? evenTags : oddTags; - using Activity activity = source.StartActivity($"span-{i}", activityKind, parentContext: default, activityTags); + using Activity? activity = source.StartActivity($"span-{i}", activityKind, parentContext: default, activityTags); } Assert.Equal(10, exportedItems.Count); @@ -232,12 +232,12 @@ public void SpanLimitsTest() SpanLinkCountLimit = 1, }; - var tags = new ActivityTagsCollection() + var tags = new ActivityTagsCollection { - new KeyValuePair("TruncatedTag", "12345"), - new KeyValuePair("TruncatedStringArray", new string[] { "12345", "1234", string.Empty, null }), - new KeyValuePair("TruncatedObjectTag", new object()), - new KeyValuePair("OneTagTooMany", 1), + new("TruncatedTag", "12345"), + new("TruncatedStringArray", new string?[] { "12345", "1234", string.Empty, null }), + new("TruncatedObjectTag", new object()), + new("OneTagTooMany", 1), }; var links = new[] @@ -249,6 +249,8 @@ public void SpanLimitsTest() using var activitySource = new ActivitySource(nameof(this.SpanLimitsTest)); using var activity = activitySource.StartActivity("root", ActivityKind.Server, default(ActivityContext), tags, links); + Assert.NotNull(activity); + var event1 = new ActivityEvent("Event", DateTime.UtcNow, tags); var event2 = new ActivityEvent("OneEventTooMany", DateTime.Now, tags); @@ -262,7 +264,7 @@ public void SpanLimitsTest() Assert.Equal(1u, otlpSpan.DroppedAttributesCount); Assert.Equal("1234", otlpSpan.Attributes[0].Value.StringValue); ArrayValueAsserts(otlpSpan.Attributes[1].Value.ArrayValue.Values); - Assert.Equal(new object().ToString().Substring(0, 4), otlpSpan.Attributes[2].Value.StringValue); + Assert.Equal(new object().ToString()!.Substring(0, 4), otlpSpan.Attributes[2].Value.StringValue); Assert.Single(otlpSpan.Events); Assert.Equal(1u, otlpSpan.DroppedEventsCount); @@ -270,7 +272,7 @@ public void SpanLimitsTest() Assert.Equal(1u, otlpSpan.Events[0].DroppedAttributesCount); Assert.Equal("1234", otlpSpan.Events[0].Attributes[0].Value.StringValue); ArrayValueAsserts(otlpSpan.Events[0].Attributes[1].Value.ArrayValue.Values); - Assert.Equal(new object().ToString().Substring(0, 4), otlpSpan.Events[0].Attributes[2].Value.StringValue); + Assert.Equal(new object().ToString()!.Substring(0, 4), otlpSpan.Events[0].Attributes[2].Value.StringValue); Assert.Single(otlpSpan.Links); Assert.Equal(1u, otlpSpan.DroppedLinksCount); @@ -278,11 +280,11 @@ public void SpanLimitsTest() Assert.Equal(1u, otlpSpan.Links[0].DroppedAttributesCount); Assert.Equal("1234", otlpSpan.Links[0].Attributes[0].Value.StringValue); ArrayValueAsserts(otlpSpan.Links[0].Attributes[1].Value.ArrayValue.Values); - Assert.Equal(new object().ToString().Substring(0, 4), otlpSpan.Links[0].Attributes[2].Value.StringValue); + Assert.Equal(new object().ToString()!.Substring(0, 4), otlpSpan.Links[0].Attributes[2].Value.StringValue); void ArrayValueAsserts(RepeatedField values) { - var expectedStringArray = new string[] { "1234", "1234", string.Empty, null }; + var expectedStringArray = new string?[] { "1234", "1234", string.Empty, null }; for (var i = 0; i < expectedStringArray.Length; ++i) { var expectedValue = expectedStringArray[i]; @@ -307,21 +309,22 @@ public void ToOtlpSpanTest() using var rootActivity = activitySource.StartActivity("root", ActivityKind.Producer); - var attributes = new List> - { - new KeyValuePair("bool", true), - new KeyValuePair("long", 1L), - new KeyValuePair("string", "text"), - new KeyValuePair("double", 3.14), - new KeyValuePair("int", 1), - new KeyValuePair("datetime", DateTime.UtcNow), - new KeyValuePair("bool_array", new bool[] { true, false }), - new KeyValuePair("int_array", new int[] { 1, 2 }), - new KeyValuePair("double_array", new double[] { 1.0, 2.09 }), - new KeyValuePair("string_array", new string[] { "a", "b" }), - new KeyValuePair("datetime_array", new DateTime[] { DateTime.UtcNow, DateTime.Now }), + var attributes = new List> + { + new("bool", true), + new("long", 1L), + new("string", "text"), + new("double", 3.14), + new("int", 1), + new("datetime", DateTime.UtcNow), + new("bool_array", new bool[] { true, false }), + new("int_array", new int[] { 1, 2 }), + new("double_array", new double[] { 1.0, 2.09 }), + new("string_array", new string[] { "a", "b" }), + new("datetime_array", new DateTime[] { DateTime.UtcNow, DateTime.Now }), }; + Assert.NotNull(rootActivity); foreach (var kvp in attributes) { rootActivity.SetTag(kvp.Key, kvp.Value); @@ -359,16 +362,17 @@ public void ToOtlpSpanTest() var expectedEndTimeUnixNano = expectedStartTimeUnixNano + (duration.TotalMilliseconds * 1_000_000); Assert.Equal(expectedEndTimeUnixNano, otlpSpan.EndTimeUnixNano); - var childLinks = new List { new ActivityLink(rootActivity.Context, new ActivityTagsCollection(attributes)) }; + var childLinks = new List { new(rootActivity.Context, new ActivityTagsCollection(attributes)) }; var childActivity = activitySource.StartActivity( "child", ActivityKind.Client, rootActivity.Context, links: childLinks); + Assert.NotNull(childActivity); childActivity.SetStatus(Status.Error); - var childEvents = new List { new ActivityEvent("e0"), new ActivityEvent("e1", default, new ActivityTagsCollection(attributes)) }; + var childEvents = new List { new("e0"), new("e1", default, new ActivityTagsCollection(attributes)) }; childActivity.AddEvent(childEvents[0]); childActivity.AddEvent(childEvents[1]); @@ -400,7 +404,9 @@ public void ToOtlpSpanTest() Assert.Equal(childLinks.Count, otlpSpan.Links.Count); for (var i = 0; i < childLinks.Count; i++) { - OtlpTestHelpers.AssertOtlpAttributes(childLinks[i].Tags.ToList(), otlpSpan.Links[i].Attributes); + var tags = childLinks[i].Tags; + Assert.NotNull(tags); + OtlpTestHelpers.AssertOtlpAttributes(tags, otlpSpan.Links[i].Attributes); } var flags = (OtlpTrace.SpanFlags)otlpSpan.Flags; @@ -416,7 +422,7 @@ public void ToOtlpSpanActivitiesWithNullArrayTest() using var rootActivity = activitySource.StartActivity("root", ActivityKind.Client); Assert.NotNull(rootActivity); - var stringArr = new string[] { "test", string.Empty, null }; + var stringArr = new string?[] { "test", string.Empty, null }; rootActivity.SetTag("stringArray", stringArr); var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); @@ -439,10 +445,11 @@ public void ToOtlpSpanNativeActivityStatusTest(ActivityStatusCode expectedStatus { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); + Assert.NotNull(activity); activity.SetStatus(expectedStatusCode, statusDescription); var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); - + Assert.NotNull(otlpSpan); if (expectedStatusCode == ActivityStatusCode.Unset) { Assert.Null(otlpSpan.Status); @@ -471,11 +478,13 @@ public void ToOtlpSpanStatusTagTest(StatusCode expectedStatusCode, string status { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); + Assert.NotNull(activity); activity.SetTag(SpanAttributeConstants.StatusCodeKey, statusCodeTagValue); activity.SetTag(SpanAttributeConstants.StatusDescriptionKey, statusDescription); var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); + Assert.NotNull(otlpSpan); Assert.NotNull(otlpSpan.Status); Assert.Equal((int)expectedStatusCode, (int)otlpSpan.Status.Code); @@ -497,10 +506,12 @@ public void ToOtlpSpanStatusTagIsCaseInsensitiveTest(StatusCode expectedStatusCo { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); + Assert.NotNull(activity); activity.SetTag(SpanAttributeConstants.StatusCodeKey, statusCodeTagValue); var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); + Assert.NotNull(otlpSpan); Assert.NotNull(otlpSpan.Status); Assert.Equal((int)expectedStatusCode, (int)otlpSpan.Status.Code); } @@ -510,13 +521,15 @@ public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivitySta { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); - const string TagDescriptionOnError = "Description when TagStatusCode is Error."; + const string tagDescriptionOnError = "Description when TagStatusCode is Error."; + Assert.NotNull(activity); activity.SetStatus(ActivityStatusCode.Ok); activity.SetTag(SpanAttributeConstants.StatusCodeKey, "ERROR"); - activity.SetTag(SpanAttributeConstants.StatusDescriptionKey, TagDescriptionOnError); + activity.SetTag(SpanAttributeConstants.StatusDescriptionKey, tagDescriptionOnError); var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); + Assert.NotNull(otlpSpan); Assert.NotNull(otlpSpan.Status); Assert.Equal((int)ActivityStatusCode.Ok, (int)otlpSpan.Status.Code); Assert.Empty(otlpSpan.Status.Message); @@ -527,15 +540,17 @@ public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivitySta { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); - const string StatusDescriptionOnError = "Description when ActivityStatusCode is Error."; - activity.SetStatus(ActivityStatusCode.Error, StatusDescriptionOnError); + const string statusDescriptionOnError = "Description when ActivityStatusCode is Error."; + Assert.NotNull(activity); + activity.SetStatus(ActivityStatusCode.Error, statusDescriptionOnError); activity.SetTag(SpanAttributeConstants.StatusCodeKey, "OK"); var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); + Assert.NotNull(otlpSpan); Assert.NotNull(otlpSpan.Status); Assert.Equal((int)ActivityStatusCode.Error, (int)otlpSpan.Status.Code); - Assert.Equal(StatusDescriptionOnError, otlpSpan.Status.Message); + Assert.Equal(statusDescriptionOnError, otlpSpan.Status.Message); } [Theory] @@ -545,6 +560,7 @@ public void ToOtlpSpanTraceStateTest(bool traceStateWasSet) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); + Assert.NotNull(activity); string tracestate = "a=b;c=d"; if (traceStateWasSet) { @@ -552,6 +568,7 @@ public void ToOtlpSpanTraceStateTest(bool traceStateWasSet) } var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); + Assert.NotNull(otlpSpan); if (traceStateWasSet) { @@ -571,6 +588,7 @@ public void ToOtlpSpanPeerServiceTest() using var rootActivity = activitySource.StartActivity("root", ActivityKind.Client); + Assert.NotNull(rootActivity); rootActivity.SetTag(SemanticConventions.AttributeHttpHost, "opentelemetry.io"); var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); @@ -641,7 +659,7 @@ public void Null_BatchExportProcessorOptions_SupportedTest() { o.Protocol = OtlpExportProtocol.HttpProtobuf; o.ExportProcessorType = ExportProcessorType.Batch; - o.BatchExportProcessorOptions = null; + o.BatchExportProcessorOptions = null!; }); } @@ -650,8 +668,8 @@ public void NonnamedOptionsMutateSharedInstanceTest() { var testOptionsInstance = new OtlpExporterOptions(); - OtlpExporterOptions tracerOptions = null; - OtlpExporterOptions meterOptions = null; + OtlpExporterOptions? tracerOptions = null; + OtlpExporterOptions? meterOptions = null; var services = new ServiceCollection(); @@ -695,8 +713,8 @@ public void NonnamedOptionsMutateSharedInstanceTest() [Fact] public void NamedOptionsMutateSeparateInstancesTest() { - OtlpExporterOptions tracerOptions = null; - OtlpExporterOptions meterOptions = null; + OtlpExporterOptions? tracerOptions = null; + OtlpExporterOptions? meterOptions = null; var services = new ServiceCollection(); @@ -753,9 +771,11 @@ public void SpanFlagsTest(bool isRecorded, bool isRemote) isRemote: isRemote); using var rootActivity = activitySource.StartActivity("root", ActivityKind.Server, ctx); + Assert.NotNull(rootActivity); var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); + Assert.NotNull(otlpSpan); var flags = (OtlpTrace.SpanFlags)otlpSpan.Flags; ActivityTraceFlags traceFlags = (ActivityTraceFlags)(flags & OtlpTrace.SpanFlags.TraceFlagsMask); @@ -802,9 +822,11 @@ public void SpanLinkFlagsTest(bool isRecorded, bool isRemote) }; using var rootActivity = activitySource.StartActivity("root", ActivityKind.Server, default(ActivityContext), links: links); + Assert.NotNull(rootActivity); var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); + Assert.NotNull(otlpSpan); var spanLink = Assert.Single(otlpSpan.Links); var flags = (OtlpTrace.SpanFlags)spanLink.Flags; diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/SdkLimitOptionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/SdkLimitOptionsTests.cs index dc36def4665..0a737ff1438 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/SdkLimitOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/SdkLimitOptionsTests.cs @@ -135,7 +135,7 @@ public void SpanAttributeCountLimitFallback() [Fact] public void SdkLimitOptionsUsingIConfiguration() { - var values = new Dictionary + var values = new Dictionary { ["OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT"] = "23", ["OTEL_ATTRIBUTE_COUNT_LIMIT"] = "24", diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestExportClient.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestExportClient.cs index eab9178db49..bbecfa2fa37 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestExportClient.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestExportClient.cs @@ -32,7 +32,7 @@ public bool Shutdown(int timeoutMilliseconds) private class TestExportClientResponse : ExportClientResponse { - public TestExportClientResponse(bool success, DateTime deadline, Exception exception) + public TestExportClientResponse(bool success, DateTime deadline, Exception? exception) : base(success, deadline, exception) { } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestHttpMessageHandler.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestHttpMessageHandler.cs index cf62af4e994..2e5d6ede2b0 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestHttpMessageHandler.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/TestHttpMessageHandler.cs @@ -9,14 +9,14 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; internal class TestHttpMessageHandler : HttpMessageHandler { - public HttpRequestMessage HttpRequestMessage { get; private set; } + public HttpRequestMessage? HttpRequestMessage { get; private set; } - public byte[] HttpRequestContent { get; private set; } + public byte[]? HttpRequestContent { get; private set; } public virtual HttpResponseMessage InternalSend(HttpRequestMessage request, CancellationToken cancellationToken) { this.HttpRequestMessage = request; - this.HttpRequestContent = request.Content.ReadAsByteArrayAsync().Result; + this.HttpRequestContent = request.Content!.ReadAsByteArrayAsync().Result; return new HttpResponseMessage(); } diff --git a/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs index c0f5055d490..26d82bb6a0b 100644 --- a/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics.Tracing; using System.Globalization; using System.Reflection; @@ -26,7 +28,7 @@ private static void VerifyMethodImplementation(EventSource eventSource, MethodIn object[] eventArguments = GenerateEventArguments(eventMethod); eventMethod.Invoke(eventSource, eventArguments); - EventWrittenEventArgs actualEvent = listener.Messages.FirstOrDefault(x => x.EventName == eventMethod.Name); + EventWrittenEventArgs? actualEvent = listener.Messages.FirstOrDefault(x => x.EventName == eventMethod.Name); if (actualEvent == null) { @@ -47,7 +49,7 @@ private static void VerifyMethodImplementation(EventSource eventSource, MethodIn } catch (Exception e) { - var name = eventMethod.DeclaringType.Name + "." + eventMethod.Name; + var name = eventMethod.DeclaringType?.Name + "." + eventMethod.Name; throw new Exception("Method '" + name + "' is implemented incorrectly.", e); } @@ -78,7 +80,7 @@ private static object GenerateArgument(ParameterInfo parameter) if (parameter.ParameterType.IsValueType) { - return Activator.CreateInstance(parameter.ParameterType); + return Activator.CreateInstance(parameter.ParameterType)!; } throw new NotSupportedException("Complex types are not supported"); @@ -99,13 +101,14 @@ private static void VerifyEventLevel(MethodInfo eventMethod, EventWrittenEventAr private static void VerifyEventMessage(MethodInfo eventMethod, EventWrittenEventArgs actualEvent, object[] eventArguments) { string expectedMessage = eventArguments.Length == 0 - ? GetEventAttribute(eventMethod).Message - : string.Format(CultureInfo.InvariantCulture, GetEventAttribute(eventMethod).Message, eventArguments); - string actualMessage = string.Format(CultureInfo.InvariantCulture, actualEvent.Message, actualEvent.Payload.ToArray()); + ? GetEventAttribute(eventMethod).Message! + : string.Format(CultureInfo.InvariantCulture, GetEventAttribute(eventMethod).Message!, eventArguments)!; + string actualMessage = string.Format(CultureInfo.InvariantCulture, actualEvent.Message!, actualEvent.Payload!.ToArray()); AssertEqual(nameof(VerifyEventMessage), expectedMessage, actualMessage); } private static void AssertEqual(string methodName, T expected, T actual) + where T : notnull { if (!expected.Equals(actual)) { diff --git a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs index adfebcaf184..0fb748ba2c2 100644 --- a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs +++ b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Xunit; namespace OpenTelemetry.Tests; @@ -15,9 +17,9 @@ public SkipUnlessEnvVarFoundFactAttribute(string environmentVariable) } } - public static string GetEnvironmentVariable(string environmentVariableName) + public static string? GetEnvironmentVariable(string environmentVariableName) { - string environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); + string? environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); if (string.IsNullOrEmpty(environmentVariableValue)) { diff --git a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index dc5ce2ca66f..056c37036dc 100644 --- a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Xunit; namespace OpenTelemetry.Tests; @@ -15,9 +17,9 @@ public SkipUnlessEnvVarFoundTheoryAttribute(string environmentVariable) } } - public static string GetEnvironmentVariable(string environmentVariableName) + public static string? GetEnvironmentVariable(string environmentVariableName) { - string environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); + string? environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); if (string.IsNullOrEmpty(environmentVariableValue)) { diff --git a/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs index 36d47b7b8fa..a386b67c8d3 100644 --- a/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs @@ -1,14 +1,16 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; namespace OpenTelemetry.Tests; internal class TestActivityProcessor : BaseProcessor { - public Action StartAction; - public Action EndAction; + public Action? StartAction; + public Action? EndAction; public TestActivityProcessor() { diff --git a/test/OpenTelemetry.Tests/Shared/TestEventListener.cs b/test/OpenTelemetry.Tests/Shared/TestEventListener.cs index b0cf1d0b120..4e9d79c4735 100644 --- a/test/OpenTelemetry.Tests/Shared/TestEventListener.cs +++ b/test/OpenTelemetry.Tests/Shared/TestEventListener.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics.Tracing; namespace OpenTelemetry.Tests; @@ -39,7 +41,7 @@ public TestEventListener() } /// Gets or sets the handler for event source creation. - public Action OnOnEventSourceCreated { get; set; } + public Action? OnOnEventSourceCreated { get; set; } /// Gets or sets the handler for event source writes. public Action OnOnEventWritten { get; set; } @@ -81,7 +83,7 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) protected override void OnEventSourceCreated(EventSource eventSource) { // Check for null because this method is called by the base class constructor before we can initialize it - Action callback = this.OnOnEventSourceCreated; + Action? callback = this.OnOnEventSourceCreated; callback?.Invoke(eventSource); } } From 7922e30255da5e654be3b2367babce7303a547b2 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 26 Jun 2024 21:17:29 -0700 Subject: [PATCH 035/133] [repo] Add Piotr as approver (#5710) Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06490b1eeb3..bf5d963e5a6 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ you're more than welcome to participate! ([@open-telemetry/dotnet-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-approvers)): * [Cijo Thomas](https://github.com/cijothomas), Microsoft +* [Piotr Kiełkowicz](https://github.com/Kielek), Splunk * [Reiley Yang](https://github.com/reyang), Microsoft * [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft * [Vishwesh Bankwar](https://github.com/vishweshbankwar), Microsoft @@ -126,7 +127,6 @@ you're more than welcome to participate! ([@open-telemetry/dotnet-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-triagers)): * [Martin Thwaites](https://github.com/martinjt), Honeycomb -* [Piotr Kiełkowicz](https://github.com/Kielek), Splunk [Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): From 978b461771c742ddc11e3c590fe52715af253450 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 27 Jun 2024 11:06:21 -0700 Subject: [PATCH 036/133] [infra] Version validation in prepare release workflow (#5723) --- build/scripts/prepare-release.psm1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build/scripts/prepare-release.psm1 b/build/scripts/prepare-release.psm1 index fee472b7a66..44ba4f41304 100644 --- a/build/scripts/prepare-release.psm1 +++ b/build/scripts/prepare-release.psm1 @@ -9,6 +9,12 @@ function CreatePullRequestToUpdateChangelogsAndPublicApis { [Parameter()][string]$gitUserEmail ) + $match = [regex]::Match($version, '^(\d+\.\d+\.\d+)(?:-((?:alpha)|(?:beta)|(?:rc))\.(\d+))?$') + if ($match.Success -eq $false) + { + throw 'Input version did not match expected format' + } + $tag="${minVerTagPrefix}${version}" $branch="release/prepare-${tag}-release" From d8ce51b1b482e7432da0e7498fdc1052eb2ca807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 28 Jun 2024 18:27:15 +0200 Subject: [PATCH 037/133] [repo] Bump Microsoft.SourceLink.GitHub to 8.0.0 (#5728) --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d7180a1c1ae..8d4e8280290 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -84,7 +84,7 @@ - + From 53cda157c97aea083b4e624a87480085d5355619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 3 Jul 2024 18:44:32 +0200 Subject: [PATCH 038/133] Bump OTLP proto files to 1.3.2 (#5736) --- .../profiles/v1experimental/profiles_service_http.yaml | 2 +- .../proto/profiles/v1experimental/pprofextended.proto | 4 +++- .../proto/profiles/v1experimental/profiles.proto | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml index 6bb7cf740b9..ea501afbbb2 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/collector/profiles/v1experimental/profiles_service_http.yaml @@ -4,6 +4,6 @@ type: google.api.Service config_version: 3 http: rules: - - selector: opentelemetry.proto.collector.profiles.v1.ProfilesService.Export + - selector: opentelemetry.proto.collector.profiles.v1experimental.ProfilesService.Export post: /v1experimental/profiles body: "*" diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/pprofextended.proto b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/pprofextended.proto index bd300835546..b5b5b88fcef 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/pprofextended.proto +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/pprofextended.proto @@ -59,6 +59,8 @@ package opentelemetry.proto.profiles.v1experimental; import "opentelemetry/proto/common/v1/common.proto"; option csharp_namespace = "OpenTelemetry.Proto.Profiles.V1Experimental"; +option java_multiple_files = true; +option java_package = "io.opentelemetry.proto.profiles.v1experimental"; option go_package = "go.opentelemetry.io/proto/otlp/profiles/v1experimental"; // Represents a complete profile, including sample types, samples, @@ -203,7 +205,7 @@ enum AggregationTemporality { 11. A request is received, the system measures 1 request. 12. The 1 second collection cycle ends. A metric is exported for the number of requests received over the interval of time t_1 to - t_0+1 with a value of 1. + t_1+1 with a value of 1. Note: Even though, when reporting changes since last report time, using CUMULATIVE is valid, it is not recommended. */ diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/profiles.proto b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/profiles.proto index bbc2b2931da..84b0108f86a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/profiles.proto +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/opentelemetry/proto/profiles/v1experimental/profiles.proto @@ -55,7 +55,7 @@ option go_package = "go.opentelemetry.io/proto/otlp/profiles/v1experimental"; // ┌──────────────────┐ // │ Profile │ // └──────────────────┘ -// │ 1-n +// │ n-1 // │ 1-n ┌───────────────────────────────────────┐ // ▼ │ ▽ // ┌──────────────────┐ 1-n ┌──────────────┐ ┌──────────┐ From da905a8264cd9383ff80df1bfbce21f0a48376fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 5 Jul 2024 21:26:18 +0200 Subject: [PATCH 039/133] [docs] Refresh getting started with AspNetCore and Jaeger (#5740) --- Directory.Packages.props | 8 ++--- .../getting-started-aspnetcore/README.md | 34 +++++++++---------- docs/trace/getting-started-jaeger/README.md | 34 +++++++++++-------- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 8d4e8280290..f15e90b0d96 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -86,10 +86,10 @@ - - - - + + + + diff --git a/docs/trace/getting-started-aspnetcore/README.md b/docs/trace/getting-started-aspnetcore/README.md index a9b7adf0b3d..7febcf4d55f 100644 --- a/docs/trace/getting-started-aspnetcore/README.md +++ b/docs/trace/getting-started-aspnetcore/README.md @@ -30,30 +30,30 @@ in the console for your application (ex `http://localhost:5154`). You should see the trace output from the console. ```text -Activity.TraceId: c1572aa14ee9c0ac037dbdc3e91e5dd7 -Activity.SpanId: 45406137f33cc279 +Activity.TraceId: c28f7b480d5c7dfc30cfbd80ad29028d +Activity.SpanId: 27e478bbf9fdec10 Activity.TraceFlags: Recorded -Activity.ActivitySourceName: OpenTelemetry.Instrumentation.AspNetCore -Activity.DisplayName: / +Activity.ActivitySourceName: Microsoft.AspNetCore +Activity.DisplayName: GET / Activity.Kind: Server -Activity.StartTime: 2023-01-13T19:38:11.5417593Z -Activity.Duration: 00:00:00.0167407 +Activity.StartTime: 2024-07-04T13:03:37.3318740Z +Activity.Duration: 00:00:00.3693734 Activity.Tags: - net.host.name: localhost - net.host.port: 5154 - http.method: GET - http.scheme: http - http.target: / - http.url: http://localhost:5154/ - http.flavor: 1.1 - http.user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76 - http.status_code: 200 + server.address: localhost + server.port: 5154 + http.request.method: GET + url.scheme: https + url.path: / + network.protocol.version: 2 + user_agent.original: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 + http.route: / + http.response.status_code: 200 Resource associated with Activity: service.name: getting-started-aspnetcore - service.instance.id: 32c9371c-ed9d-474c-a698-b169e87a5577 + service.instance.id: a388466b-4969-4bb0-ad96-8f39527fa66b telemetry.sdk.name: opentelemetry telemetry.sdk.language: dotnet - telemetry.sdk.version: 1.5.1 + telemetry.sdk.version: 1.9.0 ``` Congratulations! You are now collecting traces using OpenTelemetry. diff --git a/docs/trace/getting-started-jaeger/README.md b/docs/trace/getting-started-jaeger/README.md index b291933df00..92752ff66da 100644 --- a/docs/trace/getting-started-jaeger/README.md +++ b/docs/trace/getting-started-jaeger/README.md @@ -47,25 +47,29 @@ Run the application again and we should see the trace output from the console: ```text > dotnet run -Activity.TraceId: a80c920e0aabb50b547e2bb7455cfd39 -Activity.SpanId: 4e45a1d51744f329 -Activity.TraceFlags: Recorded -Activity.ParentSpanId: 4f7e9b78c55dcfad -Activity.ActivitySourceName: OpenTelemetry.Instrumentation.Http -Activity.DisplayName: HTTP GET -Activity.Kind: Client -Activity.StartTime: 2022-05-07T02:54:25.7840762Z -Activity.Duration: 00:00:01.9615540 +Activity.TraceId: 693f1d15634bfe6ba3254d6f9d20df27 +Activity.SpanId: 429cc5a90a753fb3 +Activity.TraceFlags: Recorded +Activity.ParentSpanId: 0d64498b736c9a11 +Activity.ActivitySourceName: System.Net.Http +Activity.DisplayName: GET +Activity.Kind: Client +Activity.StartTime: 2024-07-04T13:18:12.2408786Z +Activity.Duration: 00:00:02.1028562 Activity.Tags: - http.method: GET - http.host: httpstat.us - http.url: https://httpstat.us/200?sleep=1000 - http.status_code: 200 + http.request.method: GET + server.address: httpstat.us + server.port: 443 + url.full: https://httpstat.us/200?sleep=Redacted + network.protocol.version: 1.1 + http.response.status_code: 200 Resource associated with Activity: service.name: DemoApp service.version: 1.0.0 - service.instance.id: 1b3b3a6f-be43-46b0-819a-4db1200c633d - + service.instance.id: 03ccafab-e9a7-440a-a9cd-9a0163e0d06c + telemetry.sdk.name: opentelemetry + telemetry.sdk.language: dotnet + telemetry.sdk.version: 1.9.0 ... ``` From 46265e3379ed71ef01666af3e13e6f3803510d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 8 Jul 2024 19:45:15 +0200 Subject: [PATCH 040/133] [tests] Remove unused CustomTextMapPropagator (#5743) --- .../Shared/CustomTextMapPropagator.cs | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 test/OpenTelemetry.Tests/Shared/CustomTextMapPropagator.cs diff --git a/test/OpenTelemetry.Tests/Shared/CustomTextMapPropagator.cs b/test/OpenTelemetry.Tests/Shared/CustomTextMapPropagator.cs deleted file mode 100644 index a3524f17cbf..00000000000 --- a/test/OpenTelemetry.Tests/Shared/CustomTextMapPropagator.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Diagnostics; -using OpenTelemetry.Context.Propagation; - -namespace OpenTelemetry.Tests; - -internal sealed class CustomTextMapPropagator : TextMapPropagator -{ - private static readonly PropagationContext DefaultPropagationContext = default; - - public ActivityTraceId TraceId { get; set; } - - public ActivitySpanId SpanId { get; set; } - - public Action Injected { get; set; } - - public override ISet Fields => null; - -#pragma warning disable SA1201 // Elements should appear in the correct order -#pragma warning disable SA1010 // Opening square brackets should be spaced correctly - public Dictionary> InjectValues = []; -#pragma warning restore SA1010 // Opening square brackets should be spaced correctly -#pragma warning restore SA1201 // Elements should appear in the correct order - - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) - { - if (this.TraceId != default && this.SpanId != default) - { - return new PropagationContext( - new ActivityContext( - this.TraceId, - this.SpanId, - ActivityTraceFlags.Recorded), - default); - } - - return DefaultPropagationContext; - } - - public override void Inject(PropagationContext context, T carrier, Action setter) - { - foreach (var kv in this.InjectValues) - { - setter(carrier, kv.Key, kv.Value.Invoke(context)); - } - - this.Injected?.Invoke(context); - } -} From dbe2ce35e7066a6d8b712c3491c39cd99061cdcc Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Thu, 11 Jul 2024 11:25:23 -0700 Subject: [PATCH 041/133] Bump System.Text.Json version due to CVE-2024-30105 (#5744) --- examples/Directory.Packages.props | 2 +- test/Directory.Packages.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Directory.Packages.props b/examples/Directory.Packages.props index 902efc8cc04..549e1ed325b 100644 --- a/examples/Directory.Packages.props +++ b/examples/Directory.Packages.props @@ -1,6 +1,6 @@ - + diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props index 575224321a8..4800f76a845 100644 --- a/test/Directory.Packages.props +++ b/test/Directory.Packages.props @@ -1,7 +1,7 @@ - + From ccd3759ec86514d0f6e87e460b81d0185a2742c4 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 16 Jul 2024 11:02:21 -0700 Subject: [PATCH 042/133] [benchmarks] Add LogBenchmark when BatchProcessor is used (#5746) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Reiley Yang --- test/Benchmarks/Logs/LogBenchmarks.cs | 70 ++++++++++++++++++--------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/test/Benchmarks/Logs/LogBenchmarks.cs b/test/Benchmarks/Logs/LogBenchmarks.cs index 1854eb26f2a..bfd1edf2e21 100644 --- a/test/Benchmarks/Logs/LogBenchmarks.cs +++ b/test/Benchmarks/Logs/LogBenchmarks.cs @@ -7,23 +7,24 @@ using OpenTelemetry.Logs; /* -BenchmarkDotNet v0.13.10, Windows 11 (10.0.22621.3007/22H2/2022Update/SunValley2) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.22631.3880/23H2/2023Update/SunValley3) 11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores -.NET SDK 8.0.101 - [Host] : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2 - DefaultJob : .NET 8.0.1 (8.0.123.58001), X64 RyuJIT AVX2 - - -| Method | Mean | Error | StdDev | Gen0 | Allocated | -|------------------------------ |-----------:|----------:|----------:|-------:|----------:| -| NoListenerStringInterpolation | 124.458 ns | 2.5188 ns | 2.2329 ns | 0.0114 | 72 B | -| NoListenerExtensionMethod | 36.326 ns | 0.2916 ns | 0.2435 ns | 0.0102 | 64 B | -| NoListener | 1.375 ns | 0.0586 ns | 0.0896 ns | - | - | -| UnnecessaryIsEnabledCheck | 1.332 ns | 0.0225 ns | 0.0188 ns | - | - | -| CreateLoggerRepeatedly | 48.295 ns | 0.5951 ns | 0.4970 ns | 0.0038 | 24 B | -| OneProcessor | 98.133 ns | 1.8805 ns | 1.5703 ns | 0.0063 | 40 B | -| TwoProcessors | 105.414 ns | 0.4610 ns | 0.3850 ns | 0.0063 | 40 B | -| ThreeProcessors | 102.023 ns | 1.4187 ns | 1.1847 ns | 0.0063 | 40 B | +.NET SDK 8.0.107 + [Host] : .NET 8.0.7 (8.0.724.31311), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.7 (8.0.724.31311), X64 RyuJIT AVX2 + + +| Method | Mean | Error | StdDev | Median | Gen0 | Gen1 | Allocated | +|------------------------------ |-----------:|----------:|-----------:|-----------:|-------:|-------:|----------:| +| NoListenerStringInterpolation | 135.503 ns | 2.7458 ns | 4.5114 ns | 135.391 ns | 0.0114 | - | 72 B | +| NoListenerExtensionMethod | 40.218 ns | 0.8249 ns | 2.2581 ns | 39.809 ns | 0.0102 | - | 64 B | +| NoListener | 1.930 ns | 0.0626 ns | 0.1264 ns | 1.889 ns | - | - | - | +| UnnecessaryIsEnabledCheck | 1.531 ns | 0.0542 ns | 0.1267 ns | 1.518 ns | - | - | - | +| CreateLoggerRepeatedly | 53.797 ns | 1.0927 ns | 1.7331 ns | 53.401 ns | 0.0038 | - | 24 B | +| OneProcessor | 111.558 ns | 2.9821 ns | 8.5082 ns | 109.311 ns | 0.0063 | - | 40 B | +| BatchProcessor | 263.650 ns | 5.2908 ns | 14.1223 ns | 258.984 ns | 0.0200 | 0.0043 | 128 B | +| TwoProcessors | 108.701 ns | 2.1964 ns | 4.3355 ns | 108.025 ns | 0.0063 | - | 40 B | +| ThreeProcessors | 105.099 ns | 1.8106 ns | 2.1554 ns | 105.796 ns | 0.0063 | - | 40 B | */ namespace Benchmarks.Logs; @@ -35,11 +36,13 @@ public class LogBenchmarks private readonly ILogger loggerWithNoListener; private readonly ILogger loggerWithOneProcessor; + private readonly ILogger loggerWithBatchProcessor; private readonly ILogger loggerWithTwoProcessors; private readonly ILogger loggerWithThreeProcessors; private readonly ILoggerFactory loggerFactoryWithNoListener; private readonly ILoggerFactory loggerFactoryWithOneProcessor; + private readonly ILoggerFactory loggerFactoryWithBatchProcessor; private readonly ILoggerFactory loggerFactoryWithTwoProcessor; private readonly ILoggerFactory loggerFactoryWithThreeProcessor; @@ -51,24 +54,31 @@ public LogBenchmarks() this.loggerFactoryWithOneProcessor = LoggerFactory.Create(builder => { builder.UseOpenTelemetry(logging => logging - .AddProcessor(new DummyLogProcessor())); + .AddProcessor(new NoOpLogProcessor())); }); this.loggerWithOneProcessor = this.loggerFactoryWithOneProcessor.CreateLogger(); + this.loggerFactoryWithBatchProcessor = LoggerFactory.Create(builder => + { + builder.UseOpenTelemetry(logging => logging + .AddProcessor(new BatchLogRecordExportProcessor(new NoOpExporter()))); + }); + this.loggerWithBatchProcessor = this.loggerFactoryWithBatchProcessor.CreateLogger(); + this.loggerFactoryWithTwoProcessor = LoggerFactory.Create(builder => { builder.UseOpenTelemetry(logging => logging - .AddProcessor(new DummyLogProcessor()) - .AddProcessor(new DummyLogProcessor())); + .AddProcessor(new NoOpLogProcessor()) + .AddProcessor(new NoOpLogProcessor())); }); this.loggerWithTwoProcessors = this.loggerFactoryWithTwoProcessor.CreateLogger(); this.loggerFactoryWithThreeProcessor = LoggerFactory.Create(builder => { builder.UseOpenTelemetry(logging => logging - .AddProcessor(new DummyLogProcessor()) - .AddProcessor(new DummyLogProcessor()) - .AddProcessor(new DummyLogProcessor())); + .AddProcessor(new NoOpLogProcessor()) + .AddProcessor(new NoOpLogProcessor()) + .AddProcessor(new NoOpLogProcessor())); }); this.loggerWithThreeProcessors = this.loggerFactoryWithThreeProcessor.CreateLogger(); } @@ -122,6 +132,12 @@ public void OneProcessor() this.loggerWithOneProcessor.SayHello(FoodName, FoodPrice); } + [Benchmark] + public void BatchProcessor() + { + this.loggerWithBatchProcessor.SayHello(FoodName, FoodPrice); + } + [Benchmark] public void TwoProcessors() { @@ -134,7 +150,15 @@ public void ThreeProcessors() this.loggerWithThreeProcessors.SayHello(FoodName, FoodPrice); } - internal class DummyLogProcessor : BaseProcessor + internal class NoOpLogProcessor : BaseProcessor + { + } + + internal class NoOpExporter : BaseExporter { + public override ExportResult Export(in Batch batch) + { + return ExportResult.Success; + } } } From 46e076fbb75503f61b4df6f81b50489740f432bf Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 16 Jul 2024 12:38:35 -0700 Subject: [PATCH 043/133] [infra] Fix a couple paths in PR auto-label file change detection (#5751) --- build/scripts/add-labels.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/add-labels.psm1 b/build/scripts/add-labels.psm1 index 60c07bc4637..1e2a3f832d8 100644 --- a/build/scripts/add-labels.psm1 +++ b/build/scripts/add-labels.psm1 @@ -99,12 +99,12 @@ function AddLabelsOnPullRequestsBasedOnFilesChanged { $rootInfraFiles.Contains($fullFileName) -or $fileExtension -eq ".props" -or $fileExtension -eq ".targets" -or - $fileChanged.StartsWith('test\openTelemetry.aotcompatibility')) + $fileChanged.StartsWith('test/openTelemetry.aotcompatibility')) { $added = $labelsToAdd.Add("infra") } - if ($fileChanged.StartsWith('test\benchmarks')) + if ($fileChanged.StartsWith('test/benchmarks')) { $added = $labelsToAdd.Add("perf") } From 6a0a934107ee6cb4a59f93599c6122807b9368e3 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Wed, 17 Jul 2024 18:49:33 +0100 Subject: [PATCH 044/133] [api] Fix `Fields` in `CompositeTextMapPropagator` (#5745) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Api/CHANGELOG.md | 5 ++ .../Propagation/CompositeTextMapPropagator.cs | 53 ++++++++++-- .../Propagation/B3PropagatorTest.cs | 0 .../Propagation/BaggagePropagatorTest.cs | 0 .../Propagation/CompositePropagatorTest.cs | 85 +++++++++++++++---- .../Propagation/TestPropagator.cs | 21 +++-- .../Propagation/TracestateUtilsTests.cs | 0 .../OpenTelemetry.Api.Tests.csproj | 1 + 8 files changed, 135 insertions(+), 30 deletions(-) rename test/OpenTelemetry.Api.Tests/{Trace => Context}/Propagation/B3PropagatorTest.cs (100%) rename test/OpenTelemetry.Api.Tests/{Trace => Context}/Propagation/BaggagePropagatorTest.cs (100%) rename test/OpenTelemetry.Api.Tests/{Trace => Context}/Propagation/CompositePropagatorTest.cs (56%) rename test/OpenTelemetry.Api.Tests/{Trace => Context}/Propagation/TestPropagator.cs (78%) rename test/OpenTelemetry.Api.Tests/{Trace => Context}/Propagation/TracestateUtilsTests.cs (100%) diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index f39d81b108e..54710b1022e 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* **Breaking change:** CompositeTextMapPropagator.Fields now returns a + unioned set of fields from all combined propagators. Previously this always + returned an empty set. + ([#5745](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5745)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs index a6b12c3cd1b..016ef0fda4d 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs @@ -11,8 +11,8 @@ namespace OpenTelemetry.Context.Propagation; /// public class CompositeTextMapPropagator : TextMapPropagator { - private static readonly ISet EmptyFields = new HashSet(); - private readonly List propagators; + private readonly IReadOnlyList propagators; + private readonly ISet allFields; /// /// Initializes a new instance of the class. @@ -22,18 +22,55 @@ public CompositeTextMapPropagator(IEnumerable propagators) { Guard.ThrowIfNull(propagators); - this.propagators = new List(propagators); + var propagatorsList = new List(); + + foreach (var propagator in propagators) + { + if (propagator is not null) + { + propagatorsList.Add(propagator); + } + } + + this.propagators = propagatorsList; + + // For efficiency, we resolve the fields from all propagators only once, as they are + // not expected to change (although the implementation doesn't strictly prevent that). + if (this.propagators.Count == 0) + { + // Use a new empty HashSet for each instance to avoid any potential mutation issues. + this.allFields = new HashSet(); + } + else + { + ISet fields = this.propagators[0].Fields; + + var output = fields is not null + ? new HashSet(fields) + : []; + + for (int i = 1; i < this.propagators.Count; i++) + { + fields = this.propagators[i].Fields; + if (fields is not null) + { + output.UnionWith(fields); + } + } + + this.allFields = output; + } } /// - public override ISet Fields => EmptyFields; + public override ISet Fields => this.allFields; /// public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) { - foreach (var propagator in this.propagators) + for (int i = 0; i < this.propagators.Count; i++) { - context = propagator.Extract(context, carrier, getter); + context = this.propagators[i].Extract(context, carrier, getter); } return context; @@ -42,9 +79,9 @@ public override PropagationContext Extract(PropagationContext context, T carr /// public override void Inject(PropagationContext context, T carrier, Action setter) { - foreach (var propagator in this.propagators) + for (int i = 0; i < this.propagators.Count; i++) { - propagator.Inject(context, carrier, setter); + this.propagators[i].Inject(context, carrier, setter); } } } diff --git a/test/OpenTelemetry.Api.Tests/Trace/Propagation/B3PropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs similarity index 100% rename from test/OpenTelemetry.Api.Tests/Trace/Propagation/B3PropagatorTest.cs rename to test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs diff --git a/test/OpenTelemetry.Api.Tests/Trace/Propagation/BaggagePropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs similarity index 100% rename from test/OpenTelemetry.Api.Tests/Trace/Propagation/BaggagePropagatorTest.cs rename to test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs diff --git a/test/OpenTelemetry.Api.Tests/Trace/Propagation/CompositePropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs similarity index 56% rename from test/OpenTelemetry.Api.Tests/Trace/Propagation/CompositePropagatorTest.cs rename to test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs index f4066edcc1e..0fcf7a1952f 100644 --- a/test/OpenTelemetry.Api.Tests/Trace/Propagation/CompositePropagatorTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs @@ -31,28 +31,72 @@ public class CompositePropagatorTest private readonly ActivitySpanId spanId = ActivitySpanId.CreateRandom(); [Fact] - public void CompositePropagator_NullTextFormatList() + public void CompositePropagator_NullTextMapPropagators() { Assert.Throws(() => new CompositeTextMapPropagator(null)); } + [Fact] + public void CompositePropagator_EmptyTextMapPropagators() + { + var compositePropagator = new CompositeTextMapPropagator([]); + Assert.Empty(compositePropagator.Fields); + } + + [Fact] + public void CompositePropagator_NullTextMapPropagator() + { + var compositePropagator = new CompositeTextMapPropagator([null]); + Assert.Empty(compositePropagator.Fields); + } + + [Fact] + public void CompositePropagator_NoOpTextMapPropagators() + { + var compositePropagator = new CompositeTextMapPropagator([new NoopTextMapPropagator()]); + Assert.Empty(compositePropagator.Fields); + } + + [Fact] + public void CompositePropagator_SingleTextMapPropagator() + { + var testPropagator = new TestPropagator("custom-traceparent-1", "custom-tracestate-1"); + + var compositePropagator = new CompositeTextMapPropagator([testPropagator]); + + // We expect a new HashSet, with a copy of the values from the propagator. + Assert.Equal(testPropagator.Fields, compositePropagator.Fields); + Assert.NotSame(testPropagator.Fields, compositePropagator.Fields); + } + [Fact] public void CompositePropagator_TestPropagator() { - var compositePropagator = new CompositeTextMapPropagator(new List - { - new TestPropagator("custom-traceparent-1", "custom-tracestate-1"), - new TestPropagator("custom-traceparent-2", "custom-tracestate-2"), - }); + var testPropagatorA = new TestPropagator("custom-traceparent-1", "custom-tracestate-1"); + var testPropagatorB = new TestPropagator("custom-traceparent-2", "custom-tracestate-2"); + + var compositePropagator = new CompositeTextMapPropagator([testPropagatorA, testPropagatorB,]); var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null); - PropagationContext propagationContext = new PropagationContext(activityContext, default); + var propagationContext = new PropagationContext(activityContext, default); var carrier = new Dictionary(); using var activity = new Activity("test"); compositePropagator.Inject(propagationContext, carrier, Setter); Assert.Contains(carrier, kv => kv.Key == "custom-traceparent-1"); Assert.Contains(carrier, kv => kv.Key == "custom-traceparent-2"); + + Assert.Equal(testPropagatorA.Fields.Count + testPropagatorB.Fields.Count, compositePropagator.Fields.Count); + Assert.Subset(compositePropagator.Fields, testPropagatorA.Fields); + Assert.Subset(compositePropagator.Fields, testPropagatorB.Fields); + + Assert.Equal(1, testPropagatorA.InjectCount); + Assert.Equal(1, testPropagatorB.InjectCount); + + compositePropagator.Extract(default, new Dictionary(), Getter); + + Assert.Equal(1, testPropagatorA.ExtractCount); + Assert.Equal(1, testPropagatorB.ExtractCount); } [Fact] @@ -61,20 +105,24 @@ public void CompositePropagator_UsingSameTag() const string header01 = "custom-tracestate-01"; const string header02 = "custom-tracestate-02"; - var compositePropagator = new CompositeTextMapPropagator(new List - { - new TestPropagator("custom-traceparent", header01, true), - new TestPropagator("custom-traceparent", header02), - }); + var testPropagatorA = new TestPropagator("custom-traceparent", header01, true); + var testPropagatorB = new TestPropagator("custom-traceparent", header02); + + var compositePropagator = new CompositeTextMapPropagator([testPropagatorA, testPropagatorB,]); var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null); - PropagationContext propagationContext = new PropagationContext(activityContext, default); + var propagationContext = new PropagationContext(activityContext, default); var carrier = new Dictionary(); compositePropagator.Inject(propagationContext, carrier, Setter); Assert.Contains(carrier, kv => kv.Key == "custom-traceparent"); + Assert.Equal(3, compositePropagator.Fields.Count); + + Assert.Equal(1, testPropagatorA.InjectCount); + Assert.Equal(1, testPropagatorB.InjectCount); + // checking if the latest propagator is the one with the data. So, it will replace the previous one. Assert.Equal($"00-{this.traceId}-{this.spanId}-{header02.Split('-').Last()}", carrier["custom-traceparent"]); @@ -85,6 +133,9 @@ public void CompositePropagator_UsingSameTag() // checking if we accessed only two times: header/headerstate options // if that's true, we skipped the first one since we have a logic to for the default result Assert.Equal(2, count); + + Assert.Equal(1, testPropagatorA.ExtractCount); + Assert.Equal(1, testPropagatorB.ExtractCount); } [Fact] @@ -99,13 +150,13 @@ public void CompositePropagator_ActivityContext_Baggage() var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null, isRemote: true); var baggage = new Dictionary { ["key1"] = "value1" }; - PropagationContext propagationContextActivityOnly = new PropagationContext(activityContext, default); - PropagationContext propagationContextBaggageOnly = new PropagationContext(default, new Baggage(baggage)); - PropagationContext propagationContextBoth = new PropagationContext(activityContext, new Baggage(baggage)); + var propagationContextActivityOnly = new PropagationContext(activityContext, default); + var propagationContextBaggageOnly = new PropagationContext(default, new Baggage(baggage)); + var propagationContextBoth = new PropagationContext(activityContext, new Baggage(baggage)); var carrier = new Dictionary(); compositePropagator.Inject(propagationContextActivityOnly, carrier, Setter); - PropagationContext extractedContext = compositePropagator.Extract(default, carrier, Getter); + var extractedContext = compositePropagator.Extract(default, carrier, Getter); Assert.Equal(propagationContextActivityOnly, extractedContext); carrier = new Dictionary(); diff --git a/test/OpenTelemetry.Api.Tests/Trace/Propagation/TestPropagator.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs similarity index 78% rename from test/OpenTelemetry.Api.Tests/Trace/Propagation/TestPropagator.cs rename to test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs index abd4a17b1e9..f07875c5d28 100644 --- a/test/OpenTelemetry.Api.Tests/Trace/Propagation/TestPropagator.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs @@ -11,6 +11,9 @@ public class TestPropagator : TextMapPropagator private readonly string stateHeaderName; private readonly bool defaultContext; + private int extractCount = 0; + private int injectCount = 0; + public TestPropagator(string idHeaderName, string stateHeaderName, bool defaultContext = false) { this.idHeaderName = idHeaderName; @@ -18,16 +21,22 @@ public TestPropagator(string idHeaderName, string stateHeaderName, bool defaultC this.defaultContext = defaultContext; } + public int ExtractCount => this.extractCount; + + public int InjectCount => this.injectCount; + public override ISet Fields => new HashSet() { this.idHeaderName, this.stateHeaderName }; public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) { + Interlocked.Increment(ref this.extractCount); + if (this.defaultContext) { return context; } - IEnumerable id = getter(carrier, this.idHeaderName); + var id = getter(carrier, this.idHeaderName); if (!id.Any()) { return context; @@ -39,8 +48,8 @@ public override PropagationContext Extract(PropagationContext context, T carr return context; } - string tracestate = string.Empty; - IEnumerable tracestateCollection = getter(carrier, this.stateHeaderName); + var tracestate = string.Empty; + var tracestateCollection = getter(carrier, this.stateHeaderName); if (tracestateCollection?.Any() ?? false) { TraceContextPropagator.TryExtractTracestate(tracestateCollection.ToArray(), out tracestate); @@ -53,14 +62,16 @@ public override PropagationContext Extract(PropagationContext context, T carr public override void Inject(PropagationContext context, T carrier, Action setter) { - string headerNumber = this.stateHeaderName.Split('-').Last(); + Interlocked.Increment(ref this.injectCount); + + var headerNumber = this.stateHeaderName.Split('-').Last(); var traceparent = string.Concat("00-", context.ActivityContext.TraceId.ToHexString(), "-", context.ActivityContext.SpanId.ToHexString()); traceparent = string.Concat(traceparent, "-", headerNumber); setter(carrier, this.idHeaderName, traceparent); - string tracestateStr = context.ActivityContext.TraceState; + var tracestateStr = context.ActivityContext.TraceState; if (tracestateStr?.Length > 0) { setter(carrier, this.stateHeaderName, tracestateStr); diff --git a/test/OpenTelemetry.Api.Tests/Trace/Propagation/TracestateUtilsTests.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs similarity index 100% rename from test/OpenTelemetry.Api.Tests/Trace/Propagation/TracestateUtilsTests.cs rename to test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs diff --git a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj index b2e0fa8b6db..08073d127f7 100644 --- a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj +++ b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj @@ -9,6 +9,7 @@ + From 36c586ddcc62cc1e4da82c6f9f65dba16b78161a Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 17 Jul 2024 11:04:36 -0700 Subject: [PATCH 045/133] [benckmarks] Rename NoOp to Noop (#5752) Co-authored-by: Mikel Blanchard --- test/Benchmarks/Logs/LogBenchmarks.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/Benchmarks/Logs/LogBenchmarks.cs b/test/Benchmarks/Logs/LogBenchmarks.cs index bfd1edf2e21..312de9c2fac 100644 --- a/test/Benchmarks/Logs/LogBenchmarks.cs +++ b/test/Benchmarks/Logs/LogBenchmarks.cs @@ -54,31 +54,31 @@ public LogBenchmarks() this.loggerFactoryWithOneProcessor = LoggerFactory.Create(builder => { builder.UseOpenTelemetry(logging => logging - .AddProcessor(new NoOpLogProcessor())); + .AddProcessor(new NoopLogProcessor())); }); this.loggerWithOneProcessor = this.loggerFactoryWithOneProcessor.CreateLogger(); this.loggerFactoryWithBatchProcessor = LoggerFactory.Create(builder => { builder.UseOpenTelemetry(logging => logging - .AddProcessor(new BatchLogRecordExportProcessor(new NoOpExporter()))); + .AddProcessor(new BatchLogRecordExportProcessor(new NoopExporter()))); }); this.loggerWithBatchProcessor = this.loggerFactoryWithBatchProcessor.CreateLogger(); this.loggerFactoryWithTwoProcessor = LoggerFactory.Create(builder => { builder.UseOpenTelemetry(logging => logging - .AddProcessor(new NoOpLogProcessor()) - .AddProcessor(new NoOpLogProcessor())); + .AddProcessor(new NoopLogProcessor()) + .AddProcessor(new NoopLogProcessor())); }); this.loggerWithTwoProcessors = this.loggerFactoryWithTwoProcessor.CreateLogger(); this.loggerFactoryWithThreeProcessor = LoggerFactory.Create(builder => { builder.UseOpenTelemetry(logging => logging - .AddProcessor(new NoOpLogProcessor()) - .AddProcessor(new NoOpLogProcessor()) - .AddProcessor(new NoOpLogProcessor())); + .AddProcessor(new NoopLogProcessor()) + .AddProcessor(new NoopLogProcessor()) + .AddProcessor(new NoopLogProcessor())); }); this.loggerWithThreeProcessors = this.loggerFactoryWithThreeProcessor.CreateLogger(); } @@ -150,11 +150,11 @@ public void ThreeProcessors() this.loggerWithThreeProcessors.SayHello(FoodName, FoodPrice); } - internal class NoOpLogProcessor : BaseProcessor + internal class NoopLogProcessor : BaseProcessor { } - internal class NoOpExporter : BaseExporter + internal class NoopExporter : BaseExporter { public override ExportResult Export(in Batch batch) { From 05bb05a0dc0aab9122ae35989c12c3bf5d939ca7 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 19 Jul 2024 15:03:44 -0700 Subject: [PATCH 046/133] [sdk] Add OpenTelemetrySdk builder pattern (#5325) --- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 8 ++ src/OpenTelemetry/CHANGELOG.md | 6 + src/OpenTelemetry/OpenTelemetrySdk.cs | 124 ++++++++++++++++++ .../OpenTelemetrySdkExtensions.cs | 36 +++++ .../OpenTelemetrySdkTests.cs | 70 ++++++++++ 5 files changed, 244 insertions(+) create mode 100644 src/OpenTelemetry/OpenTelemetrySdk.cs create mode 100644 src/OpenTelemetry/OpenTelemetrySdkExtensions.cs create mode 100644 test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs diff --git a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..7dc29c7de2d 100644 --- a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +OpenTelemetry.OpenTelemetrySdk +OpenTelemetry.OpenTelemetrySdk.Dispose() -> void +OpenTelemetry.OpenTelemetrySdk.LoggerProvider.get -> OpenTelemetry.Logs.LoggerProvider! +OpenTelemetry.OpenTelemetrySdk.MeterProvider.get -> OpenTelemetry.Metrics.MeterProvider! +OpenTelemetry.OpenTelemetrySdk.TracerProvider.get -> OpenTelemetry.Trace.TracerProvider! +OpenTelemetry.OpenTelemetrySdkExtensions +static OpenTelemetry.OpenTelemetrySdk.Create(System.Action! configure) -> OpenTelemetry.OpenTelemetrySdk! +static OpenTelemetry.OpenTelemetrySdkExtensions.GetLoggerFactory(this OpenTelemetry.OpenTelemetrySdk! sdk) -> Microsoft.Extensions.Logging.ILoggerFactory! diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index ca4d195698d..100ec92d219 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Added `OpenTelemetrySdk.Create` API for configuring OpenTelemetry .NET signals + (logging, tracing, and metrics) via a single builder. This new API simplifies + bootstrap and teardown, and supports cross-cutting extensions targeting + `IOpenTelemetryBuilder`. + ([#5325](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5325)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry/OpenTelemetrySdk.cs b/src/OpenTelemetry/OpenTelemetrySdk.cs new file mode 100644 index 00000000000..7020d05ce1c --- /dev/null +++ b/src/OpenTelemetry/OpenTelemetrySdk.cs @@ -0,0 +1,124 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Internal; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace OpenTelemetry; + +/// +/// Contains methods for configuring the OpenTelemetry SDK and accessing +/// logging, metrics, and tracing providers. +/// +public sealed class OpenTelemetrySdk : IDisposable +{ + private readonly ServiceProvider serviceProvider; + + private OpenTelemetrySdk( + Action configure) + { + Debug.Assert(configure != null, "configure was null"); + + var services = new ServiceCollection(); + + var builder = new OpenTelemetrySdkBuilder(services); + + configure!(builder); + + this.serviceProvider = services.BuildServiceProvider(); + + this.LoggerProvider = (LoggerProvider?)this.serviceProvider.GetService(typeof(LoggerProvider)) + ?? new NoopLoggerProvider(); + this.MeterProvider = (MeterProvider?)this.serviceProvider.GetService(typeof(MeterProvider)) + ?? new NoopMeterProvider(); + this.TracerProvider = (TracerProvider?)this.serviceProvider.GetService(typeof(TracerProvider)) + ?? new NoopTracerProvider(); + } + + /// + /// Gets the . + /// + /// + /// Note: The default will be a no-op instance. + /// Call to + /// enable logging. + /// + public LoggerProvider LoggerProvider { get; } + + /// + /// Gets the . + /// + /// + /// Note: The default will be a no-op instance. + /// Call + /// to enable metrics. + /// + public MeterProvider MeterProvider { get; } + + /// + /// Gets the . + /// + /// + /// Note: The default will be a no-op instance. + /// Call + /// to enable tracing. + /// + public TracerProvider TracerProvider { get; } + + /// + /// Gets the containing SDK services. + /// + internal IServiceProvider Services => this.serviceProvider; + + /// + /// Create an instance. + /// + /// configuration delegate. + /// Created . + public static OpenTelemetrySdk Create( + Action configure) + { + Guard.ThrowIfNull(configure); + + return new(configure); + } + + /// + public void Dispose() + { + this.serviceProvider.Dispose(); + } + + internal sealed class NoopLoggerProvider : LoggerProvider + { + } + + internal sealed class NoopMeterProvider : MeterProvider + { + } + + internal sealed class NoopTracerProvider : TracerProvider + { + } + + private sealed class OpenTelemetrySdkBuilder : IOpenTelemetryBuilder + { + public OpenTelemetrySdkBuilder(IServiceCollection services) + { + Debug.Assert(services != null, "services was null"); + + services!.AddOpenTelemetrySharedProviderBuilderServices(); + + this.Services = services!; + } + + public IServiceCollection Services { get; } + } +} diff --git a/src/OpenTelemetry/OpenTelemetrySdkExtensions.cs b/src/OpenTelemetry/OpenTelemetrySdkExtensions.cs new file mode 100644 index 00000000000..f1f01e0f20a --- /dev/null +++ b/src/OpenTelemetry/OpenTelemetrySdkExtensions.cs @@ -0,0 +1,36 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using OpenTelemetry.Internal; + +namespace OpenTelemetry; + +/// +/// Contains methods for extending the class. +/// +public static class OpenTelemetrySdkExtensions +{ + private static readonly NullLoggerFactory NoopLoggerFactory = new(); + + /// + /// Gets the contained in an instance. + /// + /// + /// Note: The default will be a no-op instance. + /// Call + /// to enable logging. + /// + /// . + /// . + public static ILoggerFactory GetLoggerFactory(this OpenTelemetrySdk sdk) + { + Guard.ThrowIfNull(sdk); + + return (ILoggerFactory?)sdk.Services.GetService(typeof(ILoggerFactory)) + ?? NoopLoggerFactory; + } +} diff --git a/test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs b/test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs new file mode 100644 index 00000000000..3c8522cb554 --- /dev/null +++ b/test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs @@ -0,0 +1,70 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using Microsoft.Extensions.Logging.Abstractions; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Tests; + +public class OpenTelemetrySdkTests +{ + [Fact] + public void BuilderDelegateRequiredTest() + { + Assert.Throws(() => OpenTelemetrySdk.Create(null!)); + } + + [Fact] + public void NoopProvidersReturnedTest() + { + bool builderDelegateInvoked = false; + + using var sdk = OpenTelemetrySdk.Create(builder => + { + builderDelegateInvoked = true; + Assert.NotNull(builder.Services); + }); + + Assert.True(builderDelegateInvoked); + + Assert.NotNull(sdk); + Assert.NotNull(sdk.Services); + Assert.True(sdk.LoggerProvider is OpenTelemetrySdk.NoopLoggerProvider); + Assert.True(sdk.MeterProvider is OpenTelemetrySdk.NoopMeterProvider); + Assert.True(sdk.TracerProvider is OpenTelemetrySdk.NoopTracerProvider); + Assert.True(sdk.GetLoggerFactory() is NullLoggerFactory); + } + + [Fact] + public void ProvidersCreatedAndDisposedTest() + { + var sdk = OpenTelemetrySdk.Create(builder => + { + builder + .WithLogging() + .WithMetrics() + .WithTracing(); + }); + + var loggerProvider = sdk.LoggerProvider as LoggerProviderSdk; + var meterProvider = sdk.MeterProvider as MeterProviderSdk; + var tracerProvider = sdk.TracerProvider as TracerProviderSdk; + + Assert.NotNull(loggerProvider); + Assert.NotNull(meterProvider); + Assert.NotNull(tracerProvider); + + Assert.True(sdk.GetLoggerFactory() is not NullLoggerFactory); + + sdk.Dispose(); + + Assert.True(loggerProvider.Disposed); + Assert.True(meterProvider.Disposed); + Assert.True(tracerProvider.Disposed); + } +} From 22a58aa89e29cfb36fdab370957a2a6bd24aab9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 26 Jul 2024 18:24:48 +0200 Subject: [PATCH 047/133] [Exporter.Console, Exporter.InMemory] Nullable (#5765) --- .../.publicApi/Stable/PublicAPI.Shipped.txt | 43 ++++++++++--------- .../ConsoleActivityExporter.cs | 2 +- .../ConsoleExporterHelperExtensions.cs | 6 +-- .../ConsoleExporterLoggingExtensions.cs | 8 ++-- .../ConsoleExporterMetricsExtensions.cs | 12 +++--- .../ConsoleLogRecordExporter.cs | 10 ++--- .../ConsoleMetricExporter.cs | 4 +- .../Implementation/ConsoleTagWriter.cs | 7 ++- .../OpenTelemetry.Exporter.Console.csproj | 3 -- .../.publicApi/Stable/PublicAPI.Shipped.txt | 37 ++++++++-------- .../InMemoryExporter.cs | 4 +- .../InMemoryExporterMetricsExtensions.cs | 12 +++--- .../OpenTelemetry.Exporter.InMemory.csproj | 3 -- 13 files changed, 76 insertions(+), 75 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt index 0e45009bac8..d3f3a6d769a 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt @@ -1,8 +1,9 @@ +#nullable enable OpenTelemetry.Exporter.ConsoleActivityExporter -OpenTelemetry.Exporter.ConsoleActivityExporter.ConsoleActivityExporter(OpenTelemetry.Exporter.ConsoleExporterOptions options) -> void +OpenTelemetry.Exporter.ConsoleActivityExporter.ConsoleActivityExporter(OpenTelemetry.Exporter.ConsoleExporterOptions! options) -> void OpenTelemetry.Exporter.ConsoleExporter -OpenTelemetry.Exporter.ConsoleExporter.ConsoleExporter(OpenTelemetry.Exporter.ConsoleExporterOptions options) -> void -OpenTelemetry.Exporter.ConsoleExporter.WriteLine(string message) -> void +OpenTelemetry.Exporter.ConsoleExporter.ConsoleExporter(OpenTelemetry.Exporter.ConsoleExporterOptions! options) -> void +OpenTelemetry.Exporter.ConsoleExporter.WriteLine(string! message) -> void OpenTelemetry.Exporter.ConsoleExporterOptions OpenTelemetry.Exporter.ConsoleExporterOptions.ConsoleExporterOptions() -> void OpenTelemetry.Exporter.ConsoleExporterOptions.Targets.get -> OpenTelemetry.Exporter.ConsoleExporterOutputTargets @@ -11,26 +12,26 @@ OpenTelemetry.Exporter.ConsoleExporterOutputTargets OpenTelemetry.Exporter.ConsoleExporterOutputTargets.Console = 1 -> OpenTelemetry.Exporter.ConsoleExporterOutputTargets OpenTelemetry.Exporter.ConsoleExporterOutputTargets.Debug = 2 -> OpenTelemetry.Exporter.ConsoleExporterOutputTargets OpenTelemetry.Exporter.ConsoleLogRecordExporter -OpenTelemetry.Exporter.ConsoleLogRecordExporter.ConsoleLogRecordExporter(OpenTelemetry.Exporter.ConsoleExporterOptions options) -> void +OpenTelemetry.Exporter.ConsoleLogRecordExporter.ConsoleLogRecordExporter(OpenTelemetry.Exporter.ConsoleExporterOptions! options) -> void OpenTelemetry.Exporter.ConsoleMetricExporter -OpenTelemetry.Exporter.ConsoleMetricExporter.ConsoleMetricExporter(OpenTelemetry.Exporter.ConsoleExporterOptions options) -> void +OpenTelemetry.Exporter.ConsoleMetricExporter.ConsoleMetricExporter(OpenTelemetry.Exporter.ConsoleExporterOptions! options) -> void OpenTelemetry.Logs.ConsoleExporterLoggingExtensions OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions OpenTelemetry.Trace.ConsoleExporterHelperExtensions -override OpenTelemetry.Exporter.ConsoleActivityExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.ConsoleActivityExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.ConsoleMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, string name, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Action configure) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.ConsoleMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, string? name, System.Action? configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action? configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs index 9197cd1287c..08d280c6101 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs @@ -123,7 +123,7 @@ public override ExportResult Export(in Batch batch) this.WriteLine("Resource associated with Activity:"); foreach (var resourceAttribute in resource.Attributes) { - if (this.TagWriter.TryTransformTag(resourceAttribute, out var result)) + if (this.TagWriter.TryTransformTag(resourceAttribute.Key, resourceAttribute.Value, out var result)) { this.WriteLine($" {result.Key}: {result.Value}"); } diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs index b79aa0d9ed9..12e009f5439 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs @@ -24,7 +24,7 @@ public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilde /// builder to use. /// Callback action for configuring . /// The instance of to chain the calls. - public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder, Action configure) + public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder, Action? configure) => AddConsoleExporter(builder, name: null, configure); /// @@ -36,8 +36,8 @@ public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilde /// The instance of to chain the calls. public static TracerProviderBuilder AddConsoleExporter( this TracerProviderBuilder builder, - string name, - Action configure) + string? name, + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs index 80c767343b7..5066cda7d9f 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs @@ -26,7 +26,7 @@ public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLo /// Callback action for configuring . /// The instance of to chain the calls. // TODO: [Obsolete("Call LoggerProviderBuilder.AddConsoleExporter instead this method will be removed in a future version.")] - public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions, Action configure) + public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions, Action? configure) { Guard.ThrowIfNull(loggerOptions); @@ -52,7 +52,7 @@ public static LoggerProviderBuilder AddConsoleExporter( /// The supplied instance of to chain the calls. public static LoggerProviderBuilder AddConsoleExporter( this LoggerProviderBuilder loggerProviderBuilder, - Action configure) + Action? configure) => AddConsoleExporter(loggerProviderBuilder, name: null, configure); /// @@ -64,8 +64,8 @@ public static LoggerProviderBuilder AddConsoleExporter( /// The supplied instance of to chain the calls. public static LoggerProviderBuilder AddConsoleExporter( this LoggerProviderBuilder loggerProviderBuilder, - string name, - Action configure) + string? name, + Action? configure) { Guard.ThrowIfNull(loggerProviderBuilder); diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs index 103593efddd..b88953193ee 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs @@ -30,7 +30,7 @@ public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder /// builder to use. /// Callback action for configuring . /// The instance of to chain the calls. - public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder builder, Action configureExporter) + public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder builder, Action? configureExporter) => AddConsoleExporter(builder, name: null, configureExporter); /// @@ -42,8 +42,8 @@ public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder /// The instance of to chain the calls. public static MeterProviderBuilder AddConsoleExporter( this MeterProviderBuilder builder, - string name, - Action configureExporter) + string? name, + Action? configureExporter) { Guard.ThrowIfNull(builder); @@ -72,7 +72,7 @@ public static MeterProviderBuilder AddConsoleExporter( /// The instance of to chain the calls. public static MeterProviderBuilder AddConsoleExporter( this MeterProviderBuilder builder, - Action configureExporterAndMetricReader) + Action? configureExporterAndMetricReader) => AddConsoleExporter(builder, name: null, configureExporterAndMetricReader); /// @@ -86,8 +86,8 @@ public static MeterProviderBuilder AddConsoleExporter( /// The instance of to chain the calls. public static MeterProviderBuilder AddConsoleExporter( this MeterProviderBuilder builder, - string name, - Action configureExporterAndMetricReader) + string? name, + Action? configureExporterAndMetricReader) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs index 3ad90910954..9818b17f4b0 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs @@ -12,7 +12,7 @@ public class ConsoleLogRecordExporter : ConsoleExporter private const int RightPaddingLength = 35; private readonly object syncObject = new(); private bool disposed; - private string disposedStackTrace; + private string? disposedStackTrace; private bool isDisposeMessageSent; public ConsoleLogRecordExporter(ConsoleExporterOptions options) @@ -39,7 +39,7 @@ public override ExportResult Export(in Batch batch) this.WriteLine("The console exporter is still being invoked after it has been disposed. This could be due to the application's incorrect lifecycle management of the LoggerFactory/OpenTelemetry .NET SDK."); this.WriteLine(Environment.StackTrace); this.WriteLine(Environment.NewLine + "Dispose was called on the following stack trace:"); - this.WriteLine(this.disposedStackTrace); + this.WriteLine(this.disposedStackTrace!); } return ExportResult.Failure; @@ -90,7 +90,7 @@ public override ExportResult Export(in Batch batch) // See https://github.com/open-telemetry/opentelemetry-dotnet/pull/3182 // for explanation. var valueToTransform = logRecord.Attributes[i].Key.Equals("{OriginalFormat}") - ? new KeyValuePair("OriginalFormat (a.k.a Body)", logRecord.Attributes[i].Value) + ? new KeyValuePair("OriginalFormat (a.k.a Body)", logRecord.Attributes[i].Value) : logRecord.Attributes[i]; if (this.TagWriter.TryTransformTag(valueToTransform, out var result)) @@ -125,7 +125,7 @@ void ProcessScope(LogRecordScope scope, ConsoleLogRecordExporter exporter) exporter.WriteLine("LogRecord.ScopeValues (Key:Value):"); } - foreach (KeyValuePair scopeItem in scope) + foreach (KeyValuePair scopeItem in scope) { if (this.TagWriter.TryTransformTag(scopeItem, out var result)) { @@ -140,7 +140,7 @@ void ProcessScope(LogRecordScope scope, ConsoleLogRecordExporter exporter) this.WriteLine("\nResource associated with LogRecord:"); foreach (var resourceAttribute in resource.Attributes) { - if (this.TagWriter.TryTransformTag(resourceAttribute, out var result)) + if (this.TagWriter.TryTransformTag(resourceAttribute.Key, resourceAttribute.Value, out var result)) { this.WriteLine($"{result.Key}: {result.Value}"); } diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs index 4bd9772b217..264da361e6e 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs @@ -10,7 +10,7 @@ namespace OpenTelemetry.Exporter; public class ConsoleMetricExporter : ConsoleExporter { - private Resource resource; + private Resource? resource; public ConsoleMetricExporter(ConsoleExporterOptions options) : base(options) @@ -27,7 +27,7 @@ public override ExportResult Export(in Batch batch) this.WriteLine("Resource associated with Metric:"); foreach (var resourceAttribute in this.resource.Attributes) { - if (this.TagWriter.TryTransformTag(resourceAttribute, out var result)) + if (this.TagWriter.TryTransformTag(resourceAttribute.Key, resourceAttribute.Value, out var result)) { this.WriteLine($" {result.Key}: {result.Value}"); } diff --git a/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs b/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs index 2f36df00915..da8e6076f30 100644 --- a/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs +++ b/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs @@ -21,9 +21,14 @@ public ConsoleTagWriter(Action onUnsupportedTagDropped) } public bool TryTransformTag(KeyValuePair tag, out KeyValuePair result) + { + return this.TryTransformTag(tag.Key, tag.Value, out result); + } + + public bool TryTransformTag(string key, object? value, out KeyValuePair result) { ConsoleTag consoleTag = default; - if (this.TryWriteTag(ref consoleTag, tag)) + if (this.TryWriteTag(ref consoleTag, key, value)) { result = new KeyValuePair(consoleTag.Key!, consoleTag.Value!); return true; diff --git a/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj b/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj index 3e6d3b58284..511f15d59c8 100644 --- a/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj +++ b/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj @@ -5,9 +5,6 @@ Console exporter for OpenTelemetry .NET $(PackageTags);Console;distributed-tracing core- - - - disable diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt index a79ca4f2cf5..10d97f89495 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt @@ -1,25 +1,26 @@ +#nullable enable OpenTelemetry.Exporter.InMemoryExporter -OpenTelemetry.Exporter.InMemoryExporter.InMemoryExporter(System.Collections.Generic.ICollection exportedItems) -> void +OpenTelemetry.Exporter.InMemoryExporter.InMemoryExporter(System.Collections.Generic.ICollection! exportedItems) -> void OpenTelemetry.Logs.InMemoryExporterLoggingExtensions OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions OpenTelemetry.Metrics.MetricSnapshot -OpenTelemetry.Metrics.MetricSnapshot.Description.get -> string -OpenTelemetry.Metrics.MetricSnapshot.MeterName.get -> string -OpenTelemetry.Metrics.MetricSnapshot.MeterVersion.get -> string -OpenTelemetry.Metrics.MetricSnapshot.MetricPoints.get -> System.Collections.Generic.IReadOnlyList -OpenTelemetry.Metrics.MetricSnapshot.MetricSnapshot(OpenTelemetry.Metrics.Metric metric) -> void +OpenTelemetry.Metrics.MetricSnapshot.Description.get -> string! +OpenTelemetry.Metrics.MetricSnapshot.MeterName.get -> string! +OpenTelemetry.Metrics.MetricSnapshot.MeterVersion.get -> string! +OpenTelemetry.Metrics.MetricSnapshot.MetricPoints.get -> System.Collections.Generic.IReadOnlyList! +OpenTelemetry.Metrics.MetricSnapshot.MetricSnapshot(OpenTelemetry.Metrics.Metric! metric) -> void OpenTelemetry.Metrics.MetricSnapshot.MetricType.get -> OpenTelemetry.Metrics.MetricType -OpenTelemetry.Metrics.MetricSnapshot.Name.get -> string -OpenTelemetry.Metrics.MetricSnapshot.Unit.get -> string +OpenTelemetry.Metrics.MetricSnapshot.Name.get -> string! +OpenTelemetry.Metrics.MetricSnapshot.Unit.get -> string! OpenTelemetry.Trace.InMemoryExporterHelperExtensions override OpenTelemetry.Exporter.InMemoryExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.InMemoryExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.LoggerProviderBuilder loggerProviderBuilder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.InMemoryExporterHelperExtensions.AddInMemoryExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Collections.Generic.ICollection exportedItems) -> OpenTelemetry.Trace.TracerProviderBuilder +override OpenTelemetry.Exporter.InMemoryExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.InMemoryExporterHelperExtensions.AddInMemoryExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs index dedcf65b37c..8533108ce86 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs @@ -6,10 +6,10 @@ namespace OpenTelemetry.Exporter; public class InMemoryExporter : BaseExporter where T : class { - private readonly ICollection exportedItems; + private readonly ICollection? exportedItems; private readonly ExportFunc onExport; private bool disposed; - private string disposedStackTrace; + private string? disposedStackTrace; public InMemoryExporter(ICollection exportedItems) { diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs index e645b67b455..660b9db11e3 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs @@ -41,7 +41,7 @@ public static MeterProviderBuilder AddInMemoryExporter(this MeterProviderBuilder public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, ICollection exportedItems, - Action configureMetricReader) + Action? configureMetricReader) => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader); /// @@ -57,9 +57,9 @@ public static MeterProviderBuilder AddInMemoryExporter( /// The instance of to chain the calls. public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, - string name, + string? name, ICollection exportedItems, - Action configureMetricReader) + Action? configureMetricReader) { Guard.ThrowIfNull(builder); Guard.ThrowIfNull(exportedItems); @@ -108,7 +108,7 @@ public static MeterProviderBuilder AddInMemoryExporter( public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, ICollection exportedItems, - Action configureMetricReader) + Action? configureMetricReader) => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader); /// @@ -125,9 +125,9 @@ public static MeterProviderBuilder AddInMemoryExporter( /// The instance of to chain the calls. public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, - string name, + string? name, ICollection exportedItems, - Action configureMetricReader) + Action? configureMetricReader) { Guard.ThrowIfNull(builder); Guard.ThrowIfNull(exportedItems); diff --git a/src/OpenTelemetry.Exporter.InMemory/OpenTelemetry.Exporter.InMemory.csproj b/src/OpenTelemetry.Exporter.InMemory/OpenTelemetry.Exporter.InMemory.csproj index f27ac138017..8ca97988f64 100644 --- a/src/OpenTelemetry.Exporter.InMemory/OpenTelemetry.Exporter.InMemory.csproj +++ b/src/OpenTelemetry.Exporter.InMemory/OpenTelemetry.Exporter.InMemory.csproj @@ -5,9 +5,6 @@ In-memory exporter for OpenTelemetry .NET $(PackageTags) core- - - - disable From 32c64d04defb5c92d056fd8817638151168b10da Mon Sep 17 00:00:00 2001 From: Elmo Todurov Date: Thu, 1 Aug 2024 21:56:25 +0300 Subject: [PATCH 048/133] [docs-metrics] Fix tuple vs KVP confusion in code sample (#5769) --- docs/metrics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index a96ade061b3..a57d92e9b61 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -127,7 +127,7 @@ There are two different ways of passing tags to an instrument API: * Pass the tags directly to the instrument API: ```csharp - counter.Add(100, ("Key1", "Value1"), ("Key2", "Value2")); + counter.Add(100, new("Key1", "Value1"), new("Key2", "Value2")); ``` * Use From b15f9a82e3fe2052de08ab580428b4ff56f9dec6 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 7 Aug 2024 14:16:01 -0700 Subject: [PATCH 049/133] [repo] Add ReleaseNotes.md to include features shipped in stable release (#5772) Co-authored-by: Cijo Thomas Co-authored-by: Mikel Blanchard --- OpenTelemetry.sln | 1 + RELEASENOTES.md | 53 +++++++++++++++++++ build/RELEASING.md | 7 +-- .../CHANGELOG.md | 5 ++ src/OpenTelemetry.Api/CHANGELOG.md | 4 ++ .../CHANGELOG.md | 4 ++ .../CHANGELOG.md | 4 ++ .../CHANGELOG.md | 5 ++ .../CHANGELOG.md | 5 ++ .../CHANGELOG.md | 5 ++ .../CHANGELOG.md | 4 ++ .../CHANGELOG.md | 4 ++ .../CHANGELOG.md | 4 ++ .../CHANGELOG.md | 4 ++ src/OpenTelemetry/CHANGELOG.md | 4 ++ 15 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 RELEASENOTES.md diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 61963889e01..215994c16e1 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -18,6 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution LICENSE.TXT = LICENSE.TXT NuGet.config = NuGet.config README.md = README.md + RELEASENOTES.md = RELEASENOTES.md THIRD-PARTY-NOTICES.TXT = THIRD-PARTY-NOTICES.TXT VERSIONING.md = VERSIONING.md EndProjectSection diff --git a/RELEASENOTES.md b/RELEASENOTES.md new file mode 100644 index 00000000000..0f1d0b50669 --- /dev/null +++ b/RELEASENOTES.md @@ -0,0 +1,53 @@ +# Release Notes + +This file contains highlights and announcements covering all components. +For more details see `CHANGELOG.md` files maintained in the root source +directory of each individual package. + +## 1.9.0 + +* `Exemplars` are now part of the stable API! For details see: [customizing + exemplars + collection](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#exemplars). + +* `WithLogging` is now part of the stable API! Logging, Metrics, and Tracing can + now all be configured using the `With` style and the builders finally have + parity in their APIs. + +## 1.8.0 + +* `TracerProvider` sampler can now be configured via the `OTEL_TRACES_SAMPLER` & + `OTEL_TRACES_SAMPLER_ARG` envvars. + +* A new `UseOtlpExporter` cross-cutting extension has been added to register the + `OtlpExporter` and enable all signals in a single call. + +* `exception.type`, `exception.message`, `exception.stacktrace` will now + automatically be included by the `OtlpLogExporter` when logging exceptions. + Previously an experimental environment variable had to be set. + +## 1.7.0 + +* Bumped the package versions of System.Diagnostic.DiagnosticSource and other + Microsoft.Extensions.* packages to `8.0.0`. + +* Added `net8.0` targets to all the components. + +* OTLP Exporter + * Updated to use `ILogger` `CategoryName` as the instrumentation scope for + logs. + * Added named options support for OTLP Log Exporter. + * Added support for instrumentation scope attributes in metrics. + * Added support under an experimental flag to emit log exception attributes. + * Added support under an experimental flag to emit log eventId and eventName. + attributes. + +* Added support for the + [IMetricsBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.diagnostics.metrics.imetricsbuilder) + API. + +* Added an experimental opt-in metrics feature to reclaim unused MetricPoints + which enables a higher number of unique dimension combinations to be emitted. + See [reclaim unused metric + points](https://github.com/open-telemetry/opentelemetry-dotnet/blob/32c64d04defb5c92d056fd8817638151168b10da/docs/metrics/README.md#cardinality-limits) + for more details. diff --git a/build/RELEASING.md b/build/RELEASING.md index f9075727bd6..28fdc9a078e 100644 --- a/build/RELEASING.md +++ b/build/RELEASING.md @@ -203,6 +203,7 @@ Maintainers (admins) are needed to merge PRs and for the push to NuGet.** repository which opens a PR to update dependencies. Verify this PR was opened successfully. - 8. Post an announcement in the [Slack - channel](https://cloud-native.slack.com/archives/C01N3BC2W7Q). Note any big - or interesting new features as part of the announcement. + 8. For stable releases, update [Release Notes](../RELEASENOTES.md) with any big + or interesting new features and then post an announcement in the [Slack + channel](https://cloud-native.slack.com/archives/C01N3BC2W7Q) with the same + information. diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md index fecd873f3a7..6609f3d51c4 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +This file contains individual changes for the +OpenTelemetry.Api.ProviderBuilderExtensions package. For highlights and +announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0 diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 54710b1022e..11f7ded10e4 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the OpenTelemetry.Api package. For +highlights and announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased * **Breaking change:** CompositeTextMapPropagator.Fields now returns a diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index 9e94df266e8..14c7dcb2e5b 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the OpenTelemetry.Exporter.Console +package. For highlights and announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0 diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md index fc2a00afb3c..9896195900b 100644 --- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the OpenTelemetry.Exporter.InMemory +package. For highlights and announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 6c5f736426a..8d5e83d29af 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +This file contains individual changes for the +OpenTelemetry.Exporter.OpenTelemetryProtocol package. For highlights and +announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased * **Breaking change**: Non-primitive attribute (logs) and tag (traces) values diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 89392443dac..587692aa805 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +This file contains individual changes for the +OpenTelemetry.Exporter.Prometheus.AspNetCore package. For highlights and +announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0-beta.2 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index d04d8d825b2..1893e205c79 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +This file contains individual changes for the +OpenTelemetry.Exporter.Prometheus.HttpListener package. For highlights and +announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0-beta.2 diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index dedce653992..edf54750adf 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the OpenTelemetry.Exporter.Zipkin +package. For highlights and announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased * **Breaking change**: Non-primitive tag values converted using diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index 0b9b1a1c9fe..ac95bbe985e 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the OpenTelemetry.Extensions.Hosting +package. For highlights and announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0 diff --git a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md index 10b287b0dc3..aaba4c79496 100644 --- a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the +OpenTelemetry.Extensions.Propagators package. For highlights and announcements +covering all components see: [Release Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0 diff --git a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md index 2d1f86d48d9..68929da6a4e 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md +++ b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the OpenTelemetry.Shims.OpenTracing +package. For highlights and announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased ## 1.9.0-beta.2 diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 100ec92d219..844b237e1d2 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +This file contains individual changes for the OpenTelemetry package. For +highlights and announcements covering all components see: [Release +Notes](../../RELEASENOTES.md). + ## Unreleased * Added `OpenTelemetrySdk.Create` API for configuring OpenTelemetry .NET signals From 230adaba5725790ab67a7a0917482bcb613e8dcb Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 8 Aug 2024 11:09:06 -0700 Subject: [PATCH 050/133] [docs] Top-level doc showing how to initialize the OpenTelemetry SDK (#5762) --- OpenTelemetry.sln | 6 ++ README.md | 178 +++++++++++++++++++++++--------- docs/README.md | 134 ++++++++++++++++++++++++ src/OpenTelemetry.Api/README.md | 6 +- src/OpenTelemetry/README.md | 100 ++++++------------ 5 files changed, 306 insertions(+), 118 deletions(-) create mode 100644 docs/README.md diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 215994c16e1..c7b07b3a5d7 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -124,6 +124,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "test\Benchmarks\Benchmarks.csproj", "{DE9130A4-F30A-49D7-8834-41DE3021218B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7C87CAF9-79D7-4C26-9FFB-F3F1FB6911F1}" + ProjectSection(SolutionItems) = preProject + docs\README.md = docs\README.md + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{2C7DD1DA-C229-4D9E-9AF0-BCD5CD3E4948}" ProjectSection(SolutionItems) = preProject @@ -132,6 +135,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{2C EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "trace", "trace", "{5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}" + ProjectSection(SolutionItems) = preProject + docs\trace\README.md = docs\trace\README.md + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "metrics", "metrics", "{3277B1C0-BDFE-4460-9B0D-D9A661FB48DB}" ProjectSection(SolutionItems) = preProject diff --git a/README.md b/README.md index bf5d963e5a6..db28ff6028c 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,27 @@ [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.svg)](https://www.nuget.org/profiles/OpenTelemetry) [![Build](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet/actions/workflows/ci.yml) -The .NET [OpenTelemetry](https://opentelemetry.io/) client. +The .NET [OpenTelemetry](https://opentelemetry.io/) implementation. -## Supported .NET Versions +
+Table of Contents + +* [Supported .NET versions](#supported-net-versions) +* [Project status](#project-status) +* [Getting started](#getting-started) + * [Getting started with Logging](#getting-started-with-logging) + * [Getting started with Metrics](#getting-started-with-metrics) + * [Getting started with Tracing](#getting-started-with-tracing) +* [Repository structure](#repository-structure) +* [Troubleshooting](#troubleshooting) +* [Extensibility](#extensibility) +* [Releases](#releases) +* [Contributing](#contributing) +* [References](#references) + +
+ +## Supported .NET versions Packages shipped from this repository generally support all the officially supported versions of [.NET](https://dotnet.microsoft.com/download/dotnet) and @@ -17,36 +35,88 @@ older Windows-based .NET implementation), except `.NET Framework 3.5`. Any exceptions to this are noted in the individual `README.md` files. -## Project Status +## Project status -**Stable** across all 3 signals i.e. `Logs`, `Metrics`, and `Traces`. +**Stable** across all 3 signals (`Logs`, `Metrics`, and `Traces`). -See [Spec Compliance -Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md) -to understand which portions of the specification has been implemented in this -repo. +> [!CAUTION] +> Certain components, marked as +[pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases), +are still work in progress and can undergo breaking changes before stable +release. Check the individual `README.md` file for each component to understand its +current state. -## Getting Started +To understand which portions of the [OpenTelemetry +Specification](https://github.com/open-telemetry/opentelemetry-specification) +have been implemented in OpenTelemetry .NET see: [Spec Compliance +Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md). -If you are new here, please read the getting started docs: +## Getting started -* [Logs](./docs/logs/README.md) -* [Metrics](./docs/metrics/README.md) -* [Traces](./docs/trace/README.md) +If you are new here, please read the getting started docs: -This repository includes multiple installable components, available on -[NuGet](https://www.nuget.org/profiles/OpenTelemetry). Each component has its -individual `README.md` file, which covers the instruction on how to install and -how to get started. To find all the available components, please take a look at -the `src` folder. +### Getting started with Logging + +If you are new to +[logging](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/README.md), +it is recommended to first follow the [getting started in 5 minutes - ASP.NET +Core Application](./docs/logs/getting-started-aspnetcore/README.md) guide or +the [getting started in 5 minutes - Console +Application](./docs/logs/getting-started-console/README.md) guide to get up +and running. + +For general information and best practices see: [OpenTelemetry .NET +Logs](./docs/logs/README.md). For a more detailed explanation of SDK logging +features see: [Customizing OpenTelemetry .NET SDK for +Logs](./docs/logs/customizing-the-sdk/README.md). + +### Getting started with Metrics + +If you are new to +[metrics](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/README.md), +it is recommended to first follow the [getting started in 5 minutes - ASP.NET +Core Application](./docs/metrics/getting-started-aspnetcore/README.md) guide +or the [getting started in 5 minutes - Console +Application](./docs/metrics/getting-started-console/README.md) guide to get +up and running. + +For general information and best practices see: [OpenTelemetry .NET +Metrics](./docs/metrics/README.md). For a more detailed explanation of SDK +metric features see: [Customizing OpenTelemetry .NET SDK for +Metrics](./docs/metrics/customizing-the-sdk/README.md). + +### Getting started with Tracing + +If you are new to +[traces](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/README.md), +it is recommended to first follow the [getting started in 5 minutes - ASP.NET +Core Application](./docs/trace/getting-started-aspnetcore/README.md) guide +or the [getting started in 5 minutes - Console +Application](./docs/trace/getting-started-console/README.md) guide to get up +and running. + +For general information and best practices see: [OpenTelemetry .NET +Traces](./docs/trace/README.md). For a more detailed explanation of SDK tracing +features see: [Customizing OpenTelemetry .NET SDK for +Tracing](./docs/trace/customizing-the-sdk/README.md). + +## Repository structure + +This repository includes only what is defined in the [OpenTelemetry +Specification](https://github.com/open-telemetry/opentelemetry-specification) +and is shipped as separate packages through +[NuGet](https://www.nuget.org/profiles/OpenTelemetry). Each component has an +individual `README.md` and `CHANGELOG.md` file which covers the instructions on +how to install and get started, and details about the individual changes made +(respectively). To find all the available components, please take a look at the +`src` folder. Here are the most commonly used components: -* [OpenTelemetry .NET API](./src/OpenTelemetry.Api/README.md) -* [OpenTelemetry .NET SDK](./src/OpenTelemetry/README.md) - -[Instrumentation libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) -can be found in [contrib repository](https://github.com/open-telemetry/opentelemetry-dotnet-contrib). +* [OpenTelemetry API](./src/OpenTelemetry.Api/README.md) +* [OpenTelemetry SDK](./src/OpenTelemetry/README.md) +* [OpenTelemetry Hosting + Extensions](./src/OpenTelemetry.Extensions.Hosting/README.md) Here are the [exporter libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#exporter-library): @@ -59,16 +129,19 @@ libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/ma * [Prometheus HttpListener](./src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) * [Zipkin](./src/OpenTelemetry.Exporter.Zipkin/README.md) -See the [OpenTelemetry -registry](https://opentelemetry.io/ecosystem/registry/?language=dotnet) and -[OpenTelemetry .NET Contrib -repo](https://github.com/open-telemetry/opentelemetry-dotnet-contrib) for more -components. +Additional packages including [instrumentation +libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +exporters, resource detectors, and extensions can be found in the +[opentelemetry-dotnet-contrib +repository](https://github.com/open-telemetry/opentelemetry-dotnet-contrib) +and/or the [OpenTelemetry +registry](https://opentelemetry.io/ecosystem/registry/?language=dotnet). ## Troubleshooting -See [Troubleshooting](./src/OpenTelemetry/README.md#troubleshooting). -Additionally check readme file for the individual components for any additional +For general instructions see: +[Troubleshooting](./src/OpenTelemetry/README.md#troubleshooting). Additionally +`README.md` files for individual components may contain more detailed troubleshooting information. ## Extensibility @@ -80,7 +153,7 @@ extension scenarios: library](./docs/trace/extending-the-sdk/README.md#instrumentation-library). * Building a custom exporter for [logs](./docs/logs/extending-the-sdk/README.md#exporter), - [metrics](./docs/metrics/extending-the-sdk/README.md#exporter) and + [metrics](./docs/metrics/extending-the-sdk/README.md#exporter), and [traces](./docs/trace/extending-the-sdk/README.md#exporter). * Building a custom processor for [logs](./docs/logs/extending-the-sdk/README.md#processor) and @@ -88,9 +161,28 @@ extension scenarios: * Building a custom sampler for [traces](./docs/trace/extending-the-sdk/README.md#sampler). +## Releases + +For details about upcoming planned releases see: +[Milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestones). +The dates and features described in issues and milestones are estimates and +subject to change. + +For highlights and annoucements for stable releases see: [Release +Notes](./RELEASENOTES.md). + +To access packages, source code, and/or view a list of changes for all +components in a release see: +[Releases](https://github.com/open-telemetry/opentelemetry-dotnet/releases). + +Nightly builds from this repo are published to [MyGet](https://www.myget.org), +and can be installed using the +`https://www.myget.org/F/opentelemetry/api/v3/index.json` source. + ## Contributing -See [CONTRIBUTING.md](CONTRIBUTING.md) +For information about contributing to the project see: +[CONTRIBUTING.md](CONTRIBUTING.md). We meet weekly on Tuesdays, and the time of the meeting alternates between 9AM PT and 4PM PT. The meeting is subject to change depending on contributors' @@ -144,23 +236,7 @@ Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/ma [![contributors](https://contributors-img.web.app/image?repo=open-telemetry/opentelemetry-dotnet)](https://github.com/open-telemetry/opentelemetry-dotnet/graphs/contributors) -## Release Schedule - -See the [project -milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestones) -for details on upcoming releases. The dates and features described in issues and -milestones are estimates, and subject to change. - -See the [release -notes](https://github.com/open-telemetry/opentelemetry-dotnet/releases) for -existing releases. - -> [!CAUTION] -> Certain components, marked as -[pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases), -are still work in progress and can undergo breaking changes before stable -release. Check the individual `README.md` file for each component to understand its -current state. +## References -Daily builds from this repo are published to MyGet, and can be installed from -[this source](https://www.myget.org/F/opentelemetry/api/v3/index.json). +* [OpenTelemetry Project](https://opentelemetry.io/) +* [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification) diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000000..491c120aa3a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,134 @@ +# OpenTelemetry .NET SDK + +## Initialize the SDK + +There are two different common initialization styles supported by OpenTelemetry. + +### Initialize the SDK using a host + +Users building applications based on +[Microsoft.Extensions.Hosting](https://www.nuget.org/packages/Microsoft.Extensions.Hosting) +should utilize the +[OpenTelemetry.Extensions.Hosting](../src/OpenTelemetry.Extensions.Hosting/README.md) +package to initialize OpenTelemetry. This style provides a deep integration +between the host infrastructure (`IServiceCollection`, `IServiceProvider`, +`IConfiguration`, etc.) and OpenTelemetry. + +[AspNetCore](https://learn.microsoft.com/aspnet/core/fundamentals/host/web-host) +applications are the most common to use the hosting model but there is also a +[Generic Host](https://learn.microsoft.com/dotnet/core/extensions/generic-host) +which may be used in console, service, and worker applications. + +> [!NOTE] +> When using `OpenTelemetry.Extensions.Hosting` only a single pipeline will be +> created for each configured signal (logging, metrics, and/or tracing). Users +> who need more granular control can create additional pipelines using the +> manual style below. + +First install the +[OpenTelemetry.Extensions.Hosting](../src/OpenTelemetry.Extensions.Hosting/README.md) +package. + +Second call the `AddOpenTelemetry` extension using the host +`IServiceCollection`: + +```csharp +var builder = WebApplication.CreateBuilder(args); + +// Clear the default logging providers added by the host +builder.Logging.ClearProviders(); + +// Initialize OpenTelemetry +builder.Services.AddOpenTelemetry() + .ConfigureResource(resource => /* Resource configuration goes here */) + .WithLogging(logging => /* Logging configuration goes here */) + .WithMetrics(metrics => /* Metrics configuration goes here */) + .WithTracing(tracing => /* Tracing configuration goes here */)); +``` + +> [!NOTE] +> Calling `WithLogging` automatically registers the OpenTelemetry +> `ILoggerProvider` and enables `ILogger` integration. + +### Initialize the SDK manually + +Users running on .NET Framework or running without a host may initialize +OpenTelemetry manually. + +> [!IMPORTANT] +> When initializing OpenTelemetry manually make sure to ALWAYS dispose the SDK +> and/or providers when the application is shutting down. Disposing +> OpenTelemetry gives the SDK a chance to flush any telemetry held in memory. +> Skipping this step may result in data loss. + +First install the [OpenTelemetry SDK](../src/OpenTelemetry/README.md) package or +an exporter package such as +[OpenTelemetry.Exporter.OpenTelemetryProtocol](../src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md). +Exporter packages typically reference the SDK and will make it available via +transitive reference. + +Second use one of the following initialization APIs (depending on the SDK +version being used): + +#### Using 1.10.0 or newer + +The `OpenTelemetrySdk.Create` API can be used to initialize all signals off a +single root builder and supports cross-cutting extensions such as +`ConfigureResource` which configures a `Resource` to be used by all enabled +signals. An `OpenTelemetrySdk` instance is returned which may be used to access +providers for each signal. Calling `Dispose` on the returned instance will +gracefully shutdown the SDK and flush any telemetry held in memory. + +> [!NOTE] +> When calling `OpenTelemetrySdk.Create` a dedicated `IServiceCollection` and +> `IServiceProvider` will be created for the SDK and shared by all signals. An +> `IConfiguration` is created automatically from environment variables. + +```csharp +using OpenTelemetry; + +var sdk = OpenTelemetrySdk.Create(builder => builder + .ConfigureResource(resource => /* Resource configuration goes here */) + .WithLogging(logging => /* Logging configuration goes here */) + .WithMetrics(metrics => /* Metrics configuration goes here */) + .WithTracing(tracing => /* Tracing configuration goes here */)); + +// During application shutdown +sdk.Dispose(); +``` + +To obtain an `ILogger` instance for emitting logs when using the +`OpenTelemetrySdk.Create` API call the `GetLoggerFactory` extension method using +the returned `OpenTelemetrySdk` instance: + +```csharp +var logger = sdk.GetLoggerFactory().CreateLogger() +logger.LogInformation("Application started"); +``` + +#### Using 1.9.0 or older + +The following shows how to create providers for each individual signal. Each +provider is independent and must be managed and disposed explicitly. There is no +mechanism using this style to perform cross-cutting actions across signals. + +```csharp +using Microsoft.Extensions.Logging; +using OpenTelemetry; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + /* Tracing configuration goes here */ + .Build(); + +var meterProvider = Sdk.CreateMeterProviderBuilder() + /* Metrics configuration goes here */ + .Build(); + +var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => /* Logging configuration goes here */)); + +// During application shutdown +tracerProvider.Dispose(); +meterProvider.Dispose(); +loggerFactory.Dispose(); +``` diff --git a/src/OpenTelemetry.Api/README.md b/src/OpenTelemetry.Api/README.md index 5fd769f4461..db0471e1774 100644 --- a/src/OpenTelemetry.Api/README.md +++ b/src/OpenTelemetry.Api/README.md @@ -539,4 +539,8 @@ seeing these internal logs. ## References -* [OpenTelemetry Project](https://opentelemetry.io/) +* [OpenTelemetry Baggage API specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/baggage/api.md) +* [OpenTelemetry Logs Bridge API specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md) +* [OpenTelemetry Metrics API specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md) +* [OpenTelemetry Propagators API specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md) +* [OpenTelemetry Tracing API specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md) diff --git a/src/OpenTelemetry/README.md b/src/OpenTelemetry/README.md index 8e444a6f167..e05a403f42a 100644 --- a/src/OpenTelemetry/README.md +++ b/src/OpenTelemetry/README.md @@ -3,16 +3,19 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.svg)](https://www.nuget.org/packages/OpenTelemetry) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.svg)](https://www.nuget.org/packages/OpenTelemetry) +
+Table of Contents + * [Installation](#installation) * [Introduction](#introduction) -* [Getting started with Logging](#getting-started-with-logging) -* [Getting started with Metrics](#getting-started-with-metrics) -* [Getting started with Tracing](#getting-started-with-tracing) * [Troubleshooting](#troubleshooting) - * [Configuration Parameters](#configuration-parameters) - * [Remarks](#remarks) + * [Self-diagnostics](#self-diagnostics) + * [Configuration Parameters](#configuration-parameters) + * [Remarks](#remarks) * [References](#references) +
+ ## Installation ```shell @@ -22,61 +25,25 @@ dotnet add package OpenTelemetry ## Introduction OpenTelemetry SDK is a reference implementation of the OpenTelemetry API. It -implements the Tracing API, the Metrics API, and the Context API. Once a valid -SDK is installed and configured, all the OpenTelemetry API methods, which were -no-ops without an SDK, will start emitting telemetry. -This SDK also supports [ILogger](https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger) -integration. - -The SDK deals with concerns such as sampling, processing pipeline, exporting -telemetry to a particular backend etc. In most cases, users indirectly install -and enable the SDK, when they install a particular exporter. - -## Getting started with Logging - -If you are new to logging, it is recommended to first follow the [getting -started in 5 minutes - Console -Application](../../docs/logs/getting-started-console/README.md) guide to get up -and running. - -While [OpenTelemetry -logging](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/README.md) -specification is an experimental signal, `ILogger` is the de-facto logging API -provided by the .NET runtime and is a stable API recommended for production use. -This repo ships an OpenTelemetry -[provider](https://docs.microsoft.com/dotnet/core/extensions/logging-providers), -which provides the ability to enrich logs emitted with `ILogger` with -`ActivityContext`, and export them to multiple destinations, similar to tracing. -`ILogger` based API will become the OpenTelemetry .NET implementation of -OpenTelemetry logging. - -## Getting started with Metrics - -If you are new to -[metrics](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md), -it is recommended to first follow the [getting started in 5 minutes - ASP.NET -Core Application](../../docs/metrics/getting-started-aspnetcore/README.md) guide -or the [getting started in 5 minutes - Console -Application](../../docs/metrics/getting-started-console/README.md) guide to get up -and running. - -For a more detailed explanation of SDK metric features see [Customizing -OpenTelemetry .NET SDK for -Metrics](../../docs/metrics/customizing-the-sdk/README.md). - -## Getting started with Tracing - -If you are new to -[traces](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md), -it is recommended to first follow the [getting started in 5 minutes - ASP.NET -Core Application](../../docs/trace/getting-started-aspnetcore/README.md) guide -or the [getting started in 5 minutes - Console -Application](../../docs/trace/getting-started-console/README.md) guide to get up -and running. - -For a more detailed explanation of SDK tracing features see [Customizing -OpenTelemetry .NET SDK for -Tracing](../../docs/trace/customizing-the-sdk/README.md). +implements the Logging API, Metrics API, Tracing API, Resource API, and the +Context API. Once a valid SDK is installed and configured all the OpenTelemetry +API methods, which were no-ops without an SDK, will start emitting telemetry. +This SDK also ships with +[ILogger](https://learn.microsoft.com/dotnet/core/extensions/logging) +integration to automatically capture and enrich logs emitted using +`Microsoft.Extensions.Logging`. + +The SDK deals with concerns such as sampling, processing pipelines (exporting +telemetry to a particular backend, etc.), metrics aggregation, and other +concerns outlined in the [OpenTelemetry +Specification](https://github.com/open-telemetry/opentelemetry-specification). +In most cases, users indirectly install and enable the SDK when they install an +exporter. + +To learn how to set up and configure the OpenTelemetry SDK see: [Getting +started](../../README.md#getting-started). For additional details about +initialization patterns see: [Initialize the +SDK](../../docs/README.md#initialize-the-sdk). ## Troubleshooting @@ -90,9 +57,9 @@ While it is possible to view these logs using tools such as [PerfView](https://github.com/microsoft/perfview), [dotnet-trace](https://docs.microsoft.com/dotnet/core/diagnostics/dotnet-trace) etc., this SDK also ships a [self-diagnostics](#self-diagnostics) feature, which -helps troubleshooting. +helps with troubleshooting. -## Self-diagnostics +### Self-diagnostics OpenTelemetry SDK ships with built-in self-diagnostics feature. This feature, when enabled, will listen to internal logs generated by all OpenTelemetry @@ -130,7 +97,7 @@ Internally, it looks for the configuration file located in and then [AppContext.BaseDirectory](https://docs.microsoft.com/dotnet/api/system.appcontext.basedirectory). You can also find the exact directory by calling these methods from your code. -### Configuration Parameters +#### Configuration Parameters 1. `LogDirectory` is the directory where the output log file will be stored. It can be an absolute path or a relative path to the current directory. @@ -150,7 +117,7 @@ You can also find the exact directory by calling these methods from your code. higher severity levels. For example, `Warning` includes the `Error` and `Critical` levels. -### Remarks +#### Remarks A `FileSize`-KiB log file named as `ExecutableName.ProcessId.log` (e.g. `foobar.exe.12345.log`) will be generated at the specified directory @@ -172,6 +139,7 @@ start from beginning and overwrite existing text. ## References -* [OpenTelemetry Project](https://opentelemetry.io/) +* [OpenTelemetry Logging SDK specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md) +* [OpenTelemetry Metrics SDK specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md) * [OpenTelemetry Tracing SDK specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md) -* [OpenTelemetry Logging specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/README.md) +* [OpenTelemetry Resource SDK specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md) From 83ecef862d720b97925756fec90a436396ac81b3 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Mon, 12 Aug 2024 18:07:12 +0100 Subject: [PATCH 051/133] [api] Optimise `TraceContextPropagator.Extract` (#5749) Co-authored-by: Vishwesh Bankwar Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Api/CHANGELOG.md | 3 + .../Propagation/TraceContextPropagator.cs | 136 ++++++++++++++---- .../TraceContextPropagatorBenchmarks.cs | 72 ++++++++++ .../Propagation/TraceContextPropagatorTest.cs | 20 ++- 4 files changed, 202 insertions(+), 29 deletions(-) create mode 100644 test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 11f7ded10e4..458dff5ecc8 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -11,6 +11,9 @@ Notes](../../RELEASENOTES.md). returned an empty set. ([#5745](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5745)) +* Optimize performance of `TraceContextPropagator.Extract`. + ([#5749](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5749)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs index 3ef627a5bdf..b37fb93cc08 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs @@ -1,9 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Text; using OpenTelemetry.Internal; namespace OpenTelemetry.Context.Propagation; @@ -76,7 +76,7 @@ public override PropagationContext Extract(PropagationContext context, T carr var tracestateCollection = getter(carrier, TraceState); if (tracestateCollection?.Any() ?? false) { - TryExtractTracestate(tracestateCollection.ToArray(), out tracestate); + TryExtractTracestate(tracestateCollection, out tracestate); } return new PropagationContext( @@ -220,31 +220,37 @@ internal static bool TryExtractTraceparent(string traceparent, out ActivityTrace return true; } - internal static bool TryExtractTracestate(string[] tracestateCollection, out string tracestateResult) + internal static bool TryExtractTracestate(IEnumerable tracestateCollection, out string tracestateResult) { tracestateResult = string.Empty; - if (tracestateCollection != null) + char[] rentedArray = null; + Span traceStateBuffer = stackalloc char[128]; // 256B + Span keyLookupBuffer = stackalloc char[96]; // 192B (3x32 keys) + int keys = 0; + int charsWritten = 0; + + try { - var keySet = new HashSet(); - var result = new StringBuilder(); - for (int i = 0; i < tracestateCollection.Length; ++i) + foreach (var tracestateItem in tracestateCollection) { - var tracestate = tracestateCollection[i].AsSpan(); - int begin = 0; - while (begin < tracestate.Length) + var tracestate = tracestateItem.AsSpan(); + int position = 0; + + while (position < tracestate.Length) { - int length = tracestate.Slice(begin).IndexOf(','); + int length = tracestate.Slice(position).IndexOf(','); ReadOnlySpan listMember; + if (length != -1) { - listMember = tracestate.Slice(begin, length).Trim(); - begin += length + 1; + listMember = tracestate.Slice(position, length).Trim(); + position += length + 1; } else { - listMember = tracestate.Slice(begin).Trim(); - begin = tracestate.Length; + listMember = tracestate.Slice(position).Trim(); + position = tracestate.Length; } // https://github.com/w3c/trace-context/blob/master/spec/20-http_request_header_format.md#tracestate-header-field-values @@ -255,7 +261,7 @@ internal static bool TryExtractTracestate(string[] tracestateCollection, out str continue; } - if (keySet.Count >= 32) + if (keys >= 32) { // https://github.com/w3c/trace-context/blob/master/spec/20-http_request_header_format.md#list // test_tracestate_member_count_limit @@ -286,25 +292,107 @@ internal static bool TryExtractTracestate(string[] tracestateCollection, out str } // ValidateKey() call above has ensured the key does not contain upper case letters. - if (!keySet.Add(key.ToString())) + + var duplicationCheckLength = Math.Min(key.Length, 3); + + if (keys > 0) { - // test_tracestate_duplicated_keys - return false; + // Fast path check of first three chars for potential duplicated keys + var potentialMatchingKeyPosition = 1; + var found = false; + for (int i = 0; i < keys * 3; i += 3) + { + if (keyLookupBuffer.Slice(i, duplicationCheckLength).SequenceEqual(key.Slice(0, duplicationCheckLength))) + { + found = true; + break; + } + + potentialMatchingKeyPosition++; + } + + // If the fast check has found a possible duplicate, we need to do a full check + if (found) + { + var bufferToCompare = traceStateBuffer.Slice(0, charsWritten); + + // We know which key is the first possible duplicate, so skip to that key + // by slicing to the position after the appropriate comma. + for (int i = 1; i < potentialMatchingKeyPosition; i++) + { + var commaIndex = bufferToCompare.IndexOf(','); + + if (commaIndex > -1) + { + bufferToCompare.Slice(commaIndex); + } + } + + int existingIndex = -1; + while ((existingIndex = bufferToCompare.IndexOf(key)) > -1) + { + if ((existingIndex > 0 && bufferToCompare[existingIndex - 1] != ',') || bufferToCompare[existingIndex + key.Length] != '=') + { + continue; // this is not a key + } + + return false; // test_tracestate_duplicated_keys + } + } } - if (result.Length > 0) + // Store up to the first three characters of the key for use in the duplicate lookup fast path + var startKeyLookupIndex = keys > 0 ? keys * 3 : 0; + key.Slice(0, duplicationCheckLength).CopyTo(keyLookupBuffer.Slice(startKeyLookupIndex)); + + // Check we have capacity to write the key and value + var requiredCapacity = charsWritten > 0 ? listMember.Length + 1 : listMember.Length; + + while (charsWritten + requiredCapacity > traceStateBuffer.Length) { - result.Append(','); + GrowBuffer(ref rentedArray, ref traceStateBuffer); } - result.Append(listMember.ToString()); + if (charsWritten > 0) + { + traceStateBuffer[charsWritten++] = ','; + } + + listMember.CopyTo(traceStateBuffer.Slice(charsWritten)); + charsWritten += listMember.Length; + + keys++; } } - tracestateResult = result.ToString(); + tracestateResult = traceStateBuffer.Slice(0, charsWritten).ToString(); + + return true; + } + finally + { + if (rentedArray is not null) + { + ArrayPool.Shared.Return(rentedArray); + rentedArray = null; + } } - return true; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void GrowBuffer(ref char[] array, ref Span buffer) + { + var newBuffer = ArrayPool.Shared.Rent(buffer.Length * 2); + + buffer.CopyTo(newBuffer.AsSpan()); + + if (array is not null) + { + ArrayPool.Shared.Return(array); + } + + array = newBuffer; + buffer = array.AsSpan(); + } } private static byte HexCharToByte(char c) diff --git a/test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs b/test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs new file mode 100644 index 00000000000..2f9d26f9ab0 --- /dev/null +++ b/test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs @@ -0,0 +1,72 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using OpenTelemetry.Context.Propagation; + +namespace Benchmarks.Context.Propagation; + +public class TraceContextPropagatorBenchmarks +{ + private const string TraceParent = "traceparent"; + private const string TraceState = "tracestate"; + private const string TraceId = "0af7651916cd43dd8448eb211c80319c"; + private const string SpanId = "b9c7c989f97918e1"; + + private static readonly Random Random = new(455946); + private static readonly TraceContextPropagator TraceContextPropagator = new(); + + private static readonly Func, string, IEnumerable> Getter = (headers, name) => + { + if (headers.TryGetValue(name, out var value)) + { + return [value]; + } + + return []; + }; + + private Dictionary headers; + + [Params(true, false)] + public bool LongListMember { get; set; } + + [Params(0, 4, 32)] + public int MembersCount { get; set; } + + public Dictionary Headers => this.headers; + + [GlobalSetup] + public void Setup() + { + var length = this.LongListMember ? 256 : 20; + + var value = new string('a', length); + + Span keyBuffer = stackalloc char[length - 2]; + + string traceState = string.Empty; + for (var i = 0; i < this.MembersCount; i++) + { + // We want a unique key for each member + for (var j = 0; j < length - 2; j++) + { + keyBuffer[j] = (char)('a' + Random.Next(0, 26)); + } + + var key = keyBuffer.ToString(); + + var listMember = $"{key}{i:00}={value}"; + traceState += i < this.MembersCount - 1 ? $"{listMember}," : listMember; + } + + this.headers = new Dictionary + { + { TraceParent, $"00-{TraceId}-{SpanId}-01" }, + { TraceState, traceState }, + }; + } + + [Benchmark(Baseline = true)] + public void Extract() => _ = TraceContextPropagator!.Extract(default, this.headers, Getter); +} diff --git a/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs b/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs index 728d3884e45..8fbd20f11de 100644 --- a/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs +++ b/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs @@ -13,12 +13,12 @@ public class TraceContextPropagatorTest private const string TraceId = "0af7651916cd43dd8448eb211c80319c"; private const string SpanId = "b9c7c989f97918e1"; - private static readonly string[] Empty = Array.Empty(); + private static readonly string[] Empty = []; private static readonly Func, string, IEnumerable> Getter = (headers, name) => { if (headers.TryGetValue(name, out var value)) { - return new[] { value }; + return [value]; } return Empty; @@ -31,7 +31,7 @@ public class TraceContextPropagatorTest return value; } - return Array.Empty(); + return []; }; private static readonly Action, string, string> Setter = (carrier, name, value) => @@ -183,8 +183,18 @@ public void DuplicateKeys() // test_tracestate_duplicated_keys Assert.Empty(CallTraceContextPropagator("foo=1,foo=1")); Assert.Empty(CallTraceContextPropagator("foo=1,foo=2")); - Assert.Empty(CallTraceContextPropagator(new[] { "foo=1", "foo=1" })); - Assert.Empty(CallTraceContextPropagator(new[] { "foo=1", "foo=2" })); + Assert.Empty(CallTraceContextPropagator(["foo=1", "foo=1"])); + Assert.Empty(CallTraceContextPropagator(["foo=1", "foo=2"])); + Assert.Empty(CallTraceContextPropagator("foo=1,bar=2,baz=3,foo=4")); + } + + [Fact] + public void NoDuplicateKeys() + { + Assert.Equal("foo=1,bar=foo,baz=2", CallTraceContextPropagator("foo=1,bar=foo,baz=2")); + Assert.Equal("foo=1,bar=2,baz=foo", CallTraceContextPropagator("foo=1,bar=2,baz=foo")); + Assert.Equal("foo=1,foo@tenant=2", CallTraceContextPropagator("foo=1,foo@tenant=2")); + Assert.Equal("foo=1,tenant@foo=2", CallTraceContextPropagator("foo=1,tenant@foo=2")); } [Fact] From 6ec151072910b024e0e47f7a87de25695a14a502 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 12 Aug 2024 11:23:46 -0700 Subject: [PATCH 052/133] [release] Add release notes link on stable releases (#5780) --- build/scripts/post-release.psm1 | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index ab7092cf4eb..ae20f939e29 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -13,6 +13,7 @@ function CreateDraftRelease { $tagPrefix = $match.Groups[1].Value $version = $match.Groups[2].Value + $isPrerelease = $version -match '-alpha' -or $version -match '-beta' -or $version -match '-rc' $projects = @(Get-ChildItem -Path src/**/*.csproj | Select-String "$tagPrefix" -List | Select Path) @@ -22,6 +23,7 @@ function CreateDraftRelease { } $notes = '' + $previousVersion = '' foreach ($project in $projects) { @@ -44,6 +46,11 @@ function CreateDraftRelease { } elseif ($line -like "## *" -and $started -eq $true) { + $match = [regex]::Match($line, '^##\s*(.*)$') + if ($match.Success -eq $true) + { + $previousVersion = $match.Groups[1].Value + } break } else @@ -57,7 +64,7 @@ function CreateDraftRelease { if ([string]::IsNullOrWhitespace($content) -eq $true) { - $content = " No notable changes." + $content = " No notable changes." } $content = $content.trimend() @@ -70,11 +77,19 @@ $content See [CHANGELOG](https://github.com/$gitRepository/blob/$tag/src/$projectName/CHANGELOG.md) for details. + "@ } - if ($version -match '-alpha' -or $version -match '-beta' -or $version -match '-rc') + if ($isPrerelease -eq $true) { + $notes = +@" +The following changes are from the previous release [$previousVersion](https://github.com/$gitRepository/releases/tag/$tagPrefix$previousVersion). + + +"@ + $notes + gh release create $tag $releaseFiles ` --title $tag ` --verify-tag ` @@ -84,6 +99,15 @@ $content } else { + $notes = +@" +For highlights and announcements pertaining to this release see: [Release Notes > $version](https://github.com/$gitRepository/blob/main/RELEASENOTES.md#$($version.Replace('.',''))). + +The following changes are from the previous release [$previousVersion](https://github.com/$gitRepository/releases/tag/$tagPrefix$previousVersion). + + +"@ + $notes + gh release create $tag $releaseFiles ` --title $tag ` --verify-tag ` From 5a0b6865591afeae6dae2f333ad6cfa7984ac4d1 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Thu, 15 Aug 2024 18:41:23 +0200 Subject: [PATCH 053/133] [repo] Enable NuGetAudit (#5784) Co-authored-by: Mikel Blanchard --- build/Common.props | 1 + 1 file changed, 1 insertion(+) diff --git a/build/Common.props b/build/Common.props index 77337cad20a..e3b2c198243 100644 --- a/build/Common.props +++ b/build/Common.props @@ -9,6 +9,7 @@ true enable enable + true $(NoWarn);OTEL1000;OTEL1001;OTEL1002;OTEL1003;OTEL1004 From 5f13315926df000a48c2a7a5d32b50a0014050d0 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Thu, 15 Aug 2024 10:35:03 -0700 Subject: [PATCH 054/133] [repo] update stale automation to inspect issues (#5787) Co-authored-by: Mikel Blanchard --- .github/workflows/stale.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index f5657aa9f54..7c361aec680 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,7 +1,7 @@ # Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions # Github Actions Stale: https://github.com/actions/stale -name: "Close stale pull requests" +name: "Manage stale issues and pull requests" on: schedule: - cron: "12 3 * * *" # arbitrary time not to DDOS GitHub @@ -12,10 +12,14 @@ jobs: steps: - uses: actions/stale@v9 with: + stale-issue-message: 'This issue was marked stale due to lack of activity and will be closed in 7 days. Commenting will instruct the bot to automatically remove the label. This bot runs once per day.' + close-issue-message: 'Closed as inactive. Feel free to reopen if this issue is still a concern.' stale-pr-message: 'This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or Pushing will instruct the bot to automatically remove the label. This bot runs once per day.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' operations-per-run: 400 days-before-pr-stale: 7 - days-before-issue-stale: -1 + days-before-issue-stale: 1200 days-before-pr-close: 7 - days-before-issue-close: -1 + days-before-issue-close: 7 + exempt-all-issue-milestones: true + exempt-issue-labels: need-runtime-change,await-spec,help wanted,needs-triage From a0316ec3c66a89e1dc24e0c680b0a1ccf2c7350f Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 16 Aug 2024 12:42:42 -0700 Subject: [PATCH 055/133] [sdk] Switch a couple guard calls to debug.assert in CircularBuffer (#5789) --- src/OpenTelemetry/Internal/CircularBuffer.cs | 5 +++-- test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry/Internal/CircularBuffer.cs b/src/OpenTelemetry/Internal/CircularBuffer.cs index 74c3c8a6c5d..7e6a6a822d6 100644 --- a/src/OpenTelemetry/Internal/CircularBuffer.cs +++ b/src/OpenTelemetry/Internal/CircularBuffer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using System.Runtime.CompilerServices; namespace OpenTelemetry.Internal; @@ -65,7 +66,7 @@ public int Count /// public bool Add(T value) { - Guard.ThrowIfNull(value); + Debug.Assert(value != null, "value was null"); while (true) { @@ -104,7 +105,7 @@ public bool TryAdd(T value, int maxSpinCount) return this.Add(value); } - Guard.ThrowIfNull(value); + Debug.Assert(value != null, "value was null"); var spinCountDown = maxSpinCount; diff --git a/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs b/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs index 2e0e4225526..4f19a099e38 100644 --- a/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs +++ b/test/OpenTelemetry.Tests/Internal/CircularBufferTest.cs @@ -22,14 +22,6 @@ public void CheckCapacity() Assert.Equal(capacity, circularBuffer.Capacity); } - [Fact] - public void CheckNullValueWhenAdding() - { - int capacity = 1; - var circularBuffer = new CircularBuffer(capacity); - Assert.Throws(() => circularBuffer.Add(null)); - } - [Fact] public void CheckValueWhenAdding() { From 0e011e8c3c2e668c87581386e30624885536f32b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 16 Aug 2024 15:33:49 -0700 Subject: [PATCH 056/133] [repo] Add needs-triage label to new issues created via templates (#5788) --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 ++- .github/ISSUE_TEMPLATE/feature_request.yml | 3 ++- .github/ISSUE_TEMPLATE/question.yml | 3 ++- .github/workflows/stale.yml | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3bad5b876a7..baef921968e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,7 @@ name: Bug report +title: "[bug] " description: Create a report to help us improve -labels: ["bug"] +labels: [bug,needs-triage] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 7fd9b2f4eda..ab958731736 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,6 +1,7 @@ name: Feature request +title: "[feature request] " description: Suggest an idea for this project -labels: ["enhancement"] +labels: [enhancement,needs-triage] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml index 76eea553517..ccca6038516 100644 --- a/.github/ISSUE_TEMPLATE/question.yml +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -1,6 +1,7 @@ name: Question +title: "[question] " description: Ask a question to help us improve our knowledge base and documentation -labels: ["question"] +labels: [question,needs-triage] body: - type: markdown attributes: diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 7c361aec680..c57aea37e67 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,7 +14,7 @@ jobs: with: stale-issue-message: 'This issue was marked stale due to lack of activity and will be closed in 7 days. Commenting will instruct the bot to automatically remove the label. This bot runs once per day.' close-issue-message: 'Closed as inactive. Feel free to reopen if this issue is still a concern.' - stale-pr-message: 'This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or Pushing will instruct the bot to automatically remove the label. This bot runs once per day.' + stale-pr-message: 'This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or pushing will instruct the bot to automatically remove the label. This bot runs once per day.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' operations-per-run: 400 days-before-pr-stale: 7 @@ -22,4 +22,4 @@ jobs: days-before-pr-close: 7 days-before-issue-close: 7 exempt-all-issue-milestones: true - exempt-issue-labels: need-runtime-change,await-spec,help wanted,needs-triage + exempt-issue-labels: needs-triage From 41a72f45b96a74e037ea0aaa990248680dc55ea6 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Mon, 19 Aug 2024 13:04:21 -0700 Subject: [PATCH 057/133] Log Stress test to follow recommended logging practise (#5790) --- .../LoggerExtensions.cs | 18 ++++++++++++++++++ .../OpenTelemetry.Tests.Stress.Logs/Program.cs | 12 ++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 test/OpenTelemetry.Tests.Stress.Logs/LoggerExtensions.cs diff --git a/test/OpenTelemetry.Tests.Stress.Logs/LoggerExtensions.cs b/test/OpenTelemetry.Tests.Stress.Logs/LoggerExtensions.cs new file mode 100644 index 00000000000..ae3c1436663 --- /dev/null +++ b/test/OpenTelemetry.Tests.Stress.Logs/LoggerExtensions.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.Logging; + +namespace OpenTelemetry.Tests.Stress; + +internal static partial class LoggerExtensions +{ + [LoggerMessage(LogLevel.Critical, "A `{productType}` recall notice was published for `{brandName} {productDescription}` produced by `{companyName}` ({recallReasonDescription}).")] + public static partial void FoodRecallNotice( + this ILogger logger, + string brandName, + string productDescription, + string productType, + string recallReasonDescription, + string companyName); +} diff --git a/test/OpenTelemetry.Tests.Stress.Logs/Program.cs b/test/OpenTelemetry.Tests.Stress.Logs/Program.cs index c8b640aea37..f8ecff50648 100644 --- a/test/OpenTelemetry.Tests.Stress.Logs/Program.cs +++ b/test/OpenTelemetry.Tests.Stress.Logs/Program.cs @@ -34,12 +34,12 @@ public LogsStressTest(StressTestOptions options) protected override void RunWorkItemInParallel() { - this.logger.Log( - logLevel: LogLevel.Information, - eventId: 2, - state: Payload, - exception: null, - formatter: (state, ex) => string.Empty); + this.logger.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } protected override void Dispose(bool isDisposing) From 456cd26a204bd65ebba26511b2080e8f5ee7a176 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Tue, 20 Aug 2024 21:51:54 -0700 Subject: [PATCH 058/133] [repo] Update stale.yml - reduce days before stale to 1000 (#5796) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index c57aea37e67..4ea639c2228 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,7 +18,7 @@ jobs: close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' operations-per-run: 400 days-before-pr-stale: 7 - days-before-issue-stale: 1200 + days-before-issue-stale: 1000 days-before-pr-close: 7 days-before-issue-close: 7 exempt-all-issue-milestones: true From c483222ea58ddca99a1b0830ee638b057425abfa Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 21 Aug 2024 09:09:13 -0700 Subject: [PATCH 059/133] [repo] Remove .NET 7 target (#5795) Co-authored-by: Mikel Blanchard --- .github/workflows/Component.BuildTest.yml | 2 +- .github/workflows/ci.yml | 4 ++-- Directory.Packages.props | 3 --- OpenTelemetry.sln | 1 - build/Common.props | 6 +++--- build/docker-compose.net7.0.yml | 9 --------- 6 files changed, 6 insertions(+), 19 deletions(-) delete mode 100644 build/docker-compose.net7.0.yml diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index f5ef85e0dc3..df079498450 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -24,7 +24,7 @@ on: required: false type: string tfm-list: - default: '[ "net462", "net6.0", "net7.0", "net8.0" ]' + default: '[ "net462", "net6.0", "net8.0" ]' required: false type: string diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f222b07cc3..be3cdf11abe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,7 @@ jobs: strategy: fail-fast: false matrix: - version: [ net6.0, net7.0, net8.0 ] + version: [ net6.0, net8.0 ] steps: - uses: actions/checkout@v4 - name: Run OTLP Exporter docker compose @@ -129,7 +129,7 @@ jobs: strategy: fail-fast: false matrix: - version: [ net6.0, net7.0 ] + version: [ net6.0 ] steps: - uses: actions/checkout@v4 - name: Run W3C Trace Context docker compose diff --git a/Directory.Packages.props b/Directory.Packages.props index f15e90b0d96..bfe09403ee5 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -100,9 +100,6 @@ - - - diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index c7b07b3a5d7..fd7cdb94f12 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -32,7 +32,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E Directory.Packages.props = Directory.Packages.props build\docfx.cmd = build\docfx.cmd build\docker-compose.net6.0.yml = build\docker-compose.net6.0.yml - build\docker-compose.net7.0.yml = build\docker-compose.net7.0.yml build\docker-compose.net8.0.yml = build\docker-compose.net8.0.yml build\GlobalAttrExclusions.txt = build\GlobalAttrExclusions.txt build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png diff --git a/build/Common.props b/build/Common.props index e3b2c198243..e526f543e93 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,13 +31,13 @@ net8.0;net6.0 - net8.0;net7.0;net6.0 + net8.0;net6.0 net8.0 - net8.0;net7.0;net6.0 + net8.0;net6.0 $(TargetFrameworksForDocs);$(NetFrameworkSupportedVersions) - net8.0;net7.0;net6.0 + net8.0;net6.0 $(TargetFrameworksForTests);$(NetFrameworkMinimumSupportedVersion) diff --git a/build/docker-compose.net7.0.yml b/build/docker-compose.net7.0.yml deleted file mode 100644 index 48a2589cda9..00000000000 --- a/build/docker-compose.net7.0.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: '3.7' - -services: - tests: - build: - args: - PUBLISH_FRAMEWORK: net7.0 - TEST_SDK_VERSION: "7.0" - BUILD_SDK_VERSION: "8.0" From 1b3f1894d95fd01fe475245ec60ef273d5f77bb6 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Thu, 22 Aug 2024 00:08:29 +0200 Subject: [PATCH 060/133] [api] Mark SetStatus & GetStatus ActivityExtensions obsolete (#5781) Co-authored-by: Vishwesh Bankwar Co-authored-by: Mikel Blanchard --- .../.publicApi/Stable/PublicAPI.Shipped.txt | 8 +-- src/OpenTelemetry.Api/CHANGELOG.md | 11 ++++ .../Trace/ActivityExtensions.cs | 59 +++++++++++++++---- src/OpenTelemetry.Api/Trace/TelemetrySpan.cs | 4 +- .../OpenTelemetry.Shims.OpenTracing.csproj | 2 + .../Trace/Processor/ExceptionProcessor.cs | 6 +- src/Shared/ActivityHelperExtensions.cs | 1 + src/Shared/AssemblyVersionExtensions.cs | 31 +++++++++- test/Directory.Packages.props | 3 +- .../OtlpTraceExporterTests.cs | 10 +++- .../ZipkinActivityConversionTest.cs | 4 ++ .../ZipkinExporterTests.cs | 39 ++++-------- ...enTelemetry.Shims.OpenTracing.Tests.csproj | 6 +- .../SpanBuilderShimTests.cs | 28 +++++++-- .../SpanShimTests.cs | 50 ++++++++-------- .../VersionHelper.cs | 42 +++++++++++++ 16 files changed, 219 insertions(+), 85 deletions(-) create mode 100644 test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt index 7b02ca885de..94729fd41bd 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt @@ -208,10 +208,10 @@ static OpenTelemetry.Baggage.operator !=(OpenTelemetry.Baggage left, OpenTelemet static OpenTelemetry.Baggage.operator ==(OpenTelemetry.Baggage left, OpenTelemetry.Baggage right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator !=(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator ==(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool -static OpenTelemetry.Trace.ActivityExtensions.GetStatus(this System.Diagnostics.Activity! activity) -> OpenTelemetry.Trace.Status -static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity! activity, System.Exception? ex, in System.Diagnostics.TagList tags) -> void -static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity! activity, System.Exception? ex) -> void -static OpenTelemetry.Trace.ActivityExtensions.SetStatus(this System.Diagnostics.Activity! activity, OpenTelemetry.Trace.Status status) -> void +static OpenTelemetry.Trace.ActivityExtensions.GetStatus(this System.Diagnostics.Activity? activity) -> OpenTelemetry.Trace.Status +static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity? activity, System.Exception? ex, in System.Diagnostics.TagList tags) -> void +static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity? activity, System.Exception? ex) -> void +static OpenTelemetry.Trace.ActivityExtensions.SetStatus(this System.Diagnostics.Activity? activity, OpenTelemetry.Trace.Status status) -> void static OpenTelemetry.Trace.Link.operator !=(OpenTelemetry.Trace.Link link1, OpenTelemetry.Trace.Link link2) -> bool static OpenTelemetry.Trace.Link.operator ==(OpenTelemetry.Trace.Link link1, OpenTelemetry.Trace.Link link2) -> bool static OpenTelemetry.Trace.SpanContext.implicit operator System.Diagnostics.ActivityContext(OpenTelemetry.Trace.SpanContext spanContext) -> System.Diagnostics.ActivityContext diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 458dff5ecc8..b3b2738a111 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -14,6 +14,17 @@ Notes](../../RELEASENOTES.md). * Optimize performance of `TraceContextPropagator.Extract`. ([#5749](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5749)) +* Obsoleted the `ActivityExtensions.GetStatus` and + `ActivityExtensions.SetStatus` extension methods. Users should migrate to the + `System.Diagnostics.DiagnosticSource` + [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API for setting the status and + [Activity.Status](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.status) + & + [Activity.StatusDescription](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.statusdescription) + APIs for reading the status of an `Activity` instance. + ([#5781](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5781)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs index d8ac769b9c9..a94a635055b 100644 --- a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs +++ b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs @@ -21,17 +21,34 @@ public static class ActivityExtensions { /// /// Sets the status of activity execution. - /// Activity class in .NET does not support 'Status'. - /// This extension provides a workaround to store Status as special tags with key name of otel.status_code and otel.status_description. - /// Read more about SetStatus here https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status. /// + /// + /// Note: This method is obsolete. Call the + /// method instead. For more details see: . + /// /// Activity instance. /// Activity execution status. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SetStatus(this Activity activity, Status status) + [Obsolete("Call Activity.SetStatus instead this method will be removed in a future version.")] + public static void SetStatus(this Activity? activity, Status status) { if (activity != null) { + switch (status.StatusCode) + { + case StatusCode.Ok: + activity.SetStatus(ActivityStatusCode.Ok); + break; + case StatusCode.Unset: + activity.SetStatus(ActivityStatusCode.Unset); + break; + case StatusCode.Error: + activity.SetStatus(ActivityStatusCode.Error, status.Description); + break; + } + activity.SetTag(SpanAttributeConstants.StatusCodeKey, StatusHelper.GetTagValueForStatusCode(status.StatusCode)); activity.SetTag(SpanAttributeConstants.StatusDescriptionKey, status.Description); } @@ -39,21 +56,37 @@ public static void SetStatus(this Activity activity, Status status) /// /// Gets the status of activity execution. - /// Activity class in .NET does not support 'Status'. - /// This extension provides a workaround to retrieve Status from special tags with key name otel.status_code and otel.status_description. /// + /// + /// Note: This method is obsolete. Use the and + /// properties instead. For more + /// details see: . + /// /// Activity instance. /// Activity execution status. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Status GetStatus(this Activity activity) + [Obsolete("Use Activity.Status and Activity.StatusDescription instead this method will be removed in a future version.")] + public static Status GetStatus(this Activity? activity) { - if (activity == null - || !activity.TryGetStatus(out var statusCode, out var statusDescription)) + if (activity != null) { - return Status.Unset; + switch (activity.Status) + { + case ActivityStatusCode.Ok: + return Status.Ok; + case ActivityStatusCode.Error: + return new Status(StatusCode.Error, activity.StatusDescription); + } + + if (activity.TryGetStatus(out var statusCode, out var statusDescription)) + { + return new Status(statusCode, statusDescription); + } } - return new Status(statusCode, statusDescription); + return Status.Unset; } /// @@ -65,7 +98,7 @@ public static Status GetStatus(this Activity activity) /// "exception.stacktrace" is represented using the value of Exception.ToString. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RecordException(this Activity activity, Exception? ex) + public static void RecordException(this Activity? activity, Exception? ex) => RecordException(activity, ex, default); /// @@ -78,7 +111,7 @@ public static void RecordException(this Activity activity, Exception? ex) /// "exception.stacktrace" is represented using the value of Exception.ToString. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RecordException(this Activity activity, Exception? ex, in TagList tags) + public static void RecordException(this Activity? activity, Exception? ex, in TagList tags) { if (ex == null || activity == null) { diff --git a/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs b/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs index f70598d078b..cdae8d4292c 100644 --- a/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs +++ b/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs @@ -47,7 +47,9 @@ public ActivitySpanId ParentSpanId /// Status to be set. public void SetStatus(Status value) { - this.Activity?.SetStatus(value); +#pragma warning disable + this.Activity.SetStatus(value); +#pragma warning restore } /// diff --git a/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj b/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj index 645c9e49e59..e746024d006 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj +++ b/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj @@ -22,7 +22,9 @@ + + diff --git a/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs b/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs index 3473c4292ad..f3845519408 100644 --- a/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs +++ b/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs @@ -62,11 +62,9 @@ public override void OnEnd(Activity activity) if (snapshot != pointers) { - // TODO: Remove this when SetStatus is deprecated +#pragma warning disable activity.SetStatus(Status.Error); - - // For processors/exporters checking `Status` property. - activity.SetStatus(ActivityStatusCode.Error); +#pragma warning restore } } } diff --git a/src/Shared/ActivityHelperExtensions.cs b/src/Shared/ActivityHelperExtensions.cs index b237ccd5457..0540ce7c5ca 100644 --- a/src/Shared/ActivityHelperExtensions.cs +++ b/src/Shared/ActivityHelperExtensions.cs @@ -24,6 +24,7 @@ internal static class ActivityHelperExtensions /// Status description. /// if was found on the supplied Activity. [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Obsolete] public static bool TryGetStatus(this Activity activity, out StatusCode statusCode, out string? statusDescription) { Debug.Assert(activity != null, "Activity should not be null"); diff --git a/src/Shared/AssemblyVersionExtensions.cs b/src/Shared/AssemblyVersionExtensions.cs index 029a3c2451c..b3e43d5bc9f 100644 --- a/src/Shared/AssemblyVersionExtensions.cs +++ b/src/Shared/AssemblyVersionExtensions.cs @@ -4,6 +4,7 @@ #nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace OpenTelemetry.Internal; @@ -11,6 +12,33 @@ namespace OpenTelemetry.Internal; internal static class AssemblyVersionExtensions { public static string GetPackageVersion(this Assembly assembly) + { + Debug.Assert(assembly != null, "assembly was null"); + + var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; + + Debug.Assert(!string.IsNullOrEmpty(informationalVersion), "AssemblyInformationalVersionAttribute was not found in assembly"); + + return ParsePackageVersion(informationalVersion!); + } + + public static bool TryGetPackageVersion(this Assembly assembly, [NotNullWhen(true)] out string? packageVersion) + { + Debug.Assert(assembly != null, "assembly was null"); + + var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; + + if (string.IsNullOrEmpty(informationalVersion)) + { + packageVersion = null; + return false; + } + + packageVersion = ParsePackageVersion(informationalVersion!); + return true; + } + + private static string ParsePackageVersion(string informationalVersion) { // MinVer https://github.com/adamralph/minver?tab=readme-ov-file#version-numbers // together with Microsoft.SourceLink.GitHub https://github.com/dotnet/sourcelink @@ -20,9 +48,6 @@ public static string GetPackageVersion(this Assembly assembly) // The following parts are optional: pre-release label, pre-release version, git height, Git SHA of current commit // For package version, value of AssemblyInformationalVersionAttribute without commit hash is returned. - var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; - Debug.Assert(!string.IsNullOrEmpty(informationalVersion), "AssemblyInformationalVersionAttribute was not found in assembly"); - var indexOfPlusSign = informationalVersion!.IndexOf('+'); return indexOfPlusSign > 0 ? informationalVersion.Substring(0, indexOfPlusSign) diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props index 4800f76a845..b3769fc1459 100644 --- a/test/Directory.Packages.props +++ b/test/Directory.Packages.props @@ -1,8 +1,9 @@ - + + diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index 84d3076500a..9f5da4cd8d7 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -370,7 +370,8 @@ public void ToOtlpSpanTest() links: childLinks); Assert.NotNull(childActivity); - childActivity.SetStatus(Status.Error); + + childActivity.SetStatus(ActivityStatusCode.Error); var childEvents = new List { new("e0"), new("e1", default, new ActivityTagsCollection(attributes)) }; childActivity.AddEvent(childEvents[0]); @@ -388,7 +389,8 @@ public void ToOtlpSpanTest() Assert.Equal(traceId, otlpSpan.TraceId); Assert.Equal(parentId, otlpSpan.ParentSpanId); - // Assert.Equal(OtlpTrace.Status.Types.StatusCode.NotFound, otlpSpan.Status.Code); + Assert.NotNull(otlpSpan.Status); + Assert.Equal(OtlpTrace.Status.Types.StatusCode.Error, otlpSpan.Status.Code); Assert.Equal(Status.Error.Description ?? string.Empty, otlpSpan.Status.Message); Assert.Empty(otlpSpan.Attributes); @@ -474,6 +476,7 @@ public void ToOtlpSpanNativeActivityStatusTest(ActivityStatusCode expectedStatus [InlineData(StatusCode.Unset, "Unset", "Description will be ignored if status is Unset.")] [InlineData(StatusCode.Ok, "Ok", "Description must only be used with the Error StatusCode.")] [InlineData(StatusCode.Error, "Error", "Error description.")] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanStatusTagTest(StatusCode expectedStatusCode, string statusCodeTagValue, string statusDescription) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -502,6 +505,7 @@ public void ToOtlpSpanStatusTagTest(StatusCode expectedStatusCode, string status [InlineData(StatusCode.Unset, "uNsET")] [InlineData(StatusCode.Ok, "oK")] [InlineData(StatusCode.Error, "ERROR")] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanStatusTagIsCaseInsensitiveTest(StatusCode expectedStatusCode, string statusCodeTagValue) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -517,6 +521,7 @@ public void ToOtlpSpanStatusTagIsCaseInsensitiveTest(StatusCode expectedStatusCo } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivityStatusCodeIsOk() { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -536,6 +541,7 @@ public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivitySta } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivityStatusCodeIsError() { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs index da6cdcbfcbb..bfe69520fea 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs @@ -79,6 +79,7 @@ public void ToZipkinSpan_NoEvents() [InlineData(StatusCode.Ok, "Ok")] [InlineData(StatusCode.Error, "ERROR")] [InlineData(StatusCode.Unset, "iNvAlId")] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToZipkinSpan_Status_ErrorFlagTest(StatusCode expectedStatusCode, string statusCodeTagValue) { // Arrange @@ -159,6 +160,7 @@ public void ToZipkinSpan_Activity_Status_And_StatusDescription_is_Set(ActivitySt } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsOk() { // Arrange. @@ -184,6 +186,7 @@ public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeI } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsError() { // Arrange. @@ -219,6 +222,7 @@ public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeI } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsError_SettingTagFirst() { // Arrange. diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs index 01e40b66b16..b1481ac0541 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs @@ -322,31 +322,18 @@ public void UpdatesServiceNameFromIConfiguration() [InlineData(false, false, false)] [InlineData(false, true, false)] [InlineData(false, false, true)] - [InlineData(false, false, false, StatusCode.Ok)] - [InlineData(false, false, false, StatusCode.Ok, null, true)] - [InlineData(false, false, false, StatusCode.Error)] - [InlineData(false, false, false, StatusCode.Error, "Error description")] + [InlineData(false, false, false, ActivityStatusCode.Ok)] + [InlineData(false, false, false, ActivityStatusCode.Ok, null, true)] + [InlineData(false, false, false, ActivityStatusCode.Error)] + [InlineData(false, false, false, ActivityStatusCode.Error, "Error description")] public void IntegrationTest( bool useShortTraceIds, bool useTestResource, bool isRootSpan, - StatusCode statusCode = StatusCode.Unset, + ActivityStatusCode statusCode = ActivityStatusCode.Unset, string statusDescription = null, bool addErrorTag = false) { - var status = statusCode switch - { - StatusCode.Unset => Status.Unset, - StatusCode.Ok => Status.Ok, - StatusCode.Error => Status.Error, - _ => throw new InvalidOperationException(), - }; - - if (!string.IsNullOrEmpty(statusDescription)) - { - status = status.WithDescription(statusDescription); - } - Guid requestId = Guid.NewGuid(); ZipkinExporter exporter = new ZipkinExporter( @@ -360,7 +347,7 @@ public void IntegrationTest( .Where(pair => pair.Key == ResourceSemanticConventions.AttributeServiceName).FirstOrDefault().Value; var resourceTags = string.Empty; var dateTime = DateTime.UtcNow; - var activity = CreateTestActivity(isRootSpan: isRootSpan, status: status, dateTime: dateTime); + var activity = CreateTestActivity(isRootSpan: isRootSpan, statusCode: statusCode, statusDescription: statusDescription, dateTime: dateTime); if (useTestResource) { serviceName = "MyService"; @@ -409,13 +396,13 @@ public void IntegrationTest( string errorTag = string.Empty; switch (statusCode) { - case StatusCode.Ok: + case ActivityStatusCode.Ok: statusTag = $@"""{SpanAttributeConstants.StatusCodeKey}"":""OK"","; break; - case StatusCode.Unset: + case ActivityStatusCode.Unset: statusTag = string.Empty; break; - case StatusCode.Error: + case ActivityStatusCode.Error: statusTag = $@"""{SpanAttributeConstants.StatusCodeKey}"":""ERROR"","; errorTag = $@"""{ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName}"":""{statusDescription}"","; break; @@ -464,7 +451,8 @@ internal static Activity CreateTestActivity( bool addLinks = true, Resource resource = null, ActivityKind kind = ActivityKind.Client, - Status? status = null, + ActivityStatusCode statusCode = ActivityStatusCode.Unset, + string statusDescription = null, DateTime? dateTime = null) { var startTimestamp = DateTime.UtcNow; @@ -552,10 +540,7 @@ internal static Activity CreateTestActivity( } } - if (status.HasValue) - { - activity.SetStatus(status.Value); - } + activity.SetStatus(statusCode, statusDescription); activity.SetEndTime(endTimestamp); activity.Stop(); diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj index 07fe011a082..1aac45f10ca 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj @@ -2,16 +2,16 @@ Unit test project for OpenTelemetry.Shims.OpenTracing $(TargetFrameworksForTests) + $(DefineConstants);BUILDING_USING_PROJECTS disable + - - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs index ce546c868bf..a3a58facfd9 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs @@ -216,8 +216,18 @@ public void WithTag_KeyIsErrorStringValue() // build var spanShim = (SpanShim)shim.Start(); - // Span status should be set - Assert.Equal(Status.Error, spanShim.Span.Activity.GetStatus()); + // Legacy span status tag should be set + Assert.Equal("ERROR", spanShim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Error, spanShim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, spanShim.Span.Activity.Status); + } } [Fact] @@ -262,8 +272,18 @@ public void WithTag_KeyIsErrorBoolValue() // build var spanShim = (SpanShim)shim.Start(); - // Span status should be set - Assert.Equal(Status.Error, spanShim.Span.Activity.GetStatus()); + // Legacy span status tag should be set + Assert.Equal("ERROR", spanShim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Error, spanShim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, spanShim.Span.Activity.Status); + } } [Fact] diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs index 80178f405be..9911d9f76fc 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using OpenTelemetry.Trace; using OpenTracing.Tag; using Xunit; @@ -209,10 +210,34 @@ public void SetTagBoolValue() Assert.True((bool)shim.Span.Activity.TagObjects.First().Value); // A boolean tag named "error" is a special case that must be checked - Assert.Equal(Status.Error, shim.Span.Activity.GetStatus()); + + // Legacy span status tag should be set + Assert.Equal("ERROR", shim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Error, shim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, shim.Span.Activity.Status); + } shim.SetTag(Tags.Error.Key, false); - Assert.Equal(Status.Ok, shim.Span.Activity.GetStatus()); + + // Legacy span status tag should be set + Assert.Equal("OK", shim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Ok, shim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, shim.Span.Activity.Status); + } } [Fact] @@ -245,27 +270,6 @@ public void SetTagDoubleValue() Assert.Equal(1, (double)shim.Span.Activity.TagObjects.First().Value); } - [Fact] - public void SetTagBooleanTagValue() - { - var tracer = TracerProvider.Default.GetTracer(TracerName); - var shim = new SpanShim(tracer.StartSpan(SpanName)); - - Assert.Throws(() => shim.SetTag((BooleanTag)null, true)); - - shim.SetTag(new BooleanTag("foo"), true); - shim.SetTag(new BooleanTag(Tags.Error.Key), true); - - Assert.Equal("foo", shim.Span.Activity.TagObjects.First().Key); - Assert.True((bool)shim.Span.Activity.TagObjects.First().Value); - - // A boolean tag named "error" is a special case that must be checked - Assert.Equal(Status.Error, shim.Span.Activity.GetStatus()); - - shim.SetTag(Tags.Error.Key, false); - Assert.Equal(Status.Ok, shim.Span.Activity.GetStatus()); - } - [Fact] public void SetTagStringTagValue() { diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs new file mode 100644 index 00000000000..57b1b8a9f53 --- /dev/null +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs @@ -0,0 +1,42 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using NuGet.Versioning; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Shims.OpenTracing.Tests; + +internal static class VersionHelper +{ +#if BUILDING_USING_PROJECTS + private static NuGetVersion? apiVersion = new(100, 0, 0); +#else + private static NuGetVersion? apiVersion; +#endif + + public static NuGetVersion ApiVersion + { + get + { + return apiVersion ??= ResolveApiVersion(); + + static NuGetVersion ResolveApiVersion() + { + if (!typeof(TracerProvider).Assembly.TryGetPackageVersion(out var packageVersion)) + { + throw new InvalidOperationException("OpenTelemetry.Api package version could not be resolved"); + } + + return NuGetVersion.Parse(packageVersion); + } + } + } + + public static bool IsApiVersionGreaterThanOrEqualTo(int major, int minor) + { + return ApiVersion >= new NuGetVersion(major, minor, 0); + } +} From ba8a0e4c131054217555aae5c8a210da3a4b7c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 28 Aug 2024 18:56:15 +0200 Subject: [PATCH 061/133] [Propagators] Nullable annotations (#5767) --- .../.publicApi/Stable/PublicAPI.Shipped.txt | 36 +++++++++---------- .../Context/Propagation/B3Propagator.cs | 13 ++++--- .../Context/Propagation/BaggagePropagator.cs | 26 +++++++++----- .../Propagation/CompositeTextMapPropagator.cs | 6 ++-- .../Propagation/NoopTextMapPropagator.cs | 6 ++-- .../Context/Propagation/PropagationContext.cs | 4 ++- .../Context/Propagation/Propagators.cs | 2 ++ .../Context/Propagation/TextMapPropagator.cs | 12 ++++--- .../Propagation/TraceContextPropagator.cs | 12 ++++--- .../Context/Propagation/TraceStateUtilsNew.cs | 8 +++-- src/OpenTelemetry.Api/Trace/SpanContext.cs | 5 +-- .../.publicApi/PublicAPI.Shipped.txt | 13 +++---- .../B3Propagator.cs | 11 +++--- .../JaegerPropagator.cs | 4 +-- ...penTelemetry.Extensions.Propagators.csproj | 3 -- .../Context/Propagation/B3PropagatorTest.cs | 10 ++++-- .../Propagation/BaggagePropagatorTest.cs | 14 +++++--- .../Propagation/CompositePropagatorTest.cs | 6 ++-- .../Context/Propagation/PropagatorsTest.cs | 2 ++ .../Context/Propagation/TestPropagator.cs | 6 ++-- .../Propagation/TracestateUtilsTests.cs | 11 +++++- .../B3PropagatorTest.cs | 9 +++-- .../JaegerPropagatorTest.cs | 4 +-- ...emetry.Extensions.Propagators.Tests.csproj | 2 -- 24 files changed, 141 insertions(+), 84 deletions(-) diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt index 94729fd41bd..46b63e18fee 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt @@ -1,7 +1,4 @@ #nullable enable -~abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -~abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Fields.get -> System.Collections.Generic.ISet -~abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void ~OpenTelemetry.Baggage.GetBaggage() -> System.Collections.Generic.IReadOnlyDictionary ~OpenTelemetry.Baggage.GetBaggage(string name) -> string ~OpenTelemetry.Baggage.GetEnumerator() -> System.Collections.Generic.Dictionary.Enumerator @@ -14,26 +11,12 @@ ~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Value.set -> void ~OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.get -> object ~OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.set -> void -~OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.CompositeTextMapPropagator(System.Collections.Generic.IEnumerable propagators) -> void ~OpenTelemetry.Context.RuntimeContextSlot.Name.get -> string ~OpenTelemetry.Context.RuntimeContextSlot.RuntimeContextSlot(string name) -> void ~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.ThreadLocalRuntimeContextSlot(string name) -> void ~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.get -> object ~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.set -> void ~override OpenTelemetry.Baggage.Equals(object obj) -> bool -~override OpenTelemetry.Context.Propagation.B3Propagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -~override OpenTelemetry.Context.Propagation.B3Propagator.Fields.get -> System.Collections.Generic.ISet -~override OpenTelemetry.Context.Propagation.B3Propagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void -~override OpenTelemetry.Context.Propagation.BaggagePropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -~override OpenTelemetry.Context.Propagation.BaggagePropagator.Fields.get -> System.Collections.Generic.ISet -~override OpenTelemetry.Context.Propagation.BaggagePropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void -~override OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -~override OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.Fields.get -> System.Collections.Generic.ISet -~override OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void -~override OpenTelemetry.Context.Propagation.PropagationContext.Equals(object obj) -> bool -~override OpenTelemetry.Context.Propagation.TraceContextPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -~override OpenTelemetry.Context.Propagation.TraceContextPropagator.Fields.get -> System.Collections.Generic.ISet -~override OpenTelemetry.Context.Propagation.TraceContextPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void ~static OpenTelemetry.Baggage.Create(System.Collections.Generic.Dictionary baggageItems = null) -> OpenTelemetry.Baggage ~static OpenTelemetry.Baggage.GetBaggage(OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> System.Collections.Generic.IReadOnlyDictionary ~static OpenTelemetry.Baggage.GetBaggage(string name, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> string @@ -41,7 +24,6 @@ ~static OpenTelemetry.Baggage.RemoveBaggage(string name, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage ~static OpenTelemetry.Baggage.SetBaggage(string name, string value, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage ~static OpenTelemetry.Baggage.SetBaggage(System.Collections.Generic.IEnumerable> baggageItems, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage -~static OpenTelemetry.Context.Propagation.Propagators.DefaultTextMapPropagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator ~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.get -> System.Type ~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.set -> void ~static OpenTelemetry.Context.RuntimeContext.GetSlot(string slotName) -> OpenTelemetry.Context.RuntimeContextSlot @@ -50,6 +32,9 @@ ~static OpenTelemetry.Context.RuntimeContext.RegisterSlot(string slotName) -> OpenTelemetry.Context.RuntimeContextSlot ~static OpenTelemetry.Context.RuntimeContext.SetValue(string slotName, object value) -> void ~static OpenTelemetry.Context.RuntimeContext.SetValue(string slotName, T value) -> void +abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Fields.get -> System.Collections.Generic.ISet? +abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void abstract OpenTelemetry.Context.RuntimeContextSlot.Get() -> T abstract OpenTelemetry.Context.RuntimeContextSlot.Set(T value) -> void abstract OpenTelemetry.Logs.LoggerProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! @@ -73,6 +58,7 @@ OpenTelemetry.Context.IRuntimeContextSlotValueAccessor OpenTelemetry.Context.Propagation.B3Propagator OpenTelemetry.Context.Propagation.B3Propagator.B3Propagator() -> void OpenTelemetry.Context.Propagation.B3Propagator.B3Propagator(bool singleHeader) -> void +OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.CompositeTextMapPropagator(System.Collections.Generic.IEnumerable! propagators) -> void OpenTelemetry.Context.Propagation.BaggagePropagator OpenTelemetry.Context.Propagation.BaggagePropagator.BaggagePropagator() -> void OpenTelemetry.Context.Propagation.CompositeTextMapPropagator @@ -188,7 +174,20 @@ OpenTelemetry.Trace.TracerProviderBuilder.TracerProviderBuilder() -> void override OpenTelemetry.Baggage.GetHashCode() -> int override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Get() -> T override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Set(T value) -> void +override OpenTelemetry.Context.Propagation.B3Propagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Context.Propagation.B3Propagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Context.Propagation.B3Propagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +override OpenTelemetry.Context.Propagation.BaggagePropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Context.Propagation.BaggagePropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Context.Propagation.BaggagePropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +override OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Context.Propagation.CompositeTextMapPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void override OpenTelemetry.Context.Propagation.PropagationContext.GetHashCode() -> int +override OpenTelemetry.Context.Propagation.PropagationContext.Equals(object? obj) -> bool +override OpenTelemetry.Context.Propagation.TraceContextPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Context.Propagation.TraceContextPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Context.Propagation.TraceContextPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Dispose(bool disposing) -> void override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Get() -> T override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Set(T value) -> void @@ -208,6 +207,7 @@ static OpenTelemetry.Baggage.operator !=(OpenTelemetry.Baggage left, OpenTelemet static OpenTelemetry.Baggage.operator ==(OpenTelemetry.Baggage left, OpenTelemetry.Baggage right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator !=(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator ==(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool +static OpenTelemetry.Context.Propagation.Propagators.DefaultTextMapPropagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator! static OpenTelemetry.Trace.ActivityExtensions.GetStatus(this System.Diagnostics.Activity? activity) -> OpenTelemetry.Trace.Status static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity? activity, System.Exception? ex, in System.Diagnostics.TagList tags) -> void static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity? activity, System.Exception? ex) -> void diff --git a/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs b/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs index 10b4aee1d81..5969d2499c1 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Text; using OpenTelemetry.Internal; @@ -66,7 +68,7 @@ public B3Propagator(bool singleHeader) /// [Obsolete("Use B3Propagator class from OpenTelemetry.Extensions.Propagators namespace, shipped as part of OpenTelemetry.Extensions.Propagators package.")] #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member { if (context.ActivityContext.IsValid()) @@ -146,7 +148,7 @@ public override void Inject(PropagationContext context, T carrier, Action(PropagationContext context, T carrier, Func> getter) + private static PropagationContext ExtractFromMultipleHeaders(PropagationContext context, T carrier, Func?> getter) { try { @@ -179,7 +181,8 @@ private static PropagationContext ExtractFromMultipleHeaders(PropagationConte } var traceOptions = ActivityTraceFlags.None; - if (SampledValues.Contains(getter(carrier, XB3Sampled)?.FirstOrDefault()) + var xb3Sampled = getter(carrier, XB3Sampled)?.FirstOrDefault(); + if ((xb3Sampled != null && SampledValues.Contains(xb3Sampled)) || FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault(), StringComparison.Ordinal)) { traceOptions |= ActivityTraceFlags.Recorded; @@ -196,7 +199,7 @@ private static PropagationContext ExtractFromMultipleHeaders(PropagationConte } } - private static PropagationContext ExtractFromSingleHeader(PropagationContext context, T carrier, Func> getter) + private static PropagationContext ExtractFromSingleHeader(PropagationContext context, T carrier, Func?> getter) { try { @@ -206,7 +209,7 @@ private static PropagationContext ExtractFromSingleHeader(PropagationContext return context; } - var parts = header.Split(XB3CombinedDelimiter); + var parts = header!.Split(XB3CombinedDelimiter); if (parts.Length < 2 || parts.Length > 4) { return context; diff --git a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs index 57bdb453b8f..17bbf13110b 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs @@ -1,6 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +#if NET +using System.Diagnostics.CodeAnalysis; +#endif using System.Net; using System.Text; using OpenTelemetry.Internal; @@ -24,7 +29,7 @@ public class BaggagePropagator : TextMapPropagator public override ISet Fields => new HashSet { BaggageHeaderName }; /// - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { if (context.Baggage != default) { @@ -46,16 +51,16 @@ public override PropagationContext Extract(PropagationContext context, T carr try { - Dictionary baggage = null; var baggageCollection = getter(carrier, BaggageHeaderName); if (baggageCollection?.Any() ?? false) { - TryExtractBaggage(baggageCollection.ToArray(), out baggage); + if (TryExtractBaggage(baggageCollection.ToArray(), out var baggage)) + { + return new PropagationContext(context.ActivityContext, new Baggage(baggage)); + } } - return new PropagationContext( - context.ActivityContext, - baggage == null ? context.Baggage : new Baggage(baggage)); + return new PropagationContext(context.ActivityContext, context.Baggage); } catch (Exception ex) { @@ -102,11 +107,16 @@ public override void Inject(PropagationContext context, T carrier, Action baggage) + internal static bool TryExtractBaggage( + string[] baggageCollection, +#if NET + [NotNullWhen(true)] +#endif + out Dictionary? baggage) { int baggageLength = -1; bool done = false; - Dictionary baggageDictionary = null; + Dictionary? baggageDictionary = null; foreach (var item in baggageCollection) { diff --git a/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs index 016ef0fda4d..5b6939842b0 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using OpenTelemetry.Internal; namespace OpenTelemetry.Context.Propagation; @@ -43,7 +45,7 @@ public CompositeTextMapPropagator(IEnumerable propagators) } else { - ISet fields = this.propagators[0].Fields; + ISet? fields = this.propagators[0].Fields; var output = fields is not null ? new HashSet(fields) @@ -66,7 +68,7 @@ public CompositeTextMapPropagator(IEnumerable propagators) public override ISet Fields => this.allFields; /// - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { for (int i = 0; i < this.propagators.Count; i++) { diff --git a/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs index 03dd45785d4..6efd538e820 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs @@ -1,15 +1,17 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Context.Propagation; internal sealed class NoopTextMapPropagator : TextMapPropagator { private static readonly PropagationContext DefaultPropagationContext = default; - public override ISet Fields => null; + public override ISet? Fields => null; - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { return DefaultPropagationContext; } diff --git a/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs b/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs index 77b6c71e77a..bb35c88cadc 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; namespace OpenTelemetry.Context.Propagation; @@ -53,7 +55,7 @@ public bool Equals(PropagationContext value) } /// - public override bool Equals(object obj) => (obj is PropagationContext context) && this.Equals(context); + public override bool Equals(object? obj) => (obj is PropagationContext context) && this.Equals(context); /// public override int GetHashCode() diff --git a/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs b/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs index c1dab62400d..ee9c59931f5 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Context.Propagation; /// diff --git a/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs index 1000b317bf5..547d6a1890c 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Context.Propagation; /// @@ -15,12 +17,12 @@ public abstract class TextMapPropagator /// * allow pre-allocation of fields, especially in systems like gRPC Metadata /// * allow a single-pass over an iterator (ex OpenTracing has no getter in TextMap). /// - public abstract ISet Fields { get; } + public abstract ISet? Fields { get; } /// /// Injects the context into a carrier. /// - /// Type of an object to set context on. Typically HttpRequest or similar. + /// Type of object to set context on. Typically,HttpRequest or similar. /// The default context to transmit over the wire. /// Object to set context on. Instance of this object will be passed to setter. /// Action that will set name and value pair on the object. @@ -29,10 +31,10 @@ public abstract class TextMapPropagator /// /// Extracts the context from a carrier. /// - /// Type of object to extract context from. Typically HttpRequest or similar. + /// Type of object to extract context from. Typically, HttpRequest or similar. /// The default context to be used if Extract fails. /// Object to extract context from. Instance of this object will be passed to the getter. /// Function that will return string value of a key with the specified name. - /// Context from it's text representation. - public abstract PropagationContext Extract(PropagationContext context, T carrier, Func> getter); + /// Context from its text representation. + public abstract PropagationContext Extract(PropagationContext context, T carrier, Func?> getter); } diff --git a/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs index b37fb93cc08..dfa828e088b 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -34,7 +36,7 @@ public class TraceContextPropagator : TextMapPropagator public override ISet Fields => new HashSet { TraceState, TraceParent }; /// - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { if (context.ActivityContext.IsValid()) { @@ -72,7 +74,7 @@ public override PropagationContext Extract(PropagationContext context, T carr return context; } - string tracestate = null; + string? tracestate = null; var tracestateCollection = getter(carrier, TraceState); if (tracestateCollection?.Any() ?? false) { @@ -122,7 +124,7 @@ public override void Inject(PropagationContext context, T carrier, Action 0) { setter(carrier, TraceState, tracestateStr); @@ -224,7 +226,7 @@ internal static bool TryExtractTracestate(IEnumerable tracestateCollecti { tracestateResult = string.Empty; - char[] rentedArray = null; + char[]? rentedArray = null; Span traceStateBuffer = stackalloc char[128]; // 256B Span keyLookupBuffer = stackalloc char[96]; // 192B (3x32 keys) int keys = 0; @@ -379,7 +381,7 @@ internal static bool TryExtractTracestate(IEnumerable tracestateCollecti } [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void GrowBuffer(ref char[] array, ref Span buffer) + static void GrowBuffer(ref char[]? array, ref Span buffer) { var newBuffer = ArrayPool.Shared.Rent(buffer.Length * 2); diff --git a/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs b/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs index 717e1a94584..e1fe192bd6d 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Text; using OpenTelemetry.Internal; @@ -56,7 +58,7 @@ internal static bool AppendTraceState(string traceStateString, List(keyStr, value.ToString())); + tracestate!.Add(new KeyValuePair(keyStr, value.ToString())); } else { @@ -82,7 +84,7 @@ internal static bool AppendTraceState(string traceStateString, List> traceState) + internal static string GetString(IEnumerable>? traceState) { if (traceState == null || !traceState.Any()) { diff --git a/src/OpenTelemetry.Api/Trace/SpanContext.cs b/src/OpenTelemetry.Api/Trace/SpanContext.cs index b94f50cc5f6..dff0de021c2 100644 --- a/src/OpenTelemetry.Api/Trace/SpanContext.cs +++ b/src/OpenTelemetry.Api/Trace/SpanContext.cs @@ -85,13 +85,14 @@ public IEnumerable> TraceState { get { - if (string.IsNullOrEmpty(this.ActivityContext.TraceState)) + var traceState = this.ActivityContext.TraceState; + if (string.IsNullOrEmpty(traceState)) { return Enumerable.Empty>(); } var traceStateResult = new List>(); - TraceStateUtilsNew.AppendTraceState(this.ActivityContext.TraceState, traceStateResult); + TraceStateUtilsNew.AppendTraceState(traceState!, traceStateResult); return traceStateResult; } } diff --git a/src/OpenTelemetry.Extensions.Propagators/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Propagators/.publicApi/PublicAPI.Shipped.txt index eadd932c939..3379641fda2 100644 --- a/src/OpenTelemetry.Extensions.Propagators/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.Propagators/.publicApi/PublicAPI.Shipped.txt @@ -1,11 +1,12 @@ +#nullable enable OpenTelemetry.Extensions.Propagators.B3Propagator OpenTelemetry.Extensions.Propagators.B3Propagator.B3Propagator() -> void OpenTelemetry.Extensions.Propagators.B3Propagator.B3Propagator(bool singleHeader) -> void OpenTelemetry.Extensions.Propagators.JaegerPropagator OpenTelemetry.Extensions.Propagators.JaegerPropagator.JaegerPropagator() -> void -override OpenTelemetry.Extensions.Propagators.B3Propagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Extensions.Propagators.B3Propagator.Fields.get -> System.Collections.Generic.ISet -override OpenTelemetry.Extensions.Propagators.B3Propagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void -override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Fields.get -> System.Collections.Generic.ISet -override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void +override OpenTelemetry.Extensions.Propagators.B3Propagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.Propagators.B3Propagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Extensions.Propagators.B3Propagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Extensions.Propagators.JaegerPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void diff --git a/src/OpenTelemetry.Extensions.Propagators/B3Propagator.cs b/src/OpenTelemetry.Extensions.Propagators/B3Propagator.cs index 37ced1218e8..45239981f0a 100644 --- a/src/OpenTelemetry.Extensions.Propagators/B3Propagator.cs +++ b/src/OpenTelemetry.Extensions.Propagators/B3Propagator.cs @@ -62,7 +62,7 @@ public B3Propagator(bool singleHeader) public override ISet Fields => AllFields; /// - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { if (context.ActivityContext.IsValid()) { @@ -138,7 +138,7 @@ public override void Inject(PropagationContext context, T carrier, Action(PropagationContext context, T carrier, Func> getter) + private static PropagationContext ExtractFromMultipleHeaders(PropagationContext context, T carrier, Func?> getter) { try { @@ -171,7 +171,8 @@ private static PropagationContext ExtractFromMultipleHeaders(PropagationConte } var traceOptions = ActivityTraceFlags.None; - if (SampledValues.Contains(getter(carrier, XB3Sampled)?.FirstOrDefault()) + var xb3Sampled = getter(carrier, XB3Sampled)?.FirstOrDefault(); + if ((xb3Sampled != null && SampledValues.Contains(xb3Sampled)) || FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault(), StringComparison.Ordinal)) { traceOptions |= ActivityTraceFlags.Recorded; @@ -188,7 +189,7 @@ private static PropagationContext ExtractFromMultipleHeaders(PropagationConte } } - private static PropagationContext ExtractFromSingleHeader(PropagationContext context, T carrier, Func> getter) + private static PropagationContext ExtractFromSingleHeader(PropagationContext context, T carrier, Func?> getter) { try { @@ -198,7 +199,7 @@ private static PropagationContext ExtractFromSingleHeader(PropagationContext return context; } - var parts = header.Split(XB3CombinedDelimiter); + var parts = header!.Split(XB3CombinedDelimiter); if (parts.Length < 2 || parts.Length > 4) { return context; diff --git a/src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.cs b/src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.cs index 472b719ded0..045fd93e581 100644 --- a/src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.cs +++ b/src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.cs @@ -26,7 +26,7 @@ public class JaegerPropagator : TextMapPropagator public override ISet Fields => new HashSet { JaegerHeader }; /// - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { if (context.ActivityContext.IsValid()) { @@ -56,7 +56,7 @@ public override PropagationContext Extract(PropagationContext context, T carr return context; } - var jaegerHeaderParsed = TryExtractTraceContext(jaegerHeader, out var traceId, out var spanId, out var traceOptions); + var jaegerHeaderParsed = TryExtractTraceContext(jaegerHeader!, out var traceId, out var spanId, out var traceOptions); if (!jaegerHeaderParsed) { diff --git a/src/OpenTelemetry.Extensions.Propagators/OpenTelemetry.Extensions.Propagators.csproj b/src/OpenTelemetry.Extensions.Propagators/OpenTelemetry.Extensions.Propagators.csproj index c099b609a25..01ae76f4a17 100644 --- a/src/OpenTelemetry.Extensions.Propagators/OpenTelemetry.Extensions.Propagators.csproj +++ b/src/OpenTelemetry.Extensions.Propagators/OpenTelemetry.Extensions.Propagators.csproj @@ -5,9 +5,6 @@ $(PackageTags);distributed-tracing;AspNet;AspNetCore;B3 core- true - - - disable diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs index 8cc20c6ff5e..1cef6ae90e9 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using Xunit; using Xunit.Abstractions; @@ -24,8 +26,12 @@ public class B3PropagatorTest private static readonly Func, string, IEnumerable> Getter = (d, k) => { - d.TryGetValue(k, out var v); - return new string[] { v }; + if (d.TryGetValue(k, out var v)) + { + return [v]; + } + + return []; }; private readonly B3Propagator b3propagator = new(); diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs index 097f63e039d..0f236081331 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Net; using Xunit; @@ -11,8 +13,12 @@ public class BaggagePropagatorTest private static readonly Func, string, IEnumerable> Getter = (d, k) => { - d.TryGetValue(k, out var v); - return new string[] { v }; + if (d.TryGetValue(k, out var v)) + { + return [v]; + } + + return []; }; private static readonly Func>, string, IEnumerable> GetterList = @@ -38,7 +44,7 @@ public void ValidateFieldsProperty() [Fact] public void ValidateDefaultCarrierExtraction() { - var propagationContext = this.baggage.Extract(default, null, null); + var propagationContext = this.baggage.Extract(default, null!, null!); Assert.Equal(default, propagationContext); } @@ -46,7 +52,7 @@ public void ValidateDefaultCarrierExtraction() public void ValidateDefaultGetterExtraction() { var carrier = new Dictionary(); - var propagationContext = this.baggage.Extract(default, carrier, null); + var propagationContext = this.baggage.Extract(default, carrier, null!); Assert.Equal(default, propagationContext); } diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs index 0fcf7a1952f..4009ed756a6 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using Xunit; @@ -33,7 +35,7 @@ public class CompositePropagatorTest [Fact] public void CompositePropagator_NullTextMapPropagators() { - Assert.Throws(() => new CompositeTextMapPropagator(null)); + Assert.Throws(() => new CompositeTextMapPropagator(null!)); } [Fact] @@ -46,7 +48,7 @@ public void CompositePropagator_EmptyTextMapPropagators() [Fact] public void CompositePropagator_NullTextMapPropagator() { - var compositePropagator = new CompositeTextMapPropagator([null]); + var compositePropagator = new CompositeTextMapPropagator([null!]); Assert.Empty(compositePropagator.Fields); } diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs index b7993e0d848..3216baec7d7 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Xunit; namespace OpenTelemetry.Context.Propagation.Tests; diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs index f07875c5d28..a2a8ab39234 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; namespace OpenTelemetry.Context.Propagation.Tests; @@ -27,7 +29,7 @@ public TestPropagator(string idHeaderName, string stateHeaderName, bool defaultC public override ISet Fields => new HashSet() { this.idHeaderName, this.stateHeaderName }; - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { Interlocked.Increment(ref this.extractCount); @@ -37,7 +39,7 @@ public override PropagationContext Extract(PropagationContext context, T carr } var id = getter(carrier, this.idHeaderName); - if (!id.Any()) + if (id == null || !id.Any()) { return context; } diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs index 499fe66cbf4..f1271938a5a 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs @@ -1,15 +1,24 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Xunit; namespace OpenTelemetry.Context.Propagation.Tests; public class TracestateUtilsTests { + [Fact] + public void NullTracestate() + { + var tracestateEntries = new List>(); + Assert.False(TraceStateUtilsNew.AppendTraceState(null!, tracestateEntries)); + Assert.Empty(tracestateEntries); + } + [Theory] [InlineData("")] - [InlineData(null)] [InlineData(" ")] [InlineData("\t")] public void EmptyTracestate(string tracestate) diff --git a/test/OpenTelemetry.Extensions.Propagators.Tests/B3PropagatorTest.cs b/test/OpenTelemetry.Extensions.Propagators.Tests/B3PropagatorTest.cs index 5373573ad6c..15ed68c96da 100644 --- a/test/OpenTelemetry.Extensions.Propagators.Tests/B3PropagatorTest.cs +++ b/test/OpenTelemetry.Extensions.Propagators.Tests/B3PropagatorTest.cs @@ -25,8 +25,12 @@ public class B3PropagatorTest private static readonly Func, string, IEnumerable> Getter = (d, k) => { - d.TryGetValue(k, out var v); - return new string[] { v }; + if (d.TryGetValue(k, out var v)) + { + return [v]; + } + + return []; }; private readonly B3Propagator b3propagator = new(); @@ -354,6 +358,7 @@ public void ParseMissingSpanId_SingleHeader() [Fact] public void Fields_list() { + Assert.Equivalent(this.b3propagator.Fields, new List { B3Propagator.XB3TraceId, B3Propagator.XB3SpanId, B3Propagator.XB3ParentSpanId, B3Propagator.XB3Sampled, B3Propagator.XB3Flags, B3Propagator.XB3Flags }); ContainsExactly( this.b3propagator.Fields, new List { B3Propagator.XB3TraceId, B3Propagator.XB3SpanId, B3Propagator.XB3ParentSpanId, B3Propagator.XB3Sampled, B3Propagator.XB3Flags }); diff --git a/test/OpenTelemetry.Extensions.Propagators.Tests/JaegerPropagatorTest.cs b/test/OpenTelemetry.Extensions.Propagators.Tests/JaegerPropagatorTest.cs index 9e040746dd3..4e2b0486f6e 100644 --- a/test/OpenTelemetry.Extensions.Propagators.Tests/JaegerPropagatorTest.cs +++ b/test/OpenTelemetry.Extensions.Propagators.Tests/JaegerPropagatorTest.cs @@ -77,7 +77,7 @@ public void ExtractReturnsOriginalContextIfGetterIsNull() var headers = new Dictionary(); // act - var result = new JaegerPropagator().Extract(propagationContext, headers, null); + var result = new JaegerPropagator().Extract(propagationContext, headers, null!); // assert Assert.Equal(propagationContext, result); @@ -183,7 +183,7 @@ public void InjectDoesNoopIfSetterIsNull() var headers = new Dictionary(); // act - new JaegerPropagator().Inject(propagationContext, headers, null); + new JaegerPropagator().Inject(propagationContext, headers, null!); // assert Assert.Empty(headers); diff --git a/test/OpenTelemetry.Extensions.Propagators.Tests/OpenTelemetry.Extensions.Propagators.Tests.csproj b/test/OpenTelemetry.Extensions.Propagators.Tests/OpenTelemetry.Extensions.Propagators.Tests.csproj index 77eaa8a1f68..757c1d61ec6 100644 --- a/test/OpenTelemetry.Extensions.Propagators.Tests/OpenTelemetry.Extensions.Propagators.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Propagators.Tests/OpenTelemetry.Extensions.Propagators.Tests.csproj @@ -2,8 +2,6 @@ $(TargetFrameworksForTests) - - disable From f3a22c30225512647d933ed5864645adcd7435a7 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 29 Aug 2024 10:28:28 -0700 Subject: [PATCH 062/133] [otlp] Workaround DI containers which create unregistered services (#5808) --- .../Builder/OtlpExporterBuilder.cs | 6 +++--- .../Builder/UseOtlpExporterRegistration.cs | 11 +++++++++++ .../CHANGELOG.md | 6 ++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilder.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilder.cs index e20062b0e9e..d5a04aa60f2 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilder.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilder.cs @@ -174,9 +174,9 @@ private static void RegisterOtlpExporterServices(IServiceCollection services, st services!.AddOtlpExporterTracingServices(); // Note: UseOtlpExporterRegistration is added to the service collection - // to detect repeated calls to "UseOtlpExporter" and to throw if - // "AddOtlpExporter" extensions are called - services!.AddSingleton(); + // for each invocation to detect repeated calls to "UseOtlpExporter" and + // to throw if "AddOtlpExporter" extensions are called + services!.AddSingleton(UseOtlpExporterRegistration.Instance); services!.RegisterOptionsFactory((sp, configuration, name) => new OtlpExporterBuilderOptions( configuration, diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/UseOtlpExporterRegistration.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/UseOtlpExporterRegistration.cs index bf31c09eb0e..e2de10663fc 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/UseOtlpExporterRegistration.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/UseOtlpExporterRegistration.cs @@ -8,4 +8,15 @@ namespace OpenTelemetry.Exporter; // calls to signal-specific AddOtlpExporter can throw. internal sealed class UseOtlpExporterRegistration { + public static readonly UseOtlpExporterRegistration Instance = new(); + + private UseOtlpExporterRegistration() + { + // Note: Some dependency injection containers (ex: Unity, Grace) will + // automatically create services if they have a public constructor even + // if the service was never registered into the IServiceCollection. The + // behavior of UseOtlpExporterRegistration requires that it should only + // exist if registered. This private constructor is intended to prevent + // automatic instantiation. + } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 8d5e83d29af..7b274f98a90 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -12,6 +12,12 @@ Notes](../../RELEASENOTES.md). `CultureInfo.InvariantCulture`. ([#5700](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5700)) +* Fixed an issue causing `NotSupportedException`s to be thrown on startup when + `AddOtlpExporter` registration extensions are called while using custom + dependency injection containers which automatically create services (Unity, + Grace, etc.). + ([#5808](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5808)) + ## 1.9.0 Released 2024-Jun-14 From 1a836432840d657926923ccce4d09c4a4e08728c Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 29 Aug 2024 11:51:44 -0700 Subject: [PATCH 063/133] [benchmarks.logging] Use source generator pattern (#5807) Co-authored-by: Mikel Blanchard --- test/Benchmarks/Logs/Food.cs | 12 ------ test/Benchmarks/Logs/LogBenchmarks.cs | 49 ++++++++++++++++++++---- test/Benchmarks/Logs/LoggerExtensions.cs | 18 +++++++++ 3 files changed, 60 insertions(+), 19 deletions(-) delete mode 100644 test/Benchmarks/Logs/Food.cs create mode 100644 test/Benchmarks/Logs/LoggerExtensions.cs diff --git a/test/Benchmarks/Logs/Food.cs b/test/Benchmarks/Logs/Food.cs deleted file mode 100644 index b3a9096cc8f..00000000000 --- a/test/Benchmarks/Logs/Food.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using Microsoft.Extensions.Logging; - -namespace Benchmarks.Logs; - -public static partial class Food -{ - [LoggerMessage(Level = LogLevel.Information, Message = "Hello from {food} {price}.")] - public static partial void SayHello(this ILogger logger, string food, double price); -} diff --git a/test/Benchmarks/Logs/LogBenchmarks.cs b/test/Benchmarks/Logs/LogBenchmarks.cs index 312de9c2fac..915c115852a 100644 --- a/test/Benchmarks/Logs/LogBenchmarks.cs +++ b/test/Benchmarks/Logs/LogBenchmarks.cs @@ -107,7 +107,12 @@ public void NoListenerExtensionMethod() [Benchmark] public void NoListener() { - this.loggerWithNoListener.SayHello(FoodName, FoodPrice); + this.loggerWithNoListener.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } [Benchmark] @@ -115,7 +120,12 @@ public void UnnecessaryIsEnabledCheck() { if (this.loggerWithNoListener.IsEnabled(LogLevel.Information)) { - this.loggerWithNoListener.SayHello(FoodName, FoodPrice); + this.loggerWithNoListener.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } } @@ -123,31 +133,56 @@ public void UnnecessaryIsEnabledCheck() public void CreateLoggerRepeatedly() { var logger = this.loggerFactoryWithNoListener.CreateLogger(); - logger.SayHello(FoodName, FoodPrice); + logger.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } [Benchmark] public void OneProcessor() { - this.loggerWithOneProcessor.SayHello(FoodName, FoodPrice); + this.loggerWithOneProcessor.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } [Benchmark] public void BatchProcessor() { - this.loggerWithBatchProcessor.SayHello(FoodName, FoodPrice); + this.loggerWithBatchProcessor.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } [Benchmark] public void TwoProcessors() { - this.loggerWithTwoProcessors.SayHello(FoodName, FoodPrice); + this.loggerWithTwoProcessors.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } [Benchmark] public void ThreeProcessors() { - this.loggerWithThreeProcessors.SayHello(FoodName, FoodPrice); + this.loggerWithThreeProcessors.FoodRecallNotice( + brandName: "Contoso", + productDescription: "Salads", + productType: "Food & Beverages", + recallReasonDescription: "due to a possible health risk from Listeria monocytogenes", + companyName: "Contoso Fresh Vegetables, Inc."); } internal class NoopLogProcessor : BaseProcessor diff --git a/test/Benchmarks/Logs/LoggerExtensions.cs b/test/Benchmarks/Logs/LoggerExtensions.cs new file mode 100644 index 00000000000..47cd5962435 --- /dev/null +++ b/test/Benchmarks/Logs/LoggerExtensions.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.Logging; + +namespace Benchmarks.Logs; + +internal static partial class LoggerExtensions +{ + [LoggerMessage(LogLevel.Critical, "A `{productType}` recall notice was published for `{brandName} {productDescription}` produced by `{companyName}` ({recallReasonDescription}).")] + public static partial void FoodRecallNotice( + this ILogger logger, + string brandName, + string productDescription, + string productType, + string recallReasonDescription, + string companyName); +} From 685b73d3ac7a4d4f0b6d658650f93fb1ad166e40 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 30 Aug 2024 09:08:07 -0700 Subject: [PATCH 064/133] [docs] Fix OTLP Collector config in example app (#5811) --- examples/Console/otlp-collector-example/config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/Console/otlp-collector-example/config.yaml b/examples/Console/otlp-collector-example/config.yaml index 8d0584b61fa..57e59398b7c 100644 --- a/examples/Console/otlp-collector-example/config.yaml +++ b/examples/Console/otlp-collector-example/config.yaml @@ -8,7 +8,9 @@ receivers: otlp: protocols: grpc: + endpoint: 0.0.0.0:4317 http: + endpoint: 0.0.0.0:4318 exporters: debug: From 104c9f0e82d2ae7c4b0fb8ee30ff2b53a9802dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 4 Sep 2024 18:34:20 +0200 Subject: [PATCH 065/133] [repo] Extend NugetAudit by indirect references (#5812) --- Directory.Packages.props | 14 +++++++------- build/Common.props | 2 ++ .../WorkerService/WorkerService.csproj | 2 ++ test/Directory.Packages.props | 2 +- .../OpenTelemetry.Api.Tests.csproj | 2 ++ ...try.Exporter.OpenTelemetryProtocol.Tests.csproj | 2 ++ ...try.Exporter.Prometheus.AspNetCore.Tests.csproj | 2 ++ ...y.Exporter.Prometheus.HttpListener.Tests.csproj | 2 ++ .../OpenTelemetry.Exporter.Zipkin.Tests.csproj | 2 ++ .../OpenTelemetry.Extensions.Hosting.Tests.csproj | 2 ++ .../OpenTelemetry.Shims.OpenTracing.Tests.csproj | 2 ++ .../Metrics/MetricApiTestsBase.cs | 2 +- .../OpenTelemetry.Tests/OpenTelemetry.Tests.csproj | 3 ++- 13 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index bfe09403ee5..abe3785ad8d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -81,9 +81,9 @@ - + - + @@ -92,15 +92,15 @@ - - - + + + - + - + diff --git a/build/Common.props b/build/Common.props index e526f543e93..7c1f02bdebf 100644 --- a/build/Common.props +++ b/build/Common.props @@ -10,6 +10,8 @@ enable enable true + all + low $(NoWarn);OTEL1000;OTEL1001;OTEL1002;OTEL1003;OTEL1004 diff --git a/examples/MicroserviceExample/WorkerService/WorkerService.csproj b/examples/MicroserviceExample/WorkerService/WorkerService.csproj index b9b1a680772..f10cebc2d7e 100644 --- a/examples/MicroserviceExample/WorkerService/WorkerService.csproj +++ b/examples/MicroserviceExample/WorkerService/WorkerService.csproj @@ -6,6 +6,8 @@ + + diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props index b3769fc1459..d6755d05725 100644 --- a/test/Directory.Packages.props +++ b/test/Directory.Packages.props @@ -4,6 +4,6 @@ - + diff --git a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj index 08073d127f7..c8463d88343 100644 --- a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj +++ b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj @@ -27,5 +27,7 @@ runtime; build; native; contentfiles; analyzers + + diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj index 21b320de546..ed31a950360 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj @@ -14,6 +14,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj index 97e6f15e108..b361d72e7ee 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj @@ -15,6 +15,8 @@ runtime; build; native; contentfiles; analyzers + + diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj index f4901706361..295231183c2 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj @@ -14,6 +14,8 @@ runtime; build; native; contentfiles; analyzers + + diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj index f5a72a2f25f..31636f33157 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj @@ -22,6 +22,8 @@ runtime; build; native; contentfiles; analyzers + + diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj index 1ea17a421de..7dec47d5464 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj @@ -41,5 +41,7 @@ runtime; build; native; contentfiles; analyzers + + diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj index 1aac45f10ca..430bb7057e2 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj @@ -12,6 +12,8 @@ + + diff --git a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs index cc5a34d7fd1..41726da14d7 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs @@ -236,7 +236,7 @@ public void MetricInstrumentationScopeAttributesAreNotTreatedAsIdentifyingProper Assert.Equal(meterVersion, metric.MeterVersion); Assert.Single(metric.MeterTags.Where(kvp => kvp.Key == meterTags1[0].Key && kvp.Value == meterTags1[0].Value)); - Assert.Empty(metric.MeterTags.Where(kvp => kvp.Key == meterTags2[0].Key && kvp.Value == meterTags2[0].Value)); + Assert.DoesNotContain(metric.MeterTags, kvp => kvp.Key == meterTags2[0].Key && kvp.Value == meterTags2[0].Value); List metricPoints = new List(); foreach (ref readonly var mp in metric.GetMetricPoints()) diff --git a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj index 2a2532c07e9..96304bf6c6c 100644 --- a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj +++ b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj @@ -15,7 +15,6 @@ - @@ -32,5 +31,7 @@ runtime; build; native; contentfiles; analyzers + + From 1479686a6e8ec1ea84af4d4e2c3807a4e6395c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 4 Sep 2024 18:49:34 +0200 Subject: [PATCH 066/133] [sdk] Improve readability of TracerProviderSdk initialization code (#5810) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry/Trace/TracerProviderSdk.cs | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs index 2da7f0ea4d5..8fd333b1958 100644 --- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs @@ -111,7 +111,7 @@ internal TracerProviderSdk( OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent($"Instrumentations added = \"{instrumentationFactoriesAdded}\"."); } - var listener = new ActivityListener(); + var activityListener = new ActivityListener(); if (this.supportLegacyActivity) { @@ -125,7 +125,7 @@ internal TracerProviderSdk( legacyActivityPredicate = activity => state.LegacyActivityOperationNames.Contains(activity.OperationName); } - listener.ActivityStarted = activity => + activityListener.ActivityStarted = activity => { OpenTelemetrySdkEventSource.Log.ActivityStarted(activity); @@ -163,7 +163,7 @@ internal TracerProviderSdk( } }; - listener.ActivityStopped = activity => + activityListener.ActivityStopped = activity => { OpenTelemetrySdkEventSource.Log.ActivityStopped(activity); @@ -194,7 +194,7 @@ internal TracerProviderSdk( } else { - listener.ActivityStarted = activity => + activityListener.ActivityStarted = activity => { OpenTelemetrySdkEventSource.Log.ActivityStarted(activity); @@ -204,7 +204,7 @@ internal TracerProviderSdk( } }; - listener.ActivityStopped = activity => + activityListener.ActivityStopped = activity => { OpenTelemetrySdkEventSource.Log.ActivityStopped(activity); @@ -230,20 +230,20 @@ internal TracerProviderSdk( if (this.sampler is AlwaysOnSampler) { - listener.Sample = (ref ActivityCreationOptions options) => + activityListener.Sample = (ref ActivityCreationOptions options) => !Sdk.SuppressInstrumentation ? ActivitySamplingResult.AllDataAndRecorded : ActivitySamplingResult.None; this.getRequestedDataAction = this.RunGetRequestedDataAlwaysOnSampler; } else if (this.sampler is AlwaysOffSampler) { - listener.Sample = (ref ActivityCreationOptions options) => + activityListener.Sample = (ref ActivityCreationOptions options) => !Sdk.SuppressInstrumentation ? PropagateOrIgnoreData(options.Parent) : ActivitySamplingResult.None; this.getRequestedDataAction = this.RunGetRequestedDataAlwaysOffSampler; } else { // This delegate informs ActivitySource about sampling decision when the parent context is an ActivityContext. - listener.Sample = (ref ActivityCreationOptions options) => + activityListener.Sample = (ref ActivityCreationOptions options) => !Sdk.SuppressInstrumentation ? ComputeActivitySamplingResult(ref options, this.sampler) : ActivitySamplingResult.None; this.getRequestedDataAction = this.RunGetRequestedDataOtherSampler; } @@ -260,7 +260,7 @@ internal TracerProviderSdk( // Function which takes ActivitySource and returns true/false to indicate if it should be subscribed to // or not. - listener.ShouldListenTo = (activitySource) => + activityListener.ShouldListenTo = activitySource => this.supportLegacyActivity ? string.IsNullOrEmpty(activitySource.Name) || regex.IsMatch(activitySource.Name) : regex.IsMatch(activitySource.Name); @@ -276,19 +276,19 @@ internal TracerProviderSdk( // Function which takes ActivitySource and returns true/false to indicate if it should be subscribed to // or not. - listener.ShouldListenTo = (activitySource) => activitySources.Contains(activitySource.Name); + activityListener.ShouldListenTo = activitySource => activitySources.Contains(activitySource.Name); } } else { if (this.supportLegacyActivity) { - listener.ShouldListenTo = (activitySource) => string.IsNullOrEmpty(activitySource.Name); + activityListener.ShouldListenTo = activitySource => string.IsNullOrEmpty(activitySource.Name); } } - ActivitySource.AddActivityListener(listener); - this.listener = listener; + ActivitySource.AddActivityListener(activityListener); + this.listener = activityListener; OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent("TracerProvider built successfully."); } From dc8d3fd991af2b6a173a87723fdc12052b81b42d Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 4 Sep 2024 10:15:03 -0700 Subject: [PATCH 067/133] [repo] Add .NET 8 target for W3C Trace Context Integration Test in CI (#5800) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/workflows/ci.yml | 2 +- .../Dockerfile | 8 +++++--- .../W3CTraceContextTests.cs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be3cdf11abe..999985d15a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,7 +129,7 @@ jobs: strategy: fail-fast: false matrix: - version: [ net6.0 ] + version: [ net6.0, net8.0 ] steps: - uses: actions/checkout@v4 - name: Run W3C Trace Context docker compose diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile index 9723867f4f3..7a8dc6f5705 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile @@ -26,7 +26,9 @@ COPY --from=w3c /w3c . RUN apt-get update \ && apt-get install -y python3-pip python3-dev \ && cd /usr/local/bin \ - && ln -s /usr/bin/python3 python \ - && pip3 install --upgrade pip \ - && pip3 install aiohttp + && ln -s /usr/bin/python3 python + +# net6.0 image uses Python 3.9, which doesn't have `--break-system-packages` option. +RUN pip3 install --upgrade pip --break-system-packages || pip3 install --upgrade pip +RUN pip3 install aiohttp --break-system-packages ENTRYPOINT ["dotnet", "vstest", "OpenTelemetry.Instrumentation.W3cTraceContext.Tests.dll", "--logger:console;verbosity=detailed"] diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs index 323b35ecba9..b80a57f1ced 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs @@ -69,7 +69,7 @@ public void W3CTraceContextTestSuiteAsync(string value) return result; }); - app.RunAsync(); + app.RunAsync("http://localhost:5000/"); string result = RunCommand("python", "trace-context/test/test.py http://localhost:5000/"); From b46aae4dfff5739c56a785c671f9ef74a3405caa Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 9 Sep 2024 11:38:42 -0700 Subject: [PATCH 068/133] [repo] Move Vishwesh to Emeritus approver (#5817) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db28ff6028c..41ee744c3bd 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,6 @@ you're more than welcome to participate! * [Piotr Kiełkowicz](https://github.com/Kielek), Splunk * [Reiley Yang](https://github.com/reyang), Microsoft * [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft -* [Vishwesh Bankwar](https://github.com/vishweshbankwar), Microsoft [Triagers](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager) ([@open-telemetry/dotnet-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-triagers)): @@ -231,6 +230,7 @@ Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/ma * [Robert Pająk](https://github.com/pellared) * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev) * [Victor Lu](https://github.com/victlu) +* [Vishwesh Bankwar](https://github.com/vishweshbankwar) ### Thanks to all the people who have contributed From 37535a5607ee7e4056c0e274ec01d1e0111a64be Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Mon, 9 Sep 2024 14:37:22 -0700 Subject: [PATCH 069/133] [repo] Update stale.yml - reduce days before stale to 900 (#5822) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 4ea639c2228..5927cd4fac2 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,7 +18,7 @@ jobs: close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' operations-per-run: 400 days-before-pr-stale: 7 - days-before-issue-stale: 1000 + days-before-issue-stale: 900 days-before-pr-close: 7 days-before-issue-close: 7 exempt-all-issue-milestones: true From dd7405654f7349fa6238d16a10146b0df68ee30d Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Wed, 11 Sep 2024 22:07:48 +0200 Subject: [PATCH 070/133] [Exporter.Zipkin] Nullable (#5792) Co-authored-by: Mikel Blanchard --- .../.publicApi/PublicAPI.Shipped.txt | 17 ++++--- .../ZipkinActivityConversionExtensions.cs | 50 +++++++++---------- .../Implementation/ZipkinEndpoint.cs | 16 +++--- .../Implementation/ZipkinSpan.cs | 20 ++++---- .../OpenTelemetry.Exporter.Zipkin.csproj | 3 -- .../ZipkinExporter.cs | 30 +++++------ .../ZipkinExporterHelperExtensions.cs | 18 ++++--- .../ZipkinExporterOptions.cs | 6 +-- src/Shared/PooledList.cs | 8 ++- .../ZipkinActivityConversionExtensionsTest.cs | 6 +-- .../ZipkinActivityConversionTest.cs | 22 ++++---- ...pkinActivityExporterRemoteEndpointTests.cs | 10 ++-- ...OpenTelemetry.Exporter.Zipkin.Tests.csproj | 2 - .../ZipkinExporterTests.cs | 38 +++++++------- .../Shared/TestHttpServer.cs | 4 +- 15 files changed, 127 insertions(+), 123 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt index 5d94b912d2d..2e1bf086dc7 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/PublicAPI.Shipped.txt @@ -1,13 +1,14 @@ +#nullable enable OpenTelemetry.Exporter.ZipkinExporter -OpenTelemetry.Exporter.ZipkinExporter.ZipkinExporter(OpenTelemetry.Exporter.ZipkinExporterOptions options, System.Net.Http.HttpClient client = null) -> void +OpenTelemetry.Exporter.ZipkinExporter.ZipkinExporter(OpenTelemetry.Exporter.ZipkinExporterOptions! options, System.Net.Http.HttpClient? client = null) -> void OpenTelemetry.Exporter.ZipkinExporterOptions -OpenTelemetry.Exporter.ZipkinExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions OpenTelemetry.Exporter.ZipkinExporterOptions.BatchExportProcessorOptions.set -> void -OpenTelemetry.Exporter.ZipkinExporterOptions.Endpoint.get -> System.Uri +OpenTelemetry.Exporter.ZipkinExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions! +OpenTelemetry.Exporter.ZipkinExporterOptions.HttpClientFactory.get -> System.Func! +OpenTelemetry.Exporter.ZipkinExporterOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.ZipkinExporterOptions.Endpoint.set -> void OpenTelemetry.Exporter.ZipkinExporterOptions.ExportProcessorType.get -> OpenTelemetry.ExportProcessorType OpenTelemetry.Exporter.ZipkinExporterOptions.ExportProcessorType.set -> void -OpenTelemetry.Exporter.ZipkinExporterOptions.HttpClientFactory.get -> System.Func OpenTelemetry.Exporter.ZipkinExporterOptions.HttpClientFactory.set -> void OpenTelemetry.Exporter.ZipkinExporterOptions.MaxPayloadSizeInBytes.get -> int? OpenTelemetry.Exporter.ZipkinExporterOptions.MaxPayloadSizeInBytes.set -> void @@ -15,7 +16,7 @@ OpenTelemetry.Exporter.ZipkinExporterOptions.UseShortTraceIds.get -> bool OpenTelemetry.Exporter.ZipkinExporterOptions.UseShortTraceIds.set -> void OpenTelemetry.Exporter.ZipkinExporterOptions.ZipkinExporterOptions() -> void OpenTelemetry.Trace.ZipkinExporterHelperExtensions -override OpenTelemetry.Exporter.ZipkinExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +override OpenTelemetry.Exporter.ZipkinExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinActivityConversionExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinActivityConversionExtensions.cs index 802591d052a..2753f51f50a 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinActivityConversionExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinActivityConversionExtensions.cs @@ -21,13 +21,13 @@ internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint l { var context = activity.Context; - string parentId = activity.ParentSpanId == default ? + string? parentId = activity.ParentSpanId == default ? null : EncodeSpanId(activity.ParentSpanId); var tagState = new TagEnumerationState { - Tags = PooledList>.Create(), + Tags = PooledList>.Create(), }; tagState.EnumerateTags(activity); @@ -38,9 +38,9 @@ internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint l { if (activity.Status == ActivityStatusCode.Ok) { - PooledList>.Add( + PooledList>.Add( ref tagState.Tags, - new KeyValuePair( + new KeyValuePair( SpanAttributeConstants.StatusCodeKey, "OK")); } @@ -48,16 +48,16 @@ internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint l // activity.Status is Error else { - PooledList>.Add( + PooledList>.Add( ref tagState.Tags, - new KeyValuePair( + new KeyValuePair( SpanAttributeConstants.StatusCodeKey, "ERROR")); // Error flag rule from https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk_exporters/zipkin.md#status - PooledList>.Add( + PooledList>.Add( ref tagState.Tags, - new KeyValuePair( + new KeyValuePair( ZipkinErrorFlagTagName, activity.StatusDescription ?? string.Empty)); } @@ -67,18 +67,18 @@ internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint l // activity status takes precedence over status tag. else if (tagState.StatusCode.HasValue && tagState.StatusCode != StatusCode.Unset) { - PooledList>.Add( + PooledList>.Add( ref tagState.Tags, - new KeyValuePair( + new KeyValuePair( SpanAttributeConstants.StatusCodeKey, StatusHelper.GetTagValueForStatusCode(tagState.StatusCode.Value))); // Error flag rule from https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk_exporters/zipkin.md#status if (tagState.StatusCode == StatusCode.Error) { - PooledList>.Add( + PooledList>.Add( ref tagState.Tags, - new KeyValuePair( + new KeyValuePair( ZipkinErrorFlagTagName, tagState.StatusDescription ?? string.Empty)); } @@ -87,30 +87,30 @@ internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint l var activitySource = activity.Source; if (!string.IsNullOrEmpty(activitySource.Name)) { - PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.scope.name", activitySource.Name)); + PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.scope.name", activitySource.Name)); // otel.library.name is deprecated, but has to be propagated according to https://github.com/open-telemetry/opentelemetry-specification/blob/v1.31.0/specification/common/mapping-to-non-otlp.md#instrumentationscope - PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.library.name", activitySource.Name)); + PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.library.name", activitySource.Name)); if (!string.IsNullOrEmpty(activitySource.Version)) { - PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.scope.version", activitySource.Version)); + PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.scope.version", activitySource.Version)); // otel.library.version is deprecated, but has to be propagated according to https://github.com/open-telemetry/opentelemetry-specification/blob/v1.31.0/specification/common/mapping-to-non-otlp.md#instrumentationscope - PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.library.version", activitySource.Version)); + PooledList>.Add(ref tagState.Tags, new KeyValuePair("otel.library.version", activitySource.Version)); } } - ZipkinEndpoint remoteEndpoint = null; + ZipkinEndpoint? remoteEndpoint = null; if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer) { - PeerServiceResolver.Resolve(ref tagState, out string peerServiceName, out bool addAsTag); + PeerServiceResolver.Resolve(ref tagState, out string? peerServiceName, out bool addAsTag); if (peerServiceName != null) { remoteEndpoint = RemoteEndpointCache.GetOrAdd((peerServiceName, default), ZipkinEndpoint.Create); if (addAsTag) { - PooledList>.Add(ref tagState.Tags, new KeyValuePair(SemanticConventions.AttributePeerService, peerServiceName)); + PooledList>.Add(ref tagState.Tags, new KeyValuePair(SemanticConventions.AttributePeerService, peerServiceName)); } } } @@ -172,7 +172,7 @@ private static string EncodeTraceId(ActivityTraceId traceId, bool useShortTraceI return id; } - private static string ToActivityKind(Activity activity) + private static string? ToActivityKind(Activity activity) { return activity.Kind switch { @@ -186,15 +186,15 @@ private static string ToActivityKind(Activity activity) internal struct TagEnumerationState : PeerServiceResolver.IPeerServiceState { - public PooledList> Tags; + public PooledList> Tags; - public string PeerService { get; set; } + public string? PeerService { get; set; } public int? PeerServicePriority { get; set; } - public string HostName { get; set; } + public string? HostName { get; set; } - public string IpAddress { get; set; } + public string? IpAddress { get; set; } public long Port { get; set; } @@ -239,7 +239,7 @@ public void EnumerateTags(Activity activity) PeerServiceResolver.InspectTag(ref this, key, intVal); } - PooledList>.Add(ref this.Tags, tag); + PooledList>.Add(ref this.Tags, tag); } } } diff --git a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinEndpoint.cs b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinEndpoint.cs index c6c9908b38e..cec7cc7156c 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinEndpoint.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinEndpoint.cs @@ -13,11 +13,11 @@ public ZipkinEndpoint(string serviceName) } public ZipkinEndpoint( - string serviceName, - string ipv4, - string ipv6, + string? serviceName, + string? ipv4, + string? ipv6, int? port, - Dictionary tags) + Dictionary? tags) { this.ServiceName = serviceName; this.Ipv4 = ipv4; @@ -26,15 +26,15 @@ public ZipkinEndpoint( this.Tags = tags; } - public string ServiceName { get; } + public string? ServiceName { get; } - public string Ipv4 { get; } + public string? Ipv4 { get; } - public string Ipv6 { get; } + public string? Ipv6 { get; } public int? Port { get; } - public Dictionary Tags { get; } + public Dictionary? Tags { get; } public static ZipkinEndpoint Create(string serviceName) { diff --git a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinSpan.cs b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinSpan.cs index 8038492a0be..a6ea86f6cea 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinSpan.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinSpan.cs @@ -11,16 +11,16 @@ internal readonly struct ZipkinSpan { public ZipkinSpan( string traceId, - string parentId, + string? parentId, string id, - string kind, + string? kind, string name, long? timestamp, long? duration, ZipkinEndpoint localEndpoint, - ZipkinEndpoint remoteEndpoint, + ZipkinEndpoint? remoteEndpoint, in PooledList annotations, - in PooledList> tags, + in PooledList> tags, bool? debug, bool? shared) { @@ -44,11 +44,11 @@ public ZipkinSpan( public string TraceId { get; } - public string ParentId { get; } + public string? ParentId { get; } public string Id { get; } - public string Kind { get; } + public string? Kind { get; } public string Name { get; } @@ -58,11 +58,11 @@ public ZipkinSpan( public ZipkinEndpoint LocalEndpoint { get; } - public ZipkinEndpoint RemoteEndpoint { get; } + public ZipkinEndpoint? RemoteEndpoint { get; } public PooledList Annotations { get; } - public PooledList> Tags { get; } + public PooledList> Tags { get; } public bool? Debug { get; } @@ -148,7 +148,7 @@ public void Write(Utf8JsonWriter writer) writer.WriteEndArray(); } - if (!this.Tags.IsEmpty || this.LocalEndpoint.Tags != null) + if (!this.Tags.IsEmpty || this.LocalEndpoint!.Tags != null) { writer.WritePropertyName(ZipkinSpanJsonHelper.TagsPropertyName); writer.WriteStartObject(); @@ -161,7 +161,7 @@ public void Write(Utf8JsonWriter writer) try { - foreach (var tag in this.LocalEndpoint.Tags ?? Enumerable.Empty>()) + foreach (var tag in this.LocalEndpoint!.Tags! ?? Enumerable.Empty>()) { ZipkinTagWriter.Instance.TryWriteTag(ref writer, tag); } diff --git a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj index 22b6537a7dd..3e269d83c26 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj +++ b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj @@ -4,9 +4,6 @@ Zipkin exporter for OpenTelemetry .NET $(PackageTags);Zipkin;distributed-tracing core- - - - disable diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs index 69483d84a13..9ccfdc69041 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs @@ -30,7 +30,7 @@ public class ZipkinExporter : BaseExporter /// /// Configuration options. /// Http client to use to upload telemetry. - public ZipkinExporter(ZipkinExporterOptions options, HttpClient client = null) + public ZipkinExporter(ZipkinExporterOptions options, HttpClient? client = null) { Guard.ThrowIfNull(options); @@ -39,7 +39,7 @@ public ZipkinExporter(ZipkinExporterOptions options, HttpClient client = null) this.httpClient = client ?? options.HttpClientFactory?.Invoke() ?? throw new InvalidOperationException("ZipkinExporter was missing HttpClientFactory or it returned null."); } - internal ZipkinEndpoint LocalEndpoint { get; private set; } + internal ZipkinEndpoint? LocalEndpoint { get; private set; } /// public override ExportResult Export(in Batch batch) @@ -83,15 +83,15 @@ internal void SetLocalEndpointFromResource(Resource resource) { var hostName = ResolveHostName(); - string ipv4 = null; - string ipv6 = null; + string? ipv4 = null; + string? ipv6 = null; if (!string.IsNullOrEmpty(hostName)) { - ipv4 = ResolveHostAddress(hostName, AddressFamily.InterNetwork); - ipv6 = ResolveHostAddress(hostName, AddressFamily.InterNetworkV6); + ipv4 = ResolveHostAddress(hostName!, AddressFamily.InterNetwork); + ipv6 = ResolveHostAddress(hostName!, AddressFamily.InterNetworkV6); } - string serviceName = null; + string? serviceName = null; foreach (var label in resource.Attributes) { if (label.Key == ResourceSemanticConventions.AttributeServiceName) @@ -115,9 +115,9 @@ internal void SetLocalEndpointFromResource(Resource resource) tags: null); } - private static string ResolveHostAddress(string hostName, AddressFamily family) + private static string? ResolveHostAddress(string hostName, AddressFamily family) { - string result = null; + string? result = null; try { @@ -145,9 +145,9 @@ private static string ResolveHostAddress(string hostName, AddressFamily family) return result; } - private static string ResolveHostName() + private static string? ResolveHostName() { - string result = null; + string? result = null; try { @@ -180,7 +180,7 @@ private sealed class JsonContent : HttpContent private readonly ZipkinExporter exporter; private readonly Batch batch; - private Utf8JsonWriter writer; + private Utf8JsonWriter? writer; public JsonContent(ZipkinExporter exporter, in Batch batch) { @@ -191,13 +191,13 @@ public JsonContent(ZipkinExporter exporter, in Batch batch) } #if NET - protected override void SerializeToStream(Stream stream, TransportContext context, CancellationToken cancellationToken) + protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken) { this.SerializeToStreamInternal(stream); } #endif - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) { this.SerializeToStreamInternal(stream); return Task.CompletedTask; @@ -226,7 +226,7 @@ private void SerializeToStreamInternal(Stream stream) foreach (var activity in this.batch) { - var zipkinSpan = activity.ToZipkinSpan(this.exporter.LocalEndpoint, this.exporter.options.UseShortTraceIds); + var zipkinSpan = activity.ToZipkinSpan(this.exporter.LocalEndpoint!, this.exporter.options.UseShortTraceIds); zipkinSpan.Write(this.writer); diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs index ca858c649ab..b7142b985a5 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs @@ -39,13 +39,13 @@ public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder /// Adds Zipkin exporter to the TracerProvider. /// /// builder to use. - /// Name which is used when retrieving options. - /// Callback action for configuring . + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddZipkinExporter( this TracerProviderBuilder builder, - string name, - Action configure) + string? name, + Action? configure) { Guard.ThrowIfNull(builder); @@ -81,13 +81,13 @@ private static BaseProcessor BuildZipkinExporterProcessor( { options.HttpClientFactory = () => { - Type httpClientFactoryType = Type.GetType("System.Net.Http.IHttpClientFactory, Microsoft.Extensions.Http", throwOnError: false); + Type? httpClientFactoryType = Type.GetType("System.Net.Http.IHttpClientFactory, Microsoft.Extensions.Http", throwOnError: false); if (httpClientFactoryType != null) { - object httpClientFactory = serviceProvider.GetService(httpClientFactoryType); + object? httpClientFactory = serviceProvider.GetService(httpClientFactoryType); if (httpClientFactory != null) { - MethodInfo createClientMethod = httpClientFactoryType.GetMethod( + MethodInfo? createClientMethod = httpClientFactoryType.GetMethod( "CreateClient", BindingFlags.Public | BindingFlags.Instance, binder: null, @@ -95,7 +95,9 @@ private static BaseProcessor BuildZipkinExporterProcessor( modifiers: null); if (createClientMethod != null) { - return (HttpClient)createClientMethod.Invoke(httpClientFactory, new object[] { "ZipkinExporter" }); + var parameters = new object[] { "ZipkinExporter" }; + var client = (HttpClient?)createClientMethod.Invoke(httpClientFactory, parameters); + return client ?? new HttpClient(); } } } diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs index bc94307351d..1f4bcd14684 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs @@ -40,12 +40,12 @@ internal ZipkinExporterOptions( Debug.Assert(configuration != null, "configuration was null"); Debug.Assert(defaultBatchOptions != null, "defaultBatchOptions was null"); - if (configuration.TryGetUriValue(ZipkinExporterEventSource.Log, ZipkinEndpointEnvVar, out var endpoint)) + if (configuration!.TryGetUriValue(ZipkinExporterEventSource.Log, ZipkinEndpointEnvVar, out var endpoint)) { - this.Endpoint = endpoint; + this.Endpoint = endpoint!; } - this.BatchExportProcessorOptions = defaultBatchOptions; + this.BatchExportProcessorOptions = defaultBatchOptions!; } /// diff --git a/src/Shared/PooledList.cs b/src/Shared/PooledList.cs index 043cd0a4525..77a353359a7 100644 --- a/src/Shared/PooledList.cs +++ b/src/Shared/PooledList.cs @@ -1,8 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Buffers; using System.Collections; +using System.Diagnostics.CodeAnalysis; namespace OpenTelemetry.Internal; @@ -97,6 +100,7 @@ public struct Enumerator : IEnumerator, IEnumerator private readonly T[] buffer; private readonly int count; private int index; + [AllowNull] private T current; public Enumerator(in PooledList list) @@ -107,9 +111,9 @@ public Enumerator(in PooledList list) this.current = default; } - public T Current { get => this.current; } + public T Current => this.current; - object IEnumerator.Current { get => this.Current; } + object? IEnumerator.Current => this.Current; public void Dispose() { diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionExtensionsTest.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionExtensionsTest.cs index 6e28b18d88c..14f28474176 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionExtensionsTest.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionExtensionsTest.cs @@ -19,7 +19,7 @@ public void CheckProcessTag(string key, object value) { var attributeEnumerationState = new TagEnumerationState { - Tags = PooledList>.Create(), + Tags = PooledList>.Create(), }; using var activity = new Activity("TestActivity"); @@ -36,11 +36,11 @@ public void CheckProcessTag(string key, object value) [InlineData("string", null)] [InlineData("bool", null)] [InlineData("double", null)] - public void CheckNullValueProcessTag(string key, object value) + public void CheckNullValueProcessTag(string key, object? value) { var attributeEnumerationState = new TagEnumerationState { - Tags = PooledList>.Create(), + Tags = PooledList>.Create(), }; using var activity = new Activity("TestActivity"); diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs index bfe69520fea..9a23ba329d4 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs @@ -106,7 +106,7 @@ public void ToZipkinSpan_Status_ErrorFlagTest(StatusCode expectedStatusCode, str if (expectedStatusCode == StatusCode.Error) { - Assert.Contains(zipkinSpan.Tags, t => t.Key == "error" && (string)t.Value == string.Empty); + Assert.Contains(zipkinSpan.Tags, t => t.Key == "error" && (string?)t.Value == string.Empty); } else { @@ -149,7 +149,7 @@ public void ToZipkinSpan_Activity_Status_And_StatusDescription_is_Set(ActivitySt Assert.Contains( zipkinSpan.Tags, t => t.Key == ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName && - (string)t.Value == description); + (string?)t.Value == description); } else { @@ -177,11 +177,11 @@ public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeI // Assert. Assert.Equal("OK", zipkinSpan.Tags.FirstOrDefault(t => t.Key == SpanAttributeConstants.StatusCodeKey).Value); - Assert.Contains(zipkinSpan.Tags, t => t.Key == "otel.status_code" && (string)t.Value == "OK"); - Assert.DoesNotContain(zipkinSpan.Tags, t => t.Key == "otel.status_code" && (string)t.Value == "ERROR"); + Assert.Contains(zipkinSpan.Tags, t => t.Key == "otel.status_code" && (string?)t.Value == "OK"); + Assert.DoesNotContain(zipkinSpan.Tags, t => t.Key == "otel.status_code" && (string?)t.Value == "ERROR"); // Ensure additional Activity tags were being converted. - Assert.Contains(zipkinSpan.Tags, t => t.Key == "myCustomTag" && (string)t.Value == "myCustomTagValue"); + Assert.Contains(zipkinSpan.Tags, t => t.Key == "myCustomTag" && (string?)t.Value == "myCustomTagValue"); Assert.DoesNotContain(zipkinSpan.Tags, t => t.Key == ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName); } @@ -211,14 +211,14 @@ public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeI Assert.Contains( zipkinSpan.Tags, t => t.Key == ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName && - (string)t.Value == StatusDescriptionOnError); + (string?)t.Value == StatusDescriptionOnError); Assert.DoesNotContain( zipkinSpan.Tags, t => t.Key == ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName && - (string)t.Value == TagDescriptionOnError); + (string?)t.Value == TagDescriptionOnError); // Ensure additional Activity tags were being converted. - Assert.Contains(zipkinSpan.Tags, t => t.Key == "myCustomTag" && (string)t.Value == "myCustomTagValue"); + Assert.Contains(zipkinSpan.Tags, t => t.Key == "myCustomTag" && (string?)t.Value == "myCustomTagValue"); } [Fact] @@ -247,13 +247,13 @@ public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeI Assert.Contains( zipkinSpan.Tags, t => t.Key == ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName && - (string)t.Value == StatusDescriptionOnError); + (string?)t.Value == StatusDescriptionOnError); Assert.DoesNotContain( zipkinSpan.Tags, t => t.Key == ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName && - (string)t.Value == TagDescriptionOnError); + (string?)t.Value == TagDescriptionOnError); // Ensure additional Activity tags were being converted. - Assert.Contains(zipkinSpan.Tags, t => t.Key == "myCustomTag" && (string)t.Value == "myCustomTagValue"); + Assert.Contains(zipkinSpan.Tags, t => t.Key == "myCustomTag" && (string?)t.Value == "myCustomTagValue"); } } diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityExporterRemoteEndpointTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityExporterRemoteEndpointTests.cs index ddbd059c0cf..0f7c9e1bdb2 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityExporterRemoteEndpointTests.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityExporterRemoteEndpointTests.cs @@ -45,7 +45,7 @@ public void GenerateActivity_RemoteEndpointResolution() public void GenerateActivity_RemoteEndpointResolutionPriority(RemoteEndpointPriorityTestCase testCase) { // Arrange - using var activity = ZipkinExporterTests.CreateTestActivity(additionalAttributes: testCase.RemoteEndpointAttributes); + using var activity = ZipkinExporterTests.CreateTestActivity(additionalAttributes: testCase.RemoteEndpointAttributes!); // Act & Assert var zipkinSpan = ZipkinActivityConversionExtensions.ToZipkinSpan(activity, DefaultZipkinEndpoint); @@ -56,11 +56,11 @@ public void GenerateActivity_RemoteEndpointResolutionPriority(RemoteEndpointPrio public class RemoteEndpointPriorityTestCase { - public string Name { get; set; } + public string? Name { get; set; } - public string ExpectedResult { get; set; } + public string? ExpectedResult { get; set; } - public Dictionary RemoteEndpointAttributes { get; set; } + public Dictionary? RemoteEndpointAttributes { get; set; } public static IEnumerable GetTestCases() { @@ -174,7 +174,7 @@ public static IEnumerable GetTestCases() }; } - public override string ToString() + public override string? ToString() { return this.Name; } diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj index 31636f33157..fceb493d55d 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj @@ -2,8 +2,6 @@ Unit test project for Zipkin Exporter for OpenTelemetry $(TargetFrameworksForTests) - - disable diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs index b1481ac0541..97b90a5ec68 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs @@ -58,7 +58,7 @@ static void ProcessServerRequest(HttpListenerContext context) string requestContent = readStream.ReadToEnd(); Responses.TryAdd( - Guid.Parse(context.Request.QueryString["requestId"]), + Guid.Parse(context.Request.QueryString["requestId"]!), requestContent); context.Response.OutputStream.Close(); @@ -95,8 +95,8 @@ public void AddAddZipkinExporterNamedOptionsSupported() [Fact] public void BadArgs() { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddZipkinExporter()); + TracerProviderBuilder? builder = null; + Assert.Throws(() => builder!.AddZipkinExporter()); } [Fact] @@ -151,7 +151,7 @@ public void EndpointConfigurationUsingEnvironmentVariable() var exporterOptions = new ZipkinExporterOptions(); - Assert.Equal(new Uri(Environment.GetEnvironmentVariable(ZipkinExporterOptions.ZipkinEndpointEnvVar)).AbsoluteUri, exporterOptions.Endpoint.AbsoluteUri); + Assert.Equal(new Uri(Environment.GetEnvironmentVariable(ZipkinExporterOptions.ZipkinEndpointEnvVar)!).AbsoluteUri, exporterOptions.Endpoint.AbsoluteUri); } finally { @@ -205,7 +205,7 @@ public void EndpointConfigurationUsingIConfiguration() }; var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(values) + .AddInMemoryCollection(values!) .Build(); var options = new ZipkinExporterOptions(configuration, new()); @@ -247,13 +247,13 @@ public void UserHttpFactoryCalled() Assert.Equal(2, invocations); } - options.HttpClientFactory = null; + options.HttpClientFactory = null!; Assert.Throws(() => { using var exporter = new ZipkinExporter(options); }); - options.HttpClientFactory = () => null; + options.HttpClientFactory = () => null!; Assert.Throws(() => { using var exporter = new ZipkinExporter(options); @@ -288,7 +288,7 @@ public void UpdatesServiceNameFromDefaultResource() zipkinExporter.SetLocalEndpointFromResource(Resource.Empty); - Assert.StartsWith("unknown_service:", zipkinExporter.LocalEndpoint.ServiceName); + Assert.StartsWith("unknown_service:", zipkinExporter.LocalEndpoint!.ServiceName); } [Fact] @@ -303,7 +303,7 @@ public void UpdatesServiceNameFromIConfiguration() }; services.AddSingleton( - new ConfigurationBuilder().AddInMemoryCollection(configuration).Build()); + new ConfigurationBuilder().AddInMemoryCollection(configuration!).Build()); }); var zipkinExporter = new ZipkinExporter(new ZipkinExporterOptions()); @@ -314,7 +314,7 @@ public void UpdatesServiceNameFromIConfiguration() zipkinExporter.SetLocalEndpointFromResource(Resource.Empty); - Assert.Equal("myservicename", zipkinExporter.LocalEndpoint.ServiceName); + Assert.Equal("myservicename", zipkinExporter.LocalEndpoint!.ServiceName); } [Theory] @@ -331,7 +331,7 @@ public void IntegrationTest( bool useTestResource, bool isRootSpan, ActivityStatusCode statusCode = ActivityStatusCode.Unset, - string statusDescription = null, + string? statusDescription = null, bool addErrorTag = false) { Guid requestId = Guid.NewGuid(); @@ -378,7 +378,7 @@ public void IntegrationTest( var eventTimestamp = activity.Events.First().Timestamp.ToEpochMicroseconds(); StringBuilder ipInformation = new StringBuilder(); - if (!string.IsNullOrEmpty(exporter.LocalEndpoint.Ipv4)) + if (!string.IsNullOrEmpty(exporter.LocalEndpoint!.Ipv4)) { ipInformation.Append($@",""ipv4"":""{exporter.LocalEndpoint.Ipv4}"""); } @@ -446,13 +446,13 @@ public void IntegrationTest( internal static Activity CreateTestActivity( bool isRootSpan = false, bool setAttributes = true, - Dictionary additionalAttributes = null, + Dictionary? additionalAttributes = null, bool addEvents = true, bool addLinks = true, - Resource resource = null, + Resource? resource = null, ActivityKind kind = ActivityKind.Client, ActivityStatusCode statusCode = ActivityStatusCode.Unset, - string statusDescription = null, + string? statusDescription = null, DateTime? dateTime = null) { var startTimestamp = DateTime.UtcNow; @@ -494,14 +494,14 @@ internal static Activity CreateTestActivity( new ActivityEvent( "Event1", eventTimestamp, - new ActivityTagsCollection(new Dictionary + new ActivityTagsCollection(new Dictionary { { "key", "value" }, })), new ActivityEvent( "Event2", eventTimestamp, - new ActivityTagsCollection(new Dictionary + new ActivityTagsCollection(new Dictionary { { "key", "value" }, })), @@ -512,7 +512,7 @@ internal static Activity CreateTestActivity( var activitySource = new ActivitySource(nameof(CreateTestActivity)); var tags = setAttributes ? - attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value)) + attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value)) : null; var links = addLinks ? new[] @@ -530,7 +530,7 @@ internal static Activity CreateTestActivity( parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), tags, links, - startTime: startTimestamp); + startTime: startTimestamp)!; if (addEvents) { diff --git a/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs b/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs index 5965e5fecf4..9d86ae2a2aa 100644 --- a/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs +++ b/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Net; namespace OpenTelemetry.Tests; @@ -13,7 +15,7 @@ public static IDisposable RunServer(Action action, out stri { host = "localhost"; port = 0; - RunningServer server = null; + RunningServer? server = null; var retryCount = 5; while (retryCount > 0) From 2d6b03f296120af7ef040db140c52dfa4ff8b16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 12 Sep 2024 18:22:09 +0200 Subject: [PATCH 071/133] [repo] Always execute build-test step in CI workflow (#5828) --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 999985d15a1..58eef737fca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -171,8 +171,8 @@ jobs: build-test: needs: [ - lint-misspell-sanitycheck, detect-changes, + lint-misspell-sanitycheck, lint-md, lint-dotnet-format, build-test-solution, @@ -186,7 +186,8 @@ jobs: verify-aot-compat, concurrency-tests ] - if: always() && !cancelled() && !contains(needs.*.result, 'failure') - runs-on: windows-latest + if: always() && !cancelled() + runs-on: ubuntu-latest steps: - - run: echo 'build complete' + - run: | + if ( ${{ contains(needs.*.result, 'failure') }} == true ); then echo 'build failed'; exit 1; else echo 'build complete'; fi From f7e2a78f4fbfe19e8d13b52dc36358c257500c57 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Thu, 12 Sep 2024 09:53:57 -0700 Subject: [PATCH 072/133] [repo] remove questions template and redirect to discussions (#5827) Co-authored-by: Mikel Blanchard --- .github/ISSUE_TEMPLATE/config.yml | 7 +++++++ .github/ISSUE_TEMPLATE/question.yml | 22 ---------------------- OpenTelemetry.sln | 1 - 3 files changed, 7 insertions(+), 23 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/question.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..3104c7c9769 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser + +blank_issues_enabled: false +contact_links: + - name: Question + url: https://github.com/open-telemetry/opentelemetry-dotnet/discussions/new?category=q-a + about: Ask a question to help us improve our knowledge base and documentation. diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml deleted file mode 100644 index ccca6038516..00000000000 --- a/.github/ISSUE_TEMPLATE/question.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Question -title: "[question] " -description: Ask a question to help us improve our knowledge base and documentation -labels: [question,needs-triage] -body: - - type: markdown - attributes: - value: | - > [!NOTE] - > Please ask questions using [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-dotnet/discussions/new) instead of GitHub Issues. - - - type: textarea - attributes: - label: What is the question? - description: Describe the question you have. - validations: - required: true - - - type: textarea - attributes: - label: Additional context - description: Any additional information you think may be relevant to this question. diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index fd7cdb94f12..2cfcf9b1f22 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -80,7 +80,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEM ProjectSection(SolutionItems) = preProject .github\ISSUE_TEMPLATE\bug_report.yml = .github\ISSUE_TEMPLATE\bug_report.yml .github\ISSUE_TEMPLATE\feature_request.yml = .github\ISSUE_TEMPLATE\feature_request.yml - .github\ISSUE_TEMPLATE\question.yml = .github\ISSUE_TEMPLATE\question.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{E69578EB-B456-4062-A645-877CD964528B}" From 29798920da7fc211f97639c613818447dbffabc7 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Thu, 12 Sep 2024 19:08:54 +0200 Subject: [PATCH 073/133] [repo] Add Linux ARM64 to actions CI (#5824) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Mikel Blanchard --- .github/workflows/Component.BuildTest.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index df079498450..e25352b0854 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -20,7 +20,7 @@ on: required: false type: string os-list: - default: '[ "windows-latest", "ubuntu-latest" ]' + default: '[ "windows-latest", "ubuntu-latest", "otel-linux-arm64" ]' required: false type: string tfm-list: @@ -39,6 +39,10 @@ jobs: exclude: - os: ubuntu-latest version: net462 + - os: otel-linux-arm64 + version: net462 + - os: otel-linux-arm64 + version: net6.0 runs-on: ${{ matrix.os }} steps: From 2b43c096f84fea4c027962e28dbf0ea5f32046b0 Mon Sep 17 00:00:00 2001 From: benon lukyamuzi Date: Thu, 12 Sep 2024 20:23:56 +0300 Subject: [PATCH 074/133] [zipkin\otlp] Call SendAsync on mobile (#5821) Co-authored-by: Mikel Blanchard --- .../CHANGELOG.md | 4 ++++ .../ExportClient/BaseOtlpHttpExportClient.cs | 15 ++++++++++++++- .../CHANGELOG.md | 4 ++++ .../ZipkinExporter.cs | 19 +++++++++++++++++-- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 7b274f98a90..ffb47ff3a33 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -18,6 +18,10 @@ Notes](../../RELEASENOTES.md). Grace, etc.). ([#5808](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5808)) + * Fixed `PlatformNotSupportedException`s being thrown during export when running + on mobile platforms which caused telemetry to be dropped silently. + ([#5821](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/5821)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs index ab14ad466b2..7e975fa1339 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs @@ -13,6 +13,9 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClie internal abstract class BaseOtlpHttpExportClient : IExportClient { private static readonly ExportClientHttpResponse SuccessExportResponse = new ExportClientHttpResponse(success: true, deadlineUtc: default, response: null, exception: null); +#if NET + private readonly bool synchronousSendSupportedByCurrentPlatform; +#endif protected BaseOtlpHttpExportClient(OtlpExporterOptions options, HttpClient httpClient, string signalPath) { @@ -27,6 +30,14 @@ protected BaseOtlpHttpExportClient(OtlpExporterOptions options, HttpClient httpC this.Endpoint = new UriBuilder(exporterEndpoint).Uri; this.Headers = options.GetHeaders>((d, k, v) => d.Add(k, v)); this.HttpClient = httpClient; + +#if NET + // See: https://github.com/dotnet/runtime/blob/280f2a0c60ce0378b8db49adc0eecc463d00fe5d/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs#L767 + this.synchronousSendSupportedByCurrentPlatform = !OperatingSystem.IsAndroid() + && !OperatingSystem.IsIOS() + && !OperatingSystem.IsTvOS() + && !OperatingSystem.IsBrowser(); +#endif } internal HttpClient HttpClient { get; } @@ -89,7 +100,9 @@ protected HttpRequestMessage CreateHttpRequest(TRequest exportRequest) protected HttpResponseMessage SendHttpRequest(HttpRequestMessage request, CancellationToken cancellationToken) { #if NET - return this.HttpClient.Send(request, cancellationToken); + return this.synchronousSendSupportedByCurrentPlatform + ? this.HttpClient.Send(request, cancellationToken) + : this.HttpClient.SendAsync(request, cancellationToken).GetAwaiter().GetResult(); #else return this.HttpClient.SendAsync(request, cancellationToken).GetAwaiter().GetResult(); #endif diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index edf54750adf..9303d9dd88f 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -10,6 +10,10 @@ Notes](../../RELEASENOTES.md). `Convert.ToString` will now format using `CultureInfo.InvariantCulture`. ([#5700](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5700)) +* Fixed `PlatformNotSupportedException`s being thrown during export when running + on mobile platforms which caused telemetry to be dropped silently. + ([#5821](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/5821)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs index 9ccfdc69041..c65f1454284 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs @@ -24,6 +24,9 @@ public class ZipkinExporter : BaseExporter private readonly ZipkinExporterOptions options; private readonly int maxPayloadSizeInBytes; private readonly HttpClient httpClient; +#if NET + private readonly bool synchronousSendSupportedByCurrentPlatform; +#endif /// /// Initializes a new instance of the class. @@ -35,8 +38,18 @@ public ZipkinExporter(ZipkinExporterOptions options, HttpClient? client = null) Guard.ThrowIfNull(options); this.options = options; - this.maxPayloadSizeInBytes = (!options.MaxPayloadSizeInBytes.HasValue || options.MaxPayloadSizeInBytes <= 0) ? ZipkinExporterOptions.DefaultMaxPayloadSizeInBytes : options.MaxPayloadSizeInBytes.Value; + this.maxPayloadSizeInBytes = (!options.MaxPayloadSizeInBytes.HasValue || options.MaxPayloadSizeInBytes <= 0) + ? ZipkinExporterOptions.DefaultMaxPayloadSizeInBytes + : options.MaxPayloadSizeInBytes.Value; this.httpClient = client ?? options.HttpClientFactory?.Invoke() ?? throw new InvalidOperationException("ZipkinExporter was missing HttpClientFactory or it returned null."); + +#if NET + // See: https://github.com/dotnet/runtime/blob/280f2a0c60ce0378b8db49adc0eecc463d00fe5d/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs#L767 + this.synchronousSendSupportedByCurrentPlatform = !OperatingSystem.IsAndroid() + && !OperatingSystem.IsIOS() + && !OperatingSystem.IsTvOS() + && !OperatingSystem.IsBrowser(); +#endif } internal ZipkinEndpoint? LocalEndpoint { get; private set; } @@ -62,7 +75,9 @@ public override ExportResult Export(in Batch batch) }; #if NET - using var response = this.httpClient.Send(request, CancellationToken.None); + using var response = this.synchronousSendSupportedByCurrentPlatform + ? this.httpClient.Send(request, CancellationToken.None) + : this.httpClient.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult(); #else using var response = this.httpClient.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult(); #endif From 6194d9bb176af6d3949169a7781379b31f6b1a43 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Thu, 12 Sep 2024 22:05:49 +0200 Subject: [PATCH 075/133] [repo] How to maintain PublicApi files (#5823) Co-authored-by: Mikel Blanchard --- CONTRIBUTING.md | 109 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 27 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7a9590b068a..fda1c81c336 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,33 +59,88 @@ of Windows. * Visual Studio 2022+ or Visual Studio Code * .NET Framework 4.6.2+ -### Public API - -It is critical to keep public API surface small and clean. This repository is -using `Microsoft.CodeAnalysis.PublicApiAnalyzers` to validate the public APIs. -This analyzer will check if you changed a public property/method so the change -will be easily spotted in pull request. It will also ensure that OpenTelemetry -doesn't expose APIs outside of the library primary concerns like a generic -helper methods. - -#### How to enable and configure - -* Create a folder in your project called `.publicApi` with the frameworks that - as folders you target. -* Create two files called `PublicAPI.Shipped.txt` and `PublicAPI.Unshipped.txt` - in each framework that you target. -* Add the following lines to your csproj: - -```xml - - - - -``` - -* Use - [IntelliSense](https://docs.microsoft.com/visualstudio/ide/using-intellisense) - to update the publicApi files. +### Public API Validation + +It is critical to **NOT** make breaking changes to public APIs which have been +released in stable builds. We also strive to keep a minimal public API surface. +This repository is using +[Microsoft.CodeAnalysis.PublicApiAnalyzers](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +and [Package +validation](https://learn.microsoft.com/dotnet/fundamentals/apicompat/package-validation/overview) +to validate public APIs. + +* `Microsoft.CodeAnalysis.PublicApiAnalyzers` will validate public API + changes/additions against a set of "public API files" which capture the + shipped/unshipped public APIs. These files must be maintained manually (not + recommended) or by using tooling/code fixes built into the package (see below + for details). + + Public API files are also used to perform public API reviews by repo + approvers/maintainers before releasing stable builds. + +* `Package validation` will validate public API changes/additions against + previously released NuGet packages. + + This is performed automatically by the build/CI + [package-validation](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/.github/workflows/package-validation.yml) + workflow. + + By default package validation is **NOT** run for local builds. To enable + package validation in local builds set the `EnablePackageValidation` property + to `true` in + [Common.prod.props](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/build/Common.prod.props) + (please do not check in this change). + +#### Working with Microsoft.CodeAnalysis.PublicApiAnalyzers + +##### Update public API files when writing code + +[IntelliSense](https://docs.microsoft.com/visualstudio/ide/using-intellisense) +will [suggest +modifications](https://github.com/dotnet/roslyn-analyzers/issues/3322#issuecomment-591031429) +to the `PublicAPI.Unshipped.txt` file when you make changes. After reviewing +these changes, ensure they are reflected across all targeted frameworks. You can +do this by: + +* Using the "Fix all occurrences in Project" feature in Visual Studio. + +* Manually cycling through each framework using Visual Studio's target framework + dropdown (in the upper right corner) and applying the IntelliSense + suggestions. + +> [!IMPORTANT] +> Do **NOT** modify `PublicAPI.Shipped.txt` files. New features and bug fixes + **SHOULD** only require changes to `PublicAPI.Unshipped.txt` files. If you + have to modify a "shipped" file it likely means you made a mistake and broke a + stable API. Typically only maintainers modify the `PublicAPI.Shipped.txt` file + while performing stable releases. If you need help reach out to an approver or + maintainer on Slack or open a draft PR. + +##### Enable public API validation in new projects + +1. If you are **NOT** using experimental APIs: + * If your API is the same across all target frameworks: + * You only need two files: `.publicApi/PublicAPI.Shipped.txt` and + `.publicApi/PublicAPI.Unshipped.txt`. + * If your APIs differ between target frameworks: + * Place the shared APIs in `.publicApi/PublicAPI.Shipped.txt` and + `.publicApi/PublicAPI.Unshipped.txt`. + * Create framework-specific files for API differences (e.g., + `.publicApi/net462/PublicAPI.Shipped.txt` and + `.publicApi/net462/PublicAPI.Unshipped.txt`). + +2. If you are using experimental APIs: + * Follow the rules above, but create an additional layer in your folder + structure: + * For stable APIs: `.publicApi/Stable/*`. + * For experimental APIs: `.publicApi/Experimental/*`. + * The `Experimental` folder should contain APIs that are public only in + pre-release builds. Typically the `Experimental` folder only contains + `PublicAPI.Unshipped.txt` files as experimental APIs are never shipped + stable. + + Example folder structure can be found + [here](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Api/.publicApi). ## Pull Requests From 82b1fbd760eacc4bac2e4f7cf754a36f911e6d77 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Sat, 14 Sep 2024 05:45:28 +0200 Subject: [PATCH 076/133] [Exporter.Prometheus] Nullable (#5791) Co-authored-by: Mikel Blanchard --- .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 22 +++++++------- ...etry.Exporter.Prometheus.AspNetCore.csproj | 6 ++-- .../PrometheusAspNetCoreOptions.cs | 2 +- ...eusExporterApplicationBuilderExtensions.cs | 10 +++---- ...sExporterEndpointRouteBuilderExtensions.cs | 8 ++--- ...sExporterMeterProviderBuilderExtensions.cs | 8 ++--- .../PrometheusExporterMiddleware.cs | 9 +++--- .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 10 +++---- .../Internal/PrometheusCollectionManager.cs | 13 ++++---- .../Internal/PrometheusExporter.cs | 19 +++++++----- .../Internal/PrometheusHeadersParser.cs | 2 +- .../Internal/PrometheusMetric.cs | 17 +++++++---- .../Internal/PrometheusSerializer.cs | 12 +++++--- ...ry.Exporter.Prometheus.HttpListener.csproj | 6 ++-- .../PrometheusHttpListener.cs | 12 ++++---- ...pListenerMeterProviderBuilderExtensions.cs | 8 ++--- .../PrometheusHttpListenerOptions.cs | 4 ++- ...xporter.Prometheus.AspNetCore.Tests.csproj | 3 -- .../PrometheusExporterMiddlewareTests.cs | 30 +++++++++---------- ...orter.Prometheus.HttpListener.Tests.csproj | 3 -- .../PrometheusCollectionManagerTests.cs | 6 ++-- .../PrometheusHttpListenerTests.cs | 26 ++++++++-------- .../PrometheusSerializerTests.cs | 16 +++++----- 25 files changed, 133 insertions(+), 121 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Shipped.txt index e69de29bb2d..7dc5c58110b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Unshipped.txt index 99d1e9e4939..92eaa1e4111 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Unshipped.txt @@ -4,18 +4,18 @@ OpenTelemetry.Exporter.PrometheusAspNetCoreOptions OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.DisableTotalNameSuffixForCounters.get -> bool OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.DisableTotalNameSuffixForCounters.set -> void OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.PrometheusAspNetCoreOptions() -> void -OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeEndpointPath.get -> string +OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeEndpointPath.get -> string? OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeEndpointPath.set -> void OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeResponseCacheDurationMilliseconds.get -> int OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeResponseCacheDurationMilliseconds.set -> void OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions -static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app) -> Microsoft.AspNetCore.Builder.IApplicationBuilder -static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, OpenTelemetry.Metrics.MeterProvider meterProvider, System.Func predicate, string path, System.Action configureBranchedPipeline, string optionsName) -> Microsoft.AspNetCore.Builder.IApplicationBuilder -static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, string path) -> Microsoft.AspNetCore.Builder.IApplicationBuilder -static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, System.Func predicate) -> Microsoft.AspNetCore.Builder.IApplicationBuilder -static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder -static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder -static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path, OpenTelemetry.Metrics.MeterProvider meterProvider, System.Action configureBranchedPipeline, string optionsName) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder -static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app) -> Microsoft.AspNetCore.Builder.IApplicationBuilder! +static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, OpenTelemetry.Metrics.MeterProvider? meterProvider, System.Func? predicate, string? path, System.Action? configureBranchedPipeline, string? optionsName) -> Microsoft.AspNetCore.Builder.IApplicationBuilder! +static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, string! path) -> Microsoft.AspNetCore.Builder.IApplicationBuilder! +static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, System.Func! predicate) -> Microsoft.AspNetCore.Builder.IApplicationBuilder! +static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder! +static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! path) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder! +static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string? path, OpenTelemetry.Metrics.MeterProvider? meterProvider, System.Action? configureBranchedPipeline, string? optionsName) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder! +static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj index a143d39ac12..f6a49fe6a64 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj @@ -7,9 +7,6 @@ $(PackageTags);prometheus;metrics coreunstable- $(DefineConstants);PROMETHEUS_ASPNETCORE - - - disable @@ -25,7 +22,6 @@ - @@ -36,6 +32,8 @@ + + diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusAspNetCoreOptions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusAspNetCoreOptions.cs index 75acb565175..ed8186ec88d 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusAspNetCoreOptions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusAspNetCoreOptions.cs @@ -15,7 +15,7 @@ public class PrometheusAspNetCoreOptions /// /// Gets or sets the path to use for the scraping endpoint. Default value: "/metrics". /// - public string ScrapeEndpointPath { get; set; } = DefaultScrapeEndpointPath; + public string? ScrapeEndpointPath { get; set; } = DefaultScrapeEndpointPath; /// /// Gets or sets a value indicating whether addition of _total suffix for counter metric names is disabled. Default value: . diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs index 946f07d05aa..38559e6b201 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs @@ -93,11 +93,11 @@ public static IApplicationBuilder UseOpenTelemetryPrometheusScrapingEndpoint(thi /// cref="IApplicationBuilder"/> for chaining calls. public static IApplicationBuilder UseOpenTelemetryPrometheusScrapingEndpoint( this IApplicationBuilder app, - MeterProvider meterProvider, - Func predicate, - string path, - Action configureBranchedPipeline, - string optionsName) + MeterProvider? meterProvider, + Func? predicate, + string? path, + Action? configureBranchedPipeline, + string? optionsName) { // Note: Order is important here. MeterProvider is accessed before // GetOptions so that any changes made to diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs index 4e70f2f76c9..45639b378fc 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs @@ -64,10 +64,10 @@ public static IEndpointConventionBuilder MapPrometheusScrapingEndpoint(this IEnd /// A convention routes for the Prometheus scraping endpoint. public static IEndpointConventionBuilder MapPrometheusScrapingEndpoint( this IEndpointRouteBuilder endpoints, - string path, - MeterProvider meterProvider, - Action configureBranchedPipeline, - string optionsName) + string? path, + MeterProvider? meterProvider, + Action? configureBranchedPipeline, + string? optionsName) { var builder = endpoints.CreateApplicationBuilder(); diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs index 6a075fc1b99..f73455d3b08 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs @@ -37,13 +37,13 @@ public static MeterProviderBuilder AddPrometheusExporter( /// Adds to the . /// /// builder to use. - /// Name which is used when retrieving options. - /// Callback action for configuring . + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddPrometheusExporter( this MeterProviderBuilder builder, - string name, - Action configure) + string? name, + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs index fdfcd2b7113..c2bd1cc2572 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs @@ -25,8 +25,9 @@ internal sealed class PrometheusExporterMiddleware public PrometheusExporterMiddleware(MeterProvider meterProvider, RequestDelegate next) { Guard.ThrowIfNull(meterProvider); + Guard.ThrowIfNull(next); - if (!meterProvider.TryFindExporter(out PrometheusExporter exporter)) + if (!meterProvider.TryFindExporter(out PrometheusExporter? exporter)) { throw new ArgumentException("A PrometheusExporter could not be found configured on the provided MeterProvider."); } @@ -36,6 +37,8 @@ public PrometheusExporterMiddleware(MeterProvider meterProvider, RequestDelegate internal PrometheusExporterMiddleware(PrometheusExporter exporter) { + Debug.Assert(exporter != null, "exporter was null"); + this.exporter = exporter; } @@ -71,7 +74,7 @@ public async Task InvokeAsync(HttpContext httpContext) ? "application/openmetrics-text; version=1.0.0; charset=utf-8" : "text/plain; charset=utf-8; version=0.0.4"; - await response.Body.WriteAsync(dataView.Array, 0, dataView.Count).ConfigureAwait(false); + await response.Body.WriteAsync(dataView.Array!, 0, dataView.Count).ConfigureAwait(false); } else { @@ -93,8 +96,6 @@ public async Task InvokeAsync(HttpContext httpContext) response.StatusCode = 500; } } - - this.exporter.OnExport = null; } private static bool AcceptsOpenMetrics(HttpRequest request) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Shipped.txt index e69de29bb2d..7dc5c58110b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Unshipped.txt index d05f12424ea..6caa1a77cb1 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Unshipped.txt @@ -1,12 +1,12 @@ OpenTelemetry.Exporter.PrometheusHttpListenerOptions OpenTelemetry.Exporter.PrometheusHttpListenerOptions.DisableTotalNameSuffixForCounters.get -> bool OpenTelemetry.Exporter.PrometheusHttpListenerOptions.DisableTotalNameSuffixForCounters.set -> void -OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection +OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection! OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.set -> void OpenTelemetry.Exporter.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void -OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string +OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string? OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> void OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions -static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs index 4c78a12e49c..1c74e36bcf8 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using System.Runtime.CompilerServices; using OpenTelemetry.Metrics; @@ -12,7 +13,7 @@ internal sealed class PrometheusCollectionManager private readonly PrometheusExporter exporter; private readonly int scrapeResponseCacheDurationMilliseconds; - private readonly Func, ExportResult> onCollectRef; + private readonly PrometheusExporter.ExportFunc onCollectRef; private readonly Dictionary metricsCache; private readonly HashSet scopes; private int metricsCacheCount; @@ -26,7 +27,7 @@ internal sealed class PrometheusCollectionManager private DateTime? previousOpenMetricsDataViewGeneratedAtUtc; private int readerCount; private bool collectionRunning; - private TaskCompletionSource collectionTcs; + private TaskCompletionSource? collectionTcs; public PrometheusCollectionManager(PrometheusExporter exporter) { @@ -115,7 +116,7 @@ public Task EnterCollect(bool openMetricsRequested) ? this.previousOpenMetricsDataViewGeneratedAtUtc : this.previousPlainTextDataViewGeneratedAtUtc; - response = new CollectionResponse(this.previousOpenMetricsDataView, this.previousPlainTextDataView, previousDataViewGeneratedAtUtc.Value, fromCache: false); + response = new CollectionResponse(this.previousOpenMetricsDataView, this.previousPlainTextDataView, previousDataViewGeneratedAtUtc!.Value, fromCache: false); } else { @@ -188,14 +189,16 @@ private void WaitForReadersToComplete() [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool ExecuteCollect(bool openMetricsRequested) { + Debug.Assert(this.exporter.Collect != null, "this.exporter.Collect was null"); + this.exporter.OnExport = this.onCollectRef; this.exporter.OpenMetricsRequested = openMetricsRequested; - var result = this.exporter.Collect(Timeout.Infinite); + var result = this.exporter.Collect!(Timeout.Infinite); this.exporter.OnExport = null; return result; } - private ExportResult OnCollect(Batch metrics) + private ExportResult OnCollect(in Batch metrics) { var cursor = 0; ref byte[] buffer = ref (this.exporter.OpenMetricsRequested ? ref this.openMetricsBuffer : ref this.plainTextBuffer); diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusExporter.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusExporter.cs index 292b0aa7c31..c5b0e0e64d3 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusExporter.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusExporter.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -13,9 +14,9 @@ namespace OpenTelemetry.Exporter.Prometheus; [ExportModes(ExportModes.Pull)] internal sealed class PrometheusExporter : BaseExporter, IPullMetricExporter { - private Func funcCollect; - private Func, ExportResult> funcExport; - private Resource resource; + private Func? funcCollect; + private ExportFunc? funcExport; + private Resource? resource; private bool disposed; /// @@ -32,22 +33,24 @@ public PrometheusExporter(PrometheusExporterOptions options) this.CollectionManager = new PrometheusCollectionManager(this); } + public delegate ExportResult ExportFunc(in Batch batch); + /// /// Gets or sets the Collect delegate. /// - public Func Collect + public Func? Collect { get => this.funcCollect; set => this.funcCollect = value; } - internal Func, ExportResult> OnExport + internal ExportFunc? OnExport { get => this.funcExport; set => this.funcExport = value; } - internal Action OnDispose { get; set; } + internal Action? OnDispose { get; set; } internal PrometheusCollectionManager CollectionManager { get; } @@ -62,7 +65,9 @@ internal Func, ExportResult> OnExport /// public override ExportResult Export(in Batch metrics) { - return this.OnExport(metrics); + Debug.Assert(this.OnExport != null, "this.OnExport was null"); + + return this.OnExport!(in metrics); } /// diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusHeadersParser.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusHeadersParser.cs index 81576b723dc..2c2c8f5b7d6 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusHeadersParser.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusHeadersParser.cs @@ -7,7 +7,7 @@ internal static class PrometheusHeadersParser { private const string OpenMetricsMediaType = "application/openmetrics-text"; - internal static bool AcceptsOpenMetrics(string contentType) + internal static bool AcceptsOpenMetrics(string? contentType) { var value = contentType.AsSpan(); diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index 6f18f06a536..800963454a7 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text; using OpenTelemetry.Metrics; @@ -29,7 +31,7 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa var sanitizedName = SanitizeMetricName(name); var openMetricsName = SanitizeOpenMetricsName(sanitizedName); - string sanitizedUnit = null; + string? sanitizedUnit = null; if (!string.IsNullOrEmpty(unit)) { sanitizedUnit = GetUnit(unit); @@ -80,7 +82,7 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa public string OpenMetricsMetadataName { get; } - public string Unit { get; } + public string? Unit { get; } public PrometheusType Type { get; } @@ -91,7 +93,7 @@ public static PrometheusMetric Create(Metric metric, bool disableTotalNameSuffix internal static string SanitizeMetricName(string metricName) { - StringBuilder sb = null; + StringBuilder? sb = null; var lastCharUnderscore = false; for (var i = 0; i < metricName.Length; i++) @@ -134,7 +136,7 @@ internal static string RemoveAnnotations(string unit) // https://ucum.org/ucum#section-Character-Set-and-Lexical-Rules // What should happen if they are nested isn't defined. // Right now the remove annotations code doesn't attempt to balance multiple start and end braces. - StringBuilder sb = null; + StringBuilder? sb = null; var hasOpenBrace = false; var startOpenBraceIndex = 0; @@ -168,7 +170,10 @@ internal static string RemoveAnnotations(string unit) return unit; } - sb.Append(unit, lastWriteIndex, unit.Length - lastWriteIndex); + Debug.Assert(sb != null, "sb was null"); + + sb!.Append(unit, lastWriteIndex, unit.Length - lastWriteIndex); + return sb.ToString(); } @@ -204,7 +209,7 @@ private static string GetUnit(string unit) return updatedUnit; } - private static bool TryProcessRateUnits(string updatedUnit, out string updatedPerUnit) + private static bool TryProcessRateUnits(string updatedUnit, [NotNullWhen(true)] out string? updatedPerUnit) { updatedPerUnit = null; diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs index b177dda5a04..7623de4067a 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs @@ -177,7 +177,7 @@ public static int WriteLabelValue(byte[] buffer, int cursor, string value) { Debug.Assert(value != null, $"{nameof(value)} should not be null."); - for (int i = 0; i < value.Length; i++) + for (int i = 0; i < value!.Length; i++) { var ordinal = (ushort)value[i]; switch (ordinal) @@ -204,7 +204,7 @@ public static int WriteLabelValue(byte[] buffer, int cursor, string value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteLabel(byte[] buffer, int cursor, string labelKey, object labelValue) + public static int WriteLabel(byte[] buffer, int cursor, string labelKey, object? labelValue) { cursor = WriteLabelKey(buffer, cursor, labelKey); buffer[cursor++] = unchecked((byte)'='); @@ -216,7 +216,7 @@ public static int WriteLabel(byte[] buffer, int cursor, string labelKey, object return cursor; - static string GetLabelValueString(object labelValue) + static string GetLabelValueString(object? labelValue) { // TODO: Attribute values should be written as their JSON representation. Extra logic may need to be added here to correctly convert other .NET types. // More detail: https://github.com/open-telemetry/opentelemetry-dotnet/issues/4822#issuecomment-1707328495 @@ -235,6 +235,8 @@ public static int WriteMetricName(byte[] buffer, int cursor, PrometheusMetric me // Metric name has already been escaped. var name = openMetricsRequested ? metric.OpenMetricsName : metric.Name; + Debug.Assert(!string.IsNullOrWhiteSpace(name), "name was null or whitespace"); + for (int i = 0; i < name.Length; i++) { var ordinal = (ushort)name[i]; @@ -250,6 +252,8 @@ public static int WriteMetricMetadataName(byte[] buffer, int cursor, PrometheusM // Metric name has already been escaped. var name = openMetricsRequested ? metric.OpenMetricsMetadataName : metric.Name; + Debug.Assert(!string.IsNullOrWhiteSpace(name), "name was null or whitespace"); + for (int i = 0; i < name.Length; i++) { var ordinal = (ushort)name[i]; @@ -321,7 +325,7 @@ public static int WriteUnitMetadata(byte[] buffer, int cursor, PrometheusMetric buffer[cursor++] = unchecked((byte)' '); // Unit name has already been escaped. - for (int i = 0; i < metric.Unit.Length; i++) + for (int i = 0; i < metric.Unit!.Length; i++) { var ordinal = (ushort)metric.Unit[i]; buffer[cursor++] = unchecked((byte)ordinal); diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj index 3766816a7e1..91fb3f461cf 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj @@ -5,9 +5,6 @@ Stand-alone HttpListener for hosting OpenTelemetry .NET Prometheus Exporter $(PackageTags);prometheus;metrics coreunstable- - - - disable @@ -19,9 +16,10 @@ + - + diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs index 8576873f520..284a99acc87 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs @@ -13,8 +13,8 @@ internal sealed class PrometheusHttpListener : IDisposable private readonly HttpListener httpListener = new(); private readonly object syncObject = new(); - private CancellationTokenSource tokenSource; - private Task workerThread; + private CancellationTokenSource? tokenSource; + private Task? workerThread; /// /// Initializes a new instance of the class. @@ -28,7 +28,7 @@ public PrometheusHttpListener(PrometheusExporter exporter, PrometheusHttpListene this.exporter = exporter; - string path = options.ScrapeEndpointPath; + string path = options.ScrapeEndpointPath ?? PrometheusHttpListenerOptions.DefaultScrapeEndpointPath; if (!path.StartsWith("/")) { @@ -83,7 +83,7 @@ public void Stop() } this.tokenSource.Cancel(); - this.workerThread.Wait(); + this.workerThread!.Wait(); this.tokenSource = null; } } @@ -116,7 +116,7 @@ private void WorkerProc() try { using var scope = SuppressInstrumentationScope.Begin(); - while (!this.tokenSource.IsCancellationRequested) + while (!this.tokenSource!.IsCancellationRequested) { var ctxTask = this.httpListener.GetContextAsync(); ctxTask.Wait(this.tokenSource.Token); @@ -164,7 +164,7 @@ private async Task ProcessRequestAsync(HttpListenerContext context) ? "application/openmetrics-text; version=1.0.0; charset=utf-8" : "text/plain; charset=utf-8; version=0.0.4"; - await context.Response.OutputStream.WriteAsync(dataView.Array, 0, dataView.Count).ConfigureAwait(false); + await context.Response.OutputStream.WriteAsync(dataView.Array!, 0, dataView.Count).ConfigureAwait(false); } else { diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs index 929774a11f9..7289432cdcf 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs @@ -37,13 +37,13 @@ public static MeterProviderBuilder AddPrometheusHttpListener( /// Adds PrometheusHttpListener to MeterProviderBuilder. /// /// builder to use. - /// Name which is used when retrieving options. - /// Callback action for configuring . + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain calls. public static MeterProviderBuilder AddPrometheusHttpListener( this MeterProviderBuilder builder, - string name, - Action configure) + string? name, + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs index d0c6bd2edf0..dbe20b726c4 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs @@ -10,12 +10,14 @@ namespace OpenTelemetry.Exporter; /// public class PrometheusHttpListenerOptions { + internal const string DefaultScrapeEndpointPath = "/metrics"; + private IReadOnlyCollection uriPrefixes = new[] { "http://localhost:9464/" }; /// /// Gets or sets the path to use for the scraping endpoint. Default value: "/metrics". /// - public string ScrapeEndpointPath { get; set; } = "/metrics"; + public string? ScrapeEndpointPath { get; set; } = DefaultScrapeEndpointPath; /// /// Gets or sets a value indicating whether addition of _total suffix for counter metric names is disabled. Default value: . diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj index b361d72e7ee..7a91330ca56 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj @@ -3,9 +3,6 @@ Unit test project for Prometheus Exporter AspNetCore for OpenTelemetry $(TargetFrameworksForAspNetCoreTests) $(DefineConstants);PROMETHEUS_ASPNETCORE - - - disable diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs index b63cabc36b3..3f23d764e55 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs @@ -110,7 +110,7 @@ public Task PrometheusExporterMiddlewareIntegration_MixedPredicateAndPath() services => services.Configure(o => o.ScrapeEndpointPath = "/metrics_options"), validateResponse: rsp => { - if (!rsp.Headers.TryGetValues("X-MiddlewareExecuted", out IEnumerable headers)) + if (!rsp.Headers.TryGetValues("X-MiddlewareExecuted", out IEnumerable? headers)) { headers = Array.Empty(); } @@ -137,7 +137,7 @@ public Task PrometheusExporterMiddlewareIntegration_MixedPath() services => services.Configure(o => o.ScrapeEndpointPath = "/metrics_options"), validateResponse: rsp => { - if (!rsp.Headers.TryGetValues("X-MiddlewareExecuted", out IEnumerable headers)) + if (!rsp.Headers.TryGetValues("X-MiddlewareExecuted", out IEnumerable? headers)) { headers = Array.Empty(); } @@ -254,10 +254,10 @@ public async Task PrometheusExporterMiddlewareIntegration_CanServeOpenMetricsAnd using var host = await StartTestHostAsync( app => app.UseOpenTelemetryPrometheusScrapingEndpoint()); - var tags = new KeyValuePair[] + var tags = new KeyValuePair[] { - new KeyValuePair("key1", "value1"), - new KeyValuePair("key2", "value2"), + new("key1", "value1"), + new("key2", "value2"), }; using var meter = new Meter(MeterName, MeterVersion); @@ -315,10 +315,10 @@ public async Task PrometheusExporterMiddlewareIntegration_TestBufferSizeIncrease private static async Task RunPrometheusExporterMiddlewareIntegrationTest( string path, Action configure, - Action configureServices = null, - Action validateResponse = null, + Action? configureServices = null, + Action? validateResponse = null, bool registerMeterProvider = true, - Action configureOptions = null, + Action? configureOptions = null, bool skipMetrics = false, string acceptHeader = "application/openmetrics-text") { @@ -326,10 +326,10 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( using var host = await StartTestHostAsync(configure, configureServices, registerMeterProvider, configureOptions); - var tags = new KeyValuePair[] + var tags = new KeyValuePair[] { - new KeyValuePair("key1", "value1"), - new KeyValuePair("key2", "value2"), + new("key1", "value1"), + new("key2", "value2"), }; using var meter = new Meter(MeterName, MeterVersion); @@ -375,11 +375,11 @@ private static async Task VerifyAsync(long beginTimestamp, long endTimestamp, Ht if (requestOpenMetrics) { - Assert.Equal("application/openmetrics-text; version=1.0.0; charset=utf-8", response.Content.Headers.ContentType.ToString()); + Assert.Equal("application/openmetrics-text; version=1.0.0; charset=utf-8", response.Content.Headers.ContentType!.ToString()); } else { - Assert.Equal("text/plain; charset=utf-8; version=0.0.4", response.Content.Headers.ContentType.ToString()); + Assert.Equal("text/plain; charset=utf-8; version=0.0.4", response.Content.Headers.ContentType!.ToString()); } string content = (await response.Content.ReadAsStringAsync()).ReplaceLineEndings(); @@ -417,9 +417,9 @@ private static async Task VerifyAsync(long beginTimestamp, long endTimestamp, Ht private static Task StartTestHostAsync( Action configure, - Action configureServices = null, + Action? configureServices = null, bool registerMeterProvider = true, - Action configureOptions = null) + Action? configureOptions = null) { return new HostBuilder() .ConfigureWebHost(webBuilder => webBuilder diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj index 295231183c2..efab035ead8 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj @@ -3,9 +3,6 @@ Unit test project for Prometheus Exporter HttpListener for OpenTelemetry $(TargetFrameworksForTests) $(DefineConstants);PROMETHEUS_HTTP_LISTENER - - - disable diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs index 32ee87e3de5..36f5e124e67 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs @@ -31,7 +31,7 @@ public async Task EnterExitCollectTest(int scrapeResponseCacheDurationMillisecon #endif .Build()) { - if (!provider.TryFindExporter(out PrometheusExporter exporter)) + if (!provider.TryFindExporter(out PrometheusExporter? exporter)) { throw new InvalidOperationException("PrometheusExporter could not be found on MeterProvider."); } @@ -40,7 +40,7 @@ public async Task EnterExitCollectTest(int scrapeResponseCacheDurationMillisecon var collectFunc = exporter.Collect; exporter.Collect = (timeout) => { - bool result = collectFunc(timeout); + bool result = collectFunc!(timeout); runningCollectCount++; Thread.Sleep(5000); return result; @@ -156,6 +156,6 @@ private class Response { public PrometheusCollectionManager.CollectionResponse CollectionResponse; - public byte[] ViewPayload; + public byte[]? ViewPayload; } } diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs index a132cf17753..07ee28beb23 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs @@ -38,7 +38,7 @@ public void UriPrefixesNull() { Assert.Throws(() => { - TestPrometheusHttpListenerUriPrefixOptions(null); + TestPrometheusHttpListenerUriPrefixOptions(null!); }); } @@ -90,10 +90,10 @@ public void PrometheusHttpListenerThrowsOnStart() Random random = new Random(); int retryAttempts = 5; int port = 0; - string address = null; + string? address = null; - PrometheusExporter exporter = null; - PrometheusHttpListener listener = null; + PrometheusExporter? exporter = null; + PrometheusHttpListener? listener = null; // Step 1: Start a listener on a random port. while (retryAttempts-- != 0) @@ -134,7 +134,7 @@ public void PrometheusHttpListenerThrowsOnStart() exporter, new() { - UriPrefixes = new string[] { address }, + UriPrefixes = new string[] { address! }, }); listener.Start(); @@ -199,8 +199,8 @@ private static MeterProvider BuildMeterProvider(Meter meter, IEnumerable[] + var tags = new KeyValuePair[] { - new KeyValuePair("key1", "value1"), - new KeyValuePair("key2", "value2"), + new("key1", "value1"), + new("key2", "value2"), }; var counter = meter.CreateCounter("counter_double", unit: "By"); @@ -273,11 +273,11 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri if (requestOpenMetrics) { - Assert.Equal("application/openmetrics-text; version=1.0.0; charset=utf-8", response.Content.Headers.ContentType.ToString()); + Assert.Equal("application/openmetrics-text; version=1.0.0; charset=utf-8", response.Content.Headers.ContentType!.ToString()); } else { - Assert.Equal("text/plain; charset=utf-8; version=0.0.4", response.Content.Headers.ContentType.ToString()); + Assert.Equal("text/plain; charset=utf-8; version=0.0.4", response.Content.Headers.ContentType!.ToString()); } var content = await response.Content.ReadAsStringAsync(); diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusSerializerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusSerializerTests.cs index 7c4a95b05f4..2864fe59b5c 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusSerializerTests.cs @@ -129,7 +129,7 @@ public void GaugeOneDimension() meter.CreateObservableGauge( "test_gauge", - () => new Measurement(123, new KeyValuePair("tagKey", "tagValue"))); + () => new Measurement(123, new KeyValuePair("tagKey", "tagValue"))); provider.ForceFlush(); @@ -156,7 +156,7 @@ public void GaugeBoolDimension() meter.CreateObservableGauge( "test_gauge", - () => new Measurement(123, new KeyValuePair("tagKey", true))); + () => new Measurement(123, new KeyValuePair("tagKey", true))); provider.ForceFlush(); @@ -312,8 +312,8 @@ public void HistogramOneDimension() .Build(); var histogram = meter.CreateHistogram("test_histogram"); - histogram.Record(18, new KeyValuePair("x", "1")); - histogram.Record(100, new KeyValuePair("x", "1")); + histogram.Record(18, new KeyValuePair("x", "1")); + histogram.Record(100, new KeyValuePair("x", "1")); provider.ForceFlush(); @@ -539,8 +539,8 @@ public void HistogramOneDimensionWithOpenMetricsFormat() .Build(); var histogram = meter.CreateHistogram("test_histogram"); - histogram.Record(18, new KeyValuePair("x", "1")); - histogram.Record(100, new KeyValuePair("x", "1")); + histogram.Record(18, new KeyValuePair("x", "1")); + histogram.Record(100, new KeyValuePair("x", "1")); provider.ForceFlush(); @@ -622,8 +622,8 @@ public void HistogramOneDimensionWithScopeVersion() .Build(); var histogram = meter.CreateHistogram("test_histogram"); - histogram.Record(18, new KeyValuePair("x", "1")); - histogram.Record(100, new KeyValuePair("x", "1")); + histogram.Record(18, new KeyValuePair("x", "1")); + histogram.Record(100, new KeyValuePair("x", "1")); provider.ForceFlush(); From 9b83188ccd9feb8ef6d156cbf6518b7e6bd2503a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 16 Sep 2024 11:52:30 -0700 Subject: [PATCH 077/133] [console, in-memory] Tweak nullable annotations in registration extensions (#5833) --- .../.publicApi/Stable/PublicAPI.Shipped.txt | 6 +++--- .../ConsoleExporterHelperExtensions.cs | 6 +++--- .../ConsoleExporterLoggingExtensions.cs | 8 ++++---- .../ConsoleExporterMetricsExtensions.cs | 6 +++--- .../.publicApi/Stable/PublicAPI.Shipped.txt | 4 ++-- .../InMemoryExporterMetricsExtensions.cs | 12 ++++++------ 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt index d3f3a6d769a..9927c4d1475 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/Stable/PublicAPI.Shipped.txt @@ -24,14 +24,14 @@ override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Export(in OpenTelemetry override OpenTelemetry.Exporter.ConsoleMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder) -> OpenTelemetry.Logs.LoggerProviderBuilder! static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, string? name, System.Action? configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action? configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs index 12e009f5439..68a811669e3 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs @@ -24,15 +24,15 @@ public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilde /// builder to use. /// Callback action for configuring . /// The instance of to chain the calls. - public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder, Action? configure) + public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder, Action configure) => AddConsoleExporter(builder, name: null, configure); /// /// Adds Console exporter to the TracerProvider. /// /// builder to use. - /// Name which is used when retrieving options. - /// Callback action for configuring . + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddConsoleExporter( this TracerProviderBuilder builder, diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs index 5066cda7d9f..498aa3a926f 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs @@ -23,7 +23,7 @@ public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLo /// Adds Console exporter with OpenTelemetryLoggerOptions. /// /// options to use. - /// Callback action for configuring . + /// Optional callback action for configuring . /// The instance of to chain the calls. // TODO: [Obsolete("Call LoggerProviderBuilder.AddConsoleExporter instead this method will be removed in a future version.")] public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions, Action? configure) @@ -52,15 +52,15 @@ public static LoggerProviderBuilder AddConsoleExporter( /// The supplied instance of to chain the calls. public static LoggerProviderBuilder AddConsoleExporter( this LoggerProviderBuilder loggerProviderBuilder, - Action? configure) + Action configure) => AddConsoleExporter(loggerProviderBuilder, name: null, configure); /// /// Adds Console exporter with LoggerProviderBuilder. /// /// . - /// Name which is used when retrieving options. - /// Callback action for configuring . + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The supplied instance of to chain the calls. public static LoggerProviderBuilder AddConsoleExporter( this LoggerProviderBuilder loggerProviderBuilder, diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs index b88953193ee..78ee90829d9 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs @@ -30,15 +30,15 @@ public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder /// builder to use. /// Callback action for configuring . /// The instance of to chain the calls. - public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder builder, Action? configureExporter) + public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder builder, Action configureExporter) => AddConsoleExporter(builder, name: null, configureExporter); /// /// Adds to the . /// /// builder to use. - /// Name which is used when retrieving options. - /// Callback action for configuring . + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddConsoleExporter( this MeterProviderBuilder builder, diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt index 10d97f89495..3a85e139a88 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/Stable/PublicAPI.Shipped.txt @@ -20,7 +20,7 @@ static OpenTelemetry.Logs.InMemoryExporterLoggingExtensions.AddInMemoryExporter( static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems, System.Action! configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems, System.Action? configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems, System.Action! configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.InMemoryExporterHelperExtensions.AddInMemoryExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Collections.Generic.ICollection! exportedItems) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs index 660b9db11e3..da5ecda24d9 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs @@ -41,7 +41,7 @@ public static MeterProviderBuilder AddInMemoryExporter(this MeterProviderBuilder public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, ICollection exportedItems, - Action? configureMetricReader) + Action configureMetricReader) => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader); /// @@ -51,9 +51,9 @@ public static MeterProviderBuilder AddInMemoryExporter( /// Be aware that may continue to be updated after export. /// /// builder to use. - /// Name which is used when retrieving options. + /// Optional name which is used when retrieving options. /// Collection which will be populated with the exported . - /// Callback action for configuring . + /// Optional callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, @@ -108,7 +108,7 @@ public static MeterProviderBuilder AddInMemoryExporter( public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, ICollection exportedItems, - Action? configureMetricReader) + Action configureMetricReader) => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader); /// @@ -119,9 +119,9 @@ public static MeterProviderBuilder AddInMemoryExporter( /// Use this if you need a copy of that will not be updated after export. /// /// builder to use. - /// Name which is used when retrieving options. + /// Optional name which is used when retrieving options. /// Collection which will be populated with the exported represented as . - /// Callback action for configuring . + /// Optional callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, From 1c01770882bb5113ff308b2b4398347fab6e0404 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Tue, 17 Sep 2024 00:03:39 +0200 Subject: [PATCH 078/133] [Shims, W3C.Tests] Nullable (#5797) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Mikel Blanchard --- .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 14 +-- .../CHANGELOG.md | 4 + .../OpenTelemetry.Shims.OpenTracing.csproj | 3 - .../ScopeManagerShim.cs | 8 +- .../SpanBuilderShim.cs | 59 +++++----- .../SpanShim.cs | 36 ++++--- .../TracerShim.cs | 10 +- ...strumentation.W3cTraceContext.Tests.csproj | 2 - .../W3CTraceContextTests.cs | 8 +- .../IntegrationTests.cs | 2 +- ...enTelemetry.Shims.OpenTracing.Tests.csproj | 2 - .../ScopeManagerShimTests.cs | 2 + .../SpanBuilderShimTests.cs | 39 ++++--- .../SpanShimTests.cs | 101 ++++++++++-------- .../TracerShimTests.cs | 16 +-- 16 files changed, 170 insertions(+), 137 deletions(-) diff --git a/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Shipped.txt index e69de29bb2d..7dc5c58110b 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Unshipped.txt index 90f671f8a12..c5d387112fb 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Shims.OpenTracing/.publicApi/PublicAPI.Unshipped.txt @@ -1,8 +1,8 @@ OpenTelemetry.Shims.OpenTracing.TracerShim -OpenTelemetry.Shims.OpenTracing.TracerShim.ActiveSpan.get -> OpenTracing.ISpan -OpenTelemetry.Shims.OpenTracing.TracerShim.BuildSpan(string operationName) -> OpenTracing.ISpanBuilder -OpenTelemetry.Shims.OpenTracing.TracerShim.Extract(OpenTracing.Propagation.IFormat format, TCarrier carrier) -> OpenTracing.ISpanContext -OpenTelemetry.Shims.OpenTracing.TracerShim.Inject(OpenTracing.ISpanContext spanContext, OpenTracing.Propagation.IFormat format, TCarrier carrier) -> void -OpenTelemetry.Shims.OpenTracing.TracerShim.ScopeManager.get -> OpenTracing.IScopeManager -OpenTelemetry.Shims.OpenTracing.TracerShim.TracerShim(OpenTelemetry.Trace.TracerProvider tracerProvider) -> void -OpenTelemetry.Shims.OpenTracing.TracerShim.TracerShim(OpenTelemetry.Trace.TracerProvider tracerProvider, OpenTelemetry.Context.Propagation.TextMapPropagator textFormat) -> void +OpenTelemetry.Shims.OpenTracing.TracerShim.ActiveSpan.get -> OpenTracing.ISpan? +OpenTelemetry.Shims.OpenTracing.TracerShim.BuildSpan(string! operationName) -> OpenTracing.ISpanBuilder! +OpenTelemetry.Shims.OpenTracing.TracerShim.Extract(OpenTracing.Propagation.IFormat! format, TCarrier carrier) -> OpenTracing.ISpanContext? +OpenTelemetry.Shims.OpenTracing.TracerShim.Inject(OpenTracing.ISpanContext! spanContext, OpenTracing.Propagation.IFormat! format, TCarrier carrier) -> void +OpenTelemetry.Shims.OpenTracing.TracerShim.ScopeManager.get -> OpenTracing.IScopeManager! +OpenTelemetry.Shims.OpenTracing.TracerShim.TracerShim(OpenTelemetry.Trace.TracerProvider! tracerProvider) -> void +OpenTelemetry.Shims.OpenTracing.TracerShim.TracerShim(OpenTelemetry.Trace.TracerProvider! tracerProvider, OpenTelemetry.Context.Propagation.TextMapPropagator? textFormat) -> void diff --git a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md index 68929da6a4e..23775d1cdd8 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md +++ b/src/OpenTelemetry.Shims.OpenTracing/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Fixed an issue causing all tag values added via the `ISpanBuilder` API to be + converted to strings on the `ISpan` started from the builder. + ([#5797](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5797)) + ## 1.9.0-beta.2 Released 2024-Jun-24 diff --git a/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj b/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj index e746024d006..127cbfb3aa9 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj +++ b/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj @@ -4,9 +4,6 @@ OpenTracing shim for OpenTelemetry .NET $(PackageTags);distributed-tracing;OpenTracing coreunstable- - - - disable diff --git a/src/OpenTelemetry.Shims.OpenTracing/ScopeManagerShim.cs b/src/OpenTelemetry.Shims.OpenTracing/ScopeManagerShim.cs index f9464d966a1..6b2fb783355 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/ScopeManagerShim.cs +++ b/src/OpenTelemetry.Shims.OpenTracing/ScopeManagerShim.cs @@ -19,7 +19,7 @@ internal sealed class ScopeManagerShim : IScopeManager #endif /// - public IScope Active + public IScope? Active { get { @@ -56,7 +56,7 @@ public IScope Activate(ISpan span, bool finishSpanOnDispose) Interlocked.Decrement(ref this.spanScopeTableCount); } #endif - scope.Dispose(); + scope!.Dispose(); }); SpanScopeTable.Add(shim.Span, instrumentation); @@ -69,9 +69,9 @@ public IScope Activate(ISpan span, bool finishSpanOnDispose) private sealed class ScopeInstrumentation : IScope { - private readonly Action disposeAction; + private readonly Action? disposeAction; - public ScopeInstrumentation(TelemetrySpan span, Action disposeAction = null) + public ScopeInstrumentation(TelemetrySpan span, Action? disposeAction = null) { this.Span = new SpanShim(span); this.disposeAction = disposeAction; diff --git a/src/OpenTelemetry.Shims.OpenTracing/SpanBuilderShim.cs b/src/OpenTelemetry.Shims.OpenTracing/SpanBuilderShim.cs index 0359762ac3e..f95b1b77be3 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/SpanBuilderShim.cs +++ b/src/OpenTelemetry.Shims.OpenTracing/SpanBuilderShim.cs @@ -32,12 +32,12 @@ internal sealed class SpanBuilderShim : ISpanBuilder /// /// The OpenTelemetry attributes. These correspond to OpenTracing Tags. /// - private readonly List> attributes = new(); + private readonly SpanAttributes attributes = new(); /// /// The parent as an TelemetrySpan, if any. /// - private TelemetrySpan parentSpan; + private TelemetrySpan? parentSpan; /// /// The parent as an SpanContext, if any. @@ -70,7 +70,7 @@ public SpanBuilderShim(Tracer tracer, string spanName) private bool ParentSet => this.parentSpan != null || this.parentSpanContext.IsValid; /// - public ISpanBuilder AsChildOf(ISpanContext parent) + public ISpanBuilder AsChildOf(ISpanContext? parent) { if (parent == null) { @@ -81,7 +81,7 @@ public ISpanBuilder AsChildOf(ISpanContext parent) } /// - public ISpanBuilder AsChildOf(ISpan parent) + public ISpanBuilder AsChildOf(ISpan? parent) { if (parent == null) { @@ -98,7 +98,7 @@ public ISpanBuilder AsChildOf(ISpan parent) } /// - public ISpanBuilder AddReference(string referenceType, ISpanContext referencedContext) + public ISpanBuilder AddReference(string referenceType, ISpanContext? referencedContext) { if (referencedContext == null) { @@ -132,30 +132,25 @@ public ISpanBuilder IgnoreActiveSpan() /// public ISpan Start() { - TelemetrySpan span = null; + TelemetrySpan? span = null; // If specified, this takes precedence. if (this.ignoreActiveSpan) { - span = this.tracer.StartRootSpan(this.spanName, this.spanKind, default, this.links, this.explicitStartTime ?? default); + span = this.tracer.StartRootSpan(this.spanName, this.spanKind, this.attributes, this.links, this.explicitStartTime ?? default); } else if (this.parentSpan != null) { - span = this.tracer.StartSpan(this.spanName, this.spanKind, this.parentSpan, default, this.links, this.explicitStartTime ?? default); + span = this.tracer.StartSpan(this.spanName, this.spanKind, this.parentSpan, this.attributes, this.links, this.explicitStartTime ?? default); } else if (this.parentSpanContext.IsValid) { - span = this.tracer.StartSpan(this.spanName, this.spanKind, this.parentSpanContext, default, this.links, this.explicitStartTime ?? default); + span = this.tracer.StartSpan(this.spanName, this.spanKind, this.parentSpanContext, this.attributes, this.links, this.explicitStartTime ?? default); } if (span == null) { - span = this.tracer.StartSpan(this.spanName, this.spanKind, default(SpanContext), default, null, this.explicitStartTime ?? default); - } - - foreach (var kvp in this.attributes) - { - span.SetAttribute(kvp.Key, kvp.Value.ToString()); + span = this.tracer.StartSpan(this.spanName, this.spanKind, default(SpanContext), this.attributes, null, this.explicitStartTime ?? default); } if (this.error) @@ -184,8 +179,13 @@ public ISpanBuilder WithStartTimestamp(DateTimeOffset timestamp) } /// - public ISpanBuilder WithTag(string key, string value) + public ISpanBuilder WithTag(string key, string? value) { + if (key == null) + { + return this; + } + // see https://opentracing.io/specification/conventions/ for special key handling. if (global::OpenTracing.Tag.Tags.SpanKind.Key.Equals(key, StringComparison.Ordinal)) { @@ -204,12 +204,7 @@ public ISpanBuilder WithTag(string key, string value) } else { - // Keys must be non-null. - // Null values => string.Empty. - if (key != null) - { - this.attributes.Add(new KeyValuePair(key, value ?? string.Empty)); - } + this.attributes.Add(key, value); } return this; @@ -224,7 +219,7 @@ public ISpanBuilder WithTag(string key, bool value) } else { - this.attributes.Add(new KeyValuePair(key, value)); + this.attributes.Add(key, value); } return this; @@ -233,31 +228,31 @@ public ISpanBuilder WithTag(string key, bool value) /// public ISpanBuilder WithTag(string key, int value) { - this.attributes.Add(new KeyValuePair(key, value)); + this.attributes.Add(key, value); return this; } /// public ISpanBuilder WithTag(string key, double value) { - this.attributes.Add(new KeyValuePair(key, value)); + this.attributes.Add(key, value); return this; } /// public ISpanBuilder WithTag(global::OpenTracing.Tag.BooleanTag tag, bool value) { - Guard.ThrowIfNull(tag?.Key); + Guard.ThrowIfNull(tag); return this.WithTag(tag.Key, value); } /// - public ISpanBuilder WithTag(global::OpenTracing.Tag.IntOrStringTag tag, string value) + public ISpanBuilder WithTag(global::OpenTracing.Tag.IntOrStringTag tag, string? value) { - Guard.ThrowIfNull(tag?.Key); + Guard.ThrowIfNull(tag); - if (int.TryParse(value, out var result)) + if (value != null && int.TryParse(value, out var result)) { return this.WithTag(tag.Key, result); } @@ -268,15 +263,15 @@ public ISpanBuilder WithTag(global::OpenTracing.Tag.IntOrStringTag tag, string v /// public ISpanBuilder WithTag(global::OpenTracing.Tag.IntTag tag, int value) { - Guard.ThrowIfNull(tag?.Key); + Guard.ThrowIfNull(tag); return this.WithTag(tag.Key, value); } /// - public ISpanBuilder WithTag(global::OpenTracing.Tag.StringTag tag, string value) + public ISpanBuilder WithTag(global::OpenTracing.Tag.StringTag tag, string? value) { - Guard.ThrowIfNull(tag?.Key); + Guard.ThrowIfNull(tag); return this.WithTag(tag.Key, value); } diff --git a/src/OpenTelemetry.Shims.OpenTracing/SpanShim.cs b/src/OpenTelemetry.Shims.OpenTracing/SpanShim.cs index 2ab6fee4fe8..c1bde927a1b 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/SpanShim.cs +++ b/src/OpenTelemetry.Shims.OpenTracing/SpanShim.cs @@ -39,7 +39,7 @@ public SpanShim(TelemetrySpan span) /// public ISpanContext Context => this.spanContextShim; - public TelemetrySpan Span { get; private set; } + public TelemetrySpan Span { get; } /// public void Finish() @@ -54,7 +54,7 @@ public void Finish(DateTimeOffset finishTimestamp) } /// - public string GetBaggageItem(string key) + public string? GetBaggageItem(string key) => Baggage.GetBaggage(key); /// @@ -137,7 +137,7 @@ public ISpan Log(DateTimeOffset timestamp, string @event) } /// - public ISpan SetBaggageItem(string key, string value) + public ISpan SetBaggageItem(string key, string? value) { Baggage.SetBaggage(key, value); return this; @@ -153,7 +153,7 @@ public ISpan SetOperationName(string operationName) } /// - public ISpan SetTag(string key, string value) + public ISpan SetTag(string key, string? value) { Guard.ThrowIfNull(key); @@ -201,30 +201,38 @@ public ISpan SetTag(string key, double value) /// public ISpan SetTag(global::OpenTracing.Tag.BooleanTag tag, bool value) { - return this.SetTag(tag?.Key, value); + Guard.ThrowIfNull(tag); + + return this.SetTag(tag.Key, value); } /// - public ISpan SetTag(global::OpenTracing.Tag.IntOrStringTag tag, string value) + public ISpan SetTag(global::OpenTracing.Tag.IntOrStringTag tag, string? value) { - if (int.TryParse(value, out var result)) + Guard.ThrowIfNull(tag); + + if (value != null && int.TryParse(value, out var result)) { - return this.SetTag(tag?.Key, result); + return this.SetTag(tag.Key, result); } - return this.SetTag(tag?.Key, value); + return this.SetTag(tag.Key, value); } /// public ISpan SetTag(global::OpenTracing.Tag.IntTag tag, int value) { - return this.SetTag(tag?.Key, value); + Guard.ThrowIfNull(tag); + + return this.SetTag(tag.Key, value); } /// - public ISpan SetTag(global::OpenTracing.Tag.StringTag tag, string value) + public ISpan SetTag(global::OpenTracing.Tag.StringTag tag, string? value) { - return this.SetTag(tag?.Key, value); + Guard.ThrowIfNull(tag); + + return this.SetTag(tag.Key, value); } /// @@ -234,7 +242,7 @@ public ISpan SetTag(global::OpenTracing.Tag.StringTag tag, string value) /// A 2-Tuple containing the event name and payload information. private static Tuple> ConvertToEventPayload(IEnumerable> fields) { - string eventName = null; + string? eventName = null; var attributes = new Dictionary(); foreach (var field in fields) @@ -268,7 +276,7 @@ private static Tuple> ConvertToEventPayload( else { // TODO should we completely ignore unsupported types? - attributes.Add(field.Key, field.Value.ToString()); + attributes.Add(field.Key, field.Value.ToString()!); } } diff --git a/src/OpenTelemetry.Shims.OpenTracing/TracerShim.cs b/src/OpenTelemetry.Shims.OpenTracing/TracerShim.cs index 3ed448da945..504b28c5a52 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/TracerShim.cs +++ b/src/OpenTelemetry.Shims.OpenTracing/TracerShim.cs @@ -14,7 +14,7 @@ namespace OpenTelemetry.Shims.OpenTracing; public class TracerShim : global::OpenTracing.ITracer { private readonly Trace.Tracer tracer; - private readonly TextMapPropagator definedPropagator; + private readonly TextMapPropagator? definedPropagator; /// /// Initializes a new instance of the class. @@ -30,7 +30,7 @@ public TracerShim(Trace.TracerProvider tracerProvider) /// /// . /// . - public TracerShim(Trace.TracerProvider tracerProvider, TextMapPropagator textFormat) + public TracerShim(Trace.TracerProvider tracerProvider, TextMapPropagator? textFormat) { Guard.ThrowIfNull(tracerProvider); @@ -46,7 +46,7 @@ public TracerShim(Trace.TracerProvider tracerProvider, TextMapPropagator textFor public global::OpenTracing.IScopeManager ScopeManager { get; } /// - public global::OpenTracing.ISpan ActiveSpan => this.ScopeManager.Active?.Span; + public global::OpenTracing.ISpan? ActiveSpan => this.ScopeManager.Active?.Span; private TextMapPropagator Propagator { @@ -63,7 +63,7 @@ private TextMapPropagator Propagator } /// - public global::OpenTracing.ISpanContext Extract(IFormat format, TCarrier carrier) + public global::OpenTracing.ISpanContext? Extract(IFormat format, TCarrier carrier) { Guard.ThrowIfNull(format); Guard.ThrowIfNull(carrier); @@ -79,7 +79,7 @@ private TextMapPropagator Propagator carrierMap.Add(entry.Key, new[] { entry.Value }); } - static IEnumerable GetCarrierKeyValue(Dictionary> source, string key) + static IEnumerable? GetCarrierKeyValue(Dictionary> source, string key) { if (key == null || !source.TryGetValue(key, out var value)) { diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/OpenTelemetry.Instrumentation.W3cTraceContext.Tests.csproj b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/OpenTelemetry.Instrumentation.W3cTraceContext.Tests.csproj index 8d9e8800c51..fb9e640731f 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/OpenTelemetry.Instrumentation.W3cTraceContext.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/OpenTelemetry.Instrumentation.W3cTraceContext.Tests.csproj @@ -3,8 +3,6 @@ Unit test project for OpenTelemetry ASP.NET Core instrumentation for W3C Trace Context Trace $(TargetFrameworksForAspNetCoreTests) - - disable diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs index b80a57f1ced..d557ea71c59 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs @@ -21,7 +21,7 @@ public class W3CTraceContextTests : IDisposable opentelemetry>docker compose --file=test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build */ private const string W3cTraceContextEnvVarName = "OTEL_W3CTRACECONTEXT"; - private static readonly Version AspNetCoreHostingVersion = typeof(Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory).Assembly.GetName().Version; + private static readonly Version? AspNetCoreHostingVersion = typeof(Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory).Assembly.GetName().Version; private readonly HttpClient httpClient = new(); private readonly ITestOutputHelper output; @@ -84,7 +84,7 @@ public void W3CTraceContextTestSuiteAsync(string value) // run the tests with console logger (done automatically by the CI // jobs). - if (AspNetCoreHostingVersion.Major <= 6) + if (AspNetCoreHostingVersion!.Major <= 6) { Assert.StartsWith("FAILED (failures=3)", lastLine); } @@ -137,9 +137,9 @@ private static string ParseLastLine(string output) public class Data { [JsonPropertyName("url")] - public string Url { get; set; } + public string? Url { get; set; } [JsonPropertyName("arguments")] - public Data[] Arguments { get; set; } + public Data[]? Arguments { get; set; } } } diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/IntegrationTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/IntegrationTests.cs index d8f93b2df0c..cb592e8906e 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/IntegrationTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/IntegrationTests.cs @@ -76,7 +76,7 @@ public void WithActivities( } } - var expectedExportedSpans = new string[] + var expectedExportedSpans = new string?[] { childActivitySamplingDecision == SamplingDecision.RecordAndSample ? ChildActivityName : null, shimSamplingDecision == SamplingDecision.RecordAndSample ? ShimActivityName : null, diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj index 430bb7057e2..143e90e7dc4 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj @@ -3,8 +3,6 @@ Unit test project for OpenTelemetry.Shims.OpenTracing $(TargetFrameworksForTests) $(DefineConstants);BUILDING_USING_PROJECTS - - disable diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/ScopeManagerShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/ScopeManagerShimTests.cs index 6f4ca876c55..0e24b2b1673 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/ScopeManagerShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/ScopeManagerShimTests.cs @@ -33,6 +33,7 @@ public void Active_IsNotNull() Assert.NotNull(scope); var activeScope = shim.Active; + Assert.NotNull(activeScope); Assert.Equal(scope.Span.Context.SpanId, activeScope.Span.Context.SpanId); openTracingSpan.Finish(); } @@ -64,6 +65,7 @@ public void Activate() #endif spanShim.Finish(); + Assert.NotNull(spanShim.Span.Activity); Assert.NotEqual(default, spanShim.Span.Activity.Duration); } } diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs index a3a58facfd9..b99bcb2f890 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs @@ -18,8 +18,8 @@ public class SpanBuilderShimTests public void CtorArgumentValidation() { var tracer = TracerProvider.Default.GetTracer(TracerName); - Assert.Throws(() => new SpanBuilderShim(null, "foo")); - Assert.Throws(() => new SpanBuilderShim(tracer, null)); + Assert.Throws(() => new SpanBuilderShim(null!, "foo")); + Assert.Throws(() => new SpanBuilderShim(tracer, null!)); } [Fact] @@ -36,7 +36,7 @@ public void IgnoreActiveSpan() // build var spanShim = (SpanShim)shim.Start(); - + Assert.NotNull(spanShim.Span.Activity); Assert.Equal("foo", spanShim.Span.Activity.OperationName); } @@ -51,7 +51,7 @@ public void StartWithExplicitTimestamp() // build var spanShim = (SpanShim)shim.Start(); - + Assert.NotNull(spanShim.Span.Activity); Assert.Equal(startTimestamp, spanShim.Span.Activity.StartTimeUtc); } @@ -62,11 +62,12 @@ public void AsChildOf_WithNullSpan() var shim = new SpanBuilderShim(tracer, "foo"); // Add a null parent - shim.AsChildOf((global::OpenTracing.ISpan)null); + shim.AsChildOf((global::OpenTracing.ISpan?)null); // build var spanShim = (SpanShim)shim.Start(); + Assert.NotNull(spanShim.Span.Activity); Assert.Equal("foo", spanShim.Span.Activity.OperationName); Assert.Null(spanShim.Span.Activity.Parent); } @@ -84,6 +85,7 @@ public void AsChildOf_WithSpan() // build var spanShim = (SpanShim)shim.Start(); + Assert.NotNull(spanShim.Span.Activity); Assert.Equal("foo", spanShim.Span.Activity.OperationName); Assert.NotNull(spanShim.Span.Activity.ParentId); } @@ -101,12 +103,14 @@ public void Start_ActivityOperationRootSpanChecks() var shim = new SpanBuilderShim(tracer, "foo"); var spanShim1 = (SpanShim)shim.Start(); + Assert.NotNull(spanShim1.Span.Activity); Assert.Equal("foo", spanShim1.Span.Activity.OperationName); // mis-matched root operation name shim = new SpanBuilderShim(tracer, "foo"); var spanShim2 = (SpanShim)shim.Start(); + Assert.NotNull(spanShim2.Span.Activity); Assert.Equal("foo", spanShim2.Span.Activity.OperationName); Assert.Equal(spanShim1.Context.TraceId, spanShim2.Context.TraceId); } @@ -126,6 +130,7 @@ public void AsChildOf_MultipleCallsWithSpan() // build var spanShim = (SpanShim)shim.Start(); + Assert.NotNull(spanShim.Span.Activity); Assert.Equal("foo", spanShim.Span.Activity.OperationName); Assert.Contains(spanShim.Context.TraceId, spanShim.Span.Activity.TraceId.ToHexString()); @@ -139,12 +144,13 @@ public void AsChildOf_WithNullSpanContext() var shim = new SpanBuilderShim(tracer, "foo"); // Add a null parent - shim.AsChildOf((global::OpenTracing.ISpanContext)null); + shim.AsChildOf((global::OpenTracing.ISpanContext?)null); // build var spanShim = (SpanShim)shim.Start(); // should be no parent. + Assert.NotNull(spanShim.Span.Activity); Assert.Null(spanShim.Span.Activity.Parent); } @@ -161,6 +167,7 @@ public void AsChildOfWithSpanContext() // build var spanShim = (SpanShim)shim.Start(); + Assert.NotNull(spanShim.Span.Activity); Assert.NotNull(spanShim.Span.Activity.ParentId); } @@ -182,7 +189,7 @@ public void AsChildOf_MultipleCallsWithSpanContext() // build var spanShim = (SpanShim)shim.Start(); - + Assert.NotNull(spanShim.Span.Activity); Assert.Equal("foo", spanShim.Span.Activity.OperationName); Assert.Contains(spanContext1.TraceId, spanShim.Span.Activity.ParentId); Assert.Equal(spanContext2.SpanId, spanShim.Span.Activity.Links.First().Context.SpanId.ToHexString()); @@ -200,6 +207,7 @@ public void WithTag_KeyIsSpanKindStringValue() var spanShim = (SpanShim)shim.Start(); // Not an attribute + Assert.NotNull(spanShim.Span.Activity); Assert.Empty(spanShim.Span.Activity.Tags); Assert.Equal("foo", spanShim.Span.Activity.OperationName); Assert.Equal(ActivityKind.Client, spanShim.Span.Activity.Kind); @@ -217,6 +225,7 @@ public void WithTag_KeyIsErrorStringValue() var spanShim = (SpanShim)shim.Start(); // Legacy span status tag should be set + Assert.NotNull(spanShim.Span.Activity); Assert.Equal("ERROR", spanShim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) @@ -236,17 +245,18 @@ public void WithTag_KeyIsNullStringValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanBuilderShim(tracer, "foo"); - shim.WithTag((string)null, "unused"); + shim.WithTag((string)null!, "unused"); // build var spanShim = (SpanShim)shim.Start(); // Null key was ignored + Assert.NotNull(spanShim.Span.Activity); Assert.Empty(spanShim.Span.Activity.Tags); } [Fact] - public void WithTag_ValueIsNullStringValue() + public void WithTag_ValueIsIgnoredWhenNull() { var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanBuilderShim(tracer, "foo"); @@ -257,8 +267,8 @@ public void WithTag_ValueIsNullStringValue() var spanShim = (SpanShim)shim.Start(); // Null value was turned into string.empty - Assert.Equal("foo", spanShim.Span.Activity.Tags.First().Key); - Assert.Equal(string.Empty, spanShim.Span.Activity.Tags.First().Value); + Assert.NotNull(spanShim.Span.Activity); + Assert.Empty(spanShim.Span.Activity.TagObjects); } [Fact] @@ -273,8 +283,8 @@ public void WithTag_KeyIsErrorBoolValue() var spanShim = (SpanShim)shim.Start(); // Legacy span status tag should be set + Assert.NotNull(spanShim.Span.Activity); Assert.Equal("ERROR", spanShim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); - if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) { // Activity status code should also be set @@ -304,7 +314,8 @@ public void WithTag_VariousValueTypes() var spanShim = (SpanShim)shim.Start(); // Just verify the count - Assert.Equal(7, spanShim.Span.Activity.Tags.Count()); + Assert.NotNull(spanShim.Span.Activity); + Assert.Equal(7, spanShim.Span.Activity.TagObjects.Count()); } [Fact] @@ -319,6 +330,7 @@ public void Start() // Just check the return value is a SpanShim and that the underlying OpenTelemetry Span. // There is nothing left to verify because the rest of the tests were already calling .Start() prior to verification. Assert.NotNull(span); + Assert.NotNull(span.Span.Activity); Assert.Equal("foo", span.Span.Activity.OperationName); } @@ -337,6 +349,7 @@ public void Start_UnderAspNetCoreInstrumentation() Assert.NotNull(spanShim); var telemetrySpan = spanShim.Span; + Assert.NotNull(telemetrySpan.Activity); Assert.Same(telemetrySpan.Activity, Activity.Current); Assert.Same(parentSpan, telemetrySpan.Activity.Parent); diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs index 9911d9f76fc..66e8b63652b 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs @@ -17,7 +17,7 @@ public class SpanShimTests [Fact] public void CtorArgumentValidation() { - Assert.Throws(() => new SpanShim(null)); + Assert.Throws(() => new SpanShim(null!)); } [Fact] @@ -35,9 +35,9 @@ public void FinishSpan() { var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - shim.Finish(); + Assert.NotNull(shim.Span.Activity); Assert.NotEqual(default, shim.Span.Activity.Duration); } @@ -58,7 +58,7 @@ public void FinishSpanUsingSpecificTimestamp() var endTime = DateTimeOffset.UtcNow; shim.Finish(endTime); - Assert.Equal(endTime - shim.Span.Activity.StartTimeUtc, shim.Span.Activity.Duration); + Assert.Equal(endTime - shim.Span.Activity!.StartTimeUtc, shim.Span.Activity.Duration); } [Fact] @@ -68,10 +68,10 @@ public void SetOperationName() var shim = new SpanShim(tracer.StartSpan(SpanName)); // parameter validation - Assert.Throws(() => shim.SetOperationName(null)); + Assert.Throws(() => shim.SetOperationName(null!)); shim.SetOperationName("bar"); - Assert.Equal("bar", shim.Span.Activity.DisplayName); + Assert.Equal("bar", shim.Span.Activity!.DisplayName); } [Fact] @@ -81,7 +81,7 @@ public void GetBaggageItem() var shim = new SpanShim(tracer.StartSpan(SpanName)); // parameter validation - Assert.Throws(() => shim.GetBaggageItem(null)); + Assert.Throws(() => shim.GetBaggageItem(null!)); // TODO - Method not implemented } @@ -94,8 +94,8 @@ public void Log() shim.Log("foo"); - Assert.Single(shim.Span.Activity.Events); - var first = shim.Span.Activity.Events.First(); + Assert.NotNull(shim.Span.Activity); + var first = Assert.Single(shim.Span.Activity.Events); Assert.Equal("foo", first.Name); Assert.False(first.Tags.Any()); } @@ -109,8 +109,8 @@ public void LogWithExplicitTimestamp() var now = DateTimeOffset.UtcNow; shim.Log(now, "foo"); - Assert.Single(shim.Span.Activity.Events); - var first = shim.Span.Activity.Events.First(); + Assert.NotNull(shim.Span.Activity); + var first = Assert.Single(shim.Span.Activity.Events); Assert.Equal("foo", first.Name); Assert.Equal(now, first.Timestamp); Assert.False(first.Tags.Any()); @@ -122,19 +122,21 @@ public void LogUsingFields() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.Log((IEnumerable>)null)); + Assert.Throws(() => shim.Log((IEnumerable>)null!)); shim.Log(new List> { - new KeyValuePair("foo", "bar"), + new("foo", "bar"), }); // "event" is a special event name shim.Log(new List> { - new KeyValuePair("event", "foo"), + new("event", "foo"), }); + Assert.NotNull(shim.Span.Activity); + var first = shim.Span.Activity.Events.FirstOrDefault(); var last = shim.Span.Activity.Events.LastOrDefault(); @@ -153,20 +155,21 @@ public void LogUsingFieldsWithExplicitTimestamp() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.Log((IEnumerable>)null)); + Assert.Throws(() => shim.Log((IEnumerable>)null!)); var now = DateTimeOffset.UtcNow; shim.Log(now, new List> { - new KeyValuePair("foo", "bar"), + new("foo", "bar"), }); // "event" is a special event name shim.Log(now, new List> { - new KeyValuePair("event", "foo"), + new("event", "foo"), }); + Assert.NotNull(shim.Span.Activity); Assert.Equal(2, shim.Span.Activity.Events.Count()); var first = shim.Span.Activity.Events.First(); var last = shim.Span.Activity.Events.Last(); @@ -186,13 +189,14 @@ public void SetTagStringValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.SetTag((string)null, "foo")); + Assert.Throws(() => shim.SetTag((string)null!, "foo")); shim.SetTag("foo", "bar"); - Assert.Single(shim.Span.Activity.Tags); - Assert.Equal("foo", shim.Span.Activity.Tags.First().Key); - Assert.Equal("bar", shim.Span.Activity.Tags.First().Value); + Assert.NotNull(shim.Span.Activity); + var first = Assert.Single(shim.Span.Activity.Tags); + Assert.Equal("foo", first.Key); + Assert.Equal("bar", first.Value); } [Fact] @@ -201,13 +205,16 @@ public void SetTagBoolValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.SetTag((string)null, true)); + Assert.Throws(() => shim.SetTag((string)null!, true)); shim.SetTag("foo", true); shim.SetTag(Tags.Error.Key, true); - Assert.Equal("foo", shim.Span.Activity.TagObjects.First().Key); - Assert.True((bool)shim.Span.Activity.TagObjects.First().Value); + Assert.NotNull(shim.Span.Activity); + var first = shim.Span.Activity.TagObjects.First(); + Assert.Equal("foo", first.Key); + Assert.NotNull(first.Value); + Assert.True((bool)first.Value); // A boolean tag named "error" is a special case that must be checked @@ -246,13 +253,14 @@ public void SetTagIntValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.SetTag((string)null, 1)); + Assert.Throws(() => shim.SetTag((string)null!, 1)); shim.SetTag("foo", 1); + Assert.NotNull(shim.Span.Activity); Assert.Single(shim.Span.Activity.TagObjects); Assert.Equal("foo", shim.Span.Activity.TagObjects.First().Key); - Assert.Equal(1L, (int)shim.Span.Activity.TagObjects.First().Value); + Assert.Equal(1L, (int)shim.Span.Activity.TagObjects.First().Value!); } [Fact] @@ -261,13 +269,15 @@ public void SetTagDoubleValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.SetTag(null, 1D)); + Assert.Throws(() => shim.SetTag(null!, 1D)); shim.SetTag("foo", 1D); - Assert.Single(shim.Span.Activity.TagObjects); - Assert.Equal("foo", shim.Span.Activity.TagObjects.First().Key); - Assert.Equal(1, (double)shim.Span.Activity.TagObjects.First().Value); + Assert.NotNull(shim.Span.Activity); + var first = Assert.Single(shim.Span.Activity.TagObjects); + Assert.Equal("foo", first.Key); + Assert.NotNull(first.Value); + Assert.Equal(1, (double)first.Value); } [Fact] @@ -276,13 +286,14 @@ public void SetTagStringTagValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.SetTag((StringTag)null, "foo")); + Assert.Throws(() => shim.SetTag((StringTag)null!, "foo")); shim.SetTag(new StringTag("foo"), "bar"); - Assert.Single(shim.Span.Activity.Tags); - Assert.Equal("foo", shim.Span.Activity.Tags.First().Key); - Assert.Equal("bar", shim.Span.Activity.Tags.First().Value); + Assert.NotNull(shim.Span.Activity); + var first = Assert.Single(shim.Span.Activity.Tags); + Assert.Equal("foo", first.Key); + Assert.Equal("bar", first.Value); } [Fact] @@ -291,13 +302,15 @@ public void SetTagIntTagValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.SetTag((IntTag)null, 1)); + Assert.Throws(() => shim.SetTag((IntTag)null!, 1)); shim.SetTag(new IntTag("foo"), 1); - Assert.Single(shim.Span.Activity.TagObjects); - Assert.Equal("foo", shim.Span.Activity.TagObjects.First().Key); - Assert.Equal(1L, (int)shim.Span.Activity.TagObjects.First().Value); + Assert.NotNull(shim.Span.Activity); + var first = Assert.Single(shim.Span.Activity.TagObjects); + Assert.Equal("foo", first.Key); + Assert.NotNull(first.Value); + Assert.Equal(1L, (int)first.Value); } [Fact] @@ -306,17 +319,21 @@ public void SetTagIntOrStringTagValue() var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new SpanShim(tracer.StartSpan(SpanName)); - Assert.Throws(() => shim.SetTag((IntOrStringTag)null, "foo")); + Assert.Throws(() => shim.SetTag((IntOrStringTag)null!, "foo")); shim.SetTag(new IntOrStringTag("foo"), 1); shim.SetTag(new IntOrStringTag("bar"), "baz"); + Assert.NotNull(shim.Span.Activity); Assert.Equal(2, shim.Span.Activity.TagObjects.Count()); - Assert.Equal("foo", shim.Span.Activity.TagObjects.First().Key); - Assert.Equal(1L, (int)shim.Span.Activity.TagObjects.First().Value); + var first = shim.Span.Activity.TagObjects.First(); + Assert.Equal("foo", first.Key); + Assert.NotNull(first.Value); + Assert.Equal(1L, (int)first.Value); - Assert.Equal("bar", shim.Span.Activity.TagObjects.Last().Key); - Assert.Equal("baz", shim.Span.Activity.TagObjects.Last().Value); + var second = shim.Span.Activity.TagObjects.Last(); + Assert.Equal("bar", second.Key); + Assert.Equal("baz", second.Value); } } diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/TracerShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/TracerShimTests.cs index 578ed8ccbf3..64f08959424 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/TracerShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/TracerShimTests.cs @@ -17,10 +17,10 @@ public class TracerShimTests public void CtorArgumentValidation() { // null tracer provider and text format - Assert.Throws(() => new TracerShim(null, null)); + Assert.Throws(() => new TracerShim(null!, null)); // null tracer provider - Assert.Throws(() => new TracerShim(null, new TraceContextPropagator())); + Assert.Throws(() => new TracerShim(null!, new TraceContextPropagator())); } [Fact] @@ -50,10 +50,10 @@ public void Inject_ArgumentValidation() var testFormat = new TestFormatTextMap(); var testCarrier = new TestTextMap(); - Assert.Throws(() => shim.Inject(null, testFormat, testCarrier)); + Assert.Throws(() => shim.Inject(null!, testFormat, testCarrier)); Assert.Throws(() => shim.Inject(new TestSpanContext(), testFormat, testCarrier)); - Assert.Throws(() => shim.Inject(spanContextShim, null, testCarrier)); - Assert.Throws(() => shim.Inject(spanContextShim, testFormat, null)); + Assert.Throws(() => shim.Inject(spanContextShim, null!, testCarrier)); + Assert.Throws(() => shim.Inject(spanContextShim, testFormat!, null)); } [Fact] @@ -76,8 +76,8 @@ public void Extract_ArgumentValidation() { var shim = new TracerShim(TracerProvider.Default, new TraceContextPropagator()); - Assert.Throws(() => shim.Extract(null, new TestTextMap())); - Assert.Throws(() => shim.Extract(new TestFormatTextMap(), null)); + Assert.Throws(() => shim.Extract(null!, new TestTextMap())); + Assert.Throws(() => shim.Extract(new TestFormatTextMap()!, null)); } [Fact] @@ -129,7 +129,7 @@ public void InjectExtract_TextMap_Ok() // then extract var extractedSpanContext = shim.Extract(BuiltinFormats.TextMap, carrier); - AssertOpenTracerSpanContextEqual(spanContextShim, extractedSpanContext); + AssertOpenTracerSpanContextEqual(spanContextShim, extractedSpanContext!); } private static void AssertOpenTracerSpanContextEqual(ISpanContext source, ISpanContext target) From 6e1b5ab577e092dd1a4577b43388079b0cae4597 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 19 Sep 2024 13:14:57 -0700 Subject: [PATCH 079/133] [api] Baggage nullable annotations (#5840) --- .../.publicApi/Stable/PublicAPI.Shipped.txt | 30 +++++++++---------- src/OpenTelemetry.Api/Baggage.cs | 30 ++++++++++--------- .../Context/Propagation/BaggagePropagator.cs | 2 +- test/OpenTelemetry.Api.Tests/BaggageTests.cs | 28 +++++++++-------- 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt index 46b63e18fee..cd5c445997e 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt @@ -1,11 +1,4 @@ #nullable enable -~OpenTelemetry.Baggage.GetBaggage() -> System.Collections.Generic.IReadOnlyDictionary -~OpenTelemetry.Baggage.GetBaggage(string name) -> string -~OpenTelemetry.Baggage.GetEnumerator() -> System.Collections.Generic.Dictionary.Enumerator -~OpenTelemetry.Baggage.RemoveBaggage(string name) -> OpenTelemetry.Baggage -~OpenTelemetry.Baggage.SetBaggage(params System.Collections.Generic.KeyValuePair[] baggageItems) -> OpenTelemetry.Baggage -~OpenTelemetry.Baggage.SetBaggage(string name, string value) -> OpenTelemetry.Baggage -~OpenTelemetry.Baggage.SetBaggage(System.Collections.Generic.IEnumerable> baggageItems) -> OpenTelemetry.Baggage ~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.AsyncLocalRuntimeContextSlot(string name) -> void ~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Value.get -> object ~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Value.set -> void @@ -16,14 +9,6 @@ ~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.ThreadLocalRuntimeContextSlot(string name) -> void ~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.get -> object ~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.set -> void -~override OpenTelemetry.Baggage.Equals(object obj) -> bool -~static OpenTelemetry.Baggage.Create(System.Collections.Generic.Dictionary baggageItems = null) -> OpenTelemetry.Baggage -~static OpenTelemetry.Baggage.GetBaggage(OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> System.Collections.Generic.IReadOnlyDictionary -~static OpenTelemetry.Baggage.GetBaggage(string name, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> string -~static OpenTelemetry.Baggage.GetEnumerator(OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> System.Collections.Generic.Dictionary.Enumerator -~static OpenTelemetry.Baggage.RemoveBaggage(string name, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage -~static OpenTelemetry.Baggage.SetBaggage(string name, string value, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage -~static OpenTelemetry.Baggage.SetBaggage(System.Collections.Generic.IEnumerable> baggageItems, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage ~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.get -> System.Type ~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.set -> void ~static OpenTelemetry.Context.RuntimeContext.GetSlot(string slotName) -> OpenTelemetry.Context.RuntimeContextSlot @@ -49,6 +34,13 @@ OpenTelemetry.Baggage.Baggage() -> void OpenTelemetry.Baggage.ClearBaggage() -> OpenTelemetry.Baggage OpenTelemetry.Baggage.Count.get -> int OpenTelemetry.Baggage.Equals(OpenTelemetry.Baggage other) -> bool +OpenTelemetry.Baggage.GetBaggage() -> System.Collections.Generic.IReadOnlyDictionary! +OpenTelemetry.Baggage.GetBaggage(string! name) -> string? +OpenTelemetry.Baggage.GetEnumerator() -> System.Collections.Generic.Dictionary.Enumerator +OpenTelemetry.Baggage.RemoveBaggage(string! name) -> OpenTelemetry.Baggage +OpenTelemetry.Baggage.SetBaggage(params System.Collections.Generic.KeyValuePair[]! baggageItems) -> OpenTelemetry.Baggage +OpenTelemetry.Baggage.SetBaggage(string! name, string? value) -> OpenTelemetry.Baggage +OpenTelemetry.Baggage.SetBaggage(System.Collections.Generic.IEnumerable>! baggageItems) -> OpenTelemetry.Baggage OpenTelemetry.BaseProvider OpenTelemetry.BaseProvider.~BaseProvider() -> void OpenTelemetry.BaseProvider.BaseProvider() -> void @@ -171,6 +163,7 @@ OpenTelemetry.Trace.TracerProvider.GetTracer(string! name, string? version = nul OpenTelemetry.Trace.TracerProvider.TracerProvider() -> void OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.TracerProviderBuilder.TracerProviderBuilder() -> void +override OpenTelemetry.Baggage.Equals(object? obj) -> bool override OpenTelemetry.Baggage.GetHashCode() -> int override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Get() -> T override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Set(T value) -> void @@ -201,10 +194,17 @@ override OpenTelemetry.Trace.Status.ToString() -> string! override OpenTelemetry.Trace.TracerProvider.Dispose(bool disposing) -> void static OpenTelemetry.ActivityContextExtensions.IsValid(this System.Diagnostics.ActivityContext ctx) -> bool static OpenTelemetry.Baggage.ClearBaggage(OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage +static OpenTelemetry.Baggage.Create(System.Collections.Generic.Dictionary? baggageItems = null) -> OpenTelemetry.Baggage static OpenTelemetry.Baggage.Current.get -> OpenTelemetry.Baggage static OpenTelemetry.Baggage.Current.set -> void +static OpenTelemetry.Baggage.GetBaggage(OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> System.Collections.Generic.IReadOnlyDictionary! +static OpenTelemetry.Baggage.GetBaggage(string! name, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> string? +static OpenTelemetry.Baggage.GetEnumerator(OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> System.Collections.Generic.Dictionary.Enumerator static OpenTelemetry.Baggage.operator !=(OpenTelemetry.Baggage left, OpenTelemetry.Baggage right) -> bool static OpenTelemetry.Baggage.operator ==(OpenTelemetry.Baggage left, OpenTelemetry.Baggage right) -> bool +static OpenTelemetry.Baggage.RemoveBaggage(string! name, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage +static OpenTelemetry.Baggage.SetBaggage(string! name, string? value, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage +static OpenTelemetry.Baggage.SetBaggage(System.Collections.Generic.IEnumerable>! baggageItems, OpenTelemetry.Baggage baggage = default(OpenTelemetry.Baggage)) -> OpenTelemetry.Baggage static OpenTelemetry.Context.Propagation.PropagationContext.operator !=(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator ==(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool static OpenTelemetry.Context.Propagation.Propagators.DefaultTextMapPropagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator! diff --git a/src/OpenTelemetry.Api/Baggage.cs b/src/OpenTelemetry.Api/Baggage.cs index 46cdedbd7d1..835cb3a23f6 100644 --- a/src/OpenTelemetry.Api/Baggage.cs +++ b/src/OpenTelemetry.Api/Baggage.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Context; using OpenTelemetry.Internal; @@ -87,7 +89,7 @@ public static Baggage Current /// /// Baggage key/value pairs. /// . - public static Baggage Create(Dictionary baggageItems = null) + public static Baggage Create(Dictionary? baggageItems = null) { if (baggageItems == null) { @@ -133,7 +135,7 @@ public static Dictionary.Enumerator GetEnumerator(Baggage baggag /// Optional . is used if not specified. /// Baggage item or if nothing was found. [SuppressMessage("roslyn", "RS0026", Justification = "TODO: fix APIs that violate the backcompt requirement - multiple overloads with optional parameters: https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md.")] - public static string GetBaggage(string name, Baggage baggage = default) + public static string? GetBaggage(string name, Baggage baggage = default) => baggage == default ? Current.GetBaggage(name) : baggage.GetBaggage(name); /// @@ -145,7 +147,7 @@ public static string GetBaggage(string name, Baggage baggage = default) /// New containing the key/value pair. /// Note: The returned will be set as the new instance. [SuppressMessage("roslyn", "RS0026", Justification = "TODO: fix APIs that violate the backcompt requirement - multiple overloads with optional parameters: https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md.")] - public static Baggage SetBaggage(string name, string value, Baggage baggage = default) + public static Baggage SetBaggage(string name, string? value, Baggage baggage = default) { var baggageHolder = EnsureBaggageHolder(); lock (baggageHolder) @@ -164,7 +166,7 @@ public static Baggage SetBaggage(string name, string value, Baggage baggage = de /// New containing the new key/value pairs. /// Note: The returned will be set as the new instance. [SuppressMessage("roslyn", "RS0026", Justification = "TODO: fix APIs that violate the backcompt requirement - multiple overloads with optional parameters: https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md.")] - public static Baggage SetBaggage(IEnumerable> baggageItems, Baggage baggage = default) + public static Baggage SetBaggage(IEnumerable> baggageItems, Baggage baggage = default) { var baggageHolder = EnsureBaggageHolder(); lock (baggageHolder) @@ -222,11 +224,11 @@ public IReadOnlyDictionary GetBaggage() /// /// Baggage item name. /// Baggage item or if nothing was found. - public string GetBaggage(string name) + public string? GetBaggage(string name) { Guard.ThrowIfNullOrEmpty(name); - return this.baggage != null && this.baggage.TryGetValue(name, out string value) + return this.baggage != null && this.baggage.TryGetValue(name, out string? value) ? value : null; } @@ -237,7 +239,7 @@ public string GetBaggage(string name) /// Baggage item name. /// Baggage item value. /// New containing the key/value pair. - public Baggage SetBaggage(string name, string value) + public Baggage SetBaggage(string name, string? value) { if (string.IsNullOrEmpty(value)) { @@ -247,7 +249,7 @@ public Baggage SetBaggage(string name, string value) return new Baggage( new Dictionary(this.baggage ?? EmptyBaggage, StringComparer.OrdinalIgnoreCase) { - [name] = value, + [name] = value!, }); } @@ -256,15 +258,15 @@ public Baggage SetBaggage(string name, string value) /// /// Baggage key/value pairs. /// New containing the key/value pairs. - public Baggage SetBaggage(params KeyValuePair[] baggageItems) - => this.SetBaggage((IEnumerable>)baggageItems); + public Baggage SetBaggage(params KeyValuePair[] baggageItems) + => this.SetBaggage((IEnumerable>)baggageItems); /// /// Returns a new which contains the new key/value pairs. /// /// Baggage key/value pairs. /// New containing the key/value pairs. - public Baggage SetBaggage(IEnumerable> baggageItems) + public Baggage SetBaggage(IEnumerable> baggageItems) { if (baggageItems?.Any() != true) { @@ -281,7 +283,7 @@ public Baggage SetBaggage(IEnumerable> baggageItems } else { - newBaggage[item.Key] = item.Value; + newBaggage[item.Key] = item.Value!; } } @@ -325,11 +327,11 @@ public bool Equals(Baggage other) return false; } - return baggageIsNullOrEmpty || this.baggage.SequenceEqual(other.baggage); + return baggageIsNullOrEmpty || this.baggage!.SequenceEqual(other.baggage!); } /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => (obj is Baggage baggage) && this.Equals(baggage); /// diff --git a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs index 17bbf13110b..e3ca4fd96c9 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs @@ -56,7 +56,7 @@ public override PropagationContext Extract(PropagationContext context, T carr { if (TryExtractBaggage(baggageCollection.ToArray(), out var baggage)) { - return new PropagationContext(context.ActivityContext, new Baggage(baggage)); + return new PropagationContext(context.ActivityContext, new Baggage(baggage!)); } } diff --git a/test/OpenTelemetry.Api.Tests/BaggageTests.cs b/test/OpenTelemetry.Api.Tests/BaggageTests.cs index e13aa68a502..32bc6a74f62 100644 --- a/test/OpenTelemetry.Api.Tests/BaggageTests.cs +++ b/test/OpenTelemetry.Api.Tests/BaggageTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Xunit; namespace OpenTelemetry.Tests; @@ -27,8 +29,8 @@ public void SetAndGetTest() { var list = new List>(2) { - new KeyValuePair(K1, V1), - new KeyValuePair(K2, V2), + new(K1, V1), + new(K2, V2), }; Baggage.SetBaggage(K1, V1); @@ -44,7 +46,7 @@ public void SetAndGetTest() Assert.Null(Baggage.GetBaggage("NO_KEY")); Assert.Equal(V2, Baggage.Current.GetBaggage(K2)); - Assert.Throws(() => Baggage.GetBaggage(null)); + Assert.Throws(() => Baggage.GetBaggage(null!)); } [Fact] @@ -52,12 +54,12 @@ public void SetExistingKeyTest() { var list = new List>(2) { - new KeyValuePair(K1, V1), + new(K1, V1), }; - Baggage.Current.SetBaggage(new KeyValuePair(K1, V1)); + Baggage.Current.SetBaggage(new KeyValuePair(K1, V1)); var baggage = Baggage.SetBaggage(K1, V1); - Baggage.SetBaggage(new Dictionary { [K1] = V1 }, baggage); + Baggage.SetBaggage(new Dictionary { [K1] = V1 }, baggage); Assert.Equal(list, Baggage.GetBaggage()); } @@ -78,7 +80,7 @@ public void SetNullValueTest() Assert.Empty(Baggage.SetBaggage(K1, null).GetBaggage()); Baggage.SetBaggage(K1, V1); - Baggage.SetBaggage(new Dictionary + Baggage.SetBaggage(new Dictionary { [K1] = null, [K2] = V2, @@ -94,7 +96,7 @@ public void RemoveTest() var empty2 = Baggage.RemoveBaggage(K1); Assert.True(empty == empty2); - var baggage = Baggage.SetBaggage(new Dictionary + var baggage = Baggage.SetBaggage(new Dictionary { [K1] = V1, [K2] = V2, @@ -112,7 +114,7 @@ public void RemoveTest() [Fact] public void ClearTest() { - var baggage = Baggage.SetBaggage(new Dictionary + var baggage = Baggage.SetBaggage(new Dictionary { [K1] = V1, [K2] = V2, @@ -151,8 +153,8 @@ public void EnumeratorTest() { var list = new List>(2) { - new KeyValuePair(K1, V1), - new KeyValuePair(K2, V2), + new(K1, V1), + new(K2, V2), }; var baggage = Baggage.SetBaggage(K1, V1); @@ -207,7 +209,7 @@ public void CreateBaggageTest() ["key2"] = "value2", ["KEY2"] = "VALUE2", ["KEY3"] = "VALUE3", - ["Key3"] = null, + ["Key3"] = null!, // Note: This causes Key3 to be removed }); Assert.Equal(2, baggage.Count); @@ -232,7 +234,7 @@ public void EqualityTests() baggage = Baggage.SetBaggage(K1, V1); - var baggage2 = Baggage.SetBaggage(null); + var baggage2 = Baggage.SetBaggage(null!); Assert.Equal(baggage, baggage2); From cd01f932a685d8919f288bfa5a136c3d082cc387 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Thu, 19 Sep 2024 17:32:10 -0700 Subject: [PATCH 080/133] [repo] Replace .NET6 target with .NET9 (#5832) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mikel Blanchard Co-authored-by: Piotr Kiełkowicz --- .editorconfig | 38 ++++++++++--------- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/workflows/Component.BuildTest.yml | 4 +- .github/workflows/ci.yml | 4 +- .github/workflows/docfx.yml | 3 ++ .github/workflows/verifyaotcompat.yml | 2 +- CONTRIBUTING.md | 2 +- Directory.Packages.props | 6 +-- OpenTelemetry.sln | 2 +- build/Common.nonprod.props | 2 +- build/Common.prod.props | 7 ++++ build/Common.props | 14 +++---- build/docker-compose.net6.0.yml | 9 ----- build/docker-compose.net8.0.yml | 2 +- build/docker-compose.net9.0.yml | 9 +++++ global.json | 2 +- .../Internal/SelfDiagnosticsConfigParser.cs | 4 +- .../Dockerfile | 6 +-- .../SelfDiagnosticsEventListenerTest.cs | 8 +++- 19 files changed, 73 insertions(+), 53 deletions(-) delete mode 100644 build/docker-compose.net6.0.yml create mode 100644 build/docker-compose.net9.0.yml diff --git a/.editorconfig b/.editorconfig index 5bc89604c76..45d0806a20b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -41,7 +41,7 @@ csharp_indent_labels = flush_left # Modifier preferences csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion # this. preferences dotnet_style_qualification_for_field = true:suggestion @@ -53,8 +53,8 @@ dotnet_style_qualification_for_event = true:suggestion csharp_style_var_for_built_in_types = true:silent csharp_style_var_when_type_is_apparent = true:silent csharp_style_var_elsewhere = true:silent -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion # name all constant fields using PascalCase dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion @@ -75,6 +75,7 @@ dotnet_style_readonly_field = true:suggestion csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion dotnet_style_prefer_simplified_interpolation = true:suggestion dotnet_style_object_initializer = true:suggestion +csharp_style_prefer_primary_constructors = false:none # Expression-level preferences dotnet_style_object_initializer = true:suggestion @@ -82,21 +83,23 @@ dotnet_style_collection_initializer = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion dotnet_style_coalesce_expression = true:suggestion dotnet_style_null_propagation = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:suggestion csharp_prefer_simple_default_expression = true:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:none # Expression-bodied members -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_methods = true:suggestion +dotnet_diagnostic.IDE0022.severity = suggestion # dotnet format doesn't respect the suggestion in the line above +csharp_style_expression_bodied_constructors = false:warning +csharp_style_expression_bodied_operators = true:suggestion +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_expression_bodied_indexers = true:suggestion +csharp_style_expression_bodied_accessors = true:suggestion # Pattern matching csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion @@ -113,6 +116,7 @@ csharp_style_prefer_range_operator = false:none csharp_style_pattern_local_over_anonymous_function = true:suggestion csharp_style_deconstructed_variable_declaration = true:suggestion csharp_style_namespace_declarations = file_scoped:warning +dotnet_style_namespace_match_folder = false:none # Space preferences csharp_space_after_cast = false @@ -128,10 +132,10 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false csharp_space_between_parentheses = false # Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion # Code analyzers # CA1031: Do not catch general exception types diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index baef921968e..d503e982d1f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -48,7 +48,7 @@ body: - type: input attributes: label: Runtime Version - description: What .NET runtime version did you use? (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can find this information from the `*.csproj` file) + description: What .NET runtime version did you use? (e.g. `net462`, `net48`, `net8.0`, etc. You can find this information from the `*.csproj` file) validations: required: true diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index e25352b0854..de7ebb3fc4f 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -24,7 +24,7 @@ on: required: false type: string tfm-list: - default: '[ "net462", "net6.0", "net8.0" ]' + default: '[ "net462", "net8.0", "net9.0" ]' required: false type: string @@ -42,7 +42,7 @@ jobs: - os: otel-linux-arm64 version: net462 - os: otel-linux-arm64 - version: net6.0 + version: net8.0 runs-on: ${{ matrix.os }} steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58eef737fca..73ecbd165ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,7 @@ jobs: strategy: fail-fast: false matrix: - version: [ net6.0, net8.0 ] + version: [ net8.0, net9.0 ] steps: - uses: actions/checkout@v4 - name: Run OTLP Exporter docker compose @@ -129,7 +129,7 @@ jobs: strategy: fail-fast: false matrix: - version: [ net6.0, net8.0 ] + version: [ net8.0, net9.0 ] steps: - uses: actions/checkout@v4 - name: Run W3C Trace Context docker compose diff --git a/.github/workflows/docfx.yml b/.github/workflows/docfx.yml index 4c2031c9303..76ab4f2e1ec 100644 --- a/.github/workflows/docfx.yml +++ b/.github/workflows/docfx.yml @@ -13,6 +13,9 @@ jobs: - name: check out code uses: actions/checkout@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + - name: install docfx run: dotnet tool install -g docfx diff --git a/.github/workflows/verifyaotcompat.yml b/.github/workflows/verifyaotcompat.yml index 24991b9fe3c..3bdc42e3e7f 100644 --- a/.github/workflows/verifyaotcompat.yml +++ b/.github/workflows/verifyaotcompat.yml @@ -12,7 +12,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ ubuntu-latest, windows-latest ] - version: [ net8.0 ] + version: [ net8.0, net9.0 ] runs-on: ${{ matrix.os }} steps: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fda1c81c336..c6b0e6c4fe6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,7 +44,7 @@ You can contribute to this project from a Windows, macOS or Linux machine. On all platforms, the minimum requirements are: * Git client and command line tools. -* .NET 8.0 +* .NET 9.0 ### Linux or MacOS diff --git a/Directory.Packages.props b/Directory.Packages.props index abe3785ad8d..f54bd7353a3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -97,10 +97,10 @@ - - - + + + diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 2cfcf9b1f22..5ca42dd0962 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -31,8 +31,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E build\debug.snk = build\debug.snk Directory.Packages.props = Directory.Packages.props build\docfx.cmd = build\docfx.cmd - build\docker-compose.net6.0.yml = build\docker-compose.net6.0.yml build\docker-compose.net8.0.yml = build\docker-compose.net8.0.yml + build\docker-compose.net9.0.yml = build\docker-compose.net9.0.yml build\GlobalAttrExclusions.txt = build\GlobalAttrExclusions.txt build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetry.prod.loose.ruleset = build\OpenTelemetry.prod.loose.ruleset diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 6de6e014c88..ce99895ccba 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -8,7 +8,7 @@ - net8.0 + net9.0 diff --git a/build/Common.prod.props b/build/Common.prod.props index 9f2c78486c3..1b58605b4d1 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -33,6 +33,13 @@ true + + + + + diff --git a/build/Common.props b/build/Common.props index 7c1f02bdebf..54ecbacfe9b 100644 --- a/build/Common.props +++ b/build/Common.props @@ -28,18 +28,18 @@ net481;net48;net472;net471;net47;net462 - net8.0;net6.0;netstandard2.0;$(NetFrameworkMinimumSupportedVersion) - net8.0;net6.0;netstandard2.1;netstandard2.0;$(NetFrameworkMinimumSupportedVersion) - net8.0;net6.0 + net9.0;net8.0;netstandard2.0;$(NetFrameworkMinimumSupportedVersion) + net9.0;net8.0;netstandard2.1;netstandard2.0;$(NetFrameworkMinimumSupportedVersion) + net9.0;net8.0 - net8.0;net6.0 - net8.0 - net8.0;net6.0 + net9.0;net8.0 + net9.0;net8.0 + net9.0;net8.0 $(TargetFrameworksForDocs);$(NetFrameworkSupportedVersions) - net8.0;net6.0 + net9.0;net8.0 $(TargetFrameworksForTests);$(NetFrameworkMinimumSupportedVersion) diff --git a/build/docker-compose.net6.0.yml b/build/docker-compose.net6.0.yml deleted file mode 100644 index 099f1007277..00000000000 --- a/build/docker-compose.net6.0.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: '3.7' - -services: - tests: - build: - args: - PUBLISH_FRAMEWORK: net6.0 - TEST_SDK_VERSION: "6.0" - BUILD_SDK_VERSION: "8.0" diff --git a/build/docker-compose.net8.0.yml b/build/docker-compose.net8.0.yml index a5ac999e43e..22787bff66e 100644 --- a/build/docker-compose.net8.0.yml +++ b/build/docker-compose.net8.0.yml @@ -6,4 +6,4 @@ services: args: PUBLISH_FRAMEWORK: net8.0 TEST_SDK_VERSION: "8.0" - BUILD_SDK_VERSION: "8.0" + BUILD_SDK_VERSION: "9.0" diff --git a/build/docker-compose.net9.0.yml b/build/docker-compose.net9.0.yml new file mode 100644 index 00000000000..29663b3246c --- /dev/null +++ b/build/docker-compose.net9.0.yml @@ -0,0 +1,9 @@ +version: '3.7' + +services: + tests: + build: + args: + PUBLISH_FRAMEWORK: net9.0 + TEST_SDK_VERSION: "9.0" + BUILD_SDK_VERSION: "9.0" diff --git a/global.json b/global.json index 0aca8b12938..f459bbb82e4 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "rollForward": "latestFeature", - "version": "8.0.100" + "version": "9.0.100-rc.1.24452.12" } } diff --git a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs index 3216c050f7c..751154f8849 100644 --- a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs +++ b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs @@ -66,7 +66,9 @@ public bool TryGetConfiguration( this.configBuffer = buffer; } - file.Read(buffer, 0, buffer.Length); + // TODO: Fix CA2022 - Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' + // Added _ = as a workaround to suppress the warning + _ = file.Read(buffer, 0, buffer.Length); string configJson = Encoding.UTF8.GetString(buffer); if (!TryParseLogDirectory(configJson, out logDirectory)) diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile index 7a8dc6f5705..fc50a196ecf 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile @@ -2,8 +2,8 @@ # This should be run from the root of the repo: # docker build --file test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/Dockerfile . -ARG BUILD_SDK_VERSION=8.0 -ARG TEST_SDK_VERSION=8.0 +ARG BUILD_SDK_VERSION=9.0 +ARG TEST_SDK_VERSION=9.0 FROM ubuntu AS w3c #Install git @@ -13,7 +13,7 @@ RUN git clone --branch level-1 https://github.com/w3c/trace-context.git FROM mcr.microsoft.com/dotnet/sdk:${BUILD_SDK_VERSION} AS build ARG PUBLISH_CONFIGURATION=Release -ARG PUBLISH_FRAMEWORK=net8.0 +ARG PUBLISH_FRAMEWORK=net9.0 WORKDIR /repo COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests" diff --git a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs index 58777971b5d..3ea7ae3bf7a 100644 --- a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs +++ b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs @@ -124,7 +124,9 @@ public void SelfDiagnosticsEventListener_EmitEvent_OmitAsConfigured() using FileStream file = File.Open(LOGFILEPATH, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); var buffer = new byte[256]; - file.Read(buffer, 0, buffer.Length); + + // Suppress CA2022 error: Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' + _ = file.Read(buffer, 0, buffer.Length); Assert.Equal('\0', (char)buffer[0]); } @@ -256,7 +258,9 @@ private static void AssertFileOutput(string filePath, string eventMessage) { using FileStream file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); var buffer = new byte[256]; - file.Read(buffer, 0, buffer.Length); + + // Suppress CA2022 error: Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' + _ = file.Read(buffer, 0, buffer.Length); string logLine = Encoding.UTF8.GetString(buffer); string logMessage = ParseLogMessage(logLine); Assert.StartsWith(eventMessage, logMessage); From b941f1e4d6c3241d8e3cbd07ad00ed63b5d5c662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 20 Sep 2024 18:09:52 +0200 Subject: [PATCH 081/133] [docs] Typo fixes (double the) (#5852) --- docs/metrics/customizing-the-sdk/README.md | 2 +- .../IOtlpExporterOptions.cs | 2 +- src/OpenTelemetry.Exporter.Zipkin/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index 830ad66957c..ed4d9aa9d67 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -203,7 +203,7 @@ used. By default, the boundaries used for a Histogram are [`{ 0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.14.0/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation). Views can be used to provide custom boundaries for a Histogram. The measurements -are then aggregated using the custom boundaries provided instead of the the +are then aggregated using the custom boundaries provided instead of the default boundaries. This requires the use of `ExplicitBucketHistogramConfiguration`. diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/IOtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/IOtlpExporterOptions.cs index 46855f8882d..d6402bc85a8 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/IOtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/IOtlpExporterOptions.cs @@ -14,7 +14,7 @@ namespace OpenTelemetry.Exporter; internal interface IOtlpExporterOptions { /// - /// Gets or sets the the OTLP transport protocol. + /// Gets or sets the OTLP transport protocol. /// OtlpExportProtocol Protocol { get; set; } diff --git a/src/OpenTelemetry.Exporter.Zipkin/README.md b/src/OpenTelemetry.Exporter.Zipkin/README.md index aa277b7fdc2..ededcf9b07d 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/README.md +++ b/src/OpenTelemetry.Exporter.Zipkin/README.md @@ -15,7 +15,7 @@ dotnet add package OpenTelemetry.Exporter.Zipkin ## Enable/Add Zipkin as a tracing exporter -You can enable the the `ZipkinExporter` with the `AddZipkinExporter()` extension +You can enable the `ZipkinExporter` with the `AddZipkinExporter()` extension method on `TracerProviderBuilder`. ## Configuration From 86c1d8c2b3c2aeb0478825b64241b283712f0b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 20 Sep 2024 18:21:00 +0200 Subject: [PATCH 082/133] [repo] Simplify preprocessor directives after dropping support for .NET 6 and .NET7 (#5851) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs | 4 ++-- src/OpenTelemetry.Api/Logs/LogRecordData.cs | 4 ++-- src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs | 4 ++-- .../Logs/LogRecordSeverityExtensions.cs | 4 ++-- src/OpenTelemetry.Api/Logs/Logger.cs | 4 ++-- src/OpenTelemetry.Api/Logs/LoggerProvider.cs | 10 +++++----- .../PrometheusExporterMiddleware.cs | 2 +- .../Logs/ILogger/OpenTelemetryLoggingExtensions.cs | 6 +++--- src/OpenTelemetry/Logs/LogRecord.cs | 8 ++++---- src/OpenTelemetry/Metrics/AggregatorStore.cs | 6 +++--- src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs | 4 ++-- .../Metrics/Exemplar/ExemplarMeasurement.cs | 4 ++-- .../Metrics/Exemplar/ExemplarReservoir.cs | 4 ++-- .../Metrics/Exemplar/FixedSizeExemplarReservoir.cs | 4 ++-- src/OpenTelemetry/Metrics/ThreadStaticStorage.cs | 4 ++-- .../Metrics/View/MetricStreamConfiguration.cs | 6 +++--- src/OpenTelemetry/ReadOnlyFilteredTagCollection.cs | 6 +++--- src/OpenTelemetry/Sdk.cs | 4 ++-- .../Trace/Builder/TracerProviderBuilderExtensions.cs | 2 +- 19 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs b/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs index e4367d41c6e..bea5f953882 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs @@ -6,7 +6,7 @@ using System.Collections; using System.ComponentModel; using System.Diagnostics; -#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +#if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; #endif using OpenTelemetry.Internal; @@ -19,7 +19,7 @@ namespace OpenTelemetry.Logs; /// Stores attributes to be added to a log message. /// /// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry.Api/Logs/LogRecordData.cs b/src/OpenTelemetry.Api/Logs/LogRecordData.cs index cb3c49292af..92bb2765a23 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordData.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordData.cs @@ -4,7 +4,7 @@ #nullable enable using System.Diagnostics; -#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +#if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; #endif @@ -16,7 +16,7 @@ namespace OpenTelemetry.Logs; /// Stores details about a log message. /// /// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs b/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs index 9f48e71e854..b849abdcffa 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs @@ -3,7 +3,7 @@ #nullable enable -#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +#if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; #endif @@ -15,7 +15,7 @@ namespace OpenTelemetry.Logs; /// Describes the severity level of a log record. /// /// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs b/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs index f171edbc9ca..e5cb23d7fa0 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs @@ -3,7 +3,7 @@ #nullable enable -#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +#if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; #endif @@ -15,7 +15,7 @@ namespace OpenTelemetry.Logs; /// Contains extension methods for the enum. /// /// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry.Api/Logs/Logger.cs b/src/OpenTelemetry.Api/Logs/Logger.cs index 71baf7d611e..8318ed92c85 100644 --- a/src/OpenTelemetry.Api/Logs/Logger.cs +++ b/src/OpenTelemetry.Api/Logs/Logger.cs @@ -3,7 +3,7 @@ #nullable enable -#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +#if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; #endif @@ -15,7 +15,7 @@ namespace OpenTelemetry.Logs; /// Logger is the class responsible for creating log records. /// /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry.Api/Logs/LoggerProvider.cs b/src/OpenTelemetry.Api/Logs/LoggerProvider.cs index f87eddc6571..018658446cd 100644 --- a/src/OpenTelemetry.Api/Logs/LoggerProvider.cs +++ b/src/OpenTelemetry.Api/Logs/LoggerProvider.cs @@ -6,7 +6,7 @@ #if NETSTANDARD2_1_OR_GREATER || NET using System.Diagnostics.CodeAnalysis; #endif -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +#if EXPOSE_EXPERIMENTAL_FEATURES && NET using OpenTelemetry.Internal; #endif @@ -32,7 +32,7 @@ protected LoggerProvider() /// /// /// instance. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -49,7 +49,7 @@ Logger GetLogger() /// /// Optional name identifying the instrumentation library. /// instance. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -67,7 +67,7 @@ Logger GetLogger(string? name) /// Optional name identifying the instrumentation library. /// Optional version of the instrumentation library. /// instance. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -94,7 +94,7 @@ Logger GetLogger(string? name, string? version) /// Optional name identifying the instrumentation library. /// . /// if the logger was created. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif protected diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs index c2bd1cc2572..f91a93f66bb 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs @@ -65,7 +65,7 @@ public async Task InvokeAsync(HttpContext httpContext) if (dataView.Count > 0) { response.StatusCode = 200; -#if NET8_0_OR_GREATER +#if NET response.Headers.Append("Last-Modified", collectionResponse.GeneratedAtUtc.ToString("R")); #else response.Headers.Add("Last-Modified", collectionResponse.GeneratedAtUtc.ToString("R")); diff --git a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs index 973096cf7bc..e1a68730f2b 100644 --- a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs @@ -71,7 +71,7 @@ public static ILoggingBuilder AddOpenTelemetry( /// /// The to use. /// The supplied for call chaining. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -90,7 +90,7 @@ static ILoggingBuilder UseOpenTelemetry( /// The to use. /// configuration action. /// The supplied for call chaining. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -115,7 +115,7 @@ static ILoggingBuilder UseOpenTelemetry( /// Optional configuration action. /// Optional configuration action. /// The supplied for call chaining. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry/Logs/LogRecord.cs b/src/OpenTelemetry/Logs/LogRecord.cs index 58d97c38edf..8009687d551 100644 --- a/src/OpenTelemetry/Logs/LogRecord.cs +++ b/src/OpenTelemetry/Logs/LogRecord.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +#if EXPOSE_EXPERIMENTAL_FEATURES && NET using System.Diagnostics.CodeAnalysis; #endif using System.Runtime.CompilerServices; @@ -355,7 +355,7 @@ public Exception? Exception /// known at the source. ///
/// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -377,7 +377,7 @@ public Exception? Exception /// Gets or sets the log . ///
/// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -405,7 +405,7 @@ public Exception? Exception /// typically the which emitted the however the value may be different if is modified. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public Logger Logger { get; internal set; } = InstrumentationScopeLogger.Default; diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index 34a4bb5f2ce..5dc4f92dee9 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Collections.Concurrent; -#if NET8_0_OR_GREATER +#if NET using System.Collections.Frozen; #endif using System.Diagnostics; @@ -14,7 +14,7 @@ namespace OpenTelemetry.Metrics; internal sealed class AggregatorStore { -#if NET8_0_OR_GREATER +#if NET internal readonly FrozenSet? TagKeysInteresting; #else internal readonly HashSet? TagKeysInteresting; @@ -96,7 +96,7 @@ internal AggregatorStore( { this.updateLongCallback = this.UpdateLongCustomTags; this.updateDoubleCallback = this.UpdateDoubleCustomTags; -#if NET8_0_OR_GREATER +#if NET var hs = FrozenSet.ToFrozenSet(metricStreamIdentity.TagKeys, StringComparer.Ordinal); #else var hs = new HashSet(metricStreamIdentity.TagKeys, StringComparer.Ordinal); diff --git a/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs b/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs index c53a7abf8b4..d1801afdd39 100644 --- a/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs +++ b/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET8_0_OR_GREATER +#if NET using System.Collections.Frozen; #endif using System.Diagnostics; @@ -17,7 +17,7 @@ namespace OpenTelemetry.Metrics; /// public struct Exemplar { -#if NET8_0_OR_GREATER +#if NET internal FrozenSet? ViewDefinedTagKeys; #else internal HashSet? ViewDefinedTagKeys; diff --git a/src/OpenTelemetry/Metrics/Exemplar/ExemplarMeasurement.cs b/src/OpenTelemetry/Metrics/Exemplar/ExemplarMeasurement.cs index eb3882e6e08..70d6ff3e762 100644 --- a/src/OpenTelemetry/Metrics/Exemplar/ExemplarMeasurement.cs +++ b/src/OpenTelemetry/Metrics/Exemplar/ExemplarMeasurement.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +#if EXPOSE_EXPERIMENTAL_FEATURES && NET using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; #endif @@ -14,7 +14,7 @@ namespace OpenTelemetry.Metrics; ///
/// /// Measurement type. -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.ExemplarReservoirExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry/Metrics/Exemplar/ExemplarReservoir.cs b/src/OpenTelemetry/Metrics/Exemplar/ExemplarReservoir.cs index 4eb800921f1..0070074bed6 100644 --- a/src/OpenTelemetry/Metrics/Exemplar/ExemplarReservoir.cs +++ b/src/OpenTelemetry/Metrics/Exemplar/ExemplarReservoir.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +#if EXPOSE_EXPERIMENTAL_FEATURES && NET using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; #endif @@ -17,7 +17,7 @@ namespace OpenTelemetry.Metrics; /// Specification: . /// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.ExemplarReservoirExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry/Metrics/Exemplar/FixedSizeExemplarReservoir.cs b/src/OpenTelemetry/Metrics/Exemplar/FixedSizeExemplarReservoir.cs index dc929e725ed..bca577db0b6 100644 --- a/src/OpenTelemetry/Metrics/Exemplar/FixedSizeExemplarReservoir.cs +++ b/src/OpenTelemetry/Metrics/Exemplar/FixedSizeExemplarReservoir.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +#if EXPOSE_EXPERIMENTAL_FEATURES && NET using System.Diagnostics.CodeAnalysis; #endif using OpenTelemetry.Internal; @@ -14,7 +14,7 @@ namespace OpenTelemetry.Metrics; /// number of s. ///
/// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.ExemplarReservoirExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry/Metrics/ThreadStaticStorage.cs b/src/OpenTelemetry/Metrics/ThreadStaticStorage.cs index 35f9be5b5da..a66460bfb79 100644 --- a/src/OpenTelemetry/Metrics/ThreadStaticStorage.cs +++ b/src/OpenTelemetry/Metrics/ThreadStaticStorage.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET8_0_OR_GREATER +#if NET using System.Collections.Frozen; #endif using System.Diagnostics; @@ -57,7 +57,7 @@ internal void SplitToKeysAndValues( internal void SplitToKeysAndValues( ReadOnlySpan> tags, int tagLength, -#if NET8_0_OR_GREATER +#if NET FrozenSet tagKeysInteresting, #else HashSet tagKeysInteresting, diff --git a/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs b/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs index 578049f329f..cc36941ce68 100644 --- a/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs +++ b/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +#if EXPOSE_EXPERIMENTAL_FEATURES && NET using System.Diagnostics.CodeAnalysis; #endif using OpenTelemetry.Internal; @@ -116,7 +116,7 @@ public string[]? TagKeys /// If not set the default /// MeterProvider cardinality limit of 2000 will apply. /// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.CardinalityLimitExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public @@ -151,7 +151,7 @@ public string[]? TagKeys /// Specification: . /// -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.ExemplarReservoirExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public Func? ExemplarReservoirFactory { get; set; } diff --git a/src/OpenTelemetry/ReadOnlyFilteredTagCollection.cs b/src/OpenTelemetry/ReadOnlyFilteredTagCollection.cs index 8b8d7d12b3d..6369018ca0b 100644 --- a/src/OpenTelemetry/ReadOnlyFilteredTagCollection.cs +++ b/src/OpenTelemetry/ReadOnlyFilteredTagCollection.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET8_0_OR_GREATER +#if NET using System.Collections.Frozen; #endif using System.Diagnostics; @@ -16,7 +16,7 @@ namespace OpenTelemetry; // prevent accidental boxing. public readonly struct ReadOnlyFilteredTagCollection { -#if NET8_0_OR_GREATER +#if NET private readonly FrozenSet? excludedKeys; #else private readonly HashSet? excludedKeys; @@ -25,7 +25,7 @@ public readonly struct ReadOnlyFilteredTagCollection private readonly int count; internal ReadOnlyFilteredTagCollection( -#if NET8_0_OR_GREATER +#if NET FrozenSet? excludedKeys, #else HashSet? excludedKeys, diff --git a/src/OpenTelemetry/Sdk.cs b/src/OpenTelemetry/Sdk.cs index 3a95120e3ef..2cb4e0b6c9f 100644 --- a/src/OpenTelemetry/Sdk.cs +++ b/src/OpenTelemetry/Sdk.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +#if EXPOSE_EXPERIMENTAL_FEATURES && NET using System.Diagnostics.CodeAnalysis; #endif using OpenTelemetry.Context.Propagation; @@ -89,7 +89,7 @@ public static TracerProviderBuilder CreateTracerProviderBuilder() /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. /// instance, which is used /// to build a . -#if NET8_0_OR_GREATER +#if NET [Experimental(DiagnosticDefinitions.LogsBridgeExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs index c429dad7b01..c76befd9b75 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs @@ -27,7 +27,7 @@ public static class TracerProviderBuilderExtensions /// /// This method is not supported in native AOT or Mono Runtime as of .NET 8. /// -#if NET7_0_OR_GREATER +#if NET [RequiresDynamicCode("The code for detecting exception and setting error status might not be available.")] #endif public static TracerProviderBuilder SetErrorStatusOnException(this TracerProviderBuilder tracerProviderBuilder, bool enabled = true) From c1a1931319281197598d009ed531475e5a914de1 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Fri, 20 Sep 2024 12:51:14 -0700 Subject: [PATCH 083/133] [repo] Update the System.Diagnostics.DiagnosticSource and Microsoft.Extensions.* packages to .NET 9.0 RC.1 (#5853) --- Directory.Packages.props | 30 +++++++++---------- examples/Directory.Packages.props | 2 +- .../CHANGELOG.md | 4 +++ src/OpenTelemetry.Api/CHANGELOG.md | 4 +++ .../CHANGELOG.md | 4 +++ .../CHANGELOG.md | 4 +++ src/OpenTelemetry/CHANGELOG.md | 5 ++++ test/Directory.Packages.props | 2 +- 8 files changed, 38 insertions(+), 17 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index f54bd7353a3..fe1f04c7fbe 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -26,14 +26,14 @@ these packages even during major version bumps, so compatibility is not a concern here. --> - - - - - - - - + + + + + + + + @@ -52,7 +52,7 @@ 3) The .NET runtime team provides extra backward compatibility guarantee to System.Diagnostics.DiagnosticSource even during major version bumps, so compatibility is not a concern here. --> - + @@ -68,7 +68,7 @@ This section covers packages that are **not** directly referenced by the NuGet packages published from this repository. For example, these packages are used in the tests, examples or referenced as "PrivateAssets", but not in the NuGet packages themselves. --> - + @@ -77,11 +77,11 @@ - - - - - + + + + + diff --git a/examples/Directory.Packages.props b/examples/Directory.Packages.props index 549e1ed325b..02296b44608 100644 --- a/examples/Directory.Packages.props +++ b/examples/Directory.Packages.props @@ -1,6 +1,6 @@ - + diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md index 6609f3d51c4..7af158935fc 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md @@ -7,6 +7,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Updated `Microsoft.Extensions.DependencyInjection.Abstractions` package + version to `9.0.0-rc.1.24431.7`. + ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index b3b2738a111..f4d70e46949 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -25,6 +25,10 @@ Notes](../../RELEASENOTES.md). APIs for reading the status of an `Activity` instance. ([#5781](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5781)) +* Updated `System.Diagnostics.DiagnosticSource` package version to + `9.0.0-rc.1.24431.7`. + ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index ffb47ff3a33..e90109e737b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -22,6 +22,10 @@ Notes](../../RELEASENOTES.md). on mobile platforms which caused telemetry to be dropped silently. ([#5821](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/5821)) +* Updated `Microsoft.Extensions.Hosting.Abstractions` package + version to `9.0.0-rc.1.24431.7`. + ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index ac95bbe985e..935f07ffc55 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Updated `Microsoft.Extensions.Hosting.Abstractions` package + version to `9.0.0-rc.1.24431.7`. + ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 844b237e1d2..1e802f55fd1 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -12,6 +12,11 @@ Notes](../../RELEASENOTES.md). `IOpenTelemetryBuilder`. ([#5325](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5325)) +* Updated the `Microsoft.Extensions.Logging.Configuration` and + `Microsoft.Extensions.Diagnostics.Abstractions` packages version to + `9.0.0-rc.1.24431.7`. + ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props index d6755d05725..9e456e2826f 100644 --- a/test/Directory.Packages.props +++ b/test/Directory.Packages.props @@ -2,7 +2,7 @@ - + From 60b7d9baf32ee437ba3e84f1886ba8917e8d9475 Mon Sep 17 00:00:00 2001 From: Robert Coltheart <13191652+robertcoltheart@users.noreply.github.com> Date: Tue, 24 Sep 2024 02:56:38 +1000 Subject: [PATCH 084/133] [prometheus] Support meter-level tags (#5837) Co-authored-by: Cijo Thomas --- .../CHANGELOG.md | 3 + .../CHANGELOG.md | 3 + .../Internal/PrometheusSerializer.cs | 9 ++ .../PrometheusExporterMiddlewareTests.cs | 126 +++++++++++++----- .../PrometheusHttpListenerTests.cs | 42 +++++- 5 files changed, 140 insertions(+), 43 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 587692aa805..33cf84f17dd 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -7,6 +7,9 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Added meter-level tags to Prometheus exporter + ([#5837](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5837)) + ## 1.9.0-beta.2 Released 2024-Jun-24 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 1893e205c79..5873577fb86 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -7,6 +7,9 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Added meter-level tags to Prometheus exporter + ([#5837](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5837)) + ## 1.9.0-beta.2 Released 2024-Jun-24 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs index 7623de4067a..b182b521506 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs @@ -404,6 +404,15 @@ public static int WriteTags(byte[] buffer, int cursor, Metric metric, ReadOnlyTa buffer[cursor++] = unchecked((byte)','); } + if (metric.MeterTags != null) + { + foreach (var tag in metric.MeterTags) + { + cursor = WriteLabel(buffer, cursor, tag.Key, tag.Value); + buffer[cursor++] = unchecked((byte)','); + } + } + foreach (var tag in tags) { cursor = WriteLabel(buffer, cursor, tag.Key, tag.Value); diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs index 3f23d764e55..c34dba29582 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs @@ -249,43 +249,53 @@ public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader( } [Fact] - public async Task PrometheusExporterMiddlewareIntegration_CanServeOpenMetricsAndPlainFormats() + public Task PrometheusExporterMiddlewareIntegration_TextPlainResponse_WithMeterTags() { - using var host = await StartTestHostAsync( - app => app.UseOpenTelemetryPrometheusScrapingEndpoint()); - - var tags = new KeyValuePair[] + var meterTags = new KeyValuePair[] { - new("key1", "value1"), - new("key2", "value2"), + new("meterKey1", "value1"), + new("meterKey2", "value2"), }; - using var meter = new Meter(MeterName, MeterVersion); - - var beginTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + return RunPrometheusExporterMiddlewareIntegrationTest( + "/metrics", + app => app.UseOpenTelemetryPrometheusScrapingEndpoint(), + acceptHeader: "text/plain", + meterTags: meterTags); + } - var counter = meter.CreateCounter("counter_double", unit: "By"); - counter.Add(100.18D, tags); - counter.Add(0.99D, tags); + [Fact] + public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader_WithMeterTags() + { + var meterTags = new KeyValuePair[] + { + new("meterKey1", "value1"), + new("meterKey2", "value2"), + }; - var testCases = new bool[] { true, false, true, true, false }; + return RunPrometheusExporterMiddlewareIntegrationTest( + "/metrics", + app => app.UseOpenTelemetryPrometheusScrapingEndpoint(), + acceptHeader: "application/openmetrics-text; version=1.0.0", + meterTags: meterTags); + } - using var client = host.GetTestClient(); + [Fact] + public async Task PrometheusExporterMiddlewareIntegration_CanServeOpenMetricsAndPlainFormats_NoMeterTags() + { + await RunPrometheusExporterMiddlewareIntegrationTestWithBothFormats(); + } - foreach (var testCase in testCases) + [Fact] + public async Task PrometheusExporterMiddlewareIntegration_CanServeOpenMetricsAndPlainFormats_WithMeterTags() + { + var meterTags = new KeyValuePair[] { - using var request = new HttpRequestMessage - { - Headers = { { "Accept", testCase ? "application/openmetrics-text" : "text/plain" } }, - RequestUri = new Uri("/metrics", UriKind.Relative), - Method = HttpMethod.Get, - }; - using var response = await client.SendAsync(request); - var endTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); - await VerifyAsync(beginTimestamp, endTimestamp, response, testCase); - } + new("meterKey1", "value1"), + new("meterKey2", "value2"), + }; - await host.StopAsync(); + await RunPrometheusExporterMiddlewareIntegrationTestWithBothFormats(meterTags); } [Fact] @@ -312,6 +322,45 @@ public async Task PrometheusExporterMiddlewareIntegration_TestBufferSizeIncrease await host.StopAsync(); } + private static async Task RunPrometheusExporterMiddlewareIntegrationTestWithBothFormats(KeyValuePair[]? meterTags = null) + { + using var host = await StartTestHostAsync( + app => app.UseOpenTelemetryPrometheusScrapingEndpoint()); + + var counterTags = new KeyValuePair[] + { + new("key1", "value1"), + new("key2", "value2"), + }; + + using var meter = new Meter(MeterName, MeterVersion, meterTags); + + var beginTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + + var counter = meter.CreateCounter("counter_double", unit: "By"); + counter.Add(100.18D, counterTags); + counter.Add(0.99D, counterTags); + + var testCases = new bool[] { true, false, true, true, false }; + + using var client = host.GetTestClient(); + + foreach (var testCase in testCases) + { + using var request = new HttpRequestMessage + { + Headers = { { "Accept", testCase ? "application/openmetrics-text" : "text/plain" } }, + RequestUri = new Uri("/metrics", UriKind.Relative), + Method = HttpMethod.Get, + }; + using var response = await client.SendAsync(request); + var endTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + await VerifyAsync(beginTimestamp, endTimestamp, response, testCase, meterTags); + } + + await host.StopAsync(); + } + private static async Task RunPrometheusExporterMiddlewareIntegrationTest( string path, Action configure, @@ -320,27 +369,28 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( bool registerMeterProvider = true, Action? configureOptions = null, bool skipMetrics = false, - string acceptHeader = "application/openmetrics-text") + string acceptHeader = "application/openmetrics-text", + KeyValuePair[]? meterTags = null) { var requestOpenMetrics = acceptHeader.StartsWith("application/openmetrics-text"); using var host = await StartTestHostAsync(configure, configureServices, registerMeterProvider, configureOptions); - var tags = new KeyValuePair[] + var counterTags = new KeyValuePair[] { new("key1", "value1"), new("key2", "value2"), }; - using var meter = new Meter(MeterName, MeterVersion); + using var meter = new Meter(MeterName, MeterVersion, meterTags); var beginTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var counter = meter.CreateCounter("counter_double", unit: "By"); if (!skipMetrics) { - counter.Add(100.18D, tags); - counter.Add(0.99D, tags); + counter.Add(100.18D, counterTags); + counter.Add(0.99D, counterTags); } using var client = host.GetTestClient(); @@ -356,7 +406,7 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( if (!skipMetrics) { - await VerifyAsync(beginTimestamp, endTimestamp, response, requestOpenMetrics); + await VerifyAsync(beginTimestamp, endTimestamp, response, requestOpenMetrics, meterTags); } else { @@ -368,7 +418,7 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( await host.StopAsync(); } - private static async Task VerifyAsync(long beginTimestamp, long endTimestamp, HttpResponseMessage response, bool requestOpenMetrics) + private static async Task VerifyAsync(long beginTimestamp, long endTimestamp, HttpResponseMessage response, bool requestOpenMetrics, KeyValuePair[]? meterTags) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.True(response.Content.Headers.Contains("Last-Modified")); @@ -382,6 +432,10 @@ private static async Task VerifyAsync(long beginTimestamp, long endTimestamp, Ht Assert.Equal("text/plain; charset=utf-8; version=0.0.4", response.Content.Headers.ContentType!.ToString()); } + var additionalTags = meterTags != null && meterTags.Any() + ? $"{string.Join(",", meterTags.Select(x => $"{x.Key}=\"{x.Value}\""))}," + : string.Empty; + string content = (await response.Content.ReadAsStringAsync()).ReplaceLineEndings(); string expected = requestOpenMetrics @@ -394,14 +448,14 @@ private static async Task VerifyAsync(long beginTimestamp, long endTimestamp, Ht otel_scope_info{otel_scope_name="{{MeterName}}"} 1 # TYPE counter_double_bytes counter # UNIT counter_double_bytes bytes - counter_double_bytes_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",key1="value1",key2="value2"} 101.17 (\d+\.\d{3}) + counter_double_bytes_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",{{additionalTags}}key1="value1",key2="value2"} 101.17 (\d+\.\d{3}) # EOF """.ReplaceLineEndings() : $$""" # TYPE counter_double_bytes_total counter # UNIT counter_double_bytes_total bytes - counter_double_bytes_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",key1="value1",key2="value2"} 101.17 (\d+) + counter_double_bytes_total{otel_scope_name="{{MeterName}}",otel_scope_version="{{MeterVersion}}",{{additionalTags}}key1="value1",key2="value2"} 101.17 (\d+) # EOF """.ReplaceLineEndings(); diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs index 07ee28beb23..b9b6201183e 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs @@ -84,6 +84,30 @@ public async Task PrometheusExporterHttpServerIntegration_UseOpenMetricsVersionH await this.RunPrometheusExporterHttpServerIntegrationTest(acceptHeader: "application/openmetrics-text; version=1.0.0"); } + [Fact] + public async Task PrometheusExporterHttpServerIntegration_NoOpenMetrics_WithMeterTags() + { + var tags = new KeyValuePair[] + { + new("meter1", "value1"), + new("meter2", "value2"), + }; + + await this.RunPrometheusExporterHttpServerIntegrationTest(acceptHeader: string.Empty, meterTags: tags); + } + + [Fact] + public async Task PrometheusExporterHttpServerIntegration_OpenMetrics_WithMeterTags() + { + var tags = new KeyValuePair[] + { + new("meter1", "value1"), + new("meter2", "value2"), + }; + + await this.RunPrometheusExporterHttpServerIntegrationTest(acceptHeader: "application/openmetrics-text; version=1.0.0", meterTags: tags); + } + [Fact] public void PrometheusHttpListenerThrowsOnStart() { @@ -236,15 +260,15 @@ private static MeterProvider BuildMeterProvider(Meter meter, IEnumerable[]? meterTags = null) { var requestOpenMetrics = acceptHeader.StartsWith("application/openmetrics-text"); - using var meter = new Meter(MeterName, MeterVersion); + using var meter = new Meter(MeterName, MeterVersion, meterTags); var provider = BuildMeterProvider(meter, [], out var address); - var tags = new KeyValuePair[] + var counterTags = new KeyValuePair[] { new("key1", "value1"), new("key2", "value2"), @@ -253,8 +277,8 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri var counter = meter.CreateCounter("counter_double", unit: "By"); if (!skipMetrics) { - counter.Add(100.18D, tags); - counter.Add(0.99D, tags); + counter.Add(100.18D, counterTags); + counter.Add(0.99D, counterTags); } using HttpClient client = new HttpClient(); @@ -280,6 +304,10 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri Assert.Equal("text/plain; charset=utf-8; version=0.0.4", response.Content.Headers.ContentType!.ToString()); } + var additionalTags = meterTags != null && meterTags.Any() + ? $"{string.Join(",", meterTags.Select(x => $"{x.Key}='{x.Value}'"))}," + : string.Empty; + var content = await response.Content.ReadAsStringAsync(); var expected = requestOpenMetrics @@ -291,11 +319,11 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri + $"otel_scope_info{{otel_scope_name='{MeterName}'}} 1\n" + "# TYPE counter_double_bytes counter\n" + "# UNIT counter_double_bytes bytes\n" - + $"counter_double_bytes_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+\\.\\d{{3}})\n" + + $"counter_double_bytes_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',{additionalTags}key1='value1',key2='value2'}} 101.17 (\\d+\\.\\d{{3}})\n" + "# EOF\n" : "# TYPE counter_double_bytes_total counter\n" + "# UNIT counter_double_bytes_total bytes\n" - + $"counter_double_bytes_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+)\n" + + $"counter_double_bytes_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',{additionalTags}key1='value1',key2='value2'}} 101.17 (\\d+)\n" + "# EOF\n"; Assert.Matches(("^" + expected + "$").Replace('\'', '"'), content); From 1c02da746ea2365423a24ea45d03e0c4b9723da9 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 23 Sep 2024 15:06:20 -0700 Subject: [PATCH 085/133] [docs] Contributing updates (#5856) --- CONTRIBUTING.md | 68 ++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6b0e6c4fe6..f2e958021c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,8 +10,8 @@ for a summary description of past meetings. To request edit access, join the meeting or get in touch on [Slack](https://cloud-native.slack.com/archives/C01N3BC2W7Q). -Even though, anybody can contribute, there are benefits of being a member of our -community. See to the [community membership +Anyone may contribute but there are benefits of being a member of our community. +See the [community membership document](https://github.com/open-telemetry/community/blob/main/community-membership.md) on how to become a [**Member**](https://github.com/open-telemetry/community/blob/main/community-membership.md#member), @@ -19,7 +19,7 @@ on how to become a and [**Maintainer**](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer). -## Find a Buddy and Get Started Quickly +## Find a buddy and get started quickly If you are looking for someone to help you find a starting point and be a resource for your first contribution, join our Slack channel and find a buddy! @@ -34,17 +34,24 @@ resource for your first contribution, join our Slack channel and find a buddy! Your OpenTelemetry buddy is your resource to talk to directly on all aspects of contributing to OpenTelemetry: providing context, reviewing PRs, and helping -those get merged. Buddies will not be available 24/7, but is committed to -responding during their normal contribution hours. +those get merged. Buddies will not be available 24/7, but are committed to +responding during their normal working hours. ## Development Environment -You can contribute to this project from a Windows, macOS or Linux machine. +You can contribute to this project from a Windows, macOS, or Linux machine. On all platforms, the minimum requirements are: -* Git client and command line tools. -* .NET 9.0 +* Git client and command line tools + +* [.NET SDK (latest stable version)](https://dotnet.microsoft.com/download) + + > [!NOTE] + > At times a pre-release version of the .NET SDK may be required to build code + in this repository. Check + [global.json](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/global.json) + to verify the current required version. ### Linux or MacOS @@ -59,7 +66,7 @@ of Windows. * Visual Studio 2022+ or Visual Studio Code * .NET Framework 4.6.2+ -### Public API Validation +## Public API validation It is critical to **NOT** make breaking changes to public APIs which have been released in stable builds. We also strive to keep a minimal public API surface. @@ -91,9 +98,9 @@ to validate public APIs. [Common.prod.props](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/build/Common.prod.props) (please do not check in this change). -#### Working with Microsoft.CodeAnalysis.PublicApiAnalyzers +### Working with Microsoft.CodeAnalysis.PublicApiAnalyzers -##### Update public API files when writing code +#### Update public API files when writing code [IntelliSense](https://docs.microsoft.com/visualstudio/ide/using-intellisense) will [suggest @@ -116,7 +123,7 @@ do this by: while performing stable releases. If you need help reach out to an approver or maintainer on Slack or open a draft PR. -##### Enable public API validation in new projects +#### Enable public API validation in new projects 1. If you are **NOT** using experimental APIs: * If your API is the same across all target frameworks: @@ -144,12 +151,12 @@ do this by: ## Pull Requests -### How to Send Pull Requests +### How to create pull requests Everyone is welcome to contribute code to `opentelemetry-dotnet` via GitHub pull requests (PRs). -To create a new PR, fork the project in GitHub and clone the upstream repo: +To create a new PR, fork the project on GitHub and clone the upstream repo: ```sh git clone https://github.com/open-telemetry/opentelemetry-dotnet.git @@ -180,7 +187,7 @@ If you made changes to the Markdown documents (`*.md` files), install the latest markdownlint . ``` -Check out a new branch, make modifications and push the branch to your fork: +Check out a new branch, make modifications, and push the branch to your fork: ```sh $ git checkout -b feature @@ -191,7 +198,7 @@ $ git push fork feature Open a pull request against the main `opentelemetry-dotnet` repo. -### How to Receive Comments +#### Tips and best practices for pull requests * If the PR is not ready for review, please mark it as [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/). @@ -204,7 +211,7 @@ Open a pull request against the main `opentelemetry-dotnet` repo. * Include benchmarks (before/after) in the summary, for contributions that are performance enhancements. -### How to Get PRs Merged +### How to get pull requests merged A PR is considered to be **ready to merge** when: @@ -212,18 +219,21 @@ A PR is considered to be **ready to merge** when: [Approvers](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver). / [Maintainers](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer). -* Major feedbacks are resolved. +* Major feedback/comments are resolved. * It has been open for review for at least one working day. This gives people reasonable time to review. -* Trivial change (typo, cosmetic, doc, etc.) doesn't have to wait for one day. -* Urgent fix can take exception as long as it has been actively communicated. + * Trivial change (typo, cosmetic, doc, etc.) doesn't have to wait for one day. + * Urgent fix can take exception as long as it has been actively communicated. -Any Maintainer can merge the PR once it is **ready to merge**. Note, that some -PRs may not be merged immediately if the repo is in the process of a release and -the maintainers decided to defer the PR to the next release train. +Any maintainer can merge PRs once they are **ready to merge** however +maintainers might decide to wait on merging changes until there are more +approvals and/or dicussion, or based on other factors such as release timing and +risk to users. For example if a stable release is planned and a new change is +introduced adding public API(s) or behavioral changes it might be held until the +next alpha/beta release. -If a PR has been stuck (e.g. there are lots of debates and people couldn't agree -on each other), the owner should try to get people aligned by: +If a PR has become stuck (e.g. there is a lot of debate and people couldn't +agree on the direction), the owner should try to get people aligned by: * Consolidating the perspectives and putting a summary in the PR. It is recommended to add a link into the PR description, which points to a comment @@ -238,7 +248,7 @@ on each other), the owner should try to get people aligned by: the owner should bring it to the OpenTelemetry .NET SIG [meeting](README.md#contributing). -## Design Choices +## Design choices As with other OpenTelemetry clients, opentelemetry-dotnet follows the [opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification). @@ -246,7 +256,7 @@ As with other OpenTelemetry clients, opentelemetry-dotnet follows the It's especially valuable to read through the [library guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md). -### Focus on Capabilities, Not Structure Compliance +### Focus on capabilities not structural compliance OpenTelemetry is an evolving specification, one where the desires and use cases are clear, but the method to satisfy those uses cases are not. @@ -260,10 +270,10 @@ than conform to specific API names or argument patterns in the spec. For a deeper discussion, see [this spec issue](https://github.com/open-telemetry/opentelemetry-specification/issues/165). -## Style Guide +## Style guide This project includes a [`.editorconfig`](./.editorconfig) file which is -supported by all the IDEs/editor mentioned above. It works with the IDE/editor +supported by all the IDEs/editors mentioned above. It works with the IDE/editor only and does not affect the actual build of the project. This repository also includes StyleCop ruleset files under the `./build` folder. From d650352b8f510ab00beb19fa9971fb563a9442c2 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 23 Sep 2024 15:32:46 -0700 Subject: [PATCH 086/133] [sdk-metrics] Add support for .NET 9 Advice API (#5854) Co-authored-by: Mikel Blanchard Co-authored-by: Reiley Yang --- src/OpenTelemetry/CHANGELOG.md | 14 ++ .../Metrics/MetricStreamIdentity.cs | 48 ++++- .../Metrics/MetricViewTests.cs | 171 ++++++++++++++++++ 3 files changed, 232 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 1e802f55fd1..47b6536a5e5 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -17,6 +17,20 @@ Notes](../../RELEASENOTES.md). `9.0.0-rc.1.24431.7`. ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) +* Added support in metrics for histogram bucket boundaries set via the .NET 9 + [InstrumentAdvice<T>](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.instrumentadvice-1) + API. + + Note: With this change explicit bucket histogram boundary resolution will + apply in the following order: + + 1. View API + 2. Advice API + 3. SDK defaults + + See [#5854](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5854) + for details. + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry/Metrics/MetricStreamIdentity.cs b/src/OpenTelemetry/Metrics/MetricStreamIdentity.cs index 8ac0e8e10cf..a9918fb6eaa 100644 --- a/src/OpenTelemetry/Metrics/MetricStreamIdentity.cs +++ b/src/OpenTelemetry/Metrics/MetricStreamIdentity.cs @@ -22,7 +22,7 @@ public MetricStreamIdentity(Instrument instrument, MetricStreamConfiguration? me this.ViewId = metricStreamConfiguration?.ViewId; this.MetricStreamName = $"{this.MeterName}.{this.MeterVersion}.{this.InstrumentName}"; this.TagKeys = metricStreamConfiguration?.CopiedTagKeys; - this.HistogramBucketBounds = (metricStreamConfiguration as ExplicitBucketHistogramConfiguration)?.CopiedBoundaries; + this.HistogramBucketBounds = GetExplicitBucketHistogramBounds(instrument, metricStreamConfiguration); this.ExponentialHistogramMaxSize = (metricStreamConfiguration as Base2ExponentialBucketHistogramConfiguration)?.MaxSize ?? 0; this.ExponentialHistogramMaxScale = (metricStreamConfiguration as Base2ExponentialBucketHistogramConfiguration)?.MaxScale ?? 0; this.HistogramRecordMinMax = (metricStreamConfiguration as HistogramConfiguration)?.RecordMinMax ?? true; @@ -150,6 +150,52 @@ public bool Equals(MetricStreamIdentity other) public override readonly int GetHashCode() => this.hashCode; + private static double[]? GetExplicitBucketHistogramBounds(Instrument instrument, MetricStreamConfiguration? metricStreamConfiguration) + { + if (metricStreamConfiguration is ExplicitBucketHistogramConfiguration explicitBucketHistogramConfiguration + && explicitBucketHistogramConfiguration.CopiedBoundaries != null) + { + return explicitBucketHistogramConfiguration.CopiedBoundaries; + } + + return instrument switch + { + Histogram longHistogram => GetExplicitBucketHistogramBoundsFromAdvice(longHistogram), + Histogram intHistogram => GetExplicitBucketHistogramBoundsFromAdvice(intHistogram), + Histogram shortHistogram => GetExplicitBucketHistogramBoundsFromAdvice(shortHistogram), + Histogram byteHistogram => GetExplicitBucketHistogramBoundsFromAdvice(byteHistogram), + Histogram floatHistogram => GetExplicitBucketHistogramBoundsFromAdvice(floatHistogram), + Histogram doubleHistogram => GetExplicitBucketHistogramBoundsFromAdvice(doubleHistogram), + _ => null, + }; + } + + private static double[]? GetExplicitBucketHistogramBoundsFromAdvice(Histogram histogram) + where T : struct + { + var adviceExplicitBucketBoundaries = histogram.Advice?.HistogramBucketBoundaries; + if (adviceExplicitBucketBoundaries == null) + { + return null; + } + + if (typeof(T) == typeof(double)) + { + return ((IReadOnlyList)adviceExplicitBucketBoundaries).ToArray(); + } + else + { + double[] explicitBucketBoundaries = new double[adviceExplicitBucketBoundaries.Count]; + + for (int i = 0; i < adviceExplicitBucketBoundaries.Count; i++) + { + explicitBucketBoundaries[i] = Convert.ToDouble(adviceExplicitBucketBoundaries[i]); + } + + return explicitBucketBoundaries; + } + } + private static bool HistogramBoundsEqual(double[]? bounds1, double[]? bounds2) { if (ReferenceEquals(bounds1, bounds2)) diff --git a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs index c1a0fca281b..11c048512ef 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs @@ -570,6 +570,177 @@ public void ViewToProduceCustomHistogramBound() Assert.Equal(boundaries.Length + 1, actualCount); } + [Fact] + public void HistogramWithAdviceBoundaries_HandlesAllTypes() + { + using var meter = new Meter(Utils.GetCurrentMethodName()); + var exportedItems = new List(); + int counter = 0; + + using var container = this.BuildMeterProvider(out var meterProvider, builder => + { + builder.AddMeter(meter.Name); + builder.AddInMemoryExporter(exportedItems); + }); + + // Test cases for different histogram types + var histograms = new Instrument[] + { + meter.CreateHistogram("longHistogram", unit: null, description: null, tags: null, new() { HistogramBucketBoundaries = new List() { 10, 20 } }), + meter.CreateHistogram("intHistogram", unit: null, description: null, tags: null, new() { HistogramBucketBoundaries = new List() { 10, 20 } }), + meter.CreateHistogram("shortHistogram", unit: null, description: null, tags: null, new() { HistogramBucketBoundaries = new List() { 10, 20 } }), + meter.CreateHistogram("floatHistogram", unit: null, description: null, tags: null, new() { HistogramBucketBoundaries = new List() { 10.0F, 20.0F } }), + meter.CreateHistogram("doubleHistogram", unit: null, description: null, tags: null, new() { HistogramBucketBoundaries = new List() { 10.0, 20.0 } }), + }; + + foreach (var histogram in histograms) + { + exportedItems.Clear(); + + if (histogram is Histogram longHistogram) + { + longHistogram.Record(-10); + longHistogram.Record(9); + longHistogram.Record(19); + } + else if (histogram is Histogram intHistogram) + { + intHistogram.Record(-10); + intHistogram.Record(9); + intHistogram.Record(19); + counter++; + } + else if (histogram is Histogram shortHistogram) + { + shortHistogram.Record(-10); + shortHistogram.Record(9); + shortHistogram.Record(19); + counter++; + } + else if (histogram is Histogram floatHistogram) + { + floatHistogram.Record(-10.0F); + floatHistogram.Record(9.0F); + floatHistogram.Record(19.0F); + counter++; + } + else if (histogram is Histogram doubleHistogram) + { + doubleHistogram.Record(-10.0); + doubleHistogram.Record(9.0); + doubleHistogram.Record(19.0); + counter++; + } + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + var metricCustom = exportedItems[counter]; + + List metricPointsCustom = new List(); + foreach (ref readonly var mp in metricCustom.GetMetricPoints()) + { + metricPointsCustom.Add(mp); + } + + Assert.Single(metricPointsCustom); + var histogramPoint = metricPointsCustom[0]; + + var count = histogramPoint.GetHistogramCount(); + var sum = histogramPoint.GetHistogramSum(); + + Assert.Equal(18, sum); + Assert.Equal(3, count); + + var index = 0; + var actualCount = 0; + long[] expectedBucketCounts = new long[] { 2, 1, 0 }; + + foreach (var histogramMeasurement in histogramPoint.GetHistogramBuckets()) + { + Assert.Equal(expectedBucketCounts[index], histogramMeasurement.BucketCount); + index++; + actualCount++; + } + + Assert.Equal(3, actualCount); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void HistogramWithAdviceBoundariesSpecifiedTests(bool useViewToOverride) + { + using var meter = new Meter(Utils.GetCurrentMethodName()); + var exportedItems = new List(); + IReadOnlyList adviceBoundaries = new List() { 5, 10, 20 }; + double[] viewBoundaries = new double[] { 10, 20 }; + + using var container = this.BuildMeterProvider(out var meterProvider, builder => + { + builder.AddMeter(meter.Name); + + if (useViewToOverride) + { + builder.AddView("MyHistogram", new ExplicitBucketHistogramConfiguration { Boundaries = viewBoundaries }); + } + + builder.AddInMemoryExporter(exportedItems); + }); + + var histogram = meter.CreateHistogram( + "MyHistogram", + unit: null, + description: null, + tags: null, + new() + { + HistogramBucketBoundaries = adviceBoundaries, + }); + + histogram.Record(-10); + histogram.Record(0); + histogram.Record(1); + histogram.Record(9); + histogram.Record(10); + histogram.Record(11); + histogram.Record(19); + histogram.Record(22); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + Assert.Single(exportedItems); + var metricCustom = exportedItems[0]; + + Assert.Equal("MyHistogram", metricCustom.Name); + + List metricPointsCustom = new List(); + foreach (ref readonly var mp in metricCustom.GetMetricPoints()) + { + metricPointsCustom.Add(mp); + } + + Assert.Single(metricPointsCustom); + var histogramPoint = metricPointsCustom[0]; + + var count = histogramPoint.GetHistogramCount(); + var sum = histogramPoint.GetHistogramSum(); + + Assert.Equal(62, sum); + Assert.Equal(8, count); + + var index = 0; + var actualCount = 0; + long[] expectedBucketCounts = useViewToOverride ? new long[] { 5, 2, 1 } : new long[] { 3, 2, 2, 1 }; + + foreach (var histogramMeasurement in histogramPoint.GetHistogramBuckets()) + { + Assert.Equal(expectedBucketCounts[index], histogramMeasurement.BucketCount); + index++; + actualCount++; + } + + Assert.Equal(useViewToOverride ? viewBoundaries.Length + 1 : adviceBoundaries.Count + 1, actualCount); + } + [Fact] public void ViewToProduceExponentialHistogram() { From 3c38a4b00bc99f1e6aee2f3dd0dd10e3d4ab566f Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Tue, 24 Sep 2024 09:49:06 -0700 Subject: [PATCH 087/133] [repo] Update stale.yml - reduce days before stale to 600 (#5857) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 5927cd4fac2..a46d0abad3c 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,7 +18,7 @@ jobs: close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' operations-per-run: 400 days-before-pr-stale: 7 - days-before-issue-stale: 900 + days-before-issue-stale: 600 days-before-pr-close: 7 days-before-issue-close: 7 exempt-all-issue-milestones: true From 12a8ab0f45d810f40c7f7dd6340fa3acf9d26153 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Tue, 24 Sep 2024 19:44:10 +0200 Subject: [PATCH 088/133] [api] Mark ActivityExtensions.RecordException obsolete (#5841) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Api/CHANGELOG.md | 6 ++++ .../Trace/ActivityExtensions.cs | 28 ++++++------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index f4d70e46949..5f2c9925eb3 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -29,6 +29,12 @@ Notes](../../RELEASENOTES.md). `9.0.0-rc.1.24431.7`. ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) +* Obsoleted the `ActivityExtensions.RecordException` extension method. Users + should migrate to the `System.Diagnostics.DiagnosticSource` + [Activity.AddException](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.addexception) + API for adding exceptions on an `Activity` instance. + ([#5841](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5841)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs index a94a635055b..7c2a0854419 100644 --- a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs +++ b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs @@ -94,9 +94,12 @@ public static Status GetStatus(this Activity? activity) ///
/// Activity instance. /// Exception to be recorded. - /// The exception is recorded as per specification. + /// + /// Note: This method is obsolete. Please use instead. + /// The exception is recorded as per specification. /// "exception.stacktrace" is represented using the value of Exception.ToString. /// + [Obsolete("Call Activity.AddException instead this method will be removed in a future version.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RecordException(this Activity? activity, Exception? ex) => RecordException(activity, ex, default); @@ -107,9 +110,12 @@ public static void RecordException(this Activity? activity, Exception? ex) /// Activity instance. /// Exception to be recorded. /// Additional tags to record on the event. - /// The exception is recorded as per specification. + /// + /// Note: This method is obsolete. Please use instead. + /// The exception is recorded as per specification. /// "exception.stacktrace" is represented using the value of Exception.ToString. /// + [Obsolete("Call Activity.AddException instead this method will be removed in a future version.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RecordException(this Activity? activity, Exception? ex, in TagList tags) { @@ -118,22 +124,6 @@ public static void RecordException(this Activity? activity, Exception? ex, in Ta return; } - var tagsCollection = new ActivityTagsCollection - { - { SemanticConventions.AttributeExceptionType, ex.GetType().FullName }, - { SemanticConventions.AttributeExceptionStacktrace, ex.ToInvariantString() }, - }; - - if (!string.IsNullOrWhiteSpace(ex.Message)) - { - tagsCollection.Add(SemanticConventions.AttributeExceptionMessage, ex.Message); - } - - foreach (var tag in tags) - { - tagsCollection[tag.Key] = tag.Value; - } - - activity.AddEvent(new ActivityEvent(SemanticConventions.AttributeExceptionEventName, default, tagsCollection)); + activity.AddException(ex, in tags); } } From 3a09a91b1cfc4ae5e62bb126f60e78d29057f7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 24 Sep 2024 20:23:12 +0200 Subject: [PATCH 089/133] Cleanup W3CTraceContextTests (#5858) Co-authored-by: Mikel Blanchard --- .../W3CTraceContextTests.cs | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs index d557ea71c59..95f8d9b5517 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs @@ -20,8 +20,7 @@ public class W3CTraceContextTests : IDisposable To run the tests, invoke docker-compose.yml from the root of the repo: opentelemetry>docker compose --file=test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build */ - private const string W3cTraceContextEnvVarName = "OTEL_W3CTRACECONTEXT"; - private static readonly Version? AspNetCoreHostingVersion = typeof(Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory).Assembly.GetName().Version; + private const string W3CTraceContextEnvVarName = "OTEL_W3CTRACECONTEXT"; private readonly HttpClient httpClient = new(); private readonly ITestOutputHelper output; @@ -31,13 +30,13 @@ public W3CTraceContextTests(ITestOutputHelper output) } [Trait("CategoryName", "W3CTraceContextTests")] - [SkipUnlessEnvVarFoundTheory(W3cTraceContextEnvVarName)] + [SkipUnlessEnvVarFoundTheory(W3CTraceContextEnvVarName)] [InlineData("placeholder")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters", Justification = "Need to use SkipUnlessEnvVarFoundTheory")] public void W3CTraceContextTestSuiteAsync(string value) { // configure SDK - using var tracerprovider = Sdk.CreateTracerProviderBuilder() + using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAspNetCoreInstrumentation() .Build(); @@ -51,13 +50,11 @@ public void W3CTraceContextTestSuiteAsync(string value) { foreach (var argument in data) { - using var request = new HttpRequestMessage(HttpMethod.Post, argument.Url) - { - Content = new StringContent( - JsonSerializer.Serialize(argument.Arguments), - Encoding.UTF8, - "application/json"), - }; + using var request = new HttpRequestMessage(HttpMethod.Post, argument.Url); + request.Content = new StringContent( + JsonSerializer.Serialize(argument.Arguments), + Encoding.UTF8, + "application/json"); await this.httpClient.SendAsync(request); } } @@ -79,19 +76,7 @@ public void W3CTraceContextTestSuiteAsync(string value) this.output.WriteLine("result:" + result); // Assert on the last line - - // TODO: Investigate failures on .NET6 vs .NET7. To see the details - // run the tests with console logger (done automatically by the CI - // jobs). - - if (AspNetCoreHostingVersion!.Major <= 6) - { - Assert.StartsWith("FAILED (failures=3)", lastLine); - } - else - { - Assert.StartsWith("OK", lastLine); - } + Assert.StartsWith("OK", lastLine); } public void Dispose() From 2097f477f3dbfa27cdfccef56a36b603f8c8a9c6 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 24 Sep 2024 13:52:51 -0700 Subject: [PATCH 090/133] [api] Context nullable annotations (#5850) --- .../.publicApi/Stable/PublicAPI.Shipped.txt | 42 +++++----- .../Stable/net462/PublicAPI.Shipped.txt | 8 +- .../Context/AsyncLocalRuntimeContextSlot.cs | 18 +++- .../IRuntimeContextSlotValueAccessor.cs | 4 +- .../Context/RemotingRuntimeContextSlot.cs | 30 +++++-- .../Context/RuntimeContext.cs | 30 ++++--- .../Context/RuntimeContextSlot.cs | 8 +- .../Context/ThreadLocalRuntimeContextSlot.cs | 18 +++- .../Context/RuntimeContextTest.cs | 82 ++++++++++++++++++- 9 files changed, 188 insertions(+), 52 deletions(-) diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt index cd5c445997e..821cf080676 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt @@ -1,26 +1,16 @@ #nullable enable -~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.AsyncLocalRuntimeContextSlot(string name) -> void -~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Value.get -> object -~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Value.set -> void -~OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.get -> object -~OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.set -> void -~OpenTelemetry.Context.RuntimeContextSlot.Name.get -> string -~OpenTelemetry.Context.RuntimeContextSlot.RuntimeContextSlot(string name) -> void -~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.ThreadLocalRuntimeContextSlot(string name) -> void -~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.get -> object -~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.set -> void -~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.get -> System.Type -~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.set -> void -~static OpenTelemetry.Context.RuntimeContext.GetSlot(string slotName) -> OpenTelemetry.Context.RuntimeContextSlot -~static OpenTelemetry.Context.RuntimeContext.GetValue(string slotName) -> object -~static OpenTelemetry.Context.RuntimeContext.GetValue(string slotName) -> T -~static OpenTelemetry.Context.RuntimeContext.RegisterSlot(string slotName) -> OpenTelemetry.Context.RuntimeContextSlot -~static OpenTelemetry.Context.RuntimeContext.SetValue(string slotName, object value) -> void -~static OpenTelemetry.Context.RuntimeContext.SetValue(string slotName, T value) -> void +static OpenTelemetry.Context.RuntimeContext.ContextSlotType.get -> System.Type! +static OpenTelemetry.Context.RuntimeContext.ContextSlotType.set -> void +static OpenTelemetry.Context.RuntimeContext.GetSlot(string! slotName) -> OpenTelemetry.Context.RuntimeContextSlot! +static OpenTelemetry.Context.RuntimeContext.GetValue(string! slotName) -> object? +static OpenTelemetry.Context.RuntimeContext.GetValue(string! slotName) -> T? +static OpenTelemetry.Context.RuntimeContext.RegisterSlot(string! slotName) -> OpenTelemetry.Context.RuntimeContextSlot! +static OpenTelemetry.Context.RuntimeContext.SetValue(string! slotName, object? value) -> void +static OpenTelemetry.Context.RuntimeContext.SetValue(string! slotName, T value) -> void abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Fields.get -> System.Collections.Generic.ISet? abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void -abstract OpenTelemetry.Context.RuntimeContextSlot.Get() -> T +abstract OpenTelemetry.Context.RuntimeContextSlot.Get() -> T? abstract OpenTelemetry.Context.RuntimeContextSlot.Set(T value) -> void abstract OpenTelemetry.Logs.LoggerProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder! abstract OpenTelemetry.Metrics.MeterProviderBuilder.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! @@ -46,7 +36,12 @@ OpenTelemetry.BaseProvider.~BaseProvider() -> void OpenTelemetry.BaseProvider.BaseProvider() -> void OpenTelemetry.BaseProvider.Dispose() -> void OpenTelemetry.Context.AsyncLocalRuntimeContextSlot +OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.AsyncLocalRuntimeContextSlot(string! name) -> void +OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Value.get -> object? +OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Value.set -> void OpenTelemetry.Context.IRuntimeContextSlotValueAccessor +OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.get -> object? +OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.set -> void OpenTelemetry.Context.Propagation.B3Propagator OpenTelemetry.Context.Propagation.B3Propagator.B3Propagator() -> void OpenTelemetry.Context.Propagation.B3Propagator.B3Propagator(bool singleHeader) -> void @@ -68,7 +63,12 @@ OpenTelemetry.Context.Propagation.TraceContextPropagator.TraceContextPropagator( OpenTelemetry.Context.RuntimeContext OpenTelemetry.Context.RuntimeContextSlot OpenTelemetry.Context.RuntimeContextSlot.Dispose() -> void +OpenTelemetry.Context.RuntimeContextSlot.Name.get -> string! +OpenTelemetry.Context.RuntimeContextSlot.RuntimeContextSlot(string! name) -> void OpenTelemetry.Context.ThreadLocalRuntimeContextSlot +OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.ThreadLocalRuntimeContextSlot(string! name) -> void +OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.get -> object? +OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Value.set -> void OpenTelemetry.Logs.IDeferredLoggerProviderBuilder OpenTelemetry.Logs.IDeferredLoggerProviderBuilder.Configure(System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! OpenTelemetry.Logs.LoggerProvider @@ -165,7 +165,7 @@ OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.TracerProviderBuilder.TracerProviderBuilder() -> void override OpenTelemetry.Baggage.Equals(object? obj) -> bool override OpenTelemetry.Baggage.GetHashCode() -> int -override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Get() -> T +override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Get() -> T? override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot.Set(T value) -> void override OpenTelemetry.Context.Propagation.B3Propagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext override OpenTelemetry.Context.Propagation.B3Propagator.Fields.get -> System.Collections.Generic.ISet! @@ -182,7 +182,7 @@ override OpenTelemetry.Context.Propagation.TraceContextPropagator.Extract(Ope override OpenTelemetry.Context.Propagation.TraceContextPropagator.Fields.get -> System.Collections.Generic.ISet! override OpenTelemetry.Context.Propagation.TraceContextPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Dispose(bool disposing) -> void -override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Get() -> T +override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Get() -> T? override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot.Set(T value) -> void override OpenTelemetry.Trace.Link.Equals(object? obj) -> bool override OpenTelemetry.Trace.Link.GetHashCode() -> int diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/net462/PublicAPI.Shipped.txt index 58383768cd8..378097ec65c 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/net462/PublicAPI.Shipped.txt @@ -1,6 +1,6 @@ -~OpenTelemetry.Context.RemotingRuntimeContextSlot.RemotingRuntimeContextSlot(string name) -> void -~OpenTelemetry.Context.RemotingRuntimeContextSlot.Value.get -> object -~OpenTelemetry.Context.RemotingRuntimeContextSlot.Value.set -> void OpenTelemetry.Context.RemotingRuntimeContextSlot -override OpenTelemetry.Context.RemotingRuntimeContextSlot.Get() -> T +OpenTelemetry.Context.RemotingRuntimeContextSlot.RemotingRuntimeContextSlot(string! name) -> void +OpenTelemetry.Context.RemotingRuntimeContextSlot.Value.get -> object? +OpenTelemetry.Context.RemotingRuntimeContextSlot.Value.set -> void +override OpenTelemetry.Context.RemotingRuntimeContextSlot.Get() -> T? override OpenTelemetry.Context.RemotingRuntimeContextSlot.Set(T value) -> void diff --git a/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs index 15eb31d08c2..0c7d5f0cbf8 100644 --- a/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Runtime.CompilerServices; namespace OpenTelemetry.Context; @@ -24,15 +26,25 @@ public AsyncLocalRuntimeContextSlot(string name) } /// - public object Value + public object? Value { get => this.slot.Value; - set => this.slot.Value = (T)value; + set + { + if (typeof(T).IsValueType && value is null) + { + this.slot.Value = default!; + } + else + { + this.slot.Value = (T)value!; + } + } } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override T Get() + public override T? Get() { return this.slot.Value; } diff --git a/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs b/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs index 1e16ea42601..0d537c67cd3 100644 --- a/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs +++ b/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Context; /// @@ -11,5 +13,5 @@ public interface IRuntimeContextSlotValueAccessor /// /// Gets or sets the value of the slot as an . /// - object Value { get; set; } + object? Value { get; set; } } diff --git a/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs index 61d2722653b..6286c4044bf 100644 --- a/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK +#nullable enable + using System.Collections; using System.Reflection; using System.Runtime.CompilerServices; @@ -38,25 +40,39 @@ public RemotingRuntimeContextSlot(string name) } /// - public object Value + public object? Value { get => this.Get(); - set => this.Set((T)value); + set + { + if (typeof(T).IsValueType && value is null) + { + this.Set(default!); + } + else + { + this.Set((T)value!); + } + } } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override T Get() + public override T? Get() { - if (!(CallContext.LogicalGetData(this.Name) is BitArray wrapper)) + if (CallContext.LogicalGetData(this.Name) is not BitArray wrapper) { return default; } var value = WrapperField.GetValue(wrapper); - return value is T t - ? t - : default; + + if (typeof(T).IsValueType && value is null) + { + return default; + } + + return (T)value; } /// diff --git a/src/OpenTelemetry.Api/Context/RuntimeContext.cs b/src/OpenTelemetry.Api/Context/RuntimeContext.cs index 93c96299d2f..c544d7a59bb 100644 --- a/src/OpenTelemetry.Api/Context/RuntimeContext.cs +++ b/src/OpenTelemetry.Api/Context/RuntimeContext.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Collections.Concurrent; using System.Runtime.CompilerServices; using OpenTelemetry.Internal; @@ -56,7 +58,8 @@ public static Type ContextSlotType public static RuntimeContextSlot RegisterSlot(string slotName) { Guard.ThrowIfNullOrEmpty(slotName); - RuntimeContextSlot slot = null; + + RuntimeContextSlot? slot = null; lock (Slots) { @@ -80,6 +83,10 @@ public static RuntimeContextSlot RegisterSlot(string slotName) slot = new RemotingRuntimeContextSlot(slotName); } #endif + else + { + throw new NotSupportedException($"ContextSlotType '{ContextSlotType}' is not supported"); + } Slots[slotName] = slot; return slot; @@ -95,9 +102,10 @@ public static RuntimeContextSlot RegisterSlot(string slotName) public static RuntimeContextSlot GetSlot(string slotName) { Guard.ThrowIfNullOrEmpty(slotName); + var slot = GuardNotFound(slotName); - var contextSlot = Guard.ThrowIfNotOfType>(slot); - return contextSlot; + + return Guard.ThrowIfNotOfType>(slot); } /* @@ -143,7 +151,7 @@ public static void SetValue(string slotName, T value) /// The type of the value. /// The value retrieved from the context slot. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T GetValue(string slotName) + public static T? GetValue(string slotName) { return GetSlot(slotName).Get(); } @@ -153,12 +161,13 @@ public static T GetValue(string slotName) /// /// The name of the context slot. /// The value to be set. - public static void SetValue(string slotName, object value) + public static void SetValue(string slotName, object? value) { Guard.ThrowIfNullOrEmpty(slotName); + var slot = GuardNotFound(slotName); - var runtimeContextSlotValueAccessor = Guard.ThrowIfNotOfType(slot); - runtimeContextSlotValueAccessor.Value = value; + + Guard.ThrowIfNotOfType(slot).Value = value; } /// @@ -166,12 +175,13 @@ public static void SetValue(string slotName, object value) /// /// The name of the context slot. /// The value retrieved from the context slot. - public static object GetValue(string slotName) + public static object? GetValue(string slotName) { Guard.ThrowIfNullOrEmpty(slotName); + var slot = GuardNotFound(slotName); - var runtimeContextSlotValueAccessor = Guard.ThrowIfNotOfType(slot); - return runtimeContextSlotValueAccessor.Value; + + return Guard.ThrowIfNotOfType(slot).Value; } // For testing purpose diff --git a/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs index 918e4b79424..bb1321d79c8 100644 --- a/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs @@ -1,6 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +using OpenTelemetry.Internal; + namespace OpenTelemetry.Context; /// @@ -15,6 +19,8 @@ public abstract class RuntimeContextSlot : IDisposable /// The name of the context slot. protected RuntimeContextSlot(string name) { + Guard.ThrowIfNullOrEmpty(name); + this.Name = name; } @@ -27,7 +33,7 @@ protected RuntimeContextSlot(string name) /// Get the value from the context slot. /// /// The value retrieved from the context slot. - public abstract T Get(); + public abstract T? Get(); /// /// Set the value to the context slot. diff --git a/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs index c7724a842b4..35db8bcf924 100644 --- a/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Runtime.CompilerServices; namespace OpenTelemetry.Context; @@ -25,15 +27,25 @@ public ThreadLocalRuntimeContextSlot(string name) } /// - public object Value + public object? Value { get => this.slot.Value; - set => this.slot.Value = (T)value; + set + { + if (typeof(T).IsValueType && value is null) + { + this.slot.Value = default!; + } + else + { + this.slot.Value = (T)value!; + } + } } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override T Get() + public override T? Get() { return this.slot.Value; } diff --git a/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs b/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs index 1d25b4bf546..f8c53bc7f1d 100644 --- a/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Xunit; namespace OpenTelemetry.Context.Tests; @@ -16,7 +18,7 @@ public RuntimeContextTest() public static void RegisterSlotWithInvalidNameThrows() { Assert.Throws(() => RuntimeContext.RegisterSlot(string.Empty)); - Assert.Throws(() => RuntimeContext.RegisterSlot(null)); + Assert.Throws(() => RuntimeContext.RegisterSlot(null!)); } [Fact] @@ -31,7 +33,7 @@ public static void RegisterSlotWithSameName() public static void GetSlotWithInvalidNameThrows() { Assert.Throws(() => RuntimeContext.GetSlot(string.Empty)); - Assert.Throws(() => RuntimeContext.GetSlot(null)); + Assert.Throws(() => RuntimeContext.GetSlot(null!)); } [Fact] @@ -58,12 +60,88 @@ public void RegisterAndGetSlot() Assert.Equal(100, expectedSlot.Get()); } + [Fact] + public void ValueTypeSlotNullableTests() + { + var expectedSlot = RuntimeContext.RegisterSlot("testslot_valuetype"); + Assert.NotNull(expectedSlot); + + var slotValueAccessor = expectedSlot as IRuntimeContextSlotValueAccessor; + Assert.NotNull(slotValueAccessor); + + Assert.Equal(0, expectedSlot.Get()); + Assert.Equal(0, slotValueAccessor.Value); + + slotValueAccessor.Value = 100; + + Assert.Equal(100, expectedSlot.Get()); + Assert.Equal(100, slotValueAccessor.Value); + + slotValueAccessor.Value = null; + + Assert.Equal(0, expectedSlot.Get()); + Assert.Equal(0, slotValueAccessor.Value); + + Assert.Throws(() => slotValueAccessor.Value = false); + } + + [Fact] + public void NullableValueTypeSlotNullableTests() + { + var expectedSlot = RuntimeContext.RegisterSlot("testslot_nullablevaluetype"); + Assert.NotNull(expectedSlot); + + var slotValueAccessor = expectedSlot as IRuntimeContextSlotValueAccessor; + Assert.NotNull(slotValueAccessor); + + Assert.Null(expectedSlot.Get()); + Assert.Null(slotValueAccessor.Value); + + slotValueAccessor.Value = 100; + + Assert.Equal(100, expectedSlot.Get()); + Assert.Equal(100, slotValueAccessor.Value); + + slotValueAccessor.Value = null; + + Assert.Null(expectedSlot.Get()); + Assert.Null(slotValueAccessor.Value); + + Assert.Throws(() => slotValueAccessor.Value = false); + } + + [Fact] + public void ReferenceTypeSlotNullableTests() + { + var expectedSlot = RuntimeContext.RegisterSlot("testslot_referencetype"); + Assert.NotNull(expectedSlot); + + var slotValueAccessor = expectedSlot as IRuntimeContextSlotValueAccessor; + Assert.NotNull(slotValueAccessor); + + Assert.Null(expectedSlot.Get()); + Assert.Null(slotValueAccessor.Value); + + slotValueAccessor.Value = this; + + Assert.Equal(this, expectedSlot.Get()); + Assert.Equal(this, slotValueAccessor.Value); + + slotValueAccessor.Value = null; + + Assert.Null(expectedSlot.Get()); + Assert.Null(slotValueAccessor.Value); + + Assert.Throws(() => slotValueAccessor.Value = new object()); + } + #if NETFRAMEWORK [Fact] public void NetFrameworkGetSlotInAnotherAppDomain() { const string slotName = "testSlot"; var slot = RuntimeContext.RegisterSlot(slotName); + Assert.NotNull(slot); slot.Set(100); // Create an object in another AppDomain and try to access the slot From c1f1c167d27234b6a8fe2eb5bf1198eee8a5abac Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Tue, 24 Sep 2024 23:31:04 +0200 Subject: [PATCH 091/133] [Api] Nullable (#5801) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Mikel Blanchard --- .../ActivityContextExtensions.cs | 2 - src/OpenTelemetry.Api/Baggage.cs | 2 - src/OpenTelemetry.Api/BaseProvider.cs | 2 - .../Context/AsyncLocalRuntimeContextSlot.cs | 2 - .../IRuntimeContextSlotValueAccessor.cs | 2 - .../Context/Propagation/B3Propagator.cs | 2 - .../Context/Propagation/BaggagePropagator.cs | 2 - .../Propagation/CompositeTextMapPropagator.cs | 2 - .../Propagation/NoopTextMapPropagator.cs | 2 - .../Context/Propagation/PropagationContext.cs | 2 - .../Context/Propagation/Propagators.cs | 2 - .../Context/Propagation/TextMapPropagator.cs | 2 - .../Propagation/TraceContextPropagator.cs | 2 - .../Context/Propagation/TraceStateUtilsNew.cs | 2 - .../Context/RemotingRuntimeContextSlot.cs | 1 - .../Context/RuntimeContext.cs | 2 - .../Context/RuntimeContextSlot.cs | 2 - .../Context/ThreadLocalRuntimeContextSlot.cs | 2 - .../Internal/OpenTelemetryApiEventSource.cs | 2 - .../Logs/IDeferredLoggerProviderBuilder.cs | 2 - .../Logs/LogRecordAttributeList.cs | 2 - src/OpenTelemetry.Api/Logs/LogRecordData.cs | 2 - .../Logs/LogRecordSeverity.cs | 2 - .../Logs/LogRecordSeverityExtensions.cs | 2 - src/OpenTelemetry.Api/Logs/Logger.cs | 2 - src/OpenTelemetry.Api/Logs/LoggerProvider.cs | 2 - .../Logs/LoggerProviderBuilder.cs | 2 - src/OpenTelemetry.Api/Logs/NoopLogger.cs | 2 - .../Metrics/IDeferredMeterProviderBuilder.cs | 2 - .../Metrics/MeterProvider.cs | 2 - .../Metrics/MeterProviderBuilder.cs | 2 - .../OpenTelemetry.Api.csproj | 3 - .../Trace/ActivityExtensions.cs | 2 - .../Trace/IDeferredTracerProviderBuilder.cs | 2 - src/OpenTelemetry.Api/Trace/Link.cs | 2 - src/OpenTelemetry.Api/Trace/SpanAttributes.cs | 2 - src/OpenTelemetry.Api/Trace/SpanContext.cs | 2 - src/OpenTelemetry.Api/Trace/SpanKind.cs | 2 - src/OpenTelemetry.Api/Trace/Status.cs | 2 - src/OpenTelemetry.Api/Trace/StatusCode.cs | 2 - src/OpenTelemetry.Api/Trace/TelemetrySpan.cs | 2 - src/OpenTelemetry.Api/Trace/Tracer.cs | 2 - src/OpenTelemetry.Api/Trace/TracerProvider.cs | 2 - .../Trace/TracerProviderBuilder.cs | 2 - src/Shared/Guard.cs | 4 +- test/OpenTelemetry.Api.Tests/BaggageTests.cs | 10 +-- .../Context/Propagation/B3PropagatorTest.cs | 2 - .../Propagation/BaggagePropagatorTest.cs | 2 - .../Propagation/CompositePropagatorTest.cs | 2 - .../Context/Propagation/PropagatorsTest.cs | 2 - .../Context/Propagation/TestPropagator.cs | 2 - .../Propagation/TracestateUtilsTests.cs | 2 - .../Internal/GuardTest.cs | 15 ++-- .../Logs/LogRecordAttributeListTests.cs | 10 ++- .../Logs/LogRecordDataTests.cs | 2 - .../Logs/LogRecordSeverityExtensionsTests.cs | 2 - .../Logs/LoggerProviderTests.cs | 2 - .../OpenTelemetry.Api.Tests.csproj | 3 - .../Trace/ActivityExtensionsTest.cs | 2 +- .../Trace/SpanAttributesTest.cs | 14 ++-- .../Trace/TelemetrySpanTest.cs | 3 + .../Trace/TracerTest.cs | 68 ++++++++++++------- 62 files changed, 78 insertions(+), 157 deletions(-) diff --git a/src/OpenTelemetry.Api/ActivityContextExtensions.cs b/src/OpenTelemetry.Api/ActivityContextExtensions.cs index f50a9af8fee..fb630ae6613 100644 --- a/src/OpenTelemetry.Api/ActivityContextExtensions.cs +++ b/src/OpenTelemetry.Api/ActivityContextExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; // The ActivityContext class is in the System.Diagnostics namespace. diff --git a/src/OpenTelemetry.Api/Baggage.cs b/src/OpenTelemetry.Api/Baggage.cs index 835cb3a23f6..93b972f4f17 100644 --- a/src/OpenTelemetry.Api/Baggage.cs +++ b/src/OpenTelemetry.Api/Baggage.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Context; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/BaseProvider.cs b/src/OpenTelemetry.Api/BaseProvider.cs index ce8e30a46b7..117f18c3c6d 100644 --- a/src/OpenTelemetry.Api/BaseProvider.cs +++ b/src/OpenTelemetry.Api/BaseProvider.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry; /// diff --git a/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs index 0c7d5f0cbf8..7bafc0e951d 100644 --- a/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Runtime.CompilerServices; namespace OpenTelemetry.Context; diff --git a/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs b/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs index 0d537c67cd3..19c02050cd8 100644 --- a/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs +++ b/src/OpenTelemetry.Api/Context/IRuntimeContextSlotValueAccessor.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Context; /// diff --git a/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs b/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs index 5969d2499c1..18276172106 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/B3Propagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs index e3ca4fd96c9..938980931e9 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/BaggagePropagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET using System.Diagnostics.CodeAnalysis; #endif diff --git a/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs index 5b6939842b0..e160bc8ac78 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/CompositeTextMapPropagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using OpenTelemetry.Internal; namespace OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs index 6efd538e820..a722a4f087a 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Context.Propagation; internal sealed class NoopTextMapPropagator : TextMapPropagator diff --git a/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs b/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs index bb35c88cadc..0923ed45d6d 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/PropagationContext.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; namespace OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs b/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs index ee9c59931f5..c1dab62400d 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Context.Propagation; /// diff --git a/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs index 547d6a1890c..bb0432378b5 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/TextMapPropagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Context.Propagation; /// diff --git a/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs index dfa828e088b..ee67aaaaafb 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/TraceContextPropagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs b/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs index e1fe192bd6d..eef28f8ad97 100644 --- a/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs +++ b/src/OpenTelemetry.Api/Context/Propagation/TraceStateUtilsNew.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs index 6286c4044bf..93f7bd4754d 100644 --- a/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK -#nullable enable using System.Collections; using System.Reflection; diff --git a/src/OpenTelemetry.Api/Context/RuntimeContext.cs b/src/OpenTelemetry.Api/Context/RuntimeContext.cs index c544d7a59bb..c984147bf49 100644 --- a/src/OpenTelemetry.Api/Context/RuntimeContext.cs +++ b/src/OpenTelemetry.Api/Context/RuntimeContext.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Collections.Concurrent; using System.Runtime.CompilerServices; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs index bb1321d79c8..a89afd394a3 100644 --- a/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using OpenTelemetry.Internal; namespace OpenTelemetry.Context; diff --git a/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs index 35db8bcf924..360f9df564b 100644 --- a/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs +++ b/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Runtime.CompilerServices; namespace OpenTelemetry.Context; diff --git a/src/OpenTelemetry.Api/Internal/OpenTelemetryApiEventSource.cs b/src/OpenTelemetry.Api/Internal/OpenTelemetryApiEventSource.cs index ea802a6ed15..5ac56d362f3 100644 --- a/src/OpenTelemetry.Api/Internal/OpenTelemetryApiEventSource.cs +++ b/src/OpenTelemetry.Api/Internal/OpenTelemetryApiEventSource.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.Tracing; namespace OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs b/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs index 7421a9df268..11397157cea 100644 --- a/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Logs; /// diff --git a/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs b/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs index bea5f953882..2aeecf3d88c 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordAttributeList.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Collections; using System.ComponentModel; using System.Diagnostics; diff --git a/src/OpenTelemetry.Api/Logs/LogRecordData.cs b/src/OpenTelemetry.Api/Logs/LogRecordData.cs index 92bb2765a23..20d8d5f264c 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordData.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordData.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; #if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; diff --git a/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs b/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs index b849abdcffa..b6a5b3e000a 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs b/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs index e5cb23d7fa0..81453d0302f 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Logs/Logger.cs b/src/OpenTelemetry.Api/Logs/Logger.cs index 8318ed92c85..f8a50f2a6dd 100644 --- a/src/OpenTelemetry.Api/Logs/Logger.cs +++ b/src/OpenTelemetry.Api/Logs/Logger.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET && EXPOSE_EXPERIMENTAL_FEATURES using System.Diagnostics.CodeAnalysis; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Logs/LoggerProvider.cs b/src/OpenTelemetry.Api/Logs/LoggerProvider.cs index 018658446cd..71cc40e2325 100644 --- a/src/OpenTelemetry.Api/Logs/LoggerProvider.cs +++ b/src/OpenTelemetry.Api/Logs/LoggerProvider.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NETSTANDARD2_1_OR_GREATER || NET using System.Diagnostics.CodeAnalysis; #endif diff --git a/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs b/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs index b0aec6bfca7..2bc69d1d0c6 100644 --- a/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Logs; /// diff --git a/src/OpenTelemetry.Api/Logs/NoopLogger.cs b/src/OpenTelemetry.Api/Logs/NoopLogger.cs index f33ec668aca..2c2b61c4185 100644 --- a/src/OpenTelemetry.Api/Logs/NoopLogger.cs +++ b/src/OpenTelemetry.Api/Logs/NoopLogger.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Logs; internal sealed class NoopLogger : Logger diff --git a/src/OpenTelemetry.Api/Metrics/IDeferredMeterProviderBuilder.cs b/src/OpenTelemetry.Api/Metrics/IDeferredMeterProviderBuilder.cs index c283219c431..5f0dc38d34e 100644 --- a/src/OpenTelemetry.Api/Metrics/IDeferredMeterProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Metrics/IDeferredMeterProviderBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Metrics; /// diff --git a/src/OpenTelemetry.Api/Metrics/MeterProvider.cs b/src/OpenTelemetry.Api/Metrics/MeterProvider.cs index a16fd88df93..64fcb5e8e52 100644 --- a/src/OpenTelemetry.Api/Metrics/MeterProvider.cs +++ b/src/OpenTelemetry.Api/Metrics/MeterProvider.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Metrics; /// diff --git a/src/OpenTelemetry.Api/Metrics/MeterProviderBuilder.cs b/src/OpenTelemetry.Api/Metrics/MeterProviderBuilder.cs index 95075dbe703..4fb6bb007dd 100644 --- a/src/OpenTelemetry.Api/Metrics/MeterProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Metrics/MeterProviderBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Metrics; /// diff --git a/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj b/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj index 0a781a94173..403ed430bfc 100644 --- a/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj +++ b/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj @@ -4,9 +4,6 @@ OpenTelemetry .NET API OpenTelemetry core- - - - disable diff --git a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs index 7c2a0854419..b22339267ba 100644 --- a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs +++ b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Runtime.CompilerServices; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Trace/IDeferredTracerProviderBuilder.cs b/src/OpenTelemetry.Api/Trace/IDeferredTracerProviderBuilder.cs index 8be46ae4432..7b0d3f71232 100644 --- a/src/OpenTelemetry.Api/Trace/IDeferredTracerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Trace/IDeferredTracerProviderBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Trace; /// diff --git a/src/OpenTelemetry.Api/Trace/Link.cs b/src/OpenTelemetry.Api/Trace/Link.cs index 45af8791625..1972a624c25 100644 --- a/src/OpenTelemetry.Api/Trace/Link.cs +++ b/src/OpenTelemetry.Api/Trace/Link.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; namespace OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Api/Trace/SpanAttributes.cs b/src/OpenTelemetry.Api/Trace/SpanAttributes.cs index 84850ae048d..5975830c98c 100644 --- a/src/OpenTelemetry.Api/Trace/SpanAttributes.cs +++ b/src/OpenTelemetry.Api/Trace/SpanAttributes.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Trace/SpanContext.cs b/src/OpenTelemetry.Api/Trace/SpanContext.cs index dff0de021c2..825ad62bb41 100644 --- a/src/OpenTelemetry.Api/Trace/SpanContext.cs +++ b/src/OpenTelemetry.Api/Trace/SpanContext.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Api/Trace/SpanKind.cs b/src/OpenTelemetry.Api/Trace/SpanKind.cs index f3237a6bd4a..07358f7b0e8 100644 --- a/src/OpenTelemetry.Api/Trace/SpanKind.cs +++ b/src/OpenTelemetry.Api/Trace/SpanKind.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Trace; /// diff --git a/src/OpenTelemetry.Api/Trace/Status.cs b/src/OpenTelemetry.Api/Trace/Status.cs index b7d0eb35c32..a39ee8dd754 100644 --- a/src/OpenTelemetry.Api/Trace/Status.cs +++ b/src/OpenTelemetry.Api/Trace/Status.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Trace; /// diff --git a/src/OpenTelemetry.Api/Trace/StatusCode.cs b/src/OpenTelemetry.Api/Trace/StatusCode.cs index 9332d708d06..28d691c10e6 100644 --- a/src/OpenTelemetry.Api/Trace/StatusCode.cs +++ b/src/OpenTelemetry.Api/Trace/StatusCode.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Trace; /// diff --git a/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs b/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs index cdae8d4292c..47e67c6095a 100644 --- a/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs +++ b/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Runtime.CompilerServices; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Api/Trace/Tracer.cs b/src/OpenTelemetry.Api/Trace/Tracer.cs index 2a8c6e8e0a3..d0fb906ec18 100644 --- a/src/OpenTelemetry.Api/Trace/Tracer.cs +++ b/src/OpenTelemetry.Api/Trace/Tracer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Api/Trace/TracerProvider.cs b/src/OpenTelemetry.Api/Trace/TracerProvider.cs index 56fa2e90a72..21197d0abdb 100644 --- a/src/OpenTelemetry.Api/Trace/TracerProvider.cs +++ b/src/OpenTelemetry.Api/Trace/TracerProvider.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Collections.Concurrent; #if NET using System.Diagnostics.CodeAnalysis; diff --git a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs index 0a8c3dae3da..ac9b7a2dbe2 100644 --- a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; namespace OpenTelemetry.Trace; diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index 4e46d9f3384..abf894243aa 100644 --- a/src/Shared/Guard.cs +++ b/src/Shared/Guard.cs @@ -19,12 +19,12 @@ namespace System.Runtime.CompilerServices [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] internal sealed class CallerArgumentExpressionAttribute : Attribute { - public CallerArgumentExpressionAttribute(string parameterName) + public CallerArgumentExpressionAttribute(string? parameterName) { this.ParameterName = parameterName; } - public string ParameterName { get; } + public string? ParameterName { get; } } } #endif diff --git a/test/OpenTelemetry.Api.Tests/BaggageTests.cs b/test/OpenTelemetry.Api.Tests/BaggageTests.cs index 32bc6a74f62..d4fc1e26c45 100644 --- a/test/OpenTelemetry.Api.Tests/BaggageTests.cs +++ b/test/OpenTelemetry.Api.Tests/BaggageTests.cs @@ -180,11 +180,11 @@ public void EnumeratorTest() [Fact] public void EqualsTest() { - var bc1 = new Baggage(new Dictionary() { [K1] = V1, [K2] = V2 }); - var bc2 = new Baggage(new Dictionary() { [K1] = V1, [K2] = V2 }); - var bc3 = new Baggage(new Dictionary() { [K2] = V2, [K1] = V1 }); - var bc4 = new Baggage(new Dictionary() { [K1] = V1, [K2] = V1 }); - var bc5 = new Baggage(new Dictionary() { [K1] = V2, [K2] = V1 }); + var bc1 = new Baggage(new Dictionary { [K1] = V1, [K2] = V2 }); + var bc2 = new Baggage(new Dictionary { [K1] = V1, [K2] = V2 }); + var bc3 = new Baggage(new Dictionary { [K2] = V2, [K1] = V1 }); + var bc4 = new Baggage(new Dictionary { [K1] = V1, [K2] = V1 }); + var bc5 = new Baggage(new Dictionary { [K1] = V2, [K2] = V1 }); Assert.True(bc1.Equals(bc2)); diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs index 1cef6ae90e9..4ff05249c52 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/B3PropagatorTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Xunit; using Xunit.Abstractions; diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs index 0f236081331..6575d2949f1 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/BaggagePropagatorTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Net; using Xunit; diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs index 4009ed756a6..b70565affa8 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/CompositePropagatorTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Xunit; diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs index 3216baec7d7..b7993e0d848 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/PropagatorsTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Context.Propagation.Tests; diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs index a2a8ab39234..ec791743f56 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/TestPropagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; namespace OpenTelemetry.Context.Propagation.Tests; diff --git a/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs b/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs index f1271938a5a..deb9fc9e8fb 100644 --- a/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs +++ b/test/OpenTelemetry.Api.Tests/Context/Propagation/TracestateUtilsTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Context.Propagation.Tests; diff --git a/test/OpenTelemetry.Api.Tests/Internal/GuardTest.cs b/test/OpenTelemetry.Api.Tests/Internal/GuardTest.cs index 591ed00fad5..a2af242b973 100644 --- a/test/OpenTelemetry.Api.Tests/Internal/GuardTest.cs +++ b/test/OpenTelemetry.Api.Tests/Internal/GuardTest.cs @@ -20,17 +20,17 @@ public void NullTest() Guard.ThrowIfNull("hello"); // Invalid - object potato = null; + object? potato = null; var ex1 = Assert.Throws(() => Guard.ThrowIfNull(potato)); Assert.Contains("Must not be null", ex1.Message); Assert.Equal("potato", ex1.ParamName); - object @event = null; + object? @event = null; var ex2 = Assert.Throws(() => Guard.ThrowIfNull(@event)); Assert.Contains("Must not be null", ex2.Message); Assert.Equal("@event", ex2.ParamName); - Thing thing = null; + Thing? thing = null; var ex3 = Assert.Throws(() => Guard.ThrowIfNull(thing?.Bar)); Assert.Contains("Must not be null", ex3.Message); Assert.Equal("thing?.Bar", ex3.ParamName); @@ -153,12 +153,12 @@ public void ZeroTest() public class Thing { - public string Bar { get; set; } + public string? Bar { get; set; } } #if !NET /// - /// Borrowed from: . + /// Borrowed from: . /// public class CallerArgumentExpressionAttributeTests { @@ -166,7 +166,7 @@ public class CallerArgumentExpressionAttributeTests [InlineData(null)] [InlineData("")] [InlineData("paramName")] - public static void Ctor_ParameterName_Roundtrip(string value) + public static void Ctor_ParameterName_Roundtrip(string? value) { var caea = new CallerArgumentExpressionAttribute(value); Assert.Equal(value, caea.ParameterName); @@ -175,12 +175,13 @@ public static void Ctor_ParameterName_Roundtrip(string value) [Fact] public static void BasicTest() { + Assert.Equal("null", GetValue(null)); Assert.Equal("\"hello\"", GetValue("hello")); Assert.Equal("3 + 2", GetValue(3 + 2)); Assert.Equal("new object()", GetValue(new object())); } - private static string GetValue(object argument, [CallerArgumentExpression("argument")] string expr = null) => expr; + private static string? GetValue(object? argument, [CallerArgumentExpression(nameof(argument))] string? expr = null) => expr; } #endif } diff --git a/test/OpenTelemetry.Api.Tests/Logs/LogRecordAttributeListTests.cs b/test/OpenTelemetry.Api.Tests/Logs/LogRecordAttributeListTests.cs index c09c728cd55..6cc8486a23c 100644 --- a/test/OpenTelemetry.Api.Tests/Logs/LogRecordAttributeListTests.cs +++ b/test/OpenTelemetry.Api.Tests/Logs/LogRecordAttributeListTests.cs @@ -29,13 +29,15 @@ public void ReadWriteTest(int numberOfItems) var item = attributes[i]; Assert.Equal($"key{i}", item.Key); + Assert.NotNull(item.Value); Assert.Equal(i, (int)item.Value); } int index = 0; - foreach (KeyValuePair item in attributes) + foreach (KeyValuePair item in attributes) { Assert.Equal($"key{index}", item.Key); + Assert.NotNull(item.Value); Assert.Equal(index, (int)item.Value); index++; } @@ -74,6 +76,7 @@ public void ClearTest(int numberOfItems) var item = attributes[i]; Assert.Equal($"key{i}", item.Key); + Assert.NotNull(item.Value); Assert.Equal(i, (int)item.Value); } @@ -98,7 +101,7 @@ public void ExportTest(int numberOfItems) attributes.Add($"key{i}", i); } - List> storage = null; + List>? storage = null; var exportedAttributes = attributes.Export(ref storage); @@ -122,9 +125,10 @@ public void ExportTest(int numberOfItems) } int index = 0; - foreach (KeyValuePair item in exportedAttributes) + foreach (KeyValuePair item in exportedAttributes) { Assert.Equal($"key{index}", item.Key); + Assert.NotNull(item.Value); Assert.Equal(index, (int)item.Value); index++; } diff --git a/test/OpenTelemetry.Api.Tests/Logs/LogRecordDataTests.cs b/test/OpenTelemetry.Api.Tests/Logs/LogRecordDataTests.cs index 89d32795d6f..03d65ab3dd0 100644 --- a/test/OpenTelemetry.Api.Tests/Logs/LogRecordDataTests.cs +++ b/test/OpenTelemetry.Api.Tests/Logs/LogRecordDataTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Xunit; diff --git a/test/OpenTelemetry.Api.Tests/Logs/LogRecordSeverityExtensionsTests.cs b/test/OpenTelemetry.Api.Tests/Logs/LogRecordSeverityExtensionsTests.cs index 9035898cc66..10d2f90896d 100644 --- a/test/OpenTelemetry.Api.Tests/Logs/LogRecordSeverityExtensionsTests.cs +++ b/test/OpenTelemetry.Api.Tests/Logs/LogRecordSeverityExtensionsTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Logs.Tests; diff --git a/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs b/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs index 47d509208c4..27078c6307e 100644 --- a/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs +++ b/test/OpenTelemetry.Api.Tests/Logs/LoggerProviderTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NETSTANDARD2_1_OR_GREATER || NET using System.Diagnostics.CodeAnalysis; #endif diff --git a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj index c8463d88343..e6a6749107c 100644 --- a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj +++ b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj @@ -3,9 +3,6 @@ Unit test project for OpenTelemetry.Api $(TargetFrameworksForTests) $(NoWarn),CS0618 - - - disable diff --git a/test/OpenTelemetry.Api.Tests/Trace/ActivityExtensionsTest.cs b/test/OpenTelemetry.Api.Tests/Trace/ActivityExtensionsTest.cs index 31fbf806725..5f7a6ff5493 100644 --- a/test/OpenTelemetry.Api.Tests/Trace/ActivityExtensionsTest.cs +++ b/test/OpenTelemetry.Api.Tests/Trace/ActivityExtensionsTest.cs @@ -202,7 +202,7 @@ public void GetTagValue() [Theory] [InlineData("Key", "Value", true)] [InlineData("CustomTag", null, false)] - public void TryCheckFirstTag(string tagName, object expectedTagValue, bool expectedResult) + public void TryCheckFirstTag(string tagName, object? expectedTagValue, bool expectedResult) { using var activity = new Activity("Test"); activity.SetTag("Key", "Value"); diff --git a/test/OpenTelemetry.Api.Tests/Trace/SpanAttributesTest.cs b/test/OpenTelemetry.Api.Tests/Trace/SpanAttributesTest.cs index f0c5c7c110f..abf35e39350 100644 --- a/test/OpenTelemetry.Api.Tests/Trace/SpanAttributesTest.cs +++ b/test/OpenTelemetry.Api.Tests/Trace/SpanAttributesTest.cs @@ -37,7 +37,7 @@ public void ValidateAddMethods() public void ValidateNullKey() { var spanAttribute = new SpanAttributes(); - Assert.Throws(() => spanAttribute.Add(null, "null key")); + Assert.Throws(() => spanAttribute.Add(null!, "null key")); } [Fact] @@ -53,17 +53,17 @@ public void ValidateSameKey() public void ValidateConstructorWithList() { var spanAttributes = new SpanAttributes( - new List>() - { - new KeyValuePair("Span attribute int", 1), - new KeyValuePair("Span attribute string", "str"), - }); + new List> + { + new("Span attribute int", 1), + new("Span attribute string", "str"), + }); Assert.Equal(2, spanAttributes.Attributes.Count); } [Fact] public void ValidateConstructorWithNullList() { - Assert.Throws(() => new SpanAttributes(null)); + Assert.Throws(() => new SpanAttributes(null!)); } } diff --git a/test/OpenTelemetry.Api.Tests/Trace/TelemetrySpanTest.cs b/test/OpenTelemetry.Api.Tests/Trace/TelemetrySpanTest.cs index 6434569e1d9..a8c281deae5 100644 --- a/test/OpenTelemetry.Api.Tests/Trace/TelemetrySpanTest.cs +++ b/test/OpenTelemetry.Api.Tests/Trace/TelemetrySpanTest.cs @@ -18,6 +18,7 @@ public void CheckRecordExceptionData() telemetrySpan.RecordException(new ArgumentNullException(message, new Exception("new-exception"))); Assert.Single(activity.Events); + Assert.NotNull(telemetrySpan.Activity); var @event = telemetrySpan.Activity.Events.FirstOrDefault(q => q.Name == SemanticConventions.AttributeExceptionEventName); Assert.Equal(message, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionMessage).Value); Assert.Equal(typeof(ArgumentNullException).Name, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionType).Value); @@ -35,6 +36,7 @@ public void CheckRecordExceptionData2() telemetrySpan.RecordException(type, message, stack); Assert.Single(activity.Events); + Assert.NotNull(telemetrySpan.Activity); var @event = telemetrySpan.Activity.Events.FirstOrDefault(q => q.Name == SemanticConventions.AttributeExceptionEventName); Assert.Equal(message, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionMessage).Value); Assert.Equal(type, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionType).Value); @@ -62,6 +64,7 @@ public void ParentIds() // ParentId should be unset Assert.Equal(default, parentSpan.ParentSpanId); + Assert.NotNull(parentActivity.Id); using var childActivity = new Activity("childOperation").SetParentId(parentActivity.Id); using var childSpan = new TelemetrySpan(childActivity); diff --git a/test/OpenTelemetry.Api.Tests/Trace/TracerTest.cs b/test/OpenTelemetry.Api.Tests/Trace/TracerTest.cs index 7c71f41cda0..642795202d0 100644 --- a/test/OpenTelemetry.Api.Tests/Trace/TracerTest.cs +++ b/test/OpenTelemetry.Api.Tests/Trace/TracerTest.cs @@ -53,13 +53,16 @@ public void Tracer_StartRootSpan_BadArgs_NullSpanName() .AddSource("tracername") .Build(); - var span1 = this.tracer.StartRootSpan(null); + var span1 = this.tracer.StartRootSpan(null!); + Assert.NotNull(span1.Activity); Assert.True(string.IsNullOrEmpty(span1.Activity.DisplayName)); - var span2 = this.tracer.StartRootSpan(null, SpanKind.Client); + var span2 = this.tracer.StartRootSpan(null!, SpanKind.Client); + Assert.NotNull(span2.Activity); Assert.True(string.IsNullOrEmpty(span2.Activity.DisplayName)); - var span3 = this.tracer.StartRootSpan(null, SpanKind.Client, default); + var span3 = this.tracer.StartRootSpan(null!, SpanKind.Client, default); + Assert.NotNull(span3.Activity); Assert.True(string.IsNullOrEmpty(span3.Activity.DisplayName)); } @@ -109,13 +112,16 @@ public void Tracer_StartSpan_BadArgs_NullSpanName() .AddSource("tracername") .Build(); - var span1 = this.tracer.StartSpan(null); + var span1 = this.tracer.StartSpan(null!); + Assert.NotNull(span1.Activity); Assert.True(string.IsNullOrEmpty(span1.Activity.DisplayName)); - var span2 = this.tracer.StartSpan(null, SpanKind.Client); + var span2 = this.tracer.StartSpan(null!, SpanKind.Client); + Assert.NotNull(span2.Activity); Assert.True(string.IsNullOrEmpty(span2.Activity.DisplayName)); - var span3 = this.tracer.StartSpan(null, SpanKind.Client, null); + var span3 = this.tracer.StartSpan(null!, SpanKind.Client, null); + Assert.NotNull(span3.Activity); Assert.True(string.IsNullOrEmpty(span3.Activity.DisplayName)); } @@ -126,13 +132,16 @@ public void Tracer_StartActiveSpan_BadArgs_NullSpanName() .AddSource("tracername") .Build(); - var span1 = this.tracer.StartActiveSpan(null); + var span1 = this.tracer.StartActiveSpan(null!); + Assert.NotNull(span1.Activity); Assert.True(string.IsNullOrEmpty(span1.Activity.DisplayName)); - var span2 = this.tracer.StartActiveSpan(null, SpanKind.Client); + var span2 = this.tracer.StartActiveSpan(null!, SpanKind.Client); + Assert.NotNull(span2.Activity); Assert.True(string.IsNullOrEmpty(span2.Activity.DisplayName)); - var span3 = this.tracer.StartActiveSpan(null, SpanKind.Client, null); + var span3 = this.tracer.StartActiveSpan(null!, SpanKind.Client, null); + Assert.NotNull(span3.Activity); Assert.True(string.IsNullOrEmpty(span3.Activity.DisplayName)); } @@ -143,10 +152,12 @@ public void Tracer_StartSpan_FromParent_BadArgs_NullSpanName() .AddSource("tracername") .Build(); - var span1 = this.tracer.StartSpan(null, SpanKind.Client, TelemetrySpan.NoopInstance); + var span1 = this.tracer.StartSpan(null!, SpanKind.Client, TelemetrySpan.NoopInstance); + Assert.NotNull(span1.Activity); Assert.True(string.IsNullOrEmpty(span1.Activity.DisplayName)); - var span2 = this.tracer.StartSpan(null, SpanKind.Client, TelemetrySpan.NoopInstance, default); + var span2 = this.tracer.StartSpan(null!, SpanKind.Client, TelemetrySpan.NoopInstance, default); + Assert.NotNull(span2.Activity); Assert.True(string.IsNullOrEmpty(span2.Activity.DisplayName)); } @@ -159,10 +170,12 @@ public void Tracer_StartSpan_FromParentContext_BadArgs_NullSpanName() var blankContext = default(SpanContext); - var span1 = this.tracer.StartSpan(null, SpanKind.Client, blankContext); + var span1 = this.tracer.StartSpan(null!, SpanKind.Client, blankContext); + Assert.NotNull(span1.Activity); Assert.True(string.IsNullOrEmpty(span1.Activity.DisplayName)); - var span2 = this.tracer.StartSpan(null, SpanKind.Client, blankContext, default); + var span2 = this.tracer.StartSpan(null!, SpanKind.Client, blankContext, default); + Assert.NotNull(span2.Activity); Assert.True(string.IsNullOrEmpty(span2.Activity.DisplayName)); } @@ -173,10 +186,12 @@ public void Tracer_StartActiveSpan_FromParent_BadArgs_NullSpanName() .AddSource("tracername") .Build(); - var span1 = this.tracer.StartActiveSpan(null, SpanKind.Client, TelemetrySpan.NoopInstance); + var span1 = this.tracer.StartActiveSpan(null!, SpanKind.Client, TelemetrySpan.NoopInstance); + Assert.NotNull(span1.Activity); Assert.True(string.IsNullOrEmpty(span1.Activity.DisplayName)); - var span2 = this.tracer.StartActiveSpan(null, SpanKind.Client, TelemetrySpan.NoopInstance, default); + var span2 = this.tracer.StartActiveSpan(null!, SpanKind.Client, TelemetrySpan.NoopInstance, default); + Assert.NotNull(span2.Activity); Assert.True(string.IsNullOrEmpty(span2.Activity.DisplayName)); } @@ -189,10 +204,12 @@ public void Tracer_StartActiveSpan_FromParentContext_BadArgs_NullSpanName() var blankContext = default(SpanContext); - var span1 = this.tracer.StartActiveSpan(null, SpanKind.Client, blankContext); + var span1 = this.tracer.StartActiveSpan(null!, SpanKind.Client, blankContext); + Assert.NotNull(span1.Activity); Assert.True(string.IsNullOrEmpty(span1.Activity.DisplayName)); - var span2 = this.tracer.StartActiveSpan(null, SpanKind.Client, blankContext, default); + var span2 = this.tracer.StartActiveSpan(null!, SpanKind.Client, blankContext, default); + Assert.NotNull(span2.Activity); Assert.True(string.IsNullOrEmpty(span2.Activity.DisplayName)); } @@ -204,19 +221,23 @@ public void Tracer_StartActiveSpan_CreatesActiveSpan() .Build(); var span1 = this.tracer.StartActiveSpan("Test"); + Assert.NotNull(span1.Activity); Assert.Equal(span1.Activity.SpanId, Tracer.CurrentSpan.Context.SpanId); var span2 = this.tracer.StartActiveSpan("Test", SpanKind.Client); + Assert.NotNull(span2.Activity); Assert.Equal(span2.Activity.SpanId, Tracer.CurrentSpan.Context.SpanId); var span = this.tracer.StartSpan("foo"); Tracer.WithSpan(span); var span3 = this.tracer.StartActiveSpan("Test", SpanKind.Client, span); + Assert.NotNull(span3.Activity); Assert.Equal(span3.Activity.SpanId, Tracer.CurrentSpan.Context.SpanId); var spanContext = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); var span4 = this.tracer.StartActiveSpan("Test", SpanKind.Client, spanContext); + Assert.NotNull(span4.Activity); Assert.Equal(span4.Activity.SpanId, Tracer.CurrentSpan.Context.SpanId); } @@ -278,21 +299,21 @@ public void CreateSpan_NotSampled() [Fact] public void TracerBecomesNoopWhenParentProviderIsDisposedTest() { - TracerProvider provider = null; - Tracer tracer = null; + TracerProvider? provider; + Tracer? tracer1; using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("mytracer") .Build()) { provider = tracerProvider; - tracer = tracerProvider.GetTracer("mytracer"); + tracer1 = tracerProvider.GetTracer("mytracer"); - var span1 = tracer.StartSpan("foo"); + var span1 = tracer1.StartSpan("foo"); Assert.True(span1.IsRecording); } - var span2 = tracer.StartSpan("foo"); + var span2 = tracer1.StartSpan("foo"); Assert.False(span2.IsRecording); var tracer2 = provider.GetTracer("mytracer"); @@ -349,9 +370,10 @@ static void InnerTest() Thread[] getTracerThreads = new Thread[testTracerProvider.ExpectedNumberOfThreads]; for (int i = 0; i < testTracerProvider.ExpectedNumberOfThreads; i++) { - getTracerThreads[i] = new Thread((object state) => + getTracerThreads[i] = new Thread((object? state) => { var testTracerProvider = state as TestTracerProvider; + Assert.NotNull(testTracerProvider); var id = Interlocked.Increment(ref testTracerProvider.NumberOfThreads); var name = $"Tracer{id}"; From c8a8913152eb4a983df485f583a22ed706c0cbf4 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 24 Sep 2024 14:47:16 -0700 Subject: [PATCH 092/133] [repo] Take advantage of System.Threading.Lock when compiling against .NET9 (#5861) --- OpenTelemetry.sln | 1 + src/OpenTelemetry.Api/OpenTelemetry.Api.csproj | 1 + .../ConsoleLogRecordExporter.cs | 2 +- ...try.Exporter.Prometheus.HttpListener.csproj | 1 + .../PrometheusHttpListener.cs | 2 +- .../Internal/SelfDiagnosticsEventListener.cs | 2 +- src/OpenTelemetry/Metrics/AggregatorStore.cs | 4 ++-- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 2 +- .../Metrics/Reader/MetricReader.cs | 4 ++-- .../Metrics/Reader/MetricReaderExt.cs | 2 +- src/OpenTelemetry/SimpleExportProcessor.cs | 2 +- src/Shared/Shims/Lock.cs | 18 ++++++++++++++++++ 12 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 src/Shared/Shims/Lock.cs diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 5ca42dd0962..f9bde54e00a 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -281,6 +281,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shims", "Shims", "{A0CB9A10-F22D-4E66-A449-74B3D0361A9C}" ProjectSection(SolutionItems) = preProject src\Shared\Shims\IsExternalInit.cs = src\Shared\Shims\IsExternalInit.cs + src\Shared\Shims\Lock.cs = src\Shared\Shims\Lock.cs src\Shared\Shims\NullableAttributes.cs = src\Shared\Shims\NullableAttributes.cs EndProjectSection EndProject diff --git a/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj b/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj index 403ed430bfc..0e6d270b408 100644 --- a/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj +++ b/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj @@ -16,6 +16,7 @@ + diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs index 9818b17f4b0..0dfe396b30e 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs @@ -10,7 +10,7 @@ namespace OpenTelemetry.Exporter; public class ConsoleLogRecordExporter : ConsoleExporter { private const int RightPaddingLength = 35; - private readonly object syncObject = new(); + private readonly Lock syncObject = new(); private bool disposed; private string? disposedStackTrace; private bool isDisposeMessageSent; diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj index 91fb3f461cf..4e087919be2 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj @@ -19,6 +19,7 @@ + diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs index 284a99acc87..cecda73f7c9 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs @@ -11,7 +11,7 @@ internal sealed class PrometheusHttpListener : IDisposable { private readonly PrometheusExporter exporter; private readonly HttpListener httpListener = new(); - private readonly object syncObject = new(); + private readonly Lock syncObject = new(); private CancellationTokenSource? tokenSource; private Task? workerThread; diff --git a/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs b/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs index cdfe233fd66..2ace3eb5526 100644 --- a/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs +++ b/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs @@ -16,7 +16,7 @@ internal sealed class SelfDiagnosticsEventListener : EventListener // Buffer size of the log line. A UTF-16 encoded character in C# can take up to 4 bytes if encoded in UTF-8. private const int BUFFERSIZE = 4 * 5120; private const string EventSourceNamePrefix = "OpenTelemetry-"; - private readonly object lockObj = new(); + private readonly Lock lockObj = new(); private readonly EventLevel logLevel; private readonly SelfDiagnosticsConfigRefresher configRefresher; private readonly ThreadLocal writeBuffer = new(() => null); diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index 5dc4f92dee9..fbbd598a67a 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -31,8 +31,8 @@ internal sealed class AggregatorStore private static readonly string MetricPointCapHitFixMessage = "Consider opting in for the experimental SDK feature to emit all the throttled metrics under the overflow attribute by setting env variable OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE = true. You could also modify instrumentation to reduce the number of unique key/value pair combinations. Or use Views to drop unwanted tags. Or use MeterProviderBuilder.SetMaxMetricPointsPerMetricStream to set higher limit."; private static readonly Comparison> DimensionComparisonDelegate = (x, y) => x.Key.CompareTo(y.Key); - private readonly object lockZeroTags = new(); - private readonly object lockOverflowTag = new(); + private readonly Lock lockZeroTags = new(); + private readonly Lock lockOverflowTag = new(); private readonly int tagsKeysInterestingCount; // This holds the reclaimed MetricPoints that are available for reuse. diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 467da3f538b..0ec16a9c20a 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -30,7 +30,7 @@ internal sealed class MeterProviderSdk : MeterProvider private readonly List instrumentations = new(); private readonly List> viewConfigs; - private readonly object collectLock = new(); + private readonly Lock collectLock = new(); private readonly MeterListener listener; private readonly MetricReader? reader; private readonly CompositeMetricReader? compositeMetricReader; diff --git a/src/OpenTelemetry/Metrics/Reader/MetricReader.cs b/src/OpenTelemetry/Metrics/Reader/MetricReader.cs index decbf8ad70d..fce60c50f3a 100644 --- a/src/OpenTelemetry/Metrics/Reader/MetricReader.cs +++ b/src/OpenTelemetry/Metrics/Reader/MetricReader.cs @@ -36,8 +36,8 @@ public abstract partial class MetricReader : IDisposable }; }; - private readonly object newTaskLock = new(); - private readonly object onCollectLock = new(); + private readonly Lock newTaskLock = new(); + private readonly Lock onCollectLock = new(); private readonly TaskCompletionSource shutdownTcs = new(); private MetricReaderTemporalityPreference temporalityPreference = MetricReaderTemporalityPreferenceUnspecified; private Func temporalityFunc = CumulativeTemporalityPreferenceFunc; diff --git a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs index a6a0a642d46..def0591d0d4 100644 --- a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs @@ -16,7 +16,7 @@ public abstract partial class MetricReader { private readonly HashSet metricStreamNames = new(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary instrumentIdentityToMetric = new(); - private readonly object instrumentCreationLock = new(); + private readonly Lock instrumentCreationLock = new(); private int metricLimit; private int cardinalityLimit; private Metric?[]? metrics; diff --git a/src/OpenTelemetry/SimpleExportProcessor.cs b/src/OpenTelemetry/SimpleExportProcessor.cs index 10951cd8533..95387ef997f 100644 --- a/src/OpenTelemetry/SimpleExportProcessor.cs +++ b/src/OpenTelemetry/SimpleExportProcessor.cs @@ -12,7 +12,7 @@ namespace OpenTelemetry; public abstract class SimpleExportProcessor : BaseExportProcessor where T : class { - private readonly object syncObject = new(); + private readonly Lock syncObject = new(); /// /// Initializes a new instance of the class. diff --git a/src/Shared/Shims/Lock.cs b/src/Shared/Shims/Lock.cs new file mode 100644 index 00000000000..8b82deb4d5c --- /dev/null +++ b/src/Shared/Shims/Lock.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NET9_0_OR_GREATER +namespace OpenTelemetry; + +// Note: .NET9 added the System.Threading.Lock class. The goal here is when +// compiling against .NET9+ code should use System.Threading.Lock class for +// better perf. Legacy code can use this class which will perform a classic +// monitor-based lock against a reference of this class. This type is not in the +// System.Threading namespace so that the compiler doesn't get confused when it +// sees it used. It is in OpenTelemetry namespace and not OpenTelemetry.Internal +// namespace so that code should be able to use it without the presence of a +// dedicated "using OpenTelemetry.Internal" just for the shim. +internal sealed class Lock +{ +} +#endif From 9cca0ac8f1e5ca5b4d17494b7120d443f997fdf2 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 25 Sep 2024 13:25:25 -0700 Subject: [PATCH 093/133] [repo] Add Mothra as a triager (#5864) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 41ee744c3bd..50d83b153eb 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,7 @@ you're more than welcome to participate! ([@open-telemetry/dotnet-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-triagers)): * [Martin Thwaites](https://github.com/martinjt), Honeycomb +* [Timothy "Mothra" Lee](https://github.com/TimothyMothra), Microsoft [Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): From cc0b9e9d0f874d4cbafd801d4af343f02e4ffbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 26 Sep 2024 18:00:16 +0200 Subject: [PATCH 094/133] [docs] README - Fix links to membership descriptions (#5865) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 50d83b153eb..f0c69d1e1ec 100644 --- a/README.md +++ b/README.md @@ -200,13 +200,13 @@ regardless of your experience level. Whether you're a seasoned OpenTelemetry developer, just starting your journey, or simply curious about the work we do, you're more than welcome to participate! -[Maintainers](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer) +[Maintainers](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer) ([@open-telemetry/dotnet-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-maintainers)): * [Alan West](https://github.com/alanwest), New Relic * [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft -[Approvers](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) +[Approvers](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver) ([@open-telemetry/dotnet-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-approvers)): * [Cijo Thomas](https://github.com/cijothomas), Microsoft @@ -214,14 +214,14 @@ you're more than welcome to participate! * [Reiley Yang](https://github.com/reyang), Microsoft * [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft -[Triagers](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager) +[Triagers](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager) ([@open-telemetry/dotnet-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-triagers)): * [Martin Thwaites](https://github.com/martinjt), Honeycomb * [Timothy "Mothra" Lee](https://github.com/TimothyMothra), Microsoft [Emeritus -Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): +Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager): * [Bruno Garcia](https://github.com/bruno-garcia) * [Eddy Nakamura](https://github.com/eddynaka) From f4e392301f70fd187f0235a9e82a12af64774df9 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 30 Sep 2024 11:41:21 -0700 Subject: [PATCH 095/133] [sdk-metrics] Support .NET 9 Synchronous Gauge (#5867) Co-authored-by: Mikel Blanchard --- docs/metrics/README.md | 2 +- src/OpenTelemetry/CHANGELOG.md | 5 ++ src/OpenTelemetry/Metrics/Metric.cs | 14 +++ .../Metrics/Reader/MetricReader.cs | 1 + .../Metrics/MetricApiTestsBase.cs | 87 +++++++++++++++++++ 5 files changed, 108 insertions(+), 1 deletion(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index a57d92e9b61..db91e62f529 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -86,7 +86,7 @@ static readonly Meter MyMeter = new("MyCompany.MyProduct.MyLibrary", "1.0"); | [Asynchronous Gauge](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#asynchronous-gauge) | [`ObservableGauge`](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.observablegauge-1) | | [Asynchronous UpDownCounter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#asynchronous-updowncounter) | [`ObservableUpDownCounter`](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.observableupdowncounter-1) | | [Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter) | [`Counter`](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.counter-1) | - | [Gauge](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#gauge) (experimental) | N/A | + | [Gauge](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#gauge) | [`Gauge`](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.gauge-1) | | [Histogram](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#histogram) | [`Histogram`](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.histogram-1) | | [UpDownCounter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#updowncounter) | [`UpDownCounter`](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.updowncounter-1) | diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 47b6536a5e5..893b9c6c4d7 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -31,6 +31,11 @@ Notes](../../RELEASENOTES.md). See [#5854](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5854) for details. +* Added support for collecting metrics emitted via the .NET 9 + [Gauge<T>](https://learn.microsoft.com/dotnet/api/system.diagnostics.metrics.gauge-1) + API. + ([#5867](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5867)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry/Metrics/Metric.cs b/src/OpenTelemetry/Metrics/Metric.cs index 7801c2dd452..37dd3198b71 100644 --- a/src/OpenTelemetry/Metrics/Metric.cs +++ b/src/OpenTelemetry/Metrics/Metric.cs @@ -117,6 +117,12 @@ internal Metric( aggType = AggregationType.DoubleGauge; this.MetricType = MetricType.DoubleGauge; } + else if (instrumentIdentity.InstrumentType == typeof(Gauge) + || instrumentIdentity.InstrumentType == typeof(Gauge)) + { + aggType = AggregationType.DoubleGauge; + this.MetricType = MetricType.DoubleGauge; + } else if (instrumentIdentity.InstrumentType == typeof(ObservableGauge) || instrumentIdentity.InstrumentType == typeof(ObservableGauge) || instrumentIdentity.InstrumentType == typeof(ObservableGauge) @@ -125,6 +131,14 @@ internal Metric( aggType = AggregationType.LongGauge; this.MetricType = MetricType.LongGauge; } + else if (instrumentIdentity.InstrumentType == typeof(Gauge) + || instrumentIdentity.InstrumentType == typeof(Gauge) + || instrumentIdentity.InstrumentType == typeof(Gauge) + || instrumentIdentity.InstrumentType == typeof(Gauge)) + { + aggType = AggregationType.LongGauge; + this.MetricType = MetricType.LongGauge; + } else if (instrumentIdentity.IsHistogram) { var explicitBucketBounds = instrumentIdentity.HistogramBucketBounds; diff --git a/src/OpenTelemetry/Metrics/Reader/MetricReader.cs b/src/OpenTelemetry/Metrics/Reader/MetricReader.cs index fce60c50f3a..52353a1155a 100644 --- a/src/OpenTelemetry/Metrics/Reader/MetricReader.cs +++ b/src/OpenTelemetry/Metrics/Reader/MetricReader.cs @@ -27,6 +27,7 @@ public abstract partial class MetricReader : IDisposable // Temporality is not defined for gauges, so this does not really affect anything. var type when type == typeof(ObservableGauge<>) => AggregationTemporality.Delta, + var type when type == typeof(Gauge<>) => AggregationTemporality.Delta, var type when type == typeof(UpDownCounter<>) => AggregationTemporality.Cumulative, var type when type == typeof(ObservableUpDownCounter<>) => AggregationTemporality.Cumulative, diff --git a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs index 41726da14d7..d4088bb0d1a 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs @@ -1613,6 +1613,93 @@ public void UnsupportedMetricInstrument() Assert.Empty(exportedItems); } + [Fact] + public void GaugeIsExportedCorrectly() + { + var exportedItems = new List(); + + using var meter = new Meter($"{Utils.GetCurrentMethodName()}"); + + using var container = this.BuildMeterProvider(out var meterProvider, builder => builder + .AddMeter(meter.Name) + .AddInMemoryExporter(exportedItems)); + + var gauge = meter.CreateGauge(name: "NoiseLevel", unit: "dB", description: "Background Noise Level"); + gauge.Record(10); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + Assert.Single(exportedItems); + var metric = exportedItems[0]; + Assert.Equal("Background Noise Level", metric.Description); + List metricPoints = new List(); + foreach (ref readonly var mp in metric.GetMetricPoints()) + { + metricPoints.Add(mp); + } + + var lastValue = metricPoints[0].GetGaugeLastValueLong(); + Assert.Equal(10, lastValue); + } + + [Theory] + [InlineData(MetricReaderTemporalityPreference.Cumulative)] + [InlineData(MetricReaderTemporalityPreference.Delta)] + public void GaugeHandlesNoNewMeasurementsCorrectlyWithTemporality(MetricReaderTemporalityPreference temporalityPreference) + { + var exportedMetrics = new List(); + + using var meter = new Meter($"{Utils.GetCurrentMethodName()}"); + using var container = this.BuildMeterProvider(out var meterProvider, builder => builder + .AddMeter(meter.Name) + .AddInMemoryExporter(exportedMetrics, metricReaderOptions => + { + metricReaderOptions.TemporalityPreference = temporalityPreference; + })); + + var noiseLevelGauge = meter.CreateGauge(name: "NoiseLevel", unit: "dB", description: "Background Noise Level"); + noiseLevelGauge.Record(10); + + // Force a flush to export the recorded data + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + // Validate first export / flush + var firstMetric = exportedMetrics[0]; + var firstMetricPoints = new List(); + foreach (ref readonly var metricPoint in firstMetric.GetMetricPoints()) + { + firstMetricPoints.Add(metricPoint); + } + + Assert.Single(firstMetricPoints); + var firstMetricPoint = firstMetricPoints[0]; + Assert.Equal(10, firstMetricPoint.GetGaugeLastValueLong()); + + // Flush the metrics again without recording any new measurements + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + // Validate second export / flush + if (temporalityPreference == MetricReaderTemporalityPreference.Cumulative) + { + // For cumulative temporality, data points should still be collected + // without any new measurements + Assert.Equal(2, exportedMetrics.Count); + var secondMetric = exportedMetrics[1]; + var secondMetricPoints = new List(); + foreach (ref readonly var metricPoint in secondMetric.GetMetricPoints()) + { + secondMetricPoints.Add(metricPoint); + } + + Assert.Single(secondMetricPoints); + var secondMetricPoint = secondMetricPoints[0]; + Assert.Equal(10, secondMetricPoint.GetGaugeLastValueLong()); + } + else if (temporalityPreference == MetricReaderTemporalityPreference.Delta) + { + // For delta temporality, no new metric should be collected + Assert.Single(exportedMetrics); + } + } + internal static IConfiguration BuildConfiguration(bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) { var configurationData = new Dictionary(); From 1aa101bbcff1607b436a275685f661bb2c2432c0 Mon Sep 17 00:00:00 2001 From: Paulo Ferreira Date: Mon, 30 Sep 2024 19:50:12 +0100 Subject: [PATCH 096/133] [docs] Fix RecordAndSample typo (#5870) Co-authored-by: Mikel Blanchard --- docs/trace/extending-the-sdk/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/trace/extending-the-sdk/README.md b/docs/trace/extending-the-sdk/README.md index 00f72ddec09..db75bad7131 100644 --- a/docs/trace/extending-the-sdk/README.md +++ b/docs/trace/extending-the-sdk/README.md @@ -338,7 +338,7 @@ class MySampler : Sampler { public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { - return new SamplingResult(SamplingDecision.RecordAndSampled); + return new SamplingResult(SamplingDecision.RecordAndSample); } } ``` From f5023550bcea9213dda54eccfa51cf5c9328ff3f Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:00:22 -0500 Subject: [PATCH 097/133] [release] Prepare release core-1.10.0-beta.1 (#5871) --- src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Api/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.Console/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md | 4 ++++ src/OpenTelemetry/CHANGELOG.md | 4 ++++ 9 files changed, 36 insertions(+) diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md index 7af158935fc..2f71fc3655c 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md @@ -7,6 +7,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + * Updated `Microsoft.Extensions.DependencyInjection.Abstractions` package version to `9.0.0-rc.1.24431.7`. ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 5f2c9925eb3..2b5b0e883e8 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + * **Breaking change:** CompositeTextMapPropagator.Fields now returns a unioned set of fields from all combined propagators. Previously this always returned an empty set. diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index 14c7dcb2e5b..61b18117e7b 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md index 9896195900b..100ea1551e8 100644 --- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index e90109e737b..1c62bad01a9 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -7,6 +7,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + * **Breaking change**: Non-primitive attribute (logs) and tag (traces) values converted using `Convert.ToString` will now format using `CultureInfo.InvariantCulture`. diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index 9303d9dd88f..b2094347059 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + * **Breaking change**: Non-primitive tag values converted using `Convert.ToString` will now format using `CultureInfo.InvariantCulture`. ([#5700](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5700)) diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index 935f07ffc55..3ddfe3372df 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + * Updated `Microsoft.Extensions.Hosting.Abstractions` package version to `9.0.0-rc.1.24431.7`. ([#5853](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5853)) diff --git a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md index aaba4c79496..60128b5a7d1 100644 --- a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md @@ -6,6 +6,10 @@ covering all components see: [Release Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 893b9c6c4d7..d14170c35f1 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Sep-30 + * Added `OpenTelemetrySdk.Create` API for configuring OpenTelemetry .NET signals (logging, tracing, and metrics) via a single builder. This new API simplifies bootstrap and teardown, and supports cross-cutting extensions targeting From 19e1663c1e9485948d522d4f6d77ab652d6033bc Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Tue, 1 Oct 2024 23:16:32 +0200 Subject: [PATCH 098/133] [Extensions.Hosting.Tests] Nullable (#5862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Mikel Blanchard --- ...nTelemetry.Extensions.Hosting.Tests.csproj | 2 - .../OpenTelemetryServicesExtensionsTests.cs | 12 +- .../Metrics/AggregatorTestsBase.cs | 33 ++-- .../Metrics/MetricApiTestsBase.cs | 176 +++++++++--------- .../Metrics/MetricTestsBase.cs | 30 +-- .../Metrics/MetricViewTests.cs | 24 +-- .../Shared/SkipUnlessTrueTheoryAttribute.cs | 2 +- 7 files changed, 145 insertions(+), 134 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj index 7dec47d5464..73299e92b02 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj @@ -2,8 +2,6 @@ Unit test project for OpenTelemetry .NET Core hosting library $(TargetFrameworksForTests) - - disable $(DefineConstants);BUILDING_HOSTING_TESTS diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetryServicesExtensionsTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetryServicesExtensionsTests.cs index 0753220b6cc..16ee08af2c5 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetryServicesExtensionsTests.cs +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetryServicesExtensionsTests.cs @@ -129,7 +129,7 @@ public async Task AddOpenTelemetry_WithTracing_HostConfigurationHonoredTest() var builder = new HostBuilder() .ConfigureAppConfiguration(builder => { - builder.AddInMemoryCollection(new Dictionary + builder.AddInMemoryCollection(new Dictionary { ["TEST_KEY"] = "TEST_KEY_VALUE", }); @@ -147,7 +147,7 @@ public async Task AddOpenTelemetry_WithTracing_HostConfigurationHonoredTest() var configuration = sp.GetRequiredService(); - var testKeyValue = configuration.GetValue("TEST_KEY", null); + var testKeyValue = configuration.GetValue("TEST_KEY", null); Assert.Equal("TEST_KEY_VALUE", testKeyValue); }); @@ -252,7 +252,7 @@ public async Task AddOpenTelemetry_WithMetrics_HostConfigurationHonoredTest() var builder = new HostBuilder() .ConfigureAppConfiguration(builder => { - builder.AddInMemoryCollection(new Dictionary + builder.AddInMemoryCollection(new Dictionary { ["TEST_KEY"] = "TEST_KEY_VALUE", }); @@ -270,7 +270,7 @@ public async Task AddOpenTelemetry_WithMetrics_HostConfigurationHonoredTest() var configuration = sp.GetRequiredService(); - var testKeyValue = configuration.GetValue("TEST_KEY", null); + var testKeyValue = configuration.GetValue("TEST_KEY", null); Assert.Equal("TEST_KEY_VALUE", testKeyValue); }); @@ -375,7 +375,7 @@ public void AddOpenTelemetry_WithLogging_HostConfigurationHonoredTest() var builder = new HostBuilder() .ConfigureAppConfiguration(builder => { - builder.AddInMemoryCollection(new Dictionary + builder.AddInMemoryCollection(new Dictionary { ["TEST_KEY"] = "TEST_KEY_VALUE", }); @@ -393,7 +393,7 @@ public void AddOpenTelemetry_WithLogging_HostConfigurationHonoredTest() var configuration = sp.GetRequiredService(); - var testKeyValue = configuration.GetValue("TEST_KEY", null); + var testKeyValue = configuration.GetValue("TEST_KEY", null); Assert.Equal("TEST_KEY_VALUE", testKeyValue); }); diff --git a/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs index 6bd96046d3f..dd7b21c6ccc 100644 --- a/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +using System.Diagnostics; using System.Diagnostics.Metrics; using Xunit; @@ -193,11 +196,7 @@ public void MultiThreadedHistogramUpdateAndSnapShotTest() { var boundaries = Array.Empty(); var histogramPoint = new MetricPoint(this.aggregatorStore, AggregationType.Histogram, null, boundaries, Metric.DefaultExponentialHistogramMaxBuckets, Metric.DefaultExponentialHistogramMaxScale); - var argsToThread = new ThreadArguments - { - HistogramPoint = histogramPoint, - MreToEnsureAllThreadsStart = new ManualResetEvent(false), - }; + var argsToThread = new ThreadArguments(histogramPoint, new ManualResetEvent(false)); var numberOfThreads = 2; var snapshotThread = new Thread(HistogramSnapshotThread); @@ -243,7 +242,7 @@ public void MultiThreadedHistogramUpdateAndSnapShotTest() [InlineData("System.Net.Http", "http.client.request.time_in_queue", "s", KnownHistogramBuckets.DefaultShortSeconds)] [InlineData("System.Net.NameResolution", "dns.lookup.duration", "s", KnownHistogramBuckets.DefaultShortSeconds)] [InlineData("General.App", "simple.alternative.counter", "s", KnownHistogramBuckets.Default)] - public void HistogramBucketsDefaultUpdatesForSecondsTest(string meterName, string instrumentName, string unit, KnownHistogramBuckets expectedHistogramBuckets) + public void HistogramBucketsDefaultUpdatesForSecondsTest(string meterName, string instrumentName, string? unit, KnownHistogramBuckets expectedHistogramBuckets) { using var meter = new Meter(meterName); @@ -341,7 +340,7 @@ internal void ExponentialHistogramTests(AggregationType aggregationType, Aggrega foreach (var value in valuesToRecord) { - aggregatorStore.Update(value, Array.Empty>()); + aggregatorStore.Update(value, Array.Empty>()); if (value >= 0) { @@ -446,7 +445,7 @@ internal void ExponentialMaxScaleConfigWorks(int? maxScale) this.emitOverflowAttribute, this.shouldReclaimUnusedMetricPoints); - aggregatorStore.Update(10, Array.Empty>()); + aggregatorStore.Update(10, Array.Empty>()); aggregatorStore.Snapshot(); @@ -466,10 +465,11 @@ internal void ExponentialMaxScaleConfigWorks(int? maxScale) Assert.Equal(expectedScale, metricPoint.GetExponentialHistogramData().Scale); } - private static void HistogramSnapshotThread(object obj) + private static void HistogramSnapshotThread(object? obj) { var args = obj as ThreadArguments; - var mreToEnsureAllThreadsStart = args.MreToEnsureAllThreadsStart; + Debug.Assert(args != null, "args was null"); + var mreToEnsureAllThreadsStart = args!.MreToEnsureAllThreadsStart; if (Interlocked.Increment(ref args.ThreadStartedCount) == 3) { @@ -487,10 +487,11 @@ private static void HistogramSnapshotThread(object obj) } } - private static void HistogramUpdateThread(object obj) + private static void HistogramUpdateThread(object? obj) { var args = obj as ThreadArguments; - var mreToEnsureAllThreadsStart = args.MreToEnsureAllThreadsStart; + Debug.Assert(args != null, "args was null"); + var mreToEnsureAllThreadsStart = args!.MreToEnsureAllThreadsStart; if (Interlocked.Increment(ref args.ThreadStartedCount) == 3) { @@ -509,11 +510,17 @@ private static void HistogramUpdateThread(object obj) private class ThreadArguments { + public readonly ManualResetEvent MreToEnsureAllThreadsStart; public MetricPoint HistogramPoint; - public ManualResetEvent MreToEnsureAllThreadsStart; public int ThreadStartedCount; public long ThreadsFinishedAllUpdatesCount; public double SumOfDelta; + + public ThreadArguments(MetricPoint histogramPoint, ManualResetEvent mreToEnsureAllThreadsStart) + { + this.HistogramPoint = histogramPoint; + this.MreToEnsureAllThreadsStart = mreToEnsureAllThreadsStart; + } } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs index d4088bb0d1a..2dfa7373334 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Diagnostics.Metrics; using Microsoft.Extensions.Configuration; @@ -40,7 +42,7 @@ public void MeasurementWithNullValuedTag() .AddInMemoryExporter(exportedItems)); var counter = meter.CreateCounter("myCounter"); - counter.Add(100, new KeyValuePair("tagWithNullValue", null)); + counter.Add(100, new KeyValuePair("tagWithNullValue", null)); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.Single(exportedItems); @@ -125,7 +127,7 @@ public void ObserverCallbackExceptionTest() [InlineData("unit")] [InlineData("")] [InlineData(null)] - public void MetricUnitIsExportedCorrectly(string unit) + public void MetricUnitIsExportedCorrectly(string? unit) { var exportedItems = new List(); @@ -147,7 +149,7 @@ public void MetricUnitIsExportedCorrectly(string unit) [InlineData("description")] [InlineData("")] [InlineData(null)] - public void MetricDescriptionIsExportedCorrectly(string description) + public void MetricDescriptionIsExportedCorrectly(string? description) { var exportedItems = new List(); @@ -171,7 +173,7 @@ public void MetricInstrumentationScopeIsExportedCorrectly() var exportedItems = new List(); var meterName = Utils.GetCurrentMethodName(); var meterVersion = "1.0"; - var meterTags = new List> + var meterTags = new List> { new( "MeterTagKey", @@ -190,6 +192,8 @@ public void MetricInstrumentationScopeIsExportedCorrectly() Assert.Equal(meterName, metric.MeterName); Assert.Equal(meterVersion, metric.MeterVersion); + Assert.NotNull(metric.MeterTags); + Assert.Single(metric.MeterTags.Where(kvp => kvp.Key == meterTags[0].Key && kvp.Value == meterTags[0].Value)); } @@ -202,13 +206,13 @@ public void MetricInstrumentationScopeAttributesAreNotTreatedAsIdentifyingProper var exportedItems = new List(); var meterName = "MyMeter"; var meterVersion = "1.0"; - var meterTags1 = new List> + var meterTags1 = new List> { new( "Key1", "Value1"), }; - var meterTags2 = new List> + var meterTags2 = new List> { new( "Key2", @@ -235,6 +239,8 @@ public void MetricInstrumentationScopeAttributesAreNotTreatedAsIdentifyingProper Assert.Equal(meterName, metric.MeterName); Assert.Equal(meterVersion, metric.MeterVersion); + Assert.NotNull(metric.MeterTags); + Assert.Single(metric.MeterTags.Where(kvp => kvp.Key == meterTags1[0].Key && kvp.Value == meterTags1[0].Value)); Assert.DoesNotContain(metric.MeterTags, kvp => kvp.Key == meterTags2[0].Key && kvp.Value == meterTags2[0].Value); @@ -777,19 +783,19 @@ public void ObservableCounterAggregationTest(bool exportDelta) public void ObservableCounterWithTagsAggregationTest(bool exportDelta) { var exportedItems = new List(); - var tags1 = new List> + var tags1 = new List> { new("statusCode", 200), new("verb", "get"), }; - var tags2 = new List> + var tags2 = new List> { new("statusCode", 200), new("verb", "post"), }; - var tags3 = new List> + var tags3 = new List> { new("statusCode", 500), new("verb", "get"), @@ -873,19 +879,19 @@ public void ObservableCounterWithTagsAggregationTest(bool exportDelta) public void ObservableCounterSpatialAggregationTest(bool exportDelta) { var exportedItems = new List(); - var tags1 = new List> + var tags1 = new List> { new("statusCode", 200), new("verb", "get"), }; - var tags2 = new List> + var tags2 = new List> { new("statusCode", 200), new("verb", "post"), }; - var tags3 = new List> + var tags3 = new List> { new("statusCode", 500), new("verb", "get"), @@ -924,7 +930,7 @@ public void ObservableCounterSpatialAggregationTest(bool exportDelta) Assert.Single(metricPoints); - var emptyTags = new List>(); + var emptyTags = new List>(); var metricPoint1 = metricPoints[0]; ValidateMetricPointTags(emptyTags, metricPoint1.Tags); @@ -1058,19 +1064,19 @@ public void ObservableUpDownCounterAggregationTest(bool exportDelta) public void ObservableUpDownCounterWithTagsAggregationTest(bool exportDelta) { var exportedItems = new List(); - var tags1 = new List> + var tags1 = new List> { new("statusCode", 200), new("verb", "get"), }; - var tags2 = new List> + var tags2 = new List> { new("statusCode", 200), new("verb", "post"), }; - var tags3 = new List> + var tags3 = new List> { new("statusCode", 500), new("verb", "get"), @@ -1177,33 +1183,33 @@ public void DimensionsAreOrderInsensitiveWithSortedKeysFirst(bool exportDelta) meterProvider.ForceFlush(MaxTimeToAllowForFlush); - List> expectedTagsForFirstMetricPoint = new List>() - { + List> expectedTagsForFirstMetricPoint = + [ new("Key1", "Value1"), new("Key2", "Value2"), new("Key3", "Value3"), - }; + ]; - List> expectedTagsForSecondMetricPoint = new List>() - { + List> expectedTagsForSecondMetricPoint = + [ new("Key1", "Value10"), new("Key2", "Value20"), new("Key3", "Value30"), - }; + ]; - List> expectedTagsForThirdMetricPoint = new List>() - { + List> expectedTagsForThirdMetricPoint = + [ new("Key4", "Value1"), new("Key5", "Value3"), new("Key6", "Value2"), - }; + ]; - List> expectedTagsForFourthMetricPoint = new List>() - { + List> expectedTagsForFourthMetricPoint = + [ new("Key4", "Value1"), new("Key5", "Value2"), new("Key6", "Value3"), - }; + ]; Assert.Equal(4, GetNumberOfMetricPoints(exportedItems)); CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFirstMetricPoint, 1); @@ -1268,33 +1274,33 @@ public void DimensionsAreOrderInsensitiveWithUnsortedKeysFirst(bool exportDelta) meterProvider.ForceFlush(MaxTimeToAllowForFlush); - List> expectedTagsForFirstMetricPoint = new List>() - { + List> expectedTagsForFirstMetricPoint = + [ new("Key1", "Value1"), new("Key2", "Value2"), new("Key3", "Value3"), - }; + ]; - List> expectedTagsForSecondMetricPoint = new List>() - { + List> expectedTagsForSecondMetricPoint = + [ new("Key1", "Value10"), new("Key2", "Value20"), new("Key3", "Value30"), - }; + ]; - List> expectedTagsForThirdMetricPoint = new List>() - { + List> expectedTagsForThirdMetricPoint = + [ new("Key4", "Value1"), new("Key5", "Value3"), new("Key6", "Value2"), - }; + ]; - List> expectedTagsForFourthMetricPoint = new List>() - { + List> expectedTagsForFourthMetricPoint = + [ new("Key4", "Value1"), new("Key5", "Value2"), new("Key6", "Value3"), - }; + ]; Assert.Equal(4, GetNumberOfMetricPoints(exportedItems)); CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFirstMetricPoint, 1); @@ -1351,37 +1357,37 @@ public void TestInstrumentDisposal(MetricReaderTemporalityPreference temporality metricReaderOptions.TemporalityPreference = temporality; })); - counter1.Add(10, new KeyValuePair("key", "value")); - counter2.Add(10, new KeyValuePair("key", "value")); + counter1.Add(10, new KeyValuePair("key", "value")); + counter2.Add(10, new KeyValuePair("key", "value")); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.Equal(2, exportedItems.Count); exportedItems.Clear(); - counter1.Add(10, new KeyValuePair("key", "value")); - counter2.Add(10, new KeyValuePair("key", "value")); + counter1.Add(10, new KeyValuePair("key", "value")); + counter2.Add(10, new KeyValuePair("key", "value")); meter1.Dispose(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.Equal(2, exportedItems.Count); exportedItems.Clear(); - counter1.Add(10, new KeyValuePair("key", "value")); - counter2.Add(10, new KeyValuePair("key", "value")); + counter1.Add(10, new KeyValuePair("key", "value")); + counter2.Add(10, new KeyValuePair("key", "value")); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.Single(exportedItems); exportedItems.Clear(); - counter1.Add(10, new KeyValuePair("key", "value")); - counter2.Add(10, new KeyValuePair("key", "value")); + counter1.Add(10, new KeyValuePair("key", "value")); + counter2.Add(10, new KeyValuePair("key", "value")); meter2.Dispose(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.Single(exportedItems); exportedItems.Clear(); - counter1.Add(10, new KeyValuePair("key", "value")); - counter2.Add(10, new KeyValuePair("key", "value")); + counter1.Add(10, new KeyValuePair("key", "value")); + counter2.Add(10, new KeyValuePair("key", "value")); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.Empty(exportedItems); } @@ -1440,7 +1446,7 @@ int MetricPointCount() counterLong.Add(10); for (int i = 0; i < MeterProviderBuilderSdk.DefaultCardinalityLimit + 1; i++) { - counterLong.Add(10, new KeyValuePair("key", "value" + i)); + counterLong.Add(10, new KeyValuePair("key", "value" + i)); } meterProvider.ForceFlush(MaxTimeToAllowForFlush); @@ -1450,7 +1456,7 @@ int MetricPointCount() counterLong.Add(10); for (int i = 0; i < MeterProviderBuilderSdk.DefaultCardinalityLimit + 1; i++) { - counterLong.Add(10, new KeyValuePair("key", "value" + i)); + counterLong.Add(10, new KeyValuePair("key", "value" + i)); } meterProvider.ForceFlush(MaxTimeToAllowForFlush); @@ -1459,13 +1465,13 @@ int MetricPointCount() counterLong.Add(10); for (int i = 0; i < MeterProviderBuilderSdk.DefaultCardinalityLimit + 1; i++) { - counterLong.Add(10, new KeyValuePair("key", "value" + i)); + counterLong.Add(10, new KeyValuePair("key", "value" + i)); } // These updates would be dropped. - counterLong.Add(10, new KeyValuePair("key", "valueA")); - counterLong.Add(10, new KeyValuePair("key", "valueB")); - counterLong.Add(10, new KeyValuePair("key", "valueC")); + counterLong.Add(10, new KeyValuePair("key", "valueA")); + counterLong.Add(10, new KeyValuePair("key", "valueB")); + counterLong.Add(10, new KeyValuePair("key", "valueC")); exportedItems.Clear(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.Equal(MeterProviderBuilderSdk.DefaultCardinalityLimit, MetricPointCount()); @@ -1577,7 +1583,7 @@ public void SetupSdkProviderWithNoReader(bool hasViews) var counter = meter.CreateCounter("counter"); - counter.Add(10, new KeyValuePair("key", "value")); + counter.Add(10, new KeyValuePair("key", "value")); } [Fact] @@ -1702,7 +1708,7 @@ public void GaugeHandlesNoNewMeasurementsCorrectlyWithTemporality(MetricReaderTe internal static IConfiguration BuildConfiguration(bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) { - var configurationData = new Dictionary(); + var configurationData = new Dictionary(); if (emitOverflowAttribute) { @@ -1719,18 +1725,19 @@ internal static IConfiguration BuildConfiguration(bool emitOverflowAttribute, bo .Build(); } - private static void CounterUpdateThread(object obj) + private static void CounterUpdateThread(object? obj) where T : struct, IComparable { - if (obj is not UpdateThreadArguments arguments) - { - throw new Exception("Invalid args"); - } + var arguments = obj as UpdateThreadArguments; + Debug.Assert(arguments != null, "arguments was null"); - var mre = arguments.MreToBlockUpdateThread; + var mre = arguments!.MreToBlockUpdateThread; var mreToEnsureAllThreadsStart = arguments.MreToEnsureAllThreadsStart; - var counter = arguments.Instrument as Counter; var valueToUpdate = arguments.ValuesToRecord[0]; + + var counter = arguments.Instrument as Counter; + Debug.Assert(counter != null, "counter was null"); + if (Interlocked.Increment(ref arguments.ThreadsStartedCount) == NumberOfThreads) { mreToEnsureAllThreadsStart.Set(); @@ -1741,21 +1748,20 @@ private static void CounterUpdateThread(object obj) for (int i = 0; i < NumberOfMetricUpdateByEachThread; i++) { - counter.Add(valueToUpdate, new KeyValuePair("verb", "GET")); + counter!.Add(valueToUpdate, new KeyValuePair("verb", "GET")); } } - private static void HistogramUpdateThread(object obj) + private static void HistogramUpdateThread(object? obj) where T : struct, IComparable { - if (obj is not UpdateThreadArguments arguments) - { - throw new Exception("Invalid args"); - } + var arguments = obj as UpdateThreadArguments; + Debug.Assert(arguments != null, "arguments was null"); - var mre = arguments.MreToBlockUpdateThread; + var mre = arguments!.MreToBlockUpdateThread; var mreToEnsureAllThreadsStart = arguments.MreToEnsureAllThreadsStart; var histogram = arguments.Instrument as Histogram; + Debug.Assert(histogram != null, "histogram was null"); if (Interlocked.Increment(ref arguments.ThreadsStartedCount) == NumberOfThreads) { @@ -1769,7 +1775,7 @@ private static void HistogramUpdateThread(object obj) { for (int j = 0; j < arguments.ValuesToRecord.Length; j++) { - histogram.Record(arguments.ValuesToRecord[j]); + histogram!.Record(arguments.ValuesToRecord[j]); } } } @@ -1785,13 +1791,7 @@ private void MultithreadedCounterTest(T deltaValueUpdatedByEachCall) .AddMeter(meter.Name) .AddInMemoryExporter(metricItems)); - var argToThread = new UpdateThreadArguments - { - ValuesToRecord = new T[] { deltaValueUpdatedByEachCall }, - Instrument = meter.CreateCounter("counter"), - MreToBlockUpdateThread = new ManualResetEvent(false), - MreToEnsureAllThreadsStart = new ManualResetEvent(false), - }; + var argToThread = new UpdateThreadArguments(new ManualResetEvent(false), new ManualResetEvent(false), meter.CreateCounter("counter"), [deltaValueUpdatedByEachCall]); Thread[] t = new Thread[NumberOfThreads]; for (int i = 0; i < NumberOfThreads; i++) @@ -1841,13 +1841,7 @@ private void MultithreadedHistogramTest(long[] expected, T[] values) .AddMeter(meter.Name) .AddReader(metricReader)); - var argsToThread = new UpdateThreadArguments - { - Instrument = meter.CreateHistogram("histogram"), - MreToBlockUpdateThread = new ManualResetEvent(false), - MreToEnsureAllThreadsStart = new ManualResetEvent(false), - ValuesToRecord = values, - }; + var argsToThread = new UpdateThreadArguments(new ManualResetEvent(false), new ManualResetEvent(false), meter.CreateHistogram("histogram"), values); Thread[] t = new Thread[NumberOfThreads]; for (int i = 0; i < NumberOfThreads; i++) @@ -1888,6 +1882,14 @@ private class UpdateThreadArguments public int ThreadsStartedCount; public Instrument Instrument; public T[] ValuesToRecord; + + public UpdateThreadArguments(ManualResetEvent mreToBlockUpdateThread, ManualResetEvent mreToEnsureAllThreadsStart, Instrument instrument, T[] valuesToRecord) + { + this.MreToBlockUpdateThread = mreToBlockUpdateThread; + this.MreToEnsureAllThreadsStart = mreToEnsureAllThreadsStart; + this.Instrument = instrument; + this.ValuesToRecord = valuesToRecord; + } } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs index 7d72b773ea6..ee1162f4789 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + #if BUILDING_HOSTING_TESTS using System.Diagnostics; #endif @@ -19,7 +21,7 @@ public class MetricTestsBase public const string EmitOverFlowAttributeConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE"; public const string ReclaimUnusedMetricPointsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS"; - protected readonly IConfiguration configuration; + protected readonly IConfiguration? configuration; protected MetricTestsBase() { @@ -33,10 +35,10 @@ protected MetricTestsBase(IConfiguration configuration) #if BUILDING_HOSTING_TESTS public static IHost BuildHost( bool useWithMetricsStyle, - Action configureAppConfiguration = null, - Action configureServices = null, - Action configureMetricsBuilder = null, - Action configureMeterProviderBuilder = null) + Action? configureAppConfiguration = null, + Action? configureServices = null, + Action? configureMetricsBuilder = null, + Action? configureMeterProviderBuilder = null) { var hostBuilder = new HostBuilder() .ConfigureDefaults(null) @@ -74,15 +76,15 @@ public static IHost BuildHost( return host; - static void ConfigureBuilder(MeterProviderBuilder builder, Action configureMeterProviderBuilder) + static void ConfigureBuilder(MeterProviderBuilder builder, Action? configureMeterProviderBuilder) { - IServiceCollection localServices = null; + IServiceCollection? localServices = null; builder.ConfigureServices(services => localServices = services); Debug.Assert(localServices != null, "localServices was null"); - var testBuilder = new HostingMeterProviderBuilder(localServices); + var testBuilder = new HostingMeterProviderBuilder(localServices!); configureMeterProviderBuilder?.Invoke(testBuilder); } } @@ -90,7 +92,7 @@ static void ConfigureBuilder(MeterProviderBuilder builder, Action> expectedTags, ReadOnlyTagCollection actualTags) + public static void ValidateMetricPointTags(List> expectedTags, ReadOnlyTagCollection actualTags) { int tagIndex = 0; foreach (var tag in actualTags) @@ -175,7 +177,7 @@ public static int GetNumberOfMetricPoints(List metrics) // This method relies on the assumption that MetricPoints are exported in the order in which they are emitted. // For Delta AggregationTemporality, this holds true only until the AggregatorStore has not begun recaliming the MetricPoints. // Provide tags input sorted by Key - public static void CheckTagsForNthMetricPoint(List metrics, List> tags, int n) + public static void CheckTagsForNthMetricPoint(List metrics, List> tags, int n) { var metric = metrics[0]; var metricPointEnumerator = metric.GetMetricPoints().GetEnumerator(); @@ -216,7 +218,7 @@ public IDisposable BuildMeterProvider( } }); - meterProvider = host.Services.GetService(); + meterProvider = host.Services.GetRequiredService(); return host; #else @@ -277,8 +279,8 @@ private sealed class MetricsSubscriptionManagerCleanupHostedService : IHostedSer public MetricsSubscriptionManagerCleanupHostedService(IServiceProvider serviceProvider) { - this.metricsSubscriptionManager = serviceProvider.GetService( - typeof(ConsoleMetrics).Assembly.GetType("Microsoft.Extensions.Diagnostics.Metrics.MetricsSubscriptionManager")); + this.metricsSubscriptionManager = serviceProvider.GetRequiredService( + typeof(ConsoleMetrics).Assembly.GetType("Microsoft.Extensions.Diagnostics.Metrics.MetricsSubscriptionManager")!); if (this.metricsSubscriptionManager == null) { @@ -292,7 +294,7 @@ public void Dispose() // be bugged in that it doesn't implement IDisposable. This hack // manually invokes Dispose so that tests don't clobber each other. // See: https://github.com/dotnet/runtime/issues/94434. - this.metricsSubscriptionManager.GetType().GetMethod("Dispose").Invoke(this.metricsSubscriptionManager, null); + this.metricsSubscriptionManager.GetType().GetMethod("Dispose")!.Invoke(this.metricsSubscriptionManager, null); } public Task StartAsync(CancellationToken cancellationToken) diff --git a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs index 11c048512ef..6dae582151e 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics.Metrics; using OpenTelemetry.Internal; using OpenTelemetry.Tests; @@ -56,7 +58,7 @@ public void AddViewWithInvalidNameThrowsArgumentException(string viewNewName) } [Fact] - public void AddViewWithNullMetricStreamConfigurationThrowsArgumentnullException() + public void AddViewWithNullMetricStreamConfigurationThrowsArgumentNullException() { var exportedItems = new List(); @@ -64,7 +66,7 @@ public void AddViewWithNullMetricStreamConfigurationThrowsArgumentnullException( Assert.Throws(() => this.BuildMeterProvider(out var meterProvider, builder => builder .AddMeter(meter1.Name) - .AddView("name1", (MetricStreamConfiguration)null) + .AddView("name1", (MetricStreamConfiguration)null!) .AddInMemoryExporter(exportedItems))); } @@ -1233,7 +1235,7 @@ public void ViewConflict_TwoIdenticalInstruments_TwoViews_DifferentTags() var instrument1 = meter.CreateCounter("name"); var instrument2 = meter.CreateCounter("name"); - var tags = new KeyValuePair[] + var tags = new KeyValuePair[] { new("key1", "value"), new("key2", "value"), @@ -1247,8 +1249,8 @@ public void ViewConflict_TwoIdenticalInstruments_TwoViews_DifferentTags() Assert.Equal(2, exportedItems.Count); var metric1 = new List() { exportedItems[0] }; var metric2 = new List() { exportedItems[1] }; - var tag1 = new List> { tags[0] }; - var tag2 = new List> { tags[1] }; + var tag1 = new List> { tags[0] }; + var tag2 = new List> { tags[1] }; Assert.Equal("name", exportedItems[0].Name); Assert.Equal("name", exportedItems[1].Name); @@ -1280,7 +1282,7 @@ public void ViewConflict_TwoIdenticalInstruments_TwoViews_SameTags() var instrument1 = meter.CreateCounter("name"); var instrument2 = meter.CreateCounter("name"); - var tags = new KeyValuePair[] + var tags = new KeyValuePair[] { new("key1", "value"), new("key2", "value"), @@ -1294,13 +1296,13 @@ public void ViewConflict_TwoIdenticalInstruments_TwoViews_SameTags() Assert.Equal(2, exportedItems.Count); var metric1 = new List() { exportedItems[0] }; - var tag1 = new List> { tags[0] }; + var tag1 = new List> { tags[0] }; Assert.Equal("name", exportedItems[0].Name); Assert.Equal(20, GetLongSum(metric1)); CheckTagsForNthMetricPoint(metric1, tag1, 1); var metric2 = new List() { exportedItems[1] }; - var tag2 = new List> { tags[0] }; + var tag2 = new List> { tags[0] }; Assert.Equal("name", exportedItems[1].Name); Assert.Equal(20, GetLongSum(metric2)); CheckTagsForNthMetricPoint(metric2, tag2, 1); @@ -1408,7 +1410,7 @@ public void ViewConflict_TwoInstruments_OneMatchesView() var instrument1 = meter.CreateCounter("name"); var instrument2 = meter.CreateCounter("othername"); - var tags = new KeyValuePair[] + var tags = new KeyValuePair[] { new("key1", "value"), new("key2", "value"), @@ -1423,8 +1425,8 @@ public void ViewConflict_TwoInstruments_OneMatchesView() var metric1 = new List() { exportedItems[0] }; var metric2 = new List() { exportedItems[1] }; - var tags1 = new List> { tags[0] }; - var tags2 = new List> { tags[0], tags[1] }; + var tags1 = new List> { tags[0] }; + var tags2 = new List> { tags[0], tags[1] }; Assert.Equal("othername", exportedItems[0].Name); Assert.Equal("othername", exportedItems[1].Name); diff --git a/test/OpenTelemetry.Tests/Shared/SkipUnlessTrueTheoryAttribute.cs b/test/OpenTelemetry.Tests/Shared/SkipUnlessTrueTheoryAttribute.cs index 087bff4366f..e1bb7983910 100644 --- a/test/OpenTelemetry.Tests/Shared/SkipUnlessTrueTheoryAttribute.cs +++ b/test/OpenTelemetry.Tests/Shared/SkipUnlessTrueTheoryAttribute.cs @@ -23,7 +23,7 @@ public SkipUnlessTrueTheoryAttribute(Type typeContainingTest, string testFieldNa throw new InvalidOperationException($"Field '{testFieldName}' on '{typeContainingTest}' type should be defined as '{typeof(Func)}'."); } - var testFunc = (Func)field.GetValue(null); + var testFunc = (Func)field.GetValue(null)!; if (!testFunc()) { From 25d99a56bf56c20bb8b2dd4a1e8e3b1476ebf204 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 4 Oct 2024 13:38:15 -0700 Subject: [PATCH 099/133] [repo] Mitigate vulnerabilities in System.Text.Json 8.0.0 packages (#5874) --- Directory.Packages.props | 26 ++++++++++++++----- OpenTelemetry.sln | 4 +-- build/Common.props | 1 + build/Common.targets | 12 +++++++++ examples/Directory.Build.targets | 5 ++++ examples/Directory.Packages.props | 6 ----- .../WorkerService/WorkerService.csproj | 2 -- src/Directory.Build.targets | 2 ++ .../CHANGELOG.md | 8 +++++- .../OpenTelemetry.Exporter.Console.csproj | 6 +---- .../CHANGELOG.md | 5 ++++ .../OpenTelemetry.Exporter.Zipkin.csproj | 7 ++--- test/Directory.Build.targets | 14 ++++++++++ test/Directory.Packages.props | 9 ------- .../OpenTelemetry.Api.Tests.csproj | 10 +++---- ...xporter.OpenTelemetryProtocol.Tests.csproj | 6 +---- ...xporter.Prometheus.AspNetCore.Tests.csproj | 8 +++--- ...orter.Prometheus.HttpListener.Tests.csproj | 7 ++--- ...OpenTelemetry.Exporter.Zipkin.Tests.csproj | 7 ++--- ...nTelemetry.Extensions.Hosting.Tests.csproj | 8 +++--- ...enTelemetry.Shims.OpenTracing.Tests.csproj | 4 +-- .../OpenTelemetry.Tests.Stress.csproj | 4 ++- .../OpenTelemetry.Tests.csproj | 10 +++---- 23 files changed, 94 insertions(+), 77 deletions(-) create mode 100644 build/Common.targets create mode 100644 examples/Directory.Build.targets delete mode 100644 examples/Directory.Packages.props delete mode 100644 test/Directory.Packages.props diff --git a/Directory.Packages.props b/Directory.Packages.props index fe1f04c7fbe..747cff1b7d1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,10 @@ + true 1.9.0 + 8.0.0 + 8.0.4 + - + + - - - - + + + - @@ -77,6 +84,7 @@ + @@ -86,6 +94,7 @@ + @@ -93,6 +102,7 @@ + @@ -100,7 +110,9 @@ + + diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index f9bde54e00a..cea58bc408a 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -28,6 +28,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E build\Common.nonprod.props = build\Common.nonprod.props build\Common.prod.props = build\Common.prod.props build\Common.props = build\Common.props + build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk Directory.Packages.props = Directory.Packages.props build\docfx.cmd = build\docfx.cmd @@ -112,7 +113,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{D2E73927-5 ProjectSection(SolutionItems) = preProject test\Directory.Build.props = test\Directory.Build.props test\Directory.Build.targets = test\Directory.Build.targets - test\Directory.Packages.props = test\Directory.Packages.props EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Console", "examples\Console\Examples.Console.csproj", "{FF3E6E08-E8E4-4523-B526-847CD989279F}" @@ -129,7 +129,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{2C7DD1DA-C229-4D9E-9AF0-BCD5CD3E4948}" ProjectSection(SolutionItems) = preProject examples\Directory.Build.props = examples\Directory.Build.props - examples\Directory.Packages.props = examples\Directory.Packages.props + examples\Directory.Build.targets = examples\Directory.Build.targets EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "trace", "trace", "{5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}" diff --git a/build/Common.props b/build/Common.props index 54ecbacfe9b..b625439458e 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,6 +31,7 @@ net9.0;net8.0;netstandard2.0;$(NetFrameworkMinimumSupportedVersion) net9.0;net8.0;netstandard2.1;netstandard2.0;$(NetFrameworkMinimumSupportedVersion) net9.0;net8.0 + net8.0;netstandard2.1;netstandard2.0;$(NetFrameworkMinimumSupportedVersion) net9.0;net8.0 diff --git a/build/Common.targets b/build/Common.targets new file mode 100644 index 00000000000..63286efffbf --- /dev/null +++ b/build/Common.targets @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/examples/Directory.Build.targets b/examples/Directory.Build.targets new file mode 100644 index 00000000000..a0db1462028 --- /dev/null +++ b/examples/Directory.Build.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/Directory.Packages.props b/examples/Directory.Packages.props deleted file mode 100644 index 02296b44608..00000000000 --- a/examples/Directory.Packages.props +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/examples/MicroserviceExample/WorkerService/WorkerService.csproj b/examples/MicroserviceExample/WorkerService/WorkerService.csproj index f10cebc2d7e..b9b1a680772 100644 --- a/examples/MicroserviceExample/WorkerService/WorkerService.csproj +++ b/examples/MicroserviceExample/WorkerService/WorkerService.csproj @@ -6,8 +6,6 @@ - - diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 3ee054532a9..3e05f2937f9 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,5 +1,7 @@ + + + + + + + + + + diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props deleted file mode 100644 index 9e456e2826f..00000000000 --- a/test/Directory.Packages.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj index e6a6749107c..2e88e5a9587 100644 --- a/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj +++ b/test/OpenTelemetry.Api.Tests/OpenTelemetry.Api.Tests.csproj @@ -1,8 +1,10 @@ + Unit test project for OpenTelemetry.Api $(TargetFrameworksForTests) $(NoWarn),CS0618 + true @@ -20,11 +22,7 @@ - - runtime; build; native; contentfiles; analyzers - - - - + + diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj index ed31a950360..6456de26027 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj @@ -11,11 +11,7 @@ - - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj index 7a91330ca56..6c4ea8cb626 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj @@ -1,4 +1,5 @@ + Unit test project for Prometheus Exporter AspNetCore for OpenTelemetry $(TargetFrameworksForAspNetCoreTests) @@ -9,11 +10,7 @@ - - runtime; build; native; contentfiles; analyzers - - - + @@ -39,4 +36,5 @@ + diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj index efab035ead8..6d6c38ff489 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj @@ -1,4 +1,5 @@ + Unit test project for Prometheus Exporter HttpListener for OpenTelemetry $(TargetFrameworksForTests) @@ -8,11 +9,7 @@ - - runtime; build; native; contentfiles; analyzers - - - + diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj index fceb493d55d..a5494a2f920 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/OpenTelemetry.Exporter.Zipkin.Tests.csproj @@ -1,4 +1,5 @@ + Unit test project for Zipkin Exporter for OpenTelemetry $(TargetFrameworksForTests) @@ -17,11 +18,7 @@ - - runtime; build; native; contentfiles; analyzers - - - + diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj index 73299e92b02..d089eaa7079 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/OpenTelemetry.Extensions.Hosting.Tests.csproj @@ -1,4 +1,5 @@ + Unit test project for OpenTelemetry .NET Core hosting library $(TargetFrameworksForTests) @@ -36,10 +37,7 @@ - - runtime; build; native; contentfiles; analyzers - - - + + diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj index 143e90e7dc4..d21c157d1b9 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj @@ -1,4 +1,5 @@ + Unit test project for OpenTelemetry.Shims.OpenTracing $(TargetFrameworksForTests) @@ -10,8 +11,6 @@ - - @@ -25,4 +24,5 @@ + diff --git a/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj b/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj index 01af1c993ae..9e6464cf484 100644 --- a/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj +++ b/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj @@ -1,17 +1,19 @@ + Exe $(TargetFrameworksForTests) + true - + diff --git a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj index 96304bf6c6c..9d40f304c56 100644 --- a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj +++ b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj @@ -1,8 +1,10 @@ + Unit test project for OpenTelemetry $(TargetFrameworksForTests) $(NoWarn),CS0618 + true disable @@ -27,11 +29,7 @@ - - runtime; build; native; contentfiles; analyzers - - - - + + From 02f4b2d97831ae983fcca56eaa5e7bdc759c4d6d Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Fri, 4 Oct 2024 23:20:03 +0200 Subject: [PATCH 100/133] [Benchmarks] Nullabe (#5875) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Mikel Blanchard --- test/Benchmarks/Benchmarks.csproj | 3 - .../TraceContextPropagatorBenchmarks.cs | 8 +- test/Benchmarks/EventSourceBenchmarks.cs | 2 +- .../Exporter/OtlpGrpcExporterBenchmarks.cs | 14 +-- .../Exporter/OtlpHttpExporterBenchmarks.cs | 20 ++-- .../Exporter/OtlpLogExporterBenchmarks.cs | 28 +++--- .../Exporter/OtlpTraceExporterBenchmarks.cs | 32 +++--- .../PrometheusSerializerBenchmarks.cs | 6 +- .../Exporter/ZipkinExporterBenchmarks.cs | 14 +-- test/Benchmarks/Helper/ActivityHelper.cs | 10 +- test/Benchmarks/Logs/LogScopeBenchmarks.cs | 2 +- .../Base2ExponentialHistogramBenchmarks.cs | 28 +++--- ...xponentialHistogramMapToIndexBenchmarks.cs | 4 +- ...ase2ExponentialHistogramScaleBenchmarks.cs | 10 +- test/Benchmarks/Metrics/ExemplarBenchmarks.cs | 32 +++--- .../Benchmarks/Metrics/HistogramBenchmarks.cs | 28 +++--- .../Metrics/MetricCollectBenchmarks.cs | 30 +++--- test/Benchmarks/Metrics/MetricsBenchmarks.cs | 98 +++++++++---------- .../Metrics/MetricsViewBenchmarks.cs | 12 +-- test/Benchmarks/TestTraceServiceClient.cs | 2 +- .../Trace/ActivityCreationBenchmarks.cs | 6 +- test/Benchmarks/Trace/SamplerBenchmarks.cs | 2 +- .../Trace/SpanCreationBenchmarks.cs | 34 +++---- 23 files changed, 210 insertions(+), 215 deletions(-) diff --git a/test/Benchmarks/Benchmarks.csproj b/test/Benchmarks/Benchmarks.csproj index 915a68730e1..d3b36601264 100644 --- a/test/Benchmarks/Benchmarks.csproj +++ b/test/Benchmarks/Benchmarks.csproj @@ -3,9 +3,6 @@ Exe $(TargetFrameworksForTests) - - - disable diff --git a/test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs b/test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs index 2f9d26f9ab0..fdae9b0c4f7 100644 --- a/test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs +++ b/test/Benchmarks/Context/Propagation/TraceContextPropagatorBenchmarks.cs @@ -26,15 +26,13 @@ public class TraceContextPropagatorBenchmarks return []; }; - private Dictionary headers; - [Params(true, false)] public bool LongListMember { get; set; } [Params(0, 4, 32)] public int MembersCount { get; set; } - public Dictionary Headers => this.headers; + public Dictionary? Headers { get; private set; } [GlobalSetup] public void Setup() @@ -60,7 +58,7 @@ public void Setup() traceState += i < this.MembersCount - 1 ? $"{listMember}," : listMember; } - this.headers = new Dictionary + this.Headers = new Dictionary { { TraceParent, $"00-{TraceId}-{SpanId}-01" }, { TraceState, traceState }, @@ -68,5 +66,5 @@ public void Setup() } [Benchmark(Baseline = true)] - public void Extract() => _ = TraceContextPropagator!.Extract(default, this.headers, Getter); + public void Extract() => _ = TraceContextPropagator!.Extract(default, this.Headers!, Getter); } diff --git a/test/Benchmarks/EventSourceBenchmarks.cs b/test/Benchmarks/EventSourceBenchmarks.cs index f8304368632..ca8b4ffcd7f 100644 --- a/test/Benchmarks/EventSourceBenchmarks.cs +++ b/test/Benchmarks/EventSourceBenchmarks.cs @@ -17,7 +17,7 @@ public void EventWithIdAllocation() activity.Start(); activity.Stop(); - OpenTelemetrySdkEventSource.Log.ActivityStarted(activity.OperationName, activity.Id); + OpenTelemetrySdkEventSource.Log.ActivityStarted(activity.OperationName, activity.Id!); } [Benchmark] diff --git a/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs b/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs index 2a9dd7cebbb..5f41ac0a3f1 100644 --- a/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs @@ -18,9 +18,9 @@ namespace Benchmarks.Exporter; public class OtlpGrpcExporterBenchmarks { - private OtlpTraceExporter exporter; - private Activity activity; - private CircularBuffer activityBatch; + private OtlpTraceExporter? exporter; + private Activity? activity; + private CircularBuffer? activityBatch; [Params(1, 10, 100)] public int NumberOfBatches { get; set; } @@ -45,8 +45,8 @@ public void GlobalSetup() [GlobalCleanup] public void GlobalCleanup() { - this.exporter.Shutdown(); - this.exporter.Dispose(); + this.exporter?.Shutdown(); + this.exporter?.Dispose(); } [Benchmark] @@ -56,10 +56,10 @@ public void OtlpExporter_Batching() { for (int c = 0; c < this.NumberOfSpans; c++) { - this.activityBatch.Add(this.activity); + this.activityBatch!.Add(this.activity!); } - this.exporter.Export(new Batch(this.activityBatch, this.NumberOfSpans)); + this.exporter!.Export(new Batch(this.activityBatch!, this.NumberOfSpans)); } } } diff --git a/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs b/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs index d595eefd9f1..1d6c0ad5c14 100644 --- a/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs @@ -20,12 +20,12 @@ namespace Benchmarks.Exporter; public class OtlpHttpExporterBenchmarks { private readonly byte[] buffer = new byte[1024 * 1024]; - private IDisposable server; - private string serverHost; + private IDisposable? server; + private string? serverHost; private int serverPort; - private OtlpTraceExporter exporter; - private Activity activity; - private CircularBuffer activityBatch; + private OtlpTraceExporter? exporter; + private Activity? activity; + private CircularBuffer? activityBatch; [Params(1, 10, 100)] public int NumberOfBatches { get; set; } @@ -73,9 +73,9 @@ public void GlobalSetup() [GlobalCleanup] public void GlobalCleanup() { - this.exporter.Shutdown(); - this.exporter.Dispose(); - this.server.Dispose(); + this.exporter?.Shutdown(); + this.exporter?.Dispose(); + this.server?.Dispose(); } [Benchmark] @@ -85,10 +85,10 @@ public void OtlpExporter_Batching() { for (int c = 0; c < this.NumberOfSpans; c++) { - this.activityBatch.Add(this.activity); + this.activityBatch!.Add(this.activity!); } - this.exporter.Export(new Batch(this.activityBatch, this.NumberOfSpans)); + this.exporter!.Export(new Batch(this.activityBatch!, this.NumberOfSpans)); } } } diff --git a/test/Benchmarks/Exporter/OtlpLogExporterBenchmarks.cs b/test/Benchmarks/Exporter/OtlpLogExporterBenchmarks.cs index 17bcf3dda49..1ec5f4770d4 100644 --- a/test/Benchmarks/Exporter/OtlpLogExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/OtlpLogExporterBenchmarks.cs @@ -36,13 +36,13 @@ namespace Benchmarks.Exporter; public class OtlpLogExporterBenchmarks { - private OtlpLogExporter exporter; - private LogRecord logRecord; - private CircularBuffer logRecordBatch; + private OtlpLogExporter? exporter; + private LogRecord? logRecord; + private CircularBuffer? logRecordBatch; - private IHost host; - private IDisposable server; - private string serverHost; + private IHost? host; + private IDisposable? server; + private string? serverHost; private int serverPort; [GlobalSetup(Target = nameof(OtlpLogExporter_Grpc))] @@ -103,29 +103,29 @@ public void GlobalSetupHttp() [GlobalCleanup(Target = nameof(OtlpLogExporter_Grpc))] public void GlobalCleanupGrpc() { - this.exporter.Shutdown(); - this.exporter.Dispose(); - this.host.Dispose(); + this.exporter?.Shutdown(); + this.exporter?.Dispose(); + this.host?.Dispose(); } [GlobalCleanup(Target = nameof(OtlpLogExporter_Http))] public void GlobalCleanupHttp() { - this.exporter.Shutdown(); - this.exporter.Dispose(); - this.server.Dispose(); + this.exporter?.Shutdown(); + this.exporter?.Dispose(); + this.server?.Dispose(); } [Benchmark] public void OtlpLogExporter_Http() { - this.exporter.Export(new Batch(this.logRecordBatch, 1)); + this.exporter!.Export(new Batch(this.logRecordBatch!, 1)); } [Benchmark] public void OtlpLogExporter_Grpc() { - this.exporter.Export(new Batch(this.logRecordBatch, 1)); + this.exporter!.Export(new Batch(this.logRecordBatch!, 1)); } private sealed class MockLogService : OtlpCollector.LogsService.LogsServiceBase diff --git a/test/Benchmarks/Exporter/OtlpTraceExporterBenchmarks.cs b/test/Benchmarks/Exporter/OtlpTraceExporterBenchmarks.cs index 392e0612c0e..5f338fa6189 100644 --- a/test/Benchmarks/Exporter/OtlpTraceExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/OtlpTraceExporterBenchmarks.cs @@ -36,13 +36,13 @@ namespace Benchmarks.Exporter; public class OtlpTraceExporterBenchmarks { - private OtlpTraceExporter exporter; - private Activity activity; - private CircularBuffer activityBatch; + private OtlpTraceExporter? exporter; + private Activity? activity; + private CircularBuffer? activityBatch; - private IHost host; - private IDisposable server; - private string serverHost; + private IHost? host; + private IDisposable? server; + private string? serverHost; private int serverPort; [GlobalSetup(Target = nameof(OtlpTraceExporter_Grpc))] @@ -103,31 +103,31 @@ public void GlobalSetupHttp() [GlobalCleanup(Target = nameof(OtlpTraceExporter_Grpc))] public void GlobalCleanupGrpc() { - this.exporter.Shutdown(); - this.exporter.Dispose(); - this.activity.Dispose(); - this.host.Dispose(); + this.exporter?.Shutdown(); + this.exporter?.Dispose(); + this.activity?.Dispose(); + this.host?.Dispose(); } [GlobalCleanup(Target = nameof(OtlpTraceExporter_Http))] public void GlobalCleanupHttp() { - this.exporter.Shutdown(); - this.exporter.Dispose(); - this.server.Dispose(); - this.activity.Dispose(); + this.exporter?.Shutdown(); + this.exporter?.Dispose(); + this.server?.Dispose(); + this.activity?.Dispose(); } [Benchmark] public void OtlpTraceExporter_Http() { - this.exporter.Export(new Batch(this.activityBatch, 1)); + this.exporter!.Export(new Batch(this.activityBatch!, 1)); } [Benchmark] public void OtlpTraceExporter_Grpc() { - this.exporter.Export(new Batch(this.activityBatch, 1)); + this.exporter!.Export(new Batch(this.activityBatch!, 1)); } private sealed class MockTraceService : OtlpCollector.TraceService.TraceServiceBase diff --git a/test/Benchmarks/Exporter/PrometheusSerializerBenchmarks.cs b/test/Benchmarks/Exporter/PrometheusSerializerBenchmarks.cs index caeda40f44c..79f5dde5749 100644 --- a/test/Benchmarks/Exporter/PrometheusSerializerBenchmarks.cs +++ b/test/Benchmarks/Exporter/PrometheusSerializerBenchmarks.cs @@ -14,8 +14,8 @@ public class PrometheusSerializerBenchmarks { private readonly List metrics = new(); private readonly byte[] buffer = new byte[85000]; - private Meter meter; - private MeterProvider meterProvider; + private Meter? meter; + private MeterProvider? meterProvider; private Dictionary cache = new Dictionary(); [Params(1, 1000, 10000)] @@ -45,7 +45,7 @@ public void GlobalSetup() public void GlobalCleanup() { this.meter?.Dispose(); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } // TODO: this has a dependency on https://github.com/open-telemetry/opentelemetry-dotnet/issues/2361 diff --git a/test/Benchmarks/Exporter/ZipkinExporterBenchmarks.cs b/test/Benchmarks/Exporter/ZipkinExporterBenchmarks.cs index fb0f802b55a..983b6dce2cd 100644 --- a/test/Benchmarks/Exporter/ZipkinExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/ZipkinExporterBenchmarks.cs @@ -19,10 +19,10 @@ namespace Benchmarks.Exporter; public class ZipkinExporterBenchmarks { private readonly byte[] buffer = new byte[4096]; - private Activity activity; - private CircularBuffer activityBatch; - private IDisposable server; - private string serverHost; + private Activity? activity; + private CircularBuffer? activityBatch; + private IDisposable? server; + private string? serverHost; private int serverPort; [Params(1, 10, 100)] @@ -60,7 +60,7 @@ public void GlobalSetup() [GlobalCleanup] public void GlobalCleanup() { - this.server.Dispose(); + this.server?.Dispose(); } [Benchmark] @@ -76,10 +76,10 @@ public void ZipkinExporter_Batching() { for (int c = 0; c < this.NumberOfSpans; c++) { - this.activityBatch.Add(this.activity); + this.activityBatch!.Add(this.activity!); } - exporter.Export(new Batch(this.activityBatch, this.NumberOfSpans)); + exporter.Export(new Batch(this.activityBatch!, this.NumberOfSpans)); } exporter.Shutdown(); diff --git a/test/Benchmarks/Helper/ActivityHelper.cs b/test/Benchmarks/Helper/ActivityHelper.cs index 33f55dafe57..1c5e5e2ea7e 100644 --- a/test/Benchmarks/Helper/ActivityHelper.cs +++ b/test/Benchmarks/Helper/ActivityHelper.cs @@ -31,14 +31,14 @@ public static Activity CreateTestActivity() new ActivityEvent( "Event1", eventTimestamp, - new ActivityTagsCollection(new Dictionary + new ActivityTagsCollection(new Dictionary { { "key", "value" }, })), new ActivityEvent( "Event2", eventTimestamp, - new ActivityTagsCollection(new Dictionary + new ActivityTagsCollection(new Dictionary { { "key", "value" }, })), @@ -48,7 +48,7 @@ public static Activity CreateTestActivity() using var activitySource = new ActivitySource(nameof(CreateTestActivity)); - var tags = attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.ToString())); + var tags = attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.ToString())); var links = new[] { new ActivityLink(new ActivityContext( @@ -75,10 +75,10 @@ public static Activity CreateTestActivity() foreach (var evnt in events) { - activity.AddEvent(evnt); + activity!.AddEvent(evnt); } - activity.SetEndTime(endTimestamp); + activity!.SetEndTime(endTimestamp); activity.Stop(); return activity; diff --git a/test/Benchmarks/Logs/LogScopeBenchmarks.cs b/test/Benchmarks/Logs/LogScopeBenchmarks.cs index affa9f5f66c..b8bedab2319 100644 --- a/test/Benchmarks/Logs/LogScopeBenchmarks.cs +++ b/test/Benchmarks/Logs/LogScopeBenchmarks.cs @@ -75,6 +75,6 @@ public LogScopeBenchmarks() [Benchmark] public void ForEachScope() { - this.logRecord.ForEachScope(this.callback, null); + this.logRecord.ForEachScope(this.callback!, null); } } diff --git a/test/Benchmarks/Metrics/Base2ExponentialHistogramBenchmarks.cs b/test/Benchmarks/Metrics/Base2ExponentialHistogramBenchmarks.cs index aec8ba6fce5..43a2dfdc4f9 100644 --- a/test/Benchmarks/Metrics/Base2ExponentialHistogramBenchmarks.cs +++ b/test/Benchmarks/Metrics/Base2ExponentialHistogramBenchmarks.cs @@ -31,10 +31,10 @@ public class Base2ExponentialHistogramBenchmarks { private const int MaxValue = 10000; private readonly Random random = new(); - private readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; - private Histogram histogram; - private MeterProvider meterProvider; - private Meter meter; + private readonly string[] dimensionValues = ["DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10"]; + private Histogram? histogram; + private MeterProvider? meterProvider; + private Meter? meter; [GlobalSetup] public void Setup() @@ -58,29 +58,29 @@ public void Setup() public void Cleanup() { this.meter?.Dispose(); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } [Benchmark] public void HistogramHotPath() { - this.histogram.Record(this.random.Next(MaxValue)); + this.histogram!.Record(this.random.Next(MaxValue)); } [Benchmark] public void HistogramWith1LabelHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); - this.histogram.Record(this.random.Next(MaxValue), tag1); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); + this.histogram!.Record(this.random.Next(MaxValue), tag1); } [Benchmark] public void HistogramWith3LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); - this.histogram.Record(this.random.Next(MaxValue), tag1, tag2, tag3); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); + this.histogram!.Record(this.random.Next(MaxValue), tag1, tag2, tag3); } [Benchmark] @@ -94,7 +94,7 @@ public void HistogramWith5LabelsHotPath() { "DimName4", this.dimensionValues[this.random.Next(0, 5)] }, { "DimName5", this.dimensionValues[this.random.Next(0, 10)] }, }; - this.histogram.Record(this.random.Next(MaxValue), tags); + this.histogram!.Record(this.random.Next(MaxValue), tags); } [Benchmark] @@ -110,6 +110,6 @@ public void HistogramWith7LabelsHotPath() { "DimName6", this.dimensionValues[this.random.Next(0, 2)] }, { "DimName7", this.dimensionValues[this.random.Next(0, 1)] }, }; - this.histogram.Record(this.random.Next(MaxValue), tags); + this.histogram!.Record(this.random.Next(MaxValue), tags); } } diff --git a/test/Benchmarks/Metrics/Base2ExponentialHistogramMapToIndexBenchmarks.cs b/test/Benchmarks/Metrics/Base2ExponentialHistogramMapToIndexBenchmarks.cs index a7cc5edb5ca..5207716c424 100644 --- a/test/Benchmarks/Metrics/Base2ExponentialHistogramMapToIndexBenchmarks.cs +++ b/test/Benchmarks/Metrics/Base2ExponentialHistogramMapToIndexBenchmarks.cs @@ -25,7 +25,7 @@ public class Base2ExponentialHistogramMapToIndexBenchmarks { private const int MaxValue = 10000; private readonly Random random = new(); - private Base2ExponentialBucketHistogram exponentialHistogram; + private Base2ExponentialBucketHistogram? exponentialHistogram; [Params(-11, 3, 20)] public int Scale { get; set; } @@ -39,6 +39,6 @@ public void Setup() [Benchmark] public void MapToIndex() { - this.exponentialHistogram.MapToIndex(this.random.Next(MaxValue)); + this.exponentialHistogram!.MapToIndex(this.random.Next(MaxValue)); } } diff --git a/test/Benchmarks/Metrics/Base2ExponentialHistogramScaleBenchmarks.cs b/test/Benchmarks/Metrics/Base2ExponentialHistogramScaleBenchmarks.cs index d11d8743ebf..4c7d01f925c 100644 --- a/test/Benchmarks/Metrics/Base2ExponentialHistogramScaleBenchmarks.cs +++ b/test/Benchmarks/Metrics/Base2ExponentialHistogramScaleBenchmarks.cs @@ -28,9 +28,9 @@ public class Base2ExponentialHistogramScaleBenchmarks { private const int MaxValue = 10000; private readonly Random random = new(); - private Histogram histogram; - private MeterProvider meterProvider; - private Meter meter; + private Histogram? histogram; + private MeterProvider? meterProvider; + private Meter? meter; // This is a simple benchmark that records values in the range [0, 10000]. // The reason the following scales are benchmarked are as follows: @@ -66,12 +66,12 @@ public void Setup() public void Cleanup() { this.meter?.Dispose(); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } [Benchmark] public void HistogramHotPath() { - this.histogram.Record(this.random.Next(MaxValue)); + this.histogram!.Record(this.random.Next(MaxValue)); } } diff --git a/test/Benchmarks/Metrics/ExemplarBenchmarks.cs b/test/Benchmarks/Metrics/ExemplarBenchmarks.cs index ac1d347fba7..d9369d26e3e 100644 --- a/test/Benchmarks/Metrics/ExemplarBenchmarks.cs +++ b/test/Benchmarks/Metrics/ExemplarBenchmarks.cs @@ -42,12 +42,12 @@ public class ExemplarBenchmarks { private static readonly ThreadLocal ThreadLocalRandom = new(() => new Random()); private readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; - private Histogram histogramWithoutTagReduction; - private Histogram histogramWithTagReduction; - private Counter counterWithoutTagReduction; - private Counter counterWithTagReduction; - private MeterProvider meterProvider; - private Meter meter; + private Histogram? histogramWithoutTagReduction; + private Histogram? histogramWithTagReduction; + private Counter? counterWithoutTagReduction; + private Counter? counterWithTagReduction; + private MeterProvider? meterProvider; + private Meter? meter; [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Test only.")] public enum ExemplarConfigurationType @@ -104,7 +104,7 @@ public void Setup() }) .Build(); - ExemplarReservoir CreateExemplarReservoir() + ExemplarReservoir? CreateExemplarReservoir() { return this.ExemplarConfiguration == ExemplarConfigurationType.AlwaysOnWithHighValueSampling ? new HighValueExemplarReservoir(800D) @@ -116,13 +116,13 @@ ExemplarReservoir CreateExemplarReservoir() public void Cleanup() { this.meter?.Dispose(); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } [Benchmark] public void HistogramNoTagReduction() { - var random = ThreadLocalRandom.Value; + var random = ThreadLocalRandom.Value!; var tags = new TagList { { "DimName1", this.dimensionValues[random.Next(0, 2)] }, @@ -132,13 +132,13 @@ public void HistogramNoTagReduction() { "DimName5", this.dimensionValues[random.Next(0, 10)] }, }; - this.histogramWithoutTagReduction.Record(random.NextDouble() * 1000D, tags); + this.histogramWithoutTagReduction!.Record(random.NextDouble() * 1000D, tags); } [Benchmark] public void HistogramWithTagReduction() { - var random = ThreadLocalRandom.Value; + var random = ThreadLocalRandom.Value!; var tags = new TagList { { "DimName1", this.dimensionValues[random.Next(0, 2)] }, @@ -148,13 +148,13 @@ public void HistogramWithTagReduction() { "DimName5", this.dimensionValues[random.Next(0, 10)] }, }; - this.histogramWithTagReduction.Record(random.NextDouble() * 1000D, tags); + this.histogramWithTagReduction!.Record(random.NextDouble() * 1000D, tags); } [Benchmark] public void CounterNoTagReduction() { - var random = ThreadLocalRandom.Value; + var random = ThreadLocalRandom.Value!; var tags = new TagList { { "DimName1", this.dimensionValues[random.Next(0, 2)] }, @@ -164,13 +164,13 @@ public void CounterNoTagReduction() { "DimName5", this.dimensionValues[random.Next(0, 10)] }, }; - this.counterWithoutTagReduction.Add(random.Next(1000), tags); + this.counterWithoutTagReduction!.Add(random.Next(1000), tags); } [Benchmark] public void CounterWithTagReduction() { - var random = ThreadLocalRandom.Value; + var random = ThreadLocalRandom.Value!; var tags = new TagList { { "DimName1", this.dimensionValues[random.Next(0, 2)] }, @@ -180,7 +180,7 @@ public void CounterWithTagReduction() { "DimName5", this.dimensionValues[random.Next(0, 10)] }, }; - this.counterWithTagReduction.Add(random.Next(1000), tags); + this.counterWithTagReduction!.Add(random.Next(1000), tags); } private sealed class HighValueExemplarReservoir : FixedSizeExemplarReservoir diff --git a/test/Benchmarks/Metrics/HistogramBenchmarks.cs b/test/Benchmarks/Metrics/HistogramBenchmarks.cs index 17bbad18c67..e30ae2ffad9 100644 --- a/test/Benchmarks/Metrics/HistogramBenchmarks.cs +++ b/test/Benchmarks/Metrics/HistogramBenchmarks.cs @@ -47,10 +47,10 @@ public class HistogramBenchmarks private const int MaxValue = 10000; private readonly Random random = new(); private readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; - private Histogram histogram; - private MeterProvider meterProvider; - private Meter meter; - private double[] bounds; + private Histogram? histogram; + private MeterProvider? meterProvider; + private Meter? meter; + private double[]? bounds; // Note: Values related to `HistogramBuckets.DefaultHistogramCountForBinarySearch` [Params(10, 49, 50, 1000)] @@ -85,29 +85,29 @@ public void Setup() public void Cleanup() { this.meter?.Dispose(); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } [Benchmark] public void HistogramHotPath() { - this.histogram.Record(this.random.Next(MaxValue)); + this.histogram!.Record(this.random.Next(MaxValue)); } [Benchmark] public void HistogramWith1LabelHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); - this.histogram.Record(this.random.Next(MaxValue), tag1); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); + this.histogram!.Record(this.random.Next(MaxValue), tag1); } [Benchmark] public void HistogramWith3LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); - this.histogram.Record(this.random.Next(MaxValue), tag1, tag2, tag3); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); + this.histogram!.Record(this.random.Next(MaxValue), tag1, tag2, tag3); } [Benchmark] @@ -121,7 +121,7 @@ public void HistogramWith5LabelsHotPath() { "DimName4", this.dimensionValues[this.random.Next(0, 5)] }, { "DimName5", this.dimensionValues[this.random.Next(0, 10)] }, }; - this.histogram.Record(this.random.Next(MaxValue), tags); + this.histogram!.Record(this.random.Next(MaxValue), tags); } [Benchmark] @@ -137,6 +137,6 @@ public void HistogramWith7LabelsHotPath() { "DimName6", this.dimensionValues[this.random.Next(0, 2)] }, { "DimName7", this.dimensionValues[this.random.Next(0, 1)] }, }; - this.histogram.Record(this.random.Next(MaxValue), tags); + this.histogram!.Record(this.random.Next(MaxValue), tags); } } diff --git a/test/Benchmarks/Metrics/MetricCollectBenchmarks.cs b/test/Benchmarks/Metrics/MetricCollectBenchmarks.cs index c0e0bdebb42..ac3f0cf20cb 100644 --- a/test/Benchmarks/Metrics/MetricCollectBenchmarks.cs +++ b/test/Benchmarks/Metrics/MetricCollectBenchmarks.cs @@ -29,12 +29,12 @@ public class MetricCollectBenchmarks // TODO: Confirm if this needs to be thread-safe private readonly Random random = new(); - private Counter counter; - private MeterProvider provider; - private Meter meter; - private CancellationTokenSource token; - private BaseExportingMetricReader reader; - private Task writeMetricTask; + private Counter? counter; + private MeterProvider? provider; + private Meter? meter; + private CancellationTokenSource? token; + private BaseExportingMetricReader? reader; + private Task? writeMetricTask; [Params(false, true)] public bool UseWithRef { get; set; } @@ -86,9 +86,9 @@ void ProcessExport(Batch batch) { while (!this.token.IsCancellationRequested) { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); this.counter.Add(100.00, tag1, tag2, tag3); } }); @@ -98,16 +98,16 @@ void ProcessExport(Batch batch) [GlobalCleanup] public void Cleanup() { - this.token.Cancel(); - this.token.Dispose(); - this.writeMetricTask.Wait(); - this.meter.Dispose(); - this.provider.Dispose(); + this.token?.Cancel(); + this.token?.Dispose(); + this.writeMetricTask?.Wait(); + this.meter?.Dispose(); + this.provider?.Dispose(); } [Benchmark] public void Collect() { - this.reader.Collect(); + this.reader!.Collect(); } } diff --git a/test/Benchmarks/Metrics/MetricsBenchmarks.cs b/test/Benchmarks/Metrics/MetricsBenchmarks.cs index e63aeb87576..117bf59a5e1 100644 --- a/test/Benchmarks/Metrics/MetricsBenchmarks.cs +++ b/test/Benchmarks/Metrics/MetricsBenchmarks.cs @@ -60,9 +60,9 @@ public class MetricsBenchmarks { private readonly Random random = new(); private readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; - private Counter counter; - private MeterProvider meterProvider; - private Meter meter; + private Counter? counter; + private MeterProvider? meterProvider; + private Meter? meter; [Params(MetricReaderTemporalityPreference.Cumulative, MetricReaderTemporalityPreference.Delta)] public MetricReaderTemporalityPreference AggregationTemporality { get; set; } @@ -89,83 +89,83 @@ public void Setup() public void Cleanup() { this.meter?.Dispose(); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } [Benchmark] public void CounterHotPath() { - this.counter.Add(100); + this.counter!.Add(100); } [Benchmark] public void CounterWith1LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); - this.counter.Add(100, tag1); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); + this.counter!.Add(100, tag1); } [Benchmark] public void CounterWith2LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); - this.counter.Add(100, tag1, tag2); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); + this.counter!.Add(100, tag1, tag2); } [Benchmark] public void CounterWith3LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); - this.counter.Add(100, tag1, tag2, tag3); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); + this.counter!.Add(100, tag1, tag2, tag3); } [Benchmark] public void CounterWith4LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 5)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); - var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 10)]); - this.counter.Add(100, tag1, tag2, tag3, tag4); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 5)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 10)]); + var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 10)]); + this.counter!.Add(100, tag1, tag2, tag3, tag4); } [Benchmark] public void CounterWith5LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 2)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 5)]); - var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 5)]); - var tag5 = new KeyValuePair("DimName5", this.dimensionValues[this.random.Next(0, 10)]); - this.counter.Add(100, tag1, tag2, tag3, tag4, tag5); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 2)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 5)]); + var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 5)]); + var tag5 = new KeyValuePair("DimName5", this.dimensionValues[this.random.Next(0, 10)]); + this.counter!.Add(100, tag1, tag2, tag3, tag4, tag5); } [Benchmark] public void CounterWith6LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 2)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 2)]); - var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 5)]); - var tag5 = new KeyValuePair("DimName5", this.dimensionValues[this.random.Next(0, 5)]); - var tag6 = new KeyValuePair("DimName6", this.dimensionValues[this.random.Next(0, 5)]); - this.counter.Add(100, tag1, tag2, tag3, tag4, tag5, tag6); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 2)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 2)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 2)]); + var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 5)]); + var tag5 = new KeyValuePair("DimName5", this.dimensionValues[this.random.Next(0, 5)]); + var tag6 = new KeyValuePair("DimName6", this.dimensionValues[this.random.Next(0, 5)]); + this.counter!.Add(100, tag1, tag2, tag3, tag4, tag5, tag6); } [Benchmark] public void CounterWith7LabelsHotPath() { - var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 1)]); - var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 2)]); - var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 2)]); - var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 2)]); - var tag5 = new KeyValuePair("DimName5", this.dimensionValues[this.random.Next(0, 5)]); - var tag6 = new KeyValuePair("DimName6", this.dimensionValues[this.random.Next(0, 5)]); - var tag7 = new KeyValuePair("DimName7", this.dimensionValues[this.random.Next(0, 5)]); - this.counter.Add(100, tag1, tag2, tag3, tag4, tag5, tag6, tag7); + var tag1 = new KeyValuePair("DimName1", this.dimensionValues[this.random.Next(0, 1)]); + var tag2 = new KeyValuePair("DimName2", this.dimensionValues[this.random.Next(0, 2)]); + var tag3 = new KeyValuePair("DimName3", this.dimensionValues[this.random.Next(0, 2)]); + var tag4 = new KeyValuePair("DimName4", this.dimensionValues[this.random.Next(0, 2)]); + var tag5 = new KeyValuePair("DimName5", this.dimensionValues[this.random.Next(0, 5)]); + var tag6 = new KeyValuePair("DimName6", this.dimensionValues[this.random.Next(0, 5)]); + var tag7 = new KeyValuePair("DimName7", this.dimensionValues[this.random.Next(0, 5)]); + this.counter!.Add(100, tag1, tag2, tag3, tag4, tag5, tag6, tag7); } [Benchmark] @@ -175,7 +175,7 @@ public void CounterWith1LabelsHotPathUsingTagList() { { "DimName1", this.dimensionValues[this.random.Next(0, 10)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -186,7 +186,7 @@ public void CounterWith2LabelsHotPathUsingTagList() { "DimName1", this.dimensionValues[this.random.Next(0, 10)] }, { "DimName2", this.dimensionValues[this.random.Next(0, 10)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -198,7 +198,7 @@ public void CounterWith3LabelsHotPathUsingTagList() { "DimName2", this.dimensionValues[this.random.Next(0, 10)] }, { "DimName3", this.dimensionValues[this.random.Next(0, 10)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -211,7 +211,7 @@ public void CounterWith4LabelsHotPathUsingTagList() { "DimName3", this.dimensionValues[this.random.Next(0, 10)] }, { "DimName4", this.dimensionValues[this.random.Next(0, 10)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -225,7 +225,7 @@ public void CounterWith5LabelsHotPathUsingTagList() { "DimName4", this.dimensionValues[this.random.Next(0, 5)] }, { "DimName5", this.dimensionValues[this.random.Next(0, 10)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -240,7 +240,7 @@ public void CounterWith6LabelsHotPathUsingTagList() { "DimName5", this.dimensionValues[this.random.Next(0, 5)] }, { "DimName6", this.dimensionValues[this.random.Next(0, 5)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -256,7 +256,7 @@ public void CounterWith7LabelsHotPathUsingTagList() { "DimName6", this.dimensionValues[this.random.Next(0, 5)] }, { "DimName7", this.dimensionValues[this.random.Next(0, 5)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -273,7 +273,7 @@ public void CounterWith8LabelsHotPathUsingTagList() { "DimName7", this.dimensionValues[this.random.Next(0, 5)] }, { "DimName8", this.dimensionValues[this.random.Next(0, 5)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } [Benchmark] @@ -291,6 +291,6 @@ public void CounterWith9LabelsHotPathUsingTagList() { "DimName8", this.dimensionValues[this.random.Next(0, 5)] }, { "DimName9", this.dimensionValues[this.random.Next(0, 5)] }, }; - this.counter.Add(100, tags); + this.counter!.Add(100, tags); } } diff --git a/test/Benchmarks/Metrics/MetricsViewBenchmarks.cs b/test/Benchmarks/Metrics/MetricsViewBenchmarks.cs index 359313ac9bf..ce9cb40b6c5 100644 --- a/test/Benchmarks/Metrics/MetricsViewBenchmarks.cs +++ b/test/Benchmarks/Metrics/MetricsViewBenchmarks.cs @@ -32,10 +32,10 @@ public class MetricsViewBenchmarks private static readonly ThreadLocal ThreadLocalRandom = new(() => new Random()); private static readonly string[] DimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; private static readonly int DimensionsValuesLength = DimensionValues.Length; - private List metrics; - private Counter counter; - private MeterProvider meterProvider; - private Meter meter; + private List? metrics; + private Counter? counter; + private MeterProvider? meterProvider; + private Meter? meter; public enum ViewConfiguration { @@ -130,13 +130,13 @@ public void Setup() public void Cleanup() { this.meter?.Dispose(); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } [Benchmark] public void CounterHotPath() { - var random = ThreadLocalRandom.Value; + var random = ThreadLocalRandom.Value!; var tags = new TagList { { "DimName1", DimensionValues[random.Next(0, 2)] }, diff --git a/test/Benchmarks/TestTraceServiceClient.cs b/test/Benchmarks/TestTraceServiceClient.cs index 968ddd75715..fc60f90278a 100644 --- a/test/Benchmarks/TestTraceServiceClient.cs +++ b/test/Benchmarks/TestTraceServiceClient.cs @@ -10,7 +10,7 @@ namespace Benchmarks; internal class TestTraceServiceClient : TraceService.TraceServiceClient { - public override ExportTraceServiceResponse Export(ExportTraceServiceRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default) + public override ExportTraceServiceResponse Export(ExportTraceServiceRequest request, Metadata? headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default) { return new ExportTraceServiceResponse(); } diff --git a/test/Benchmarks/Trace/ActivityCreationBenchmarks.cs b/test/Benchmarks/Trace/ActivityCreationBenchmarks.cs index 447e550bd87..2ec79e4ef36 100644 --- a/test/Benchmarks/Trace/ActivityCreationBenchmarks.cs +++ b/test/Benchmarks/Trace/ActivityCreationBenchmarks.cs @@ -29,7 +29,7 @@ public class ActivityCreationBenchmarks { private readonly ActivitySource benchmarkSource = new("Benchmark"); private readonly ActivityContext parentCtx = new(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None); - private TracerProvider tracerProvider; + private TracerProvider? tracerProvider; [GlobalSetup] public void GlobalSetup() @@ -43,8 +43,8 @@ public void GlobalSetup() [GlobalCleanup] public void GlobalCleanup() { - this.tracerProvider.Dispose(); - this.benchmarkSource.Dispose(); + this.tracerProvider?.Dispose(); + this.benchmarkSource?.Dispose(); } [Benchmark] diff --git a/test/Benchmarks/Trace/SamplerBenchmarks.cs b/test/Benchmarks/Trace/SamplerBenchmarks.cs index 440536f281e..a835daea375 100644 --- a/test/Benchmarks/Trace/SamplerBenchmarks.cs +++ b/test/Benchmarks/Trace/SamplerBenchmarks.cs @@ -92,7 +92,7 @@ public void SamplerAppendingTraceState() internal class TestSampler : Sampler { - public Func SamplingAction { get; set; } + public Func? SamplingAction { get; set; } public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { diff --git a/test/Benchmarks/Trace/SpanCreationBenchmarks.cs b/test/Benchmarks/Trace/SpanCreationBenchmarks.cs index 9ca218f2dc8..4aacae1586d 100644 --- a/test/Benchmarks/Trace/SpanCreationBenchmarks.cs +++ b/test/Benchmarks/Trace/SpanCreationBenchmarks.cs @@ -32,11 +32,11 @@ namespace Benchmarks.Trace; public class SpanCreationBenchmarks { - private Tracer alwaysSampleTracer; - private Tracer neverSampleTracer; - private Tracer noopTracer; - private TracerProvider tracerProviderAlwaysOnSample; - private TracerProvider tracerProviderAlwaysOffSample; + private Tracer? alwaysSampleTracer; + private Tracer? neverSampleTracer; + private Tracer? noopTracer; + private TracerProvider? tracerProviderAlwaysOnSample; + private TracerProvider? tracerProviderAlwaysOffSample; [GlobalSetup] public void GlobalSetup() @@ -61,37 +61,37 @@ public void GlobalSetup() [GlobalCleanup] public void GlobalCleanup() { - this.tracerProviderAlwaysOffSample.Dispose(); - this.tracerProviderAlwaysOnSample.Dispose(); + this.tracerProviderAlwaysOffSample?.Dispose(); + this.tracerProviderAlwaysOnSample?.Dispose(); } [Benchmark] - public void CreateSpan_Sampled() => SpanCreationScenarios.CreateSpan(this.alwaysSampleTracer); + public void CreateSpan_Sampled() => SpanCreationScenarios.CreateSpan(this.alwaysSampleTracer!); [Benchmark] - public void CreateSpan_ParentContext() => SpanCreationScenarios.CreateSpan_ParentContext(this.alwaysSampleTracer); + public void CreateSpan_ParentContext() => SpanCreationScenarios.CreateSpan_ParentContext(this.alwaysSampleTracer!); [Benchmark] - public void CreateSpan_Attributes_Sampled() => SpanCreationScenarios.CreateSpan_Attributes(this.alwaysSampleTracer); + public void CreateSpan_Attributes_Sampled() => SpanCreationScenarios.CreateSpan_Attributes(this.alwaysSampleTracer!); [Benchmark] - public void CreateSpan_WithSpan() => SpanCreationScenarios.CreateSpan_Propagate(this.alwaysSampleTracer); + public void CreateSpan_WithSpan() => SpanCreationScenarios.CreateSpan_Propagate(this.alwaysSampleTracer!); [Benchmark] - public void CreateSpan_Active() => SpanCreationScenarios.CreateSpan_Active(this.alwaysSampleTracer); + public void CreateSpan_Active() => SpanCreationScenarios.CreateSpan_Active(this.alwaysSampleTracer!); [Benchmark] - public void CreateSpan_Active_GetCurrent() => SpanCreationScenarios.CreateSpan_Active_GetCurrent(this.alwaysSampleTracer); + public void CreateSpan_Active_GetCurrent() => SpanCreationScenarios.CreateSpan_Active_GetCurrent(this.alwaysSampleTracer!); [Benchmark] - public void CreateSpan_Attributes_NotSampled() => SpanCreationScenarios.CreateSpan_Attributes(this.neverSampleTracer); + public void CreateSpan_Attributes_NotSampled() => SpanCreationScenarios.CreateSpan_Attributes(this.neverSampleTracer!); [Benchmark(Baseline = true)] - public void CreateSpan_Noop() => SpanCreationScenarios.CreateSpan(this.noopTracer); + public void CreateSpan_Noop() => SpanCreationScenarios.CreateSpan(this.noopTracer!); [Benchmark] - public void CreateSpan_Attributes_Noop() => SpanCreationScenarios.CreateSpan_Attributes(this.noopTracer); + public void CreateSpan_Attributes_Noop() => SpanCreationScenarios.CreateSpan_Attributes(this.noopTracer!); [Benchmark] - public void CreateSpan_Propagate_Noop() => SpanCreationScenarios.CreateSpan_Propagate(this.noopTracer); + public void CreateSpan_Propagate_Noop() => SpanCreationScenarios.CreateSpan_Propagate(this.noopTracer!); } From 5106e3082f92bcd1cc0a3a259198f116a4a51fb1 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sun, 6 Oct 2024 09:39:57 -0700 Subject: [PATCH 101/133] [repo] Remove implicit using tweak as it is no longer needed (#5887) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/Directory.Build.targets | 9 --------- test/Directory.Build.targets | 9 --------- 2 files changed, 18 deletions(-) diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 3e05f2937f9..6cef70da6c1 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -16,15 +16,6 @@ - - - - - - - - - - From a55a5ac997204e571a41c495f83de828d3e07685 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Mon, 7 Oct 2024 16:26:10 -0700 Subject: [PATCH 102/133] [repo] Update stale.yml - reduce days before stale to 450 (#5888) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index a46d0abad3c..7a7b91c3e67 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,7 +18,7 @@ jobs: close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' operations-per-run: 400 days-before-pr-stale: 7 - days-before-issue-stale: 600 + days-before-issue-stale: 450 days-before-pr-close: 7 days-before-issue-close: 7 exempt-all-issue-milestones: true From 66c2e4b778c69e051393b3a2c5d52ae66b34adbf Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Tue, 8 Oct 2024 12:13:18 -0700 Subject: [PATCH 103/133] [sdk] Support split reads in OTEL_DIAGNOSTICS.json config file parser logic (#5884) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../Internal/SelfDiagnosticsConfigParser.cs | 19 ++++++++--- .../SelfDiagnosticsEventListenerTest.cs | 34 ++++++++++++++++--- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs index 751154f8849..1f23bdee779 100644 --- a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs +++ b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs @@ -66,10 +66,21 @@ public bool TryGetConfiguration( this.configBuffer = buffer; } - // TODO: Fix CA2022 - Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' - // Added _ = as a workaround to suppress the warning - _ = file.Read(buffer, 0, buffer.Length); - string configJson = Encoding.UTF8.GetString(buffer); + int bytesRead = 0; + int totalBytesRead = 0; + + while (totalBytesRead < buffer.Length) + { + bytesRead = file.Read(buffer, totalBytesRead, buffer.Length - totalBytesRead); + if (bytesRead == 0) + { + break; + } + + totalBytesRead += bytesRead; + } + + string configJson = Encoding.UTF8.GetString(buffer, 0, totalBytesRead); if (!TryParseLogDirectory(configJson, out logDirectory)) { diff --git a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs index 3ea7ae3bf7a..a26cb0530d6 100644 --- a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs +++ b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs @@ -125,8 +125,20 @@ public void SelfDiagnosticsEventListener_EmitEvent_OmitAsConfigured() using FileStream file = File.Open(LOGFILEPATH, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); var buffer = new byte[256]; - // Suppress CA2022 error: Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' - _ = file.Read(buffer, 0, buffer.Length); + int bytesRead = 0; + int totalBytesRead = 0; + + while (totalBytesRead < buffer.Length) + { + bytesRead = file.Read(buffer, totalBytesRead, buffer.Length - totalBytesRead); + if (bytesRead == 0) + { + break; + } + + totalBytesRead += bytesRead; + } + Assert.Equal('\0', (char)buffer[0]); } @@ -259,9 +271,21 @@ private static void AssertFileOutput(string filePath, string eventMessage) using FileStream file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); var buffer = new byte[256]; - // Suppress CA2022 error: Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' - _ = file.Read(buffer, 0, buffer.Length); - string logLine = Encoding.UTF8.GetString(buffer); + int bytesRead = 0; + int totalBytesRead = 0; + + while (totalBytesRead < buffer.Length) + { + bytesRead = file.Read(buffer, totalBytesRead, buffer.Length - totalBytesRead); + if (bytesRead == 0) + { + break; + } + + totalBytesRead += bytesRead; + } + + string logLine = Encoding.UTF8.GetString(buffer, 0, totalBytesRead); string logMessage = ParseLogMessage(logLine); Assert.StartsWith(eventMessage, logMessage); } From 9b08508541cf4c5bd5610f5d7c3c0737d81d45e0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 8 Oct 2024 12:45:14 -0700 Subject: [PATCH 104/133] [repo] Mitigate vulnerabilities in System.Text.Json 8.0.4 package (#5891) --- Directory.Packages.props | 11 +++++++++-- src/OpenTelemetry.Exporter.Console/CHANGELOG.md | 8 +++++--- src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md | 8 +++++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 747cff1b7d1..a24c8c7dbe8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,8 +3,10 @@ true 1.9.0 + + 8.0.0 - 8.0.4 + 8.0.5 + + diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index 0a6734593e0..d50c0cd8be5 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -7,9 +7,11 @@ Notes](../../RELEASENOTES.md). ## Unreleased * Added direct reference to `System.Text.Json` for the `net8.0` target with - minimum version of `8.0.4` in response to - [CVE-2024-30105](https://github.com/advisories/GHSA-hh2w-p6rv-4g7w). - ([#5874](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5874)) + minimum version of `8.0.5` in response to + [CVE-2024-30105](https://github.com/advisories/GHSA-hh2w-p6rv-4g7w) & + [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). + ([#5874](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5874), + [#5891](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5891)) ## 1.10.0-beta.1 diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index bae3b61acbf..617098116d9 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -7,9 +7,11 @@ Notes](../../RELEASENOTES.md). ## Unreleased * Added direct reference to `System.Text.Json` for the `net8.0` target with - minimum version of `8.0.4` in response to - [CVE-2024-30105](https://github.com/advisories/GHSA-hh2w-p6rv-4g7w). - ([#5874](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5874)) + minimum version of `8.0.5` in response to + [CVE-2024-30105](https://github.com/advisories/GHSA-hh2w-p6rv-4g7w) & + [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). + ([#5874](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5874), + [#5891](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5891)) ## 1.10.0-beta.1 From 2499ecdf8e0b7cf32ab1111243600bb698dc9295 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 9 Oct 2024 23:50:52 -0700 Subject: [PATCH 105/133] [docs] Clarify the position regarding bot generated and AI-assisted PRs (#5894) --- CONTRIBUTING.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2e958021c7..7f53dfbe35b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -203,13 +203,19 @@ Open a pull request against the main `opentelemetry-dotnet` repo. * If the PR is not ready for review, please mark it as [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/). * Make sure CLA is signed and all required CI checks are clear. -* Submit small, focused PRs addressing a single - concern/issue. +* Submit small, focused PRs addressing a single concern/issue. * Make sure the PR title reflects the contribution. * Write a summary that helps understand the change. * Include usage examples in the summary, where applicable. * Include benchmarks (before/after) in the summary, for contributions that are performance enhancements. +* We are open to bot generated PRs or AI/LLM assisted PRs. Actually, we are + using + [dependabot](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates) + to automate the security updates. However, if you use bots to generate spam + PRs (e.g. incorrect, noisy, non-improvements, unintelligible, trying to sell + your product, etc.), we might close the PR right away with a warning, and if + you keep doing so, we might block your user account. ### How to get pull requests merged From 331e1267b6dec35427ae2440a5d030efa046bf04 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 10 Oct 2024 09:30:46 -0700 Subject: [PATCH 106/133] [repo] Directory.Packages.props cleanup (#5886) --- Directory.Packages.props | 57 ++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index a24c8c7dbe8..7678397d0ed 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,6 +4,13 @@ true 1.9.0 + + 9.0.0-rc.1.24431.7 + 8.0.0 8.0.5 @@ -15,12 +22,6 @@ vulnerability in the NuGet packages that are published from this repository. --> - - - - - - + + + + + + + + - - - - - - - - - + @@ -50,14 +53,22 @@ - + + + + + + @@ -92,10 +103,10 @@ - - - - + + + + From b0ebf3518cf47a7eea19b8721c4470344cb7fd79 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 10 Oct 2024 14:15:16 -0700 Subject: [PATCH 107/133] [docs-metrics] Improve View documentation to show its additive nature (#5896) --- docs/metrics/customizing-the-sdk/Program.cs | 12 +++ docs/metrics/customizing-the-sdk/README.md | 84 +++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/docs/metrics/customizing-the-sdk/Program.cs b/docs/metrics/customizing-the-sdk/Program.cs index c88a295fdd7..bbfd4bea98f 100644 --- a/docs/metrics/customizing-the-sdk/Program.cs +++ b/docs/metrics/customizing-the-sdk/Program.cs @@ -40,6 +40,12 @@ public static void Main() // Drop the instrument "MyCounterDrop". .AddView(instrumentName: "MyCounterDrop", MetricStreamConfiguration.Drop) + // Configure the Explicit Bucket Histogram aggregation with custom boundaries and new name. + .AddView(instrumentName: "histogramWithMultipleAggregations", new ExplicitBucketHistogramConfiguration() { Boundaries = new double[] { 10, 20 }, Name = "MyHistogramWithExplicitHistogram" }) + + // Use Base2 Exponential Bucket Histogram aggregation and new name. + .AddView(instrumentName: "histogramWithMultipleAggregations", new Base2ExponentialBucketHistogramConfiguration() { Name = "MyHistogramWithBase2ExponentialBucketHistogram" }) + // An instrument which does not match any views // gets processed with default behavior. (SDK default) // Uncommenting the following line will @@ -70,6 +76,12 @@ public static void Main() exponentialBucketHistogram.Record(random.Next(1, 1000), new("tag1", "value1"), new("tag2", "value2")); } + var histogramWithMultipleAggregations = Meter1.CreateHistogram("histogramWithMultipleAggregations"); + for (int i = 0; i < 20000; i++) + { + histogramWithMultipleAggregations.Record(random.Next(1, 1000), new("tag1", "value1"), new("tag2", "value2")); + } + var counterCustomTags = Meter1.CreateCounter("MyCounterCustomTags"); for (int i = 0; i < 20000; i++) { diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index ed4d9aa9d67..8aaeef19fad 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -245,6 +245,90 @@ within the maximum number of buckets defined by `MaxSize`. The default new Base2ExponentialBucketHistogramConfiguration { MaxSize = 40 }) ``` +#### Produce multiple metrics from single instrument + +When an instrument matches multiple views, it can generate multiple metrics. For +instance, if an instrument is matched by two different view configurations, it +will result in two separate metrics being produced from that single instrument. +Below is an example demonstrating how to leverage this capability to create two +independent metrics from a single instrument. In this example, a histogram +instrument is used to report measurements, and views are configured to produce +two metrics : one aggregated using `ExplicitBucketHistogramConfiguration` and the +other using `Base2ExponentialBucketHistogramConfiguration`. + +```csharp + var histogramWithMultipleAggregations = meter.CreateHistogram("HistogramWithMultipleAggregations"); + + // Configure the Explicit Bucket Histogram aggregation with custom boundaries and new name. + .AddView(instrumentName: "HistogramWithMultipleAggregations", new ExplicitBucketHistogramConfiguration() { Boundaries = new double[] { 10, 20 }, Name = "MyHistogramWithExplicitHistogram" }) + + // Use Base2 Exponential Bucket Histogram aggregation and new name. + .AddView(instrumentName: "HistogramWithMultipleAggregations", new Base2ExponentialBucketHistogramConfiguration() { Name = "MyHistogramWithBase2ExponentialBucketHistogram" }) + + // Both views rename the metric to avoid name conflicts. However, in this case, + // renaming one would be sufficient. + + // This measurement will be aggregated into two separate metrics. + histogramWithMultipleAggregations.Record(10, new("tag1", "value1"), new("tag2", "value2")); +``` + +When using views that produce multiple metrics from single instrument, it's +crucial to rename the metric to prevent conflicts. In the event of conflict, +OpenTelemetry will emit an internal warning but will still export both metrics. +The impact of this behavior depends on the backend or receiver being used. You +can refer to [OpenTelemetry's +specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#opentelemetry-protocol-data-model-consumer-recommendations) +for more details. + +Below example is showing the *BAD* practice. DO NOT FOLLOW it. + +```csharp + var histogram = meter.CreateHistogram("MyHistogram"); + + // Configure a view to aggregate based only on the "location" tag. + .AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration + { + TagKeys = new string[] { "location" }, + }) + + // Configure another view to aggregate based only on the "status" tag. + .AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration + { + TagKeys = new string[] { "status" }, + }) + + // The measurement below will be aggregated into two metric streams, but both will have the same name. + // OpenTelemetry will issue a warning about this conflict and pass both streams to the exporter. + // However, this may cause issues depending on the backend. + histogram.Record(10, new("location", "seattle"), new("status", "OK")); +``` + +The modified version, avoiding name conflict is shown below: + +```csharp + var histogram = meter.CreateHistogram("MyHistogram"); + + // Configure a view to aggregate based only on the "location" tag, + // and rename the metric. + .AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration + { + Name = "MyHistogramWithLocation", + TagKeys = new string[] { "location" }, + }) + + // Configure a view to aggregate based only on the "status" tag, + // and rename the metric. + .AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration + { + Name = "MyHistogramWithStatus", + TagKeys = new string[] { "status" }, + }) + + // The measurement below will be aggregated into two separate metrics, "MyHistogramWithLocation" + // and "MyHistogramWithStatus". + histogram.Record(10, new("location", "seattle"), new("status", "OK")); +``` + > [!NOTE] > The SDK currently does not support any changes to `Aggregation` type by using Views. From 36d5900be0f403c7be61b2765c1fbafdeaaeae96 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Fri, 11 Oct 2024 20:27:43 +0200 Subject: [PATCH 108/133] [Examples] Nullable (#5881) Co-authored-by: Mikel Blanchard --- examples/Console/Examples.Console.csproj | 3 -- .../InstrumentationWithActivitySource.cs | 12 ++--- examples/Console/Program.cs | 28 +++++------ examples/Console/TestConsoleExporter.cs | 16 +++--- examples/Console/TestGrpcNetClient.cs | 6 ++- examples/Console/TestHttpClient.cs | 6 ++- examples/Console/TestInMemoryExporter.cs | 12 ++--- examples/Console/TestLogs.cs | 50 ++++++++++++------- examples/Console/TestMetrics.cs | 38 +++++++------- .../TestOTelShimWithConsoleExporter.cs | 12 ++--- examples/Console/TestOpenTracingShim.cs | 12 ++--- examples/Console/TestOtlpExporter.cs | 40 +++++++-------- examples/Console/TestPrometheusExporter.cs | 10 ++-- examples/Console/TestZipkinExporter.cs | 19 +++---- .../Utils/Messaging/RabbitMqHelper.cs | 2 +- .../MicroserviceExample/Utils/Utils.csproj | 3 -- 16 files changed, 142 insertions(+), 127 deletions(-) diff --git a/examples/Console/Examples.Console.csproj b/examples/Console/Examples.Console.csproj index d2b74f2e648..86c6b1df037 100644 --- a/examples/Console/Examples.Console.csproj +++ b/examples/Console/Examples.Console.csproj @@ -4,9 +4,6 @@ Exe $(DefaultTargetFrameworkForExampleApps) $(NoWarn),CS0618 - - - disable diff --git a/examples/Console/InstrumentationWithActivitySource.cs b/examples/Console/InstrumentationWithActivitySource.cs index 240f58289d8..706d68ad993 100644 --- a/examples/Console/InstrumentationWithActivitySource.cs +++ b/examples/Console/InstrumentationWithActivitySource.cs @@ -47,13 +47,13 @@ public void Start(string url) var context = this.listener.GetContext(); using var activity = source.StartActivity( - $"{context.Request.HttpMethod}:{context.Request.Url.AbsolutePath}", + $"{context.Request.HttpMethod}:{context.Request.Url!.AbsolutePath}", ActivityKind.Server); var headerKeys = context.Request.Headers.AllKeys; foreach (var headerKey in headerKeys) { - string headerValue = context.Request.Headers[headerKey]; + string? headerValue = context.Request.Headers[headerKey]; activity?.SetTag($"http.header.{headerKey}", headerValue); } @@ -62,7 +62,7 @@ public void Start(string url) using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding)) { requestContent = reader.ReadToEnd(); - childSpan.AddEvent(new ActivityEvent("StreamReader.ReadToEnd")); + childSpan?.AddEvent(new ActivityEvent("StreamReader.ReadToEnd")); } activity?.SetTag("request.content", requestContent); @@ -90,8 +90,8 @@ public void Dispose() private class SampleClient : IDisposable { - private CancellationTokenSource cts; - private Task requestTask; + private CancellationTokenSource? cts; + private Task? requestTask; public void Start(string url) { @@ -154,7 +154,7 @@ public void Dispose() if (this.cts != null) { this.cts.Cancel(); - this.requestTask.Wait(); + this.requestTask!.Wait(); this.requestTask.Dispose(); this.cts.Dispose(); } diff --git a/examples/Console/Program.cs b/examples/Console/Program.cs index 2b93979e071..bca2e4339c7 100644 --- a/examples/Console/Program.cs +++ b/examples/Console/Program.cs @@ -33,16 +33,16 @@ public static void Main(string[] args) { Parser.Default.ParseArguments(args) .MapResult( - (ZipkinOptions options) => TestZipkinExporter.Run(options.Uri), - (PrometheusOptions options) => TestPrometheusExporter.Run(options.Port), + (ZipkinOptions options) => TestZipkinExporter.Run(options), + (PrometheusOptions options) => TestPrometheusExporter.Run(options), (MetricsOptions options) => TestMetrics.Run(options), (LogsOptions options) => TestLogs.Run(options), - (GrpcNetClientOptions options) => TestGrpcNetClient.Run(), - (HttpClientOptions options) => TestHttpClient.Run(), + (GrpcNetClientOptions options) => TestGrpcNetClient.Run(options), + (HttpClientOptions options) => TestHttpClient.Run(options), (ConsoleOptions options) => TestConsoleExporter.Run(options), (OpenTelemetryShimOptions options) => TestOTelShimWithConsoleExporter.Run(options), (OpenTracingShimOptions options) => TestOpenTracingShim.Run(options), - (OtlpOptions options) => TestOtlpExporter.Run(options.Endpoint, options.Protocol), + (OtlpOptions options) => TestOtlpExporter.Run(options), (InMemoryOptions options) => TestInMemoryExporter.Run(options), errs => 1); } @@ -54,7 +54,7 @@ public static void Main(string[] args) internal class ZipkinOptions { [Option('u', "uri", HelpText = "Please specify the uri of Zipkin backend", Required = true)] - public string Uri { get; set; } + public required string Uri { get; set; } } [Verb("prometheus", HelpText = "Specify the options required to test Prometheus")] @@ -83,10 +83,10 @@ internal class MetricsOptions public int DefaultCollectionPeriodMilliseconds { get; set; } [Option("useExporter", Default = "console", HelpText = "Options include otlp or console.", Required = false)] - public string UseExporter { get; set; } + public string? UseExporter { get; set; } [Option('e', "endpoint", HelpText = "Target to which the exporter is going to send metrics (default value depends on protocol).", Default = null)] - public string Endpoint { get; set; } + public string? Endpoint { get; set; } [Option('p', "useGrpc", HelpText = "Use gRPC or HTTP when using the OTLP exporter", Required = false, Default = true)] public bool UseGrpc { get; set; } @@ -121,26 +121,26 @@ internal class OpenTracingShimOptions internal class OtlpOptions { [Option('e', "endpoint", HelpText = "Target to which the exporter is going to send traces (default value depends on protocol).", Default = null)] - public string Endpoint { get; set; } + public string? Endpoint { get; set; } [Option('p', "protocol", HelpText = "Transport protocol used by exporter. Supported values: grpc and http/protobuf.", Default = "grpc")] - public string Protocol { get; set; } + public string? Protocol { get; set; } } [Verb("logs", HelpText = "Specify the options required to test Logs")] internal class LogsOptions { [Option("useExporter", Default = "otlp", HelpText = "Options include otlp or console.", Required = false)] - public string UseExporter { get; set; } + public string? UseExporter { get; set; } [Option('e', "endpoint", HelpText = "Target to which the OTLP exporter is going to send logs (default value depends on protocol).", Default = null)] - public string Endpoint { get; set; } + public string? Endpoint { get; set; } [Option('p', "protocol", HelpText = "Transport protocol used by OTLP exporter. Supported values: grpc and http/protobuf. Only applicable if Exporter is OTLP", Default = "grpc")] - public string Protocol { get; set; } + public string? Protocol { get; set; } [Option("processorType", Default = "batch", HelpText = "export processor type. Supported values: simple and batch", Required = false)] - public string ProcessorType { get; set; } + public string? ProcessorType { get; set; } [Option("scheduledDelay", Default = 5000, HelpText = "The delay interval in milliseconds between two consecutive exports.", Required = false)] public int ScheduledDelayInMilliseconds { get; set; } diff --git a/examples/Console/TestConsoleExporter.cs b/examples/Console/TestConsoleExporter.cs index cf3f803c4fd..7a70c0ef1e4 100644 --- a/examples/Console/TestConsoleExporter.cs +++ b/examples/Console/TestConsoleExporter.cs @@ -15,21 +15,21 @@ internal class TestConsoleExporter // (eg: C:\repos\opentelemetry-dotnet\examples\Console\) // // dotnet run console - internal static object Run(ConsoleOptions options) + internal static int Run(ConsoleOptions options) { return RunWithActivitySource(); } - private static object RunWithActivitySource() + private static int RunWithActivitySource() { // Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient" // and use Console exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSource("Samples.SampleClient", "Samples.SampleServer") - .ConfigureResource(res => res.AddService("console-test")) - .AddProcessor(new MyProcessor()) // This must be added before ConsoleExporter - .AddConsoleExporter() - .Build(); + .AddSource("Samples.SampleClient", "Samples.SampleServer") + .ConfigureResource(res => res.AddService("console-test")) + .AddProcessor(new MyProcessor()) // This must be added before ConsoleExporter + .AddConsoleExporter() + .Build(); // The above line is required only in applications // which decide to use OpenTelemetry. @@ -43,7 +43,7 @@ private static object RunWithActivitySource() System.Console.ReadLine(); } - return null; + return 0; } /// diff --git a/examples/Console/TestGrpcNetClient.cs b/examples/Console/TestGrpcNetClient.cs index d179d93913e..31dce4a1679 100644 --- a/examples/Console/TestGrpcNetClient.cs +++ b/examples/Console/TestGrpcNetClient.cs @@ -12,8 +12,10 @@ namespace Examples.Console; internal class TestGrpcNetClient { - internal static object Run() + internal static int Run(GrpcNetClientOptions options) { + Debug.Assert(options != null, "options was null"); + // Prerequisite for running this example. // In a separate console window, start the example // ASP.NET Core gRPC service by running the following command @@ -55,6 +57,6 @@ internal static object Run() System.Console.WriteLine("Press Enter key to exit."); System.Console.ReadLine(); - return null; + return 0; } } diff --git a/examples/Console/TestHttpClient.cs b/examples/Console/TestHttpClient.cs index 27305a50523..7629a622af7 100644 --- a/examples/Console/TestHttpClient.cs +++ b/examples/Console/TestHttpClient.cs @@ -15,8 +15,10 @@ internal class TestHttpClient // (eg: C:\repos\opentelemetry-dotnet\examples\Console\) // // dotnet run httpclient - internal static object Run() + internal static int Run(HttpClientOptions options) { + Debug.Assert(options != null, "options was null"); + System.Console.WriteLine("Hello World!"); using var tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -36,6 +38,6 @@ internal static object Run() System.Console.WriteLine("Press Enter key to exit."); System.Console.ReadLine(); - return null; + return 0; } } diff --git a/examples/Console/TestInMemoryExporter.cs b/examples/Console/TestInMemoryExporter.cs index 53d3dd7f49e..057bc19cdec 100644 --- a/examples/Console/TestInMemoryExporter.cs +++ b/examples/Console/TestInMemoryExporter.cs @@ -15,7 +15,7 @@ internal class TestInMemoryExporter // (eg: C:\repos\opentelemetry-dotnet\examples\Console\) // // dotnet run inmemory - internal static object Run(InMemoryOptions options) + internal static int Run(InMemoryOptions options) { // List that will be populated with the traces by InMemoryExporter var exportedItems = new List(); @@ -28,7 +28,7 @@ internal static object Run(InMemoryOptions options) System.Console.WriteLine($"ActivitySource: {activity.Source.Name} logged the activity {activity.DisplayName}"); } - return null; + return 0; } private static void RunWithActivitySource(ICollection exportedItems) @@ -36,10 +36,10 @@ private static void RunWithActivitySource(ICollection exportedItems) // Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient" // and use InMemory exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSource("Samples.SampleClient", "Samples.SampleServer") - .ConfigureResource(r => r.AddService("inmemory-test")) - .AddInMemoryExporter(exportedItems) - .Build(); + .AddSource("Samples.SampleClient", "Samples.SampleServer") + .ConfigureResource(r => r.AddService("inmemory-test")) + .AddInMemoryExporter(exportedItems) + .Build(); // The above line is required only in applications // which decide to use OpenTelemetry. diff --git a/examples/Console/TestLogs.cs b/examples/Console/TestLogs.cs index 4c88753ffd7..427193799ac 100644 --- a/examples/Console/TestLogs.cs +++ b/examples/Console/TestLogs.cs @@ -9,7 +9,7 @@ namespace Examples.Console; internal class TestLogs { - internal static object Run(LogsOptions options) + internal static int Run(LogsOptions options) { using var loggerFactory = LoggerFactory.Create(builder => { @@ -17,7 +17,8 @@ internal static object Run(LogsOptions options) { opt.IncludeFormattedMessage = true; opt.IncludeScopes = true; - if (options.UseExporter.Equals("otlp", StringComparison.OrdinalIgnoreCase)) + + if ("otlp".Equals(options.UseExporter, StringComparison.OrdinalIgnoreCase)) { /* * Prerequisite to run this example: @@ -43,31 +44,46 @@ internal static object Run(LogsOptions options) var protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc; - if (options.Protocol.Trim().ToLower().Equals("grpc")) - { - protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc; - } - else if (options.Protocol.Trim().ToLower().Equals("http/protobuf")) + if (!string.IsNullOrEmpty(options.Protocol)) { - protocol = OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf; + switch (options.Protocol.Trim()) + { + case "grpc": + protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc; + break; + case "http/protobuf": + protocol = OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf; + break; + default: + System.Console.WriteLine($"Export protocol {options.Protocol} is not supported. Default protocol 'grpc' will be used."); + break; + } } else { - System.Console.WriteLine($"Export protocol {options.Protocol} is not supported. Default protocol 'grpc' will be used."); + System.Console.WriteLine("Protocol is null or empty. Default protocol 'grpc' will be used."); } var processorType = ExportProcessorType.Batch; - if (options.ProcessorType.Trim().ToLower().Equals("batch")) - { - processorType = ExportProcessorType.Batch; - } - else if (options.ProcessorType.Trim().ToLower().Equals("simple")) + + if (!string.IsNullOrEmpty(options.ProcessorType)) { - processorType = ExportProcessorType.Simple; + switch (options.ProcessorType.Trim()) + { + case "batch": + processorType = ExportProcessorType.Batch; + break; + case "simple": + processorType = ExportProcessorType.Simple; + break; + default: + System.Console.WriteLine($"Export processor type {options.ProcessorType} is not supported. Default processor type 'batch' will be used."); + break; + } } else { - System.Console.WriteLine($"Export processor type {options.ProcessorType} is not supported. Default processor type 'batch' will be used."); + System.Console.WriteLine("Processor type is null or empty. Default processor type 'batch' will be used."); } opt.AddOtlpExporter((exporterOptions, processorOptions) => @@ -103,6 +119,6 @@ internal static object Run(LogsOptions options) logger.LogInformation("Hello from {name} {price}.", "tomato", 2.99); } - return null; + return 0; } } diff --git a/examples/Console/TestMetrics.cs b/examples/Console/TestMetrics.cs index ba943e91775..9582a0f561e 100644 --- a/examples/Console/TestMetrics.cs +++ b/examples/Console/TestMetrics.cs @@ -12,10 +12,10 @@ namespace Examples.Console; internal class TestMetrics { - internal static object Run(MetricsOptions options) + internal static int Run(MetricsOptions options) { var meterVersion = "1.0"; - var meterTags = new List> + var meterTags = new List> { new( "MeterTagKey", @@ -27,7 +27,7 @@ internal static object Run(MetricsOptions options) .ConfigureResource(r => r.AddService("myservice")) .AddMeter(meter.Name); // All instruments from this meter are enabled. - if (options.UseExporter.Equals("otlp", StringComparison.OrdinalIgnoreCase)) + if ("otlp".Equals(options.UseExporter, StringComparison.OrdinalIgnoreCase)) { /* * Prerequisite to run this example: @@ -79,13 +79,13 @@ internal static object Run(MetricsOptions options) using var provider = providerBuilder.Build(); - Counter counter = null; + Counter? counter = null; if (options.FlagCounter ?? true) { counter = meter.CreateCounter("counter", "things", "A count of things"); } - Histogram histogram = null; + Histogram? histogram = null; if (options.FlagHistogram ?? false) { histogram = meter.CreateHistogram("histogram"); @@ -99,7 +99,7 @@ internal static object Run(MetricsOptions options) { new Measurement( (int)Process.GetCurrentProcess().PrivateMemorySize64, - new KeyValuePair("tag1", "value1")), + new KeyValuePair("tag1", "value1")), }; }); } @@ -111,45 +111,45 @@ internal static object Run(MetricsOptions options) histogram?.Record( 100, - new KeyValuePair("tag1", "value1")); + new KeyValuePair("tag1", "value1")); histogram?.Record( 200, - new KeyValuePair("tag1", "value2"), - new KeyValuePair("tag2", "value2")); + new KeyValuePair("tag1", "value2"), + new KeyValuePair("tag2", "value2")); histogram?.Record( 100, - new KeyValuePair("tag1", "value1")); + new KeyValuePair("tag1", "value1")); histogram?.Record( 200, - new KeyValuePair("tag2", "value2"), - new KeyValuePair("tag1", "value2")); + new KeyValuePair("tag2", "value2"), + new KeyValuePair("tag1", "value2")); counter?.Add(10); counter?.Add( 100, - new KeyValuePair("tag1", "value1")); + new KeyValuePair("tag1", "value1")); counter?.Add( 200, - new KeyValuePair("tag1", "value2"), - new KeyValuePair("tag2", "value2")); + new KeyValuePair("tag1", "value2"), + new KeyValuePair("tag2", "value2")); counter?.Add( 100, - new KeyValuePair("tag1", "value1")); + new KeyValuePair("tag1", "value1")); counter?.Add( 200, - new KeyValuePair("tag2", "value2"), - new KeyValuePair("tag1", "value2")); + new KeyValuePair("tag2", "value2"), + new KeyValuePair("tag1", "value2")); Task.Delay(500).Wait(); } - return null; + return 0; } } diff --git a/examples/Console/TestOTelShimWithConsoleExporter.cs b/examples/Console/TestOTelShimWithConsoleExporter.cs index 6557357a963..42e6f368f54 100644 --- a/examples/Console/TestOTelShimWithConsoleExporter.cs +++ b/examples/Console/TestOTelShimWithConsoleExporter.cs @@ -9,15 +9,15 @@ namespace Examples.Console; internal class TestOTelShimWithConsoleExporter { - internal static object Run(OpenTelemetryShimOptions options) + internal static int Run(OpenTelemetryShimOptions options) { // Enable OpenTelemetry for the source "MyCompany.MyProduct.MyWebServer" // and use a single pipeline with a custom MyProcessor, and Console exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSource("MyCompany.MyProduct.MyWebServer") - .ConfigureResource(r => r.AddService("MyServiceName")) - .AddConsoleExporter() - .Build(); + .AddSource("MyCompany.MyProduct.MyWebServer") + .ConfigureResource(r => r.AddService("MyServiceName")) + .AddConsoleExporter() + .Build(); // The above line is required only in applications // which decide to use OpenTelemetry. @@ -40,6 +40,6 @@ internal static object Run(OpenTelemetryShimOptions options) System.Console.WriteLine("Press Enter key to exit."); System.Console.ReadLine(); - return null; + return 0; } } diff --git a/examples/Console/TestOpenTracingShim.cs b/examples/Console/TestOpenTracingShim.cs index 0de2419b6ef..386cfe48ab1 100644 --- a/examples/Console/TestOpenTracingShim.cs +++ b/examples/Console/TestOpenTracingShim.cs @@ -12,15 +12,15 @@ namespace Examples.Console; internal class TestOpenTracingShim { - internal static object Run(OpenTracingShimOptions options) + internal static int Run(OpenTracingShimOptions options) { // Enable OpenTelemetry for the source "opentracing-shim" // and use Console exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSource("opentracing-shim") - .ConfigureResource(r => r.AddService("MyServiceName")) - .AddConsoleExporter() - .Build(); + .AddSource("opentracing-shim") + .ConfigureResource(r => r.AddService("MyServiceName")) + .AddConsoleExporter() + .Build(); // Instantiate the OpenTracing shim. The underlying OpenTelemetry tracer will create // spans using the "opentracing-shim" source. @@ -53,6 +53,6 @@ internal static object Run(OpenTracingShimOptions options) System.Console.WriteLine("Press Enter key to exit."); System.Console.ReadLine(); - return null; + return 0; } } diff --git a/examples/Console/TestOtlpExporter.cs b/examples/Console/TestOtlpExporter.cs index 94d749eafef..3af0ceea14b 100644 --- a/examples/Console/TestOtlpExporter.cs +++ b/examples/Console/TestOtlpExporter.cs @@ -10,7 +10,7 @@ namespace Examples.Console; internal static class TestOtlpExporter { - internal static object Run(string endpoint, string protocol) + internal static int Run(OtlpOptions options) { /* * Prerequisite to run this example: @@ -36,36 +36,36 @@ internal static object Run(string endpoint, string protocol) * For more information about the OpenTelemetry Collector go to https://github.com/open-telemetry/opentelemetry-collector * */ - return RunWithActivitySource(endpoint, protocol); + return RunWithActivitySource(options); } - private static object RunWithActivitySource(string endpoint, string protocol) + private static int RunWithActivitySource(OtlpOptions options) { - var otlpExportProtocol = ToOtlpExportProtocol(protocol); + var otlpExportProtocol = ToOtlpExportProtocol(options.Protocol); if (!otlpExportProtocol.HasValue) { - System.Console.WriteLine($"Export protocol {protocol} is not supported. Default protocol 'grpc' will be used."); + System.Console.WriteLine($"Export protocol {options.Protocol} is not supported. Default protocol 'grpc' will be used."); otlpExportProtocol = OtlpExportProtocol.Grpc; } // Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient" // and use OTLP exporter. using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSource("Samples.SampleClient", "Samples.SampleServer") - .ConfigureResource(r => r.AddService("otlp-test")) - .AddOtlpExporter(opt => + .AddSource("Samples.SampleClient", "Samples.SampleServer") + .ConfigureResource(r => r.AddService("otlp-test")) + .AddOtlpExporter(opt => + { + // If endpoint was not specified, the proper one will be selected according to the protocol. + if (!string.IsNullOrEmpty(options.Endpoint)) { - // If endpoint was not specified, the proper one will be selected according to the protocol. - if (!string.IsNullOrEmpty(endpoint)) - { - opt.Endpoint = new Uri(endpoint); - } + opt.Endpoint = new Uri(options.Endpoint); + } - opt.Protocol = otlpExportProtocol.Value; + opt.Protocol = otlpExportProtocol.Value; - System.Console.WriteLine($"OTLP Exporter is using {opt.Protocol} protocol and endpoint {opt.Endpoint}"); - }) - .Build(); + System.Console.WriteLine($"OTLP Exporter is using {opt.Protocol} protocol and endpoint {opt.Endpoint}"); + }) + .Build(); // The above line is required only in Applications // which decide to use OpenTelemetry. @@ -79,11 +79,11 @@ private static object RunWithActivitySource(string endpoint, string protocol) System.Console.ReadLine(); } - return null; + return 0; } - private static OtlpExportProtocol? ToOtlpExportProtocol(string protocol) => - protocol.Trim().ToLower() switch + private static OtlpExportProtocol? ToOtlpExportProtocol(string? protocol) => + protocol?.Trim().ToLower() switch { "grpc" => OtlpExportProtocol.Grpc, "http/protobuf" => OtlpExportProtocol.HttpProtobuf, diff --git a/examples/Console/TestPrometheusExporter.cs b/examples/Console/TestPrometheusExporter.cs index 57f38c466df..a6bc1888f2b 100644 --- a/examples/Console/TestPrometheusExporter.cs +++ b/examples/Console/TestPrometheusExporter.cs @@ -17,7 +17,7 @@ internal class TestPrometheusExporter private static readonly Histogram MyHistogram = MyMeter.CreateHistogram("myHistogram"); private static readonly ThreadLocal ThreadLocalRandom = new(() => new Random()); - internal static object Run(int port) + internal static int Run(PrometheusOptions options) { /* prometheus.yml example. Adjust port as per actual. @@ -35,7 +35,7 @@ internal static object Run(int port) .AddMeter(MyMeter.Name) .AddMeter(MyMeter2.Name) .AddPrometheusHttpListener( - options => options.UriPrefixes = new string[] { $"http://localhost:{port}/" }) + o => o.UriPrefixes = new string[] { $"http://localhost:{options.Port}/" }) .Build(); var process = Process.GetCurrentProcess(); @@ -57,12 +57,12 @@ internal static object Run(int port) { Counter.Add(9.9, new("name", "apple"), new("color", "red")); Counter.Add(99.9, new("name", "lemon"), new("color", "yellow")); - MyHistogram.Record(ThreadLocalRandom.Value.Next(1, 1500), new("tag1", "value1"), new("tag2", "value2")); + MyHistogram.Record(ThreadLocalRandom.Value!.Next(1, 1500), new("tag1", "value1"), new("tag2", "value2")); Task.Delay(10).Wait(); } }); - System.Console.WriteLine($"PrometheusExporter exposes metrics via http://localhost:{port}/metrics/"); + System.Console.WriteLine($"PrometheusExporter exposes metrics via http://localhost:{options.Port}/metrics/"); System.Console.WriteLine($"Press Esc key to exit..."); while (true) { @@ -80,7 +80,7 @@ internal static object Run(int port) Task.Delay(200).Wait(); } - return null; + return 0; } private static IEnumerable> GetThreadCpuTime(Process process) diff --git a/examples/Console/TestZipkinExporter.cs b/examples/Console/TestZipkinExporter.cs index 271826a7c2b..0bb64323442 100644 --- a/examples/Console/TestZipkinExporter.cs +++ b/examples/Console/TestZipkinExporter.cs @@ -9,7 +9,7 @@ namespace Examples.Console; internal class TestZipkinExporter { - internal static object Run(string zipkinUri) + internal static int Run(ZipkinOptions options) { // Prerequisite for running this example. // Setup zipkin inside local docker using following command: @@ -23,14 +23,15 @@ internal static object Run(string zipkinUri) // Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient" // and use the Zipkin exporter. + using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSource("Samples.SampleClient", "Samples.SampleServer") - .ConfigureResource(r => r.AddService("zipkin-test")) - .AddZipkinExporter(o => - { - o.Endpoint = new Uri(zipkinUri); - }) - .Build(); + .AddSource("Samples.SampleClient", "Samples.SampleServer") + .ConfigureResource(r => r.AddService("zipkin-test")) + .AddZipkinExporter(o => + { + o.Endpoint = new Uri(options.Uri); + }) + .Build(); using (var sample = new InstrumentationWithActivitySource()) { @@ -42,6 +43,6 @@ internal static object Run(string zipkinUri) System.Console.ReadLine(); } - return null; + return 0; } } diff --git a/examples/MicroserviceExample/Utils/Messaging/RabbitMqHelper.cs b/examples/MicroserviceExample/Utils/Messaging/RabbitMqHelper.cs index 476bc26a853..cbc8f0d8344 100644 --- a/examples/MicroserviceExample/Utils/Messaging/RabbitMqHelper.cs +++ b/examples/MicroserviceExample/Utils/Messaging/RabbitMqHelper.cs @@ -54,7 +54,7 @@ public static void StartConsumer(IModel channel, Action p channel.BasicConsume(queue: TestQueueName, autoAck: true, consumer: consumer); } - public static void AddMessagingTags(Activity activity) + public static void AddMessagingTags(Activity? activity) { // These tags are added demonstrating the semantic conventions of the OpenTelemetry messaging specification // See: diff --git a/examples/MicroserviceExample/Utils/Utils.csproj b/examples/MicroserviceExample/Utils/Utils.csproj index cc7382d4995..54d07243470 100644 --- a/examples/MicroserviceExample/Utils/Utils.csproj +++ b/examples/MicroserviceExample/Utils/Utils.csproj @@ -1,9 +1,6 @@ netstandard2.0 - - - disable From f3cd0e7ac46cf61c11212096da074c467d9067c0 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Fri, 11 Oct 2024 21:31:35 +0200 Subject: [PATCH 109/133] [Tests] Nullable (#5882) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Mikel Blanchard --- src/Shared/PooledList.cs | 8 +- .../Internal/PooledListTest.cs | 13 +- .../SelfDiagnosticsConfigParserTest.cs | 2 +- .../SelfDiagnosticsEventListenerTest.cs | 2 +- .../Internal/WildcardHelperTests.cs | 2 +- .../BatchLogRecordExportProcessorTests.cs | 7 +- .../OpenTelemetry.Tests/Logs/LogRecordTest.cs | 124 ++++++++++-------- .../LoggerFactoryAndResourceBuilderTests.cs | 2 +- .../Metrics/InMemoryExporterTests.cs | 4 +- .../Metrics/MemoryEfficiencyTests.cs | 2 +- .../MeterProviderBuilderExtensionsTests.cs | 16 ++- .../Metrics/MeterProviderSdkTest.cs | 2 +- .../Metrics/MeterProviderTests.cs | 4 +- .../Metrics/MetricExporterTests.cs | 14 +- .../MetricOverflowAttributeTestsBase.cs | 16 +-- .../Metrics/MetricPointReclaimTestsBase.cs | 15 ++- .../Metrics/MultipleReadersTests.cs | 4 +- .../OpenTelemetry.Tests.csproj | 3 - .../Resources/OtelEnvResourceDetectorTest.cs | 2 +- .../OtelServiceNameEnvVarDetectorTests.cs | 2 +- .../Resources/ResourceTest.cs | 6 +- .../Shared/TestActivityProcessor.cs | 2 +- .../OpenTelemetry.Tests/Shared/TestSampler.cs | 2 +- .../TestSelfDiagnosticsConfigRefresher.cs | 8 +- ...BatchExportActivityProcessorOptionsTest.cs | 2 +- .../Trace/BatchExportActivityProcessorTest.cs | 2 +- test/OpenTelemetry.Tests/Trace/BatchTest.cs | 2 +- .../Trace/CompositeActivityProcessorTests.cs | 4 +- .../Trace/CurrentSpanTests.cs | 2 +- .../Trace/ExceptionProcessorTest.cs | 28 ++-- .../Trace/ExportProcessorTest.cs | 3 + test/OpenTelemetry.Tests/Trace/LinkTest.cs | 3 +- .../Trace/ParentBasedSamplerTests.cs | 2 +- .../Propagation/TraceContextPropagatorTest.cs | 10 +- .../OpenTelemetry.Tests/Trace/SamplersTest.cs | 4 +- .../SimpleExportActivityProcessorTest.cs | 2 +- .../TracerProviderBuilderExtensionsTest.cs | 28 ++-- .../Trace/TracerProviderSdkTest.cs | 30 +++-- 38 files changed, 211 insertions(+), 173 deletions(-) diff --git a/src/Shared/PooledList.cs b/src/Shared/PooledList.cs index 77a353359a7..817eb482f4a 100644 --- a/src/Shared/PooledList.cs +++ b/src/Shared/PooledList.cs @@ -11,7 +11,7 @@ namespace OpenTelemetry.Internal; internal readonly struct PooledList : IEnumerable, ICollection { - private static int lastAllocatedSize = 64; + public static int LastAllocatedSize = 64; private readonly T[] buffer; @@ -36,7 +36,7 @@ public ref T this[int index] public static PooledList Create() { - return new PooledList(ArrayPool.Shared.Rent(lastAllocatedSize), 0); + return new PooledList(ArrayPool.Shared.Rent(LastAllocatedSize), 0); } public static void Add(ref PooledList list, T item) @@ -47,10 +47,10 @@ public static void Add(ref PooledList list, T item) if (list.Count >= buffer.Length) { - lastAllocatedSize = buffer.Length * 2; + LastAllocatedSize = buffer.Length * 2; var previousBuffer = buffer; - buffer = ArrayPool.Shared.Rent(lastAllocatedSize); + buffer = ArrayPool.Shared.Rent(LastAllocatedSize); var span = previousBuffer.AsSpan(); span.CopyTo(buffer); diff --git a/test/OpenTelemetry.Tests/Internal/PooledListTest.cs b/test/OpenTelemetry.Tests/Internal/PooledListTest.cs index eccbef450ad..6db06b6fadc 100644 --- a/test/OpenTelemetry.Tests/Internal/PooledListTest.cs +++ b/test/OpenTelemetry.Tests/Internal/PooledListTest.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Collections; -using System.Reflection; using Xunit; @@ -44,17 +43,9 @@ public void Verify_CreateAddClear() [Fact] public void Verify_AllocatedSize() { - int GetLastAllocatedSize(PooledList pooledList) - { - var value = typeof(PooledList) - .GetField("lastAllocatedSize", BindingFlags.NonPublic | BindingFlags.Static) - .GetValue(pooledList); - return (int)value; - } - var pooledList = PooledList.Create(); - var size = GetLastAllocatedSize(pooledList); + var size = PooledList.LastAllocatedSize; Assert.Equal(64, size); // The Add() method has a condition to double the size of the buffer @@ -65,7 +56,7 @@ int GetLastAllocatedSize(PooledList pooledList) PooledList.Add(ref pooledList, i); } - size = GetLastAllocatedSize(pooledList); + size = PooledList.LastAllocatedSize; Assert.Equal(128, size); } diff --git a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs index 9249728690d..2cb86dcbc14 100644 --- a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs +++ b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs @@ -69,7 +69,7 @@ public void SelfDiagnosticsConfigParser_TryParseLogLevel() ""FileSize"": 1024, ""LogLevel"": ""Error"" }"; - Assert.True(SelfDiagnosticsConfigParser.TryParseLogLevel(configJson, out string logLevelString)); + Assert.True(SelfDiagnosticsConfigParser.TryParseLogLevel(configJson, out string? logLevelString)); Assert.Equal("Error", logLevelString); } } diff --git a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs index a26cb0530d6..0ee7d0dc71e 100644 --- a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs +++ b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs @@ -21,7 +21,7 @@ public void SelfDiagnosticsEventListener_constructor_Invalid_Input() // no configRefresher object Assert.Throws(() => { - _ = new SelfDiagnosticsEventListener(EventLevel.Error, null); + _ = new SelfDiagnosticsEventListener(EventLevel.Error, null!); }); } diff --git a/test/OpenTelemetry.Tests/Internal/WildcardHelperTests.cs b/test/OpenTelemetry.Tests/Internal/WildcardHelperTests.cs index 9b079580b87..847f483fd1f 100644 --- a/test/OpenTelemetry.Tests/Internal/WildcardHelperTests.cs +++ b/test/OpenTelemetry.Tests/Internal/WildcardHelperTests.cs @@ -30,7 +30,7 @@ public void WildcardRegex_ShouldMatch(string[] patterns, string matchWith, bool [InlineData("a", false)] [InlineData("a.*", true)] [InlineData("a.?", true)] - public void Verify_ContainsWildcard(string pattern, bool expected) + public void Verify_ContainsWildcard(string? pattern, bool expected) { Assert.Equal(expected, WildcardHelper.ContainsWildcard(pattern)); } diff --git a/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs b/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs index d285302fcfd..02835e80e00 100644 --- a/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs +++ b/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs @@ -43,20 +43,23 @@ public void StateValuesAndScopeBufferingTest() Assert.NotNull(logRecord.AttributeStorage); Assert.NotNull(logRecord.ILoggerData.BufferedScopes); - KeyValuePair actualState = logRecord.StateValues[0]; + KeyValuePair actualState = logRecord.StateValues[0]; Assert.Same("Value", actualState.Key); Assert.Same("Hello world", actualState.Value); + int scopeCount = 0; bool foundScope = false; - logRecord.ForEachScope( + logRecord.ForEachScope( (s, o) => { foundScope = ReferenceEquals(s.Scope, exportedItems); + scopeCount++; }, null); + Assert.Equal(1, scopeCount); Assert.True(foundScope); processor.Shutdown(); diff --git a/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs b/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs index 138af7ac695..d20a822f061 100644 --- a/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs +++ b/test/OpenTelemetry.Tests/Logs/LogRecordTest.cs @@ -25,7 +25,7 @@ private enum Field [Fact] public void CheckCategoryNameForLog() { - using var loggerFactory = InitializeLoggerFactory(out List exportedItems, configure: null); + using var loggerFactory = InitializeLoggerFactory(out List exportedItems); var logger = loggerFactory.CreateLogger(); logger.LogInformation("Log"); @@ -179,9 +179,10 @@ public void CheckStateForStructuredLogWithStrongType(bool includeFormattedMessag // Check if state has food Assert.Contains(attributes, item => item.Key == "food"); - var foodParameter = (Food)attributes.First(item => item.Key == "food").Value; - Assert.Equal(food.Name, foodParameter.Name); - Assert.Equal(food.Price, foodParameter.Price); + var foodParameter = attributes.First(item => item.Key == "food").Value as Food?; + Assert.NotNull(foodParameter); + Assert.Equal(food.Name, foodParameter.Value.Name); + Assert.Equal(food.Price, foodParameter.Value.Price); // Check if state has OriginalFormat Assert.Contains(attributes, item => item.Key == "{OriginalFormat}"); @@ -221,8 +222,9 @@ public void CheckStateForStructuredLogWithAnonymousType(bool includeFormattedMes Assert.Contains(attributes, item => item.Key == "food"); var foodParameter = attributes.First(item => item.Key == "food").Value as dynamic; - Assert.Equal(anonymousType.Name, foodParameter.Name); - Assert.Equal(anonymousType.Price, foodParameter.Price); + Assert.NotNull(foodParameter); + Assert.Equal(anonymousType.Name, foodParameter!.Name); + Assert.Equal(anonymousType.Price, foodParameter!.Price); // Check if state has OriginalFormat Assert.Contains(attributes, item => item.Key == "{OriginalFormat}"); @@ -266,6 +268,7 @@ public void CheckStateForStructuredLogWithGeneralType(bool includeFormattedMessa Assert.Contains(attributes, item => item.Key == "food"); var foodParameter = attributes.First(item => item.Key == "food").Value as Dictionary; + Assert.NotNull(foodParameter); Assert.True(food.Count == foodParameter.Count && !food.Except(foodParameter).Any()); // Check if state has OriginalFormat @@ -306,8 +309,9 @@ public void CheckStateForExceptionLogged() Assert.NotNull(exportedItems[0].State); - var state = exportedItems[0].State; - var itemCount = state.GetType().GetProperty("Count").GetValue(state); + var state = exportedItems[0].State as IReadOnlyList>; + Assert.NotNull(state); + var itemCount = state.Count; // state only has {OriginalFormat} Assert.Equal(1, itemCount); @@ -351,12 +355,12 @@ public void CheckStateValuesCanBeSet() logger.Log( LogLevel.Information, 0, - new List> { new KeyValuePair("Key1", "Value1") }, + new List> { new KeyValuePair("Key1", "Value1") }, null, (s, e) => "OpenTelemetry!"); var logRecord = exportedItems[0]; - var expectedStateValues = new List> { new KeyValuePair("Key2", "Value2") }; + var expectedStateValues = new List> { new KeyValuePair("Key2", "Value2") }; logRecord.StateValues = expectedStateValues; Assert.Equal(expectedStateValues, logRecord.StateValues); @@ -394,6 +398,7 @@ public void CheckStateCanBeSetByProcessor() logger.LogInformation($"This does not matter."); var state = exportedItems[0].State as IReadOnlyList>; + Assert.NotNull(state); Assert.Equal("newStateKey", state[0].Key.ToString()); Assert.Equal("newStateValue", state[0].Value.ToString()); } @@ -417,7 +422,9 @@ public void CheckStateValuesCanBeSetByProcessor() logger.LogInformation("This does not matter."); var stateValue = exportedItems[0]; - Assert.Equal(new KeyValuePair("newStateValueKey", "newStateValueValue"), stateValue.StateValues[0]); + Assert.NotNull(stateValue.StateValues); + Assert.NotEmpty(stateValue.StateValues); + Assert.Equal(new KeyValuePair("newStateValueKey", "newStateValueValue"), stateValue.StateValues[0]); } [Fact] @@ -476,13 +483,14 @@ public void CheckTraceIdForLogWithinActivityMarkedAsRecordOnly(bool includeTrace .Build(); using var activity = activitySource.StartActivity("Activity"); + Assert.NotNull(activity); activity.TraceStateString = "key1=value1"; logger.LogInformation("Log within activity marked as RecordOnly"); var logRecord = exportedItems[0]; var currentActivity = Activity.Current; - Assert.NotNull(Activity.Current); + Assert.NotNull(currentActivity); Assert.Equal(currentActivity.TraceId, logRecord.TraceId); Assert.Equal(currentActivity.SpanId, logRecord.SpanId); Assert.Equal(currentActivity.ActivityTraceFlags, logRecord.TraceFlags); @@ -519,7 +527,7 @@ public void CheckTraceIdForLogWithinActivityMarkedAsRecordAndSample() var logRecord = exportedItems[0]; var currentActivity = Activity.Current; - Assert.NotNull(Activity.Current); + Assert.NotNull(currentActivity); Assert.Equal(currentActivity.TraceId, logRecord.TraceId); Assert.Equal(currentActivity.SpanId, logRecord.SpanId); Assert.Equal(currentActivity.ActivityTraceFlags, logRecord.TraceFlags); @@ -557,12 +565,12 @@ public void IncludeFormattedMessageTestWhenFormatterNull() using var loggerFactory = InitializeLoggerFactory(out List exportedItems, configure: options => options.IncludeFormattedMessage = true); var logger = loggerFactory.CreateLogger(); - logger.Log(LogLevel.Information, default, "Hello World!", null, null); + logger.Log(LogLevel.Information, default, "Hello World!", null, null!); var logRecord = exportedItems[0]; Assert.Equal("Hello World!", logRecord.FormattedMessage); Assert.Equal("Hello World!", logRecord.Body); - logger.Log(LogLevel.Information, default, new CustomState(), null, null); + logger.Log(LogLevel.Information, default, new CustomState(), null, null!); logRecord = exportedItems[1]; Assert.Equal(CustomState.ToStringValue, logRecord.FormattedMessage); Assert.Equal(CustomState.ToStringValue, logRecord.Body); @@ -585,8 +593,8 @@ public void VerifyIncludeScopes_False() logger.LogInformation("OpenTelemetry!"); var logRecord = exportedItems[0]; - List scopes = new List(); - logRecord.ForEachScope((scope, state) => scopes.Add(scope.Scope), null); + List scopes = []; + logRecord.ForEachScope((scope, state) => scopes.Add(scope.Scope), null); Assert.Empty(scopes); } @@ -601,18 +609,18 @@ public void VerifyIncludeScopes_True() logger.LogInformation("OpenTelemetry!"); var logRecord = exportedItems[0]; - List scopes = new List(); + List scopes = []; logger.LogInformation("OpenTelemetry!"); logRecord = exportedItems[1]; int reachedDepth = -1; - logRecord.ForEachScope( + logRecord.ForEachScope( (scope, state) => { reachedDepth++; scopes.Add(scope.Scope); - foreach (KeyValuePair item in scope) + foreach (KeyValuePair item in scope) { Assert.Equal(string.Empty, item.Key); Assert.Equal("string_scope", item.Value); @@ -625,24 +633,24 @@ public void VerifyIncludeScopes_True() scopes.Clear(); - List> expectedScope2 = new List> - { - new KeyValuePair("item1", "value1"), - new KeyValuePair("item2", "value2"), - }; + List> expectedScope2 = + [ + new KeyValuePair("item1", "value1"), + new KeyValuePair("item2", "value2"), + ]; using var scope2 = logger.BeginScope(expectedScope2); logger.LogInformation("OpenTelemetry!"); logRecord = exportedItems[2]; reachedDepth = -1; - logRecord.ForEachScope( + logRecord.ForEachScope( (scope, state) => { scopes.Add(scope.Scope); if (reachedDepth++ == 1) { - foreach (KeyValuePair item in scope) + foreach (KeyValuePair item in scope) { Assert.Contains(item, expectedScope2); } @@ -656,24 +664,24 @@ public void VerifyIncludeScopes_True() scopes.Clear(); - KeyValuePair[] expectedScope3 = new KeyValuePair[] - { - new KeyValuePair("item3", "value3"), - new KeyValuePair("item4", "value4"), - }; + KeyValuePair[] expectedScope3 = + [ + new KeyValuePair("item3", "value3"), + new KeyValuePair("item4", "value4"), + ]; using var scope3 = logger.BeginScope(expectedScope3); logger.LogInformation("OpenTelemetry!"); logRecord = exportedItems[3]; reachedDepth = -1; - logRecord.ForEachScope( + logRecord.ForEachScope( (scope, state) => { scopes.Add(scope.Scope); if (reachedDepth++ == 2) { - foreach (KeyValuePair item in scope) + foreach (KeyValuePair item in scope) { Assert.Contains(item, expectedScope3); } @@ -712,9 +720,9 @@ public void VerifyParseStateValues_UsingStandardExtensions(bool parseStateValues Assert.NotNull(logRecord.StateValues); Assert.Equal(3, logRecord.StateValues.Count); - Assert.Equal(new KeyValuePair("Product", "OpenTelemetry"), logRecord.StateValues[0]); - Assert.Equal(new KeyValuePair("Year", 2021), logRecord.StateValues[1]); - Assert.Equal(new KeyValuePair("{OriginalFormat}", "{Product} {Year}!"), logRecord.StateValues[2]); + Assert.Equal(new KeyValuePair("Product", "OpenTelemetry"), logRecord.StateValues[0]); + Assert.Equal(new KeyValuePair("Year", 2021), logRecord.StateValues[1]); + Assert.Equal(new KeyValuePair("{OriginalFormat}", "{Product} {Year}!"), logRecord.StateValues[2]); var complex = new { Property = "Value" }; @@ -733,11 +741,11 @@ public void VerifyParseStateValues_UsingStandardExtensions(bool parseStateValues Assert.NotNull(logRecord.StateValues); Assert.Equal(4, logRecord.StateValues.Count); - Assert.Equal(new KeyValuePair("Product", "OpenTelemetry"), logRecord.StateValues[0]); - Assert.Equal(new KeyValuePair("Year", 2021), logRecord.StateValues[1]); - Assert.Equal(new KeyValuePair("{OriginalFormat}", "{Product} {Year} {Complex}!"), logRecord.StateValues[3]); + Assert.Equal(new KeyValuePair("Product", "OpenTelemetry"), logRecord.StateValues[0]); + Assert.Equal(new KeyValuePair("Year", 2021), logRecord.StateValues[1]); + Assert.Equal(new KeyValuePair("{OriginalFormat}", "{Product} {Year} {Complex}!"), logRecord.StateValues[3]); - KeyValuePair actualComplex = logRecord.StateValues[2]; + KeyValuePair actualComplex = logRecord.StateValues[2]; Assert.Equal("Complex", actualComplex.Key); Assert.Same(complex, actualComplex.Value); } @@ -761,7 +769,7 @@ public void ParseStateValuesUsingStructTest() Assert.Null(logRecord.State); Assert.NotNull(logRecord.StateValues); Assert.Single(logRecord.StateValues); - Assert.Equal(new KeyValuePair("Key1", "Value1"), logRecord.StateValues[0]); + Assert.Equal(new KeyValuePair("Key1", "Value1"), logRecord.StateValues[0]); } [Fact] @@ -783,7 +791,7 @@ public void ParseStateValuesUsingListTest() Assert.Null(logRecord.State); Assert.NotNull(logRecord.StateValues); Assert.Single(logRecord.StateValues); - Assert.Equal(new KeyValuePair("Key1", "Value1"), logRecord.StateValues[0]); + Assert.Equal(new KeyValuePair("Key1", "Value1"), logRecord.StateValues[0]); } [Fact] @@ -805,7 +813,7 @@ public void ParseStateValuesUsingIEnumerableTest() Assert.Null(logRecord.State); Assert.NotNull(logRecord.StateValues); Assert.Single(logRecord.StateValues); - Assert.Equal(new KeyValuePair("Key1", "Value1"), logRecord.StateValues[0]); + Assert.Equal(new KeyValuePair("Key1", "Value1"), logRecord.StateValues[0]); } [Fact] @@ -860,7 +868,7 @@ public void DisposingStateTest() Assert.NotNull(logRecord.StateValues); Assert.Single(logRecord.StateValues); - KeyValuePair actualState = logRecord.StateValues[0]; + KeyValuePair actualState = logRecord.StateValues[0]; Assert.Same("Value", actualState.Key); Assert.Same("Hello world", actualState.Value); @@ -1016,7 +1024,7 @@ public void LogRecordCategoryNameAliasForInstrumentationScopeTests() Assert.Equal(exportedItems[0].CategoryName, exportedItems[0].Logger.Name); } - private static ILoggerFactory InitializeLoggerFactory(out List exportedItems, Action configure = null) + private static ILoggerFactory InitializeLoggerFactory(out List exportedItems, Action? configure = null) { var items = exportedItems = new List(); @@ -1062,19 +1070,19 @@ IEnumerator IEnumerable.GetEnumerator() } } - internal sealed class DisposingState : IReadOnlyList>, IDisposable + internal sealed class DisposingState : IReadOnlyList>, IDisposable { - private string value; + private string? value; private bool disposed; - public DisposingState(string value) + public DisposingState(string? value) { this.Value = value; } public int Count => 1; - public string Value + public string? Value { get { @@ -1088,9 +1096,9 @@ public string Value private set => this.value = value; } - public KeyValuePair this[int index] => index switch + public KeyValuePair this[int index] => index switch { - 0 => new KeyValuePair(nameof(this.Value), this.Value), + 0 => new KeyValuePair(nameof(this.Value), this.Value), _ => throw new IndexOutOfRangeException(nameof(index)), }; @@ -1099,7 +1107,7 @@ public void Dispose() this.disposed = true; } - public IEnumerator> GetEnumerator() + public IEnumerator> GetEnumerator() { for (var i = 0; i < this.Count; i++) { @@ -1123,11 +1131,11 @@ public override void OnEnd(LogRecord logRecord) { if (this.fieldToUpdate == Field.State) { - logRecord.State = new List> { new KeyValuePair("newStateKey", "newStateValue") }; + logRecord.State = new List> { new KeyValuePair("newStateKey", "newStateValue") }; } else if (this.fieldToUpdate == Field.StateValues) { - logRecord.StateValues = new List> { new KeyValuePair("newStateValueKey", "newStateValueValue") }; + logRecord.StateValues = new List> { new KeyValuePair("newStateValueKey", "newStateValueValue") }; } else { @@ -1160,7 +1168,7 @@ private class CustomState { public const string ToStringValue = "CustomState.ToString"; - public string Property { get; set; } + public string? Property { get; set; } public override string ToString() => ToStringValue; @@ -1175,11 +1183,11 @@ public ScopeProcessor(bool buffer) this.buffer = buffer; } - public List Scopes { get; } = new(); + public List Scopes { get; } = new(); public override void OnEnd(LogRecord data) { - data.ForEachScope( + data.ForEachScope( (scope, state) => { this.Scopes.Add(scope.Scope); diff --git a/test/OpenTelemetry.Tests/Logs/LoggerFactoryAndResourceBuilderTests.cs b/test/OpenTelemetry.Tests/Logs/LoggerFactoryAndResourceBuilderTests.cs index 073160b6e5c..e955939aea2 100644 --- a/test/OpenTelemetry.Tests/Logs/LoggerFactoryAndResourceBuilderTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LoggerFactoryAndResourceBuilderTests.cs @@ -16,7 +16,7 @@ public void TestLogExporterCanAccessResource() VerifyResourceBuilder( assert: (Resource resource) => { - Assert.Contains(resource.Attributes, (kvp) => kvp.Key == ResourceSemanticConventions.AttributeServiceName && kvp.Value.ToString().Contains("unknown_service")); + Assert.Contains(resource.Attributes, (kvp) => kvp.Key == ResourceSemanticConventions.AttributeServiceName && kvp.Value.ToString()!.Contains("unknown_service")); }); } diff --git a/test/OpenTelemetry.Tests/Metrics/InMemoryExporterTests.cs b/test/OpenTelemetry.Tests/Metrics/InMemoryExporterTests.cs index bb44505bd9c..54dbe28069b 100644 --- a/test/OpenTelemetry.Tests/Metrics/InMemoryExporterTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/InMemoryExporterTests.cs @@ -28,7 +28,7 @@ public void InMemoryExporterShouldDeepCopyMetricPoints() var counter = meter.CreateCounter("meter"); // TEST 1: Emit 10 for the MetricPoint with a single key-vaue pair: ("tag1", "value1") - counter.Add(10, new KeyValuePair("tag1", "value1")); + counter.Add(10, new KeyValuePair("tag1", "value1")); meterProvider.ForceFlush(); @@ -38,7 +38,7 @@ public void InMemoryExporterShouldDeepCopyMetricPoints() Assert.Equal(10, metric1.MetricPoints[0].GetSumLong()); // TEST 2: Emit 25 for the MetricPoint with a single key-vaue pair: ("tag1", "value1") - counter.Add(25, new KeyValuePair("tag1", "value1")); + counter.Add(25, new KeyValuePair("tag1", "value1")); meterProvider.ForceFlush(); diff --git a/test/OpenTelemetry.Tests/Metrics/MemoryEfficiencyTests.cs b/test/OpenTelemetry.Tests/Metrics/MemoryEfficiencyTests.cs index 3965aa0599c..6418be16263 100644 --- a/test/OpenTelemetry.Tests/Metrics/MemoryEfficiencyTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MemoryEfficiencyTests.cs @@ -28,7 +28,7 @@ public void ExportOnlyWhenPointChanged(MetricReaderTemporalityPreference tempora var counter = meter.CreateCounter("meter"); - counter.Add(10, new KeyValuePair("tag1", "value1")); + counter.Add(10, new KeyValuePair("tag1", "value1")); meterProvider.ForceFlush(); Assert.Single(exportedItems); diff --git a/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs index 5ddd39fee0d..6b2a13f1c00 100644 --- a/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs @@ -16,7 +16,7 @@ public void ServiceLifecycleAvailableToSDKBuilderTest() { var builder = Sdk.CreateMeterProviderBuilder(); - MyInstrumentation myInstrumentation = null; + MyInstrumentation? myInstrumentation = null; RunBuilderServiceLifecycleTest( builder, @@ -54,6 +54,7 @@ public void AddReaderUsingDependencyInjectionTest() using var provider = builder.Build() as MeterProviderSdk; Assert.NotNull(provider); + Assert.NotNull(provider.OwnedServiceProvider); var readers = ((IServiceProvider)provider.OwnedServiceProvider).GetServices(); @@ -72,13 +73,13 @@ public void AddReaderUsingDependencyInjectionTest() [Fact] public void AddInstrumentationTest() { - List instrumentation = null; + List? instrumentation = null; using (var provider = Sdk.CreateMeterProviderBuilder() .AddInstrumentation() .AddInstrumentation((sp, provider) => new MyInstrumentation() { Provider = provider }) .AddInstrumentation(new MyInstrumentation()) - .AddInstrumentation(() => (object)null) + .AddInstrumentation(() => (object?)null) .Build() as MeterProviderSdk) { Assert.NotNull(provider); @@ -144,6 +145,7 @@ public void SetAndConfigureResourceTest() Assert.True(serviceProviderTestExecuted); Assert.Equal(2, configureInvocations); + Assert.NotNull(provider); Assert.Single(provider.Resource.Attributes); Assert.Contains(provider.Resource.Attributes, kvp => kvp.Key == "key2" && (string)kvp.Value == "value2"); } @@ -162,7 +164,7 @@ public void ConfigureBuilderIConfigurationAvailableTest() configureBuilderCalled = true; - var testKeyValue = configuration.GetValue("TEST_KEY", null); + var testKeyValue = configuration.GetValue("TEST_KEY", null); Assert.Equal("TEST_KEY_VALUE", testKeyValue); }) @@ -182,7 +184,7 @@ public void ConfigureBuilderIConfigurationModifiableTest() .ConfigureServices(services => { var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { ["TEST_KEY_2"] = "TEST_KEY_2_VALUE" }) + .AddInMemoryCollection(new Dictionary { ["TEST_KEY_2"] = "TEST_KEY_2_VALUE" }) .Build(); services.AddSingleton(configuration); @@ -193,7 +195,7 @@ public void ConfigureBuilderIConfigurationModifiableTest() configureBuilderCalled = true; - var testKey2Value = configuration.GetValue("TEST_KEY_2", null); + var testKey2Value = configuration.GetValue("TEST_KEY_2", null); Assert.Equal("TEST_KEY_2_VALUE", testKey2Value); }) @@ -358,7 +360,7 @@ private static void RunBuilderServiceLifecycleTest( private sealed class MyInstrumentation : IDisposable { - internal MeterProvider Provider; + internal MeterProvider? Provider; internal bool Disposed; public void Dispose() diff --git a/test/OpenTelemetry.Tests/Metrics/MeterProviderSdkTest.cs b/test/OpenTelemetry.Tests/Metrics/MeterProviderSdkTest.cs index bce959764f2..83d5d4644cf 100644 --- a/test/OpenTelemetry.Tests/Metrics/MeterProviderSdkTest.cs +++ b/test/OpenTelemetry.Tests/Metrics/MeterProviderSdkTest.cs @@ -83,7 +83,7 @@ public void TransientMeterExhaustsMetricStorageTest(bool withView, bool forceFlu Assert.Single(exportedItems); } - var metricInstrumentIgnoredEvents = inMemoryEventListener.Events.Where((e) => e.EventId == 33 && e.Payload[1] as string == meterName); + var metricInstrumentIgnoredEvents = inMemoryEventListener.Events.Where((e) => e.EventId == 33 && (e.Payload?.Count ?? 0) >= 2 && e.Payload![1] as string == meterName); Assert.Single(metricInstrumentIgnoredEvents); diff --git a/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs b/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs index d179363c035..df0cfec4b04 100644 --- a/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs @@ -16,8 +16,8 @@ public void MeterProviderFindExporterTest() .AddInMemoryExporter(exportedItems) .Build(); - Assert.True(meterProvider.TryFindExporter(out InMemoryExporter inMemoryExporter)); - Assert.False(meterProvider.TryFindExporter(out MyExporter myExporter)); + Assert.True(meterProvider.TryFindExporter(out InMemoryExporter? inMemoryExporter)); + Assert.False(meterProvider.TryFindExporter(out MyExporter? myExporter)); } private class MyExporter : BaseExporter diff --git a/test/OpenTelemetry.Tests/Metrics/MetricExporterTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricExporterTests.cs index 185679acac9..8c1d10cf48c 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricExporterTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricExporterTests.cs @@ -13,7 +13,7 @@ public class MetricExporterTests [InlineData(ExportModes.Pull | ExportModes.Push)] public void FlushMetricExporterTest(ExportModes mode) { - BaseExporter exporter = null; + BaseExporter? exporter = null; switch (mode) { @@ -26,6 +26,8 @@ public void FlushMetricExporterTest(ExportModes mode) case ExportModes.Pull | ExportModes.Push: exporter = new PushPullMetricExporter(); break; + default: + throw new NotSupportedException($"Export mode '{mode}' is not supported"); } var reader = new BaseExportingMetricReader(exporter); @@ -42,7 +44,7 @@ public void FlushMetricExporterTest(ExportModes mode) case ExportModes.Pull: Assert.False(reader.Collect()); Assert.False(meterProvider.ForceFlush()); - Assert.True((exporter as IPullMetricExporter).Collect(-1)); + Assert.True((exporter as IPullMetricExporter)?.Collect?.Invoke(-1) ?? false); break; case ExportModes.Pull | ExportModes.Push: Assert.True(reader.Collect()); @@ -63,13 +65,7 @@ public override ExportResult Export(in Batch batch) [ExportModes(ExportModes.Pull)] private class PullOnlyMetricExporter : BaseExporter, IPullMetricExporter { - private Func funcCollect; - - public Func Collect - { - get => this.funcCollect; - set { this.funcCollect = value; } - } + public Func? Collect { get; set; } public override ExportResult Export(in Batch batch) { diff --git a/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs index 6e929d1468a..43d91819232 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs @@ -14,7 +14,7 @@ namespace OpenTelemetry.Metrics.Tests; public abstract class MetricOverflowAttributeTestsBase { private readonly bool shouldReclaimUnusedMetricPoints; - private readonly Dictionary configurationData = new() + private readonly Dictionary configurationData = new() { [MetricTestsBase.EmitOverFlowAttributeConfigKey] = "true", }; @@ -86,7 +86,7 @@ public void TestEmitOverflowAttributeConfigWithOtherConfigProvider(string value, .ConfigureServices(services => { var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [MetricTestsBase.EmitOverFlowAttributeConfigKey] = value }) + .AddInMemoryCollection(new Dictionary { [MetricTestsBase.EmitOverFlowAttributeConfigKey] = value }) .Build(); services.AddSingleton(configuration); @@ -164,7 +164,7 @@ public void MetricOverflowAttributeIsRecordedCorrectlyForCounter(MetricReaderTem { // Emit unique key-value pairs to use up the available MetricPoints // Once this loop is run, we have used up all available MetricPoints for metrics emitted with tags - counter.Add(10, new KeyValuePair("Key", i)); + counter.Add(10, new KeyValuePair("Key", i)); } meterProvider.ForceFlush(); @@ -186,7 +186,7 @@ public void MetricOverflowAttributeIsRecordedCorrectlyForCounter(MetricReaderTem exportedItems.Clear(); metricPoints.Clear(); - counter.Add(5, new KeyValuePair("Key", 2000)); // Emit a metric to exceed the max MetricPoint limit + counter.Add(5, new KeyValuePair("Key", 2000)); // Emit a metric to exceed the max MetricPoint limit meterProvider.ForceFlush(); metric = exportedItems[0]; @@ -217,7 +217,7 @@ public void MetricOverflowAttributeIsRecordedCorrectlyForCounter(MetricReaderTem // Emit 2500 more newer MetricPoints with distinct dimension combinations for (int i = 2001; i < 4501; i++) { - counter.Add(5, new KeyValuePair("Key", i)); + counter.Add(5, new KeyValuePair("Key", i)); } meterProvider.ForceFlush(); @@ -315,7 +315,7 @@ public void MetricOverflowAttributeIsRecordedCorrectlyForHistogram(MetricReaderT { // Emit unique key-value pairs to use up the available MetricPoints // Once this loop is run, we have used up all available MetricPoints for metrics emitted with tags - histogram.Record(10, new KeyValuePair("Key", i)); + histogram.Record(10, new KeyValuePair("Key", i)); } meterProvider.ForceFlush(); @@ -337,7 +337,7 @@ public void MetricOverflowAttributeIsRecordedCorrectlyForHistogram(MetricReaderT exportedItems.Clear(); metricPoints.Clear(); - histogram.Record(5, new KeyValuePair("Key", 2000)); // Emit a metric to exceed the max MetricPoint limit + histogram.Record(5, new KeyValuePair("Key", 2000)); // Emit a metric to exceed the max MetricPoint limit meterProvider.ForceFlush(); metric = exportedItems[0]; @@ -368,7 +368,7 @@ public void MetricOverflowAttributeIsRecordedCorrectlyForHistogram(MetricReaderT // Emit 2500 more newer MetricPoints with distinct dimension combinations for (int i = 2001; i < 4501; i++) { - histogram.Record(5, new KeyValuePair("Key", i)); + histogram.Record(5, new KeyValuePair("Key", i)); } meterProvider.ForceFlush(); diff --git a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs index fa33298643e..f455967884a 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs @@ -13,7 +13,7 @@ namespace OpenTelemetry.Metrics.Tests; public abstract class MetricPointReclaimTestsBase { - private readonly Dictionary configurationData = new() + private readonly Dictionary configurationData = new() { [MetricTestsBase.ReclaimUnusedMetricPointsConfigKey] = "true", }; @@ -57,6 +57,7 @@ public void TestReclaimAttributeConfigWithEnvVar(string value, bool isReclaimAtt .Build(); var meterProviderSdk = meterProvider as MeterProviderSdk; + Assert.NotNull(meterProviderSdk); Assert.Equal(isReclaimAttributeKeySet, meterProviderSdk.ReclaimUnusedMetricPoints); } @@ -77,7 +78,7 @@ public void TestReclaimAttributeConfigWithOtherConfigProvider(string value, bool .ConfigureServices(services => { var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [MetricTestsBase.ReclaimUnusedMetricPointsConfigKey] = value }) + .AddInMemoryCollection(new Dictionary { [MetricTestsBase.ReclaimUnusedMetricPointsConfigKey] = value }) .Build(); services.AddSingleton(configuration); @@ -87,6 +88,7 @@ public void TestReclaimAttributeConfigWithOtherConfigProvider(string value, bool .Build(); var meterProviderSdk = meterProvider as MeterProviderSdk; + Assert.NotNull(meterProviderSdk); Assert.Equal(isReclaimAttributeKeySet, meterProviderSdk.ReclaimUnusedMetricPoints); } @@ -134,11 +136,11 @@ void EmitMetric(object obj) // There are separate code paths for single dimension vs multiple dimensions if (random.Next(2) == 0) { - counter.Add(100, new KeyValuePair("key", $"value{i}")); + counter.Add(100, new KeyValuePair("key", $"value{i}")); } else { - counter.Add(100, new KeyValuePair("key", $"value{i}"), new KeyValuePair("dimensionKey", "dimensionValue")); + counter.Add(100, new KeyValuePair("key", $"value{i}"), new KeyValuePair("dimensionKey", "dimensionValue")); } Thread.Sleep(25); @@ -217,7 +219,7 @@ public void MeasurementsAreAggregatedEvenAfterTheyAreDropped(bool emitMetricWith // aggregated later on when there are free MetricPoints available. for (int i = 0; i < 10; i++) { - counter.Add(100, new KeyValuePair("key", $"value{i}")); + counter.Add(100, new KeyValuePair("key", $"value{i}")); } meterProvider.ForceFlush(); @@ -242,7 +244,7 @@ void EmitMetric() var index = random.Next(measurementValues.Length); var measurement = measurementValues[index]; - counter.Add(measurement, new KeyValuePair("key", $"value{index}")); + counter.Add(measurement, new KeyValuePair("key", $"value{index}")); Interlocked.Add(ref sum, measurement); numberOfMeasurements++; @@ -303,6 +305,7 @@ public override ExportResult Export(in Batch batch) } // This is to ensure that the lookup dictionary does not have unbounded growth + Assert.NotNull(metricPointLookupDictionary); Assert.True(metricPointLookupDictionary.Count <= (MeterProviderBuilderSdk.DefaultCardinalityLimit * 2)); foreach (ref readonly var metricPoint in metric.GetMetricPoints()) diff --git a/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs b/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs index 16309219654..c2a1ca5ccbb 100644 --- a/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs @@ -71,7 +71,7 @@ public void SdkSupportsMultipleReaders(MetricReaderTemporalityPreference aggrega Assert.True(defaultNamedOptionsConfigureCalled); Assert.True(namedOptionsConfigureCalled); - counter.Add(10, new KeyValuePair("key", "value")); + counter.Add(10, new KeyValuePair("key", "value")); meterProvider.ForceFlush(); @@ -123,7 +123,7 @@ public void SdkSupportsMultipleReaders(MetricReaderTemporalityPreference aggrega exportedItems1.Clear(); exportedItems2.Clear(); - counter.Add(15, new KeyValuePair("key", "value")); + counter.Add(15, new KeyValuePair("key", "value")); meterProvider.ForceFlush(); diff --git a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj index 9d40f304c56..2b66cc258d7 100644 --- a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj +++ b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj @@ -5,9 +5,6 @@ $(TargetFrameworksForTests) $(NoWarn),CS0618 true - - - disable diff --git a/test/OpenTelemetry.Tests/Resources/OtelEnvResourceDetectorTest.cs b/test/OpenTelemetry.Tests/Resources/OtelEnvResourceDetectorTest.cs index a6180b7a4cd..ae9df7faaf1 100644 --- a/test/OpenTelemetry.Tests/Resources/OtelEnvResourceDetectorTest.cs +++ b/test/OpenTelemetry.Tests/Resources/OtelEnvResourceDetectorTest.cs @@ -71,7 +71,7 @@ public void OtelEnvResource_WithEnvVar_2() [Fact] public void OtelEnvResource_UsingIConfiguration() { - var values = new Dictionary() + var values = new Dictionary() { [OtelEnvResourceDetector.EnvVarKey] = "Key1=Val1,Key2=Val2", }; diff --git a/test/OpenTelemetry.Tests/Resources/OtelServiceNameEnvVarDetectorTests.cs b/test/OpenTelemetry.Tests/Resources/OtelServiceNameEnvVarDetectorTests.cs index 9b3bf437cc8..305c1d403b8 100644 --- a/test/OpenTelemetry.Tests/Resources/OtelServiceNameEnvVarDetectorTests.cs +++ b/test/OpenTelemetry.Tests/Resources/OtelServiceNameEnvVarDetectorTests.cs @@ -57,7 +57,7 @@ public void OtelServiceNameEnvVar_WithValue() [Fact] public void OtelServiceNameEnvVar_UsingIConfiguration() { - var values = new Dictionary() + var values = new Dictionary() { [OtelServiceNameEnvVarDetector.EnvVarKey] = "my-service", }; diff --git a/test/OpenTelemetry.Tests/Resources/ResourceTest.cs b/test/OpenTelemetry.Tests/Resources/ResourceTest.cs index 337870a8a11..9d5ab40a78d 100644 --- a/test/OpenTelemetry.Tests/Resources/ResourceTest.cs +++ b/test/OpenTelemetry.Tests/Resources/ResourceTest.cs @@ -26,7 +26,7 @@ public void Dispose() public void CreateResource_NullAttributeCollection() { // Act and Assert - var resource = new Resource(null); + var resource = new Resource(null!); Assert.Empty(resource.Attributes); } @@ -34,10 +34,10 @@ public void CreateResource_NullAttributeCollection() public void CreateResource_NullAttributeValue() { // Arrange - var attributes = new Dictionary { { "NullValue", null } }; + var attributes = new Dictionary { { "NullValue", null } }; // Act and Assert - Assert.Throws(() => new Resource(attributes)); + Assert.Throws(() => new Resource(attributes!)); } [Fact] diff --git a/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs index a386b67c8d3..56c2c25eaef 100644 --- a/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs @@ -16,7 +16,7 @@ public TestActivityProcessor() { } - public TestActivityProcessor(Action onStart, Action onEnd) + public TestActivityProcessor(Action? onStart, Action? onEnd) { this.StartAction = onStart; this.EndAction = onEnd; diff --git a/test/OpenTelemetry.Tests/Shared/TestSampler.cs b/test/OpenTelemetry.Tests/Shared/TestSampler.cs index 7bc39ba454c..972985bfad0 100644 --- a/test/OpenTelemetry.Tests/Shared/TestSampler.cs +++ b/test/OpenTelemetry.Tests/Shared/TestSampler.cs @@ -7,7 +7,7 @@ namespace OpenTelemetry.Tests; internal class TestSampler : Sampler { - public Func SamplingAction { get; set; } + public Func? SamplingAction { get; set; } public SamplingParameters LatestSamplingParameters { get; private set; } diff --git a/test/OpenTelemetry.Tests/TestSelfDiagnosticsConfigRefresher.cs b/test/OpenTelemetry.Tests/TestSelfDiagnosticsConfigRefresher.cs index faee6e8f287..9038cb00087 100644 --- a/test/OpenTelemetry.Tests/TestSelfDiagnosticsConfigRefresher.cs +++ b/test/OpenTelemetry.Tests/TestSelfDiagnosticsConfigRefresher.cs @@ -6,17 +6,17 @@ namespace OpenTelemetry.Tests; -internal class TestSelfDiagnosticsConfigRefresher(Stream stream = null) : SelfDiagnosticsConfigRefresher +internal class TestSelfDiagnosticsConfigRefresher(Stream? stream = null) : SelfDiagnosticsConfigRefresher { - private readonly Stream stream = stream; + private readonly Stream? stream = stream; public bool TryGetLogStreamCalled { get; private set; } - public override bool TryGetLogStream(int byteCount, [NotNullWhen(true)] out Stream stream, out int availableByteCount) + public override bool TryGetLogStream(int byteCount, [NotNullWhen(true)] out Stream? stream, out int availableByteCount) { this.TryGetLogStreamCalled = true; stream = this.stream; availableByteCount = 0; - return true; + return this.stream != null; } } diff --git a/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorOptionsTest.cs b/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorOptionsTest.cs index 27f1e3de92f..a741928fa26 100644 --- a/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorOptionsTest.cs +++ b/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorOptionsTest.cs @@ -49,7 +49,7 @@ public void BatchExportProcessorOptions_EnvironmentVariableOverride() [Fact] public void BatchExportProcessorOptions_UsingIConfiguration() { - var values = new Dictionary() + var values = new Dictionary() { [BatchExportActivityProcessorOptions.MaxQueueSizeEnvVarKey] = "1", [BatchExportActivityProcessorOptions.MaxExportBatchSizeEnvVarKey] = "2", diff --git a/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorTest.cs b/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorTest.cs index bce50338359..02a5d86ed98 100644 --- a/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorTest.cs +++ b/test/OpenTelemetry.Tests/Trace/BatchExportActivityProcessorTest.cs @@ -12,7 +12,7 @@ public class BatchExportActivityProcessorTest [Fact] public void CheckNullExporter() { - Assert.Throws(() => new BatchActivityExportProcessor(null)); + Assert.Throws(() => new BatchActivityExportProcessor(null!)); } [Fact] diff --git a/test/OpenTelemetry.Tests/Trace/BatchTest.cs b/test/OpenTelemetry.Tests/Trace/BatchTest.cs index b1d5b170d52..8ecbe02f7ad 100644 --- a/test/OpenTelemetry.Tests/Trace/BatchTest.cs +++ b/test/OpenTelemetry.Tests/Trace/BatchTest.cs @@ -11,7 +11,7 @@ public class BatchTest [Fact] public void CheckConstructorExceptions() { - Assert.Throws(() => new Batch((string[])null, 0)); + Assert.Throws(() => new Batch((string[]?)null!, 0)); Assert.Throws(() => new Batch(Array.Empty(), -1)); Assert.Throws(() => new Batch(Array.Empty(), 1)); } diff --git a/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs b/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs index 8f8bccb8e29..343bfa6eec4 100644 --- a/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs +++ b/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs @@ -12,12 +12,12 @@ public class CompositeActivityProcessorTests [Fact] public void CompositeActivityProcessor_BadArgs() { - Assert.Throws(() => new CompositeProcessor(null)); + Assert.Throws(() => new CompositeProcessor(null!)); Assert.Throws(() => new CompositeProcessor(Array.Empty>())); using var p1 = new TestActivityProcessor(null, null); using var processor = new CompositeProcessor(new[] { p1 }); - Assert.Throws(() => processor.AddProcessor(null)); + Assert.Throws(() => processor.AddProcessor(null!)); } [Fact] diff --git a/test/OpenTelemetry.Tests/Trace/CurrentSpanTests.cs b/test/OpenTelemetry.Tests/Trace/CurrentSpanTests.cs index e9b76794625..080242299e6 100644 --- a/test/OpenTelemetry.Tests/Trace/CurrentSpanTests.cs +++ b/test/OpenTelemetry.Tests/Trace/CurrentSpanTests.cs @@ -15,7 +15,7 @@ public CurrentSpanTests() Activity.DefaultIdFormat = ActivityIdFormat.W3C; Activity.ForceDefaultIdFormat = true; - this.tracer = TracerProvider.Default.GetTracer(null); + this.tracer = TracerProvider.Default.GetTracer(null!); } [Fact] diff --git a/test/OpenTelemetry.Tests/Trace/ExceptionProcessorTest.cs b/test/OpenTelemetry.Tests/Trace/ExceptionProcessorTest.cs index 98d8d01a034..c597cd7c5fd 100644 --- a/test/OpenTelemetry.Tests/Trace/ExceptionProcessorTest.cs +++ b/test/OpenTelemetry.Tests/Trace/ExceptionProcessorTest.cs @@ -20,11 +20,11 @@ public void ActivityStatusSetToErrorWhenExceptionProcessorEnabled() .AddProcessor(new ExceptionProcessor()) .Build(); - Activity activity1 = null; - Activity activity2 = null; - Activity activity3 = null; - Activity activity4 = null; - Activity activity5 = null; + Activity? activity1 = null; + Activity? activity2 = null; + Activity? activity3 = null; + Activity? activity4 = null; + Activity? activity5 = null; try { @@ -69,17 +69,27 @@ Marshal.GetExceptionPointers returns non-zero. } finally { - activity5.Dispose(); + activity5?.Dispose(); } + Assert.NotNull(activity1); Assert.Equal(StatusCode.Error, activity1.GetStatus().StatusCode); Assert.Null(GetTagValue(activity1, "otel.exception_pointers")); + + Assert.NotNull(activity2); Assert.Equal(StatusCode.Error, activity2.GetStatus().StatusCode); Assert.Null(GetTagValue(activity2, "otel.exception_pointers")); + + Assert.NotNull(activity3); Assert.Equal(StatusCode.Unset, activity3.GetStatus().StatusCode); Assert.Null(GetTagValue(activity3, "otel.exception_pointers")); + + Assert.NotNull(activity4); Assert.Equal(StatusCode.Unset, activity4.GetStatus().StatusCode); + Assert.Null(GetTagValue(activity4, "otel.exception_pointers")); + + Assert.NotNull(activity5); Assert.Equal(StatusCode.Unset, activity5.GetStatus().StatusCode); #if !NETFRAMEWORK if (Environment.Is64BitProcess) @@ -104,7 +114,7 @@ public void ActivityStatusNotSetWhenExceptionProcessorNotEnabled() .SetSampler(new AlwaysOnSampler()) .Build(); - Activity activity = null; + Activity? activity = null; try { @@ -120,11 +130,11 @@ public void ActivityStatusNotSetWhenExceptionProcessorNotEnabled() Assert.Equal(StatusCode.Unset, activity.GetStatus().StatusCode); } - private static object GetTagValue(Activity activity, string tagName) + private static object? GetTagValue(Activity activity, string tagName) { Debug.Assert(activity != null, "Activity should not be null"); - foreach (ref readonly var tag in activity.EnumerateTagObjects()) + foreach (ref readonly var tag in activity!.EnumerateTagObjects()) { if (tag.Key == tagName) { diff --git a/test/OpenTelemetry.Tests/Trace/ExportProcessorTest.cs b/test/OpenTelemetry.Tests/Trace/ExportProcessorTest.cs index 9c4768bc251..a696d7a2cd1 100644 --- a/test/OpenTelemetry.Tests/Trace/ExportProcessorTest.cs +++ b/test/OpenTelemetry.Tests/Trace/ExportProcessorTest.cs @@ -26,6 +26,7 @@ public void ExportProcessorIgnoresActivityWhenDropped() using (var activity = activitySource.StartActivity("Activity")) { + Assert.NotNull(activity); Assert.False(activity.IsAllDataRequested); Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); } @@ -49,6 +50,7 @@ public void ExportProcessorIgnoresActivityMarkedAsRecordOnly() using (var activity = activitySource.StartActivity("Activity")) { + Assert.NotNull(activity); Assert.True(activity.IsAllDataRequested); Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); } @@ -72,6 +74,7 @@ public void ExportProcessorExportsActivityMarkedAsRecordAndSample() using (var activity = activitySource.StartActivity("Activity")) { + Assert.NotNull(activity); Assert.True(activity.IsAllDataRequested); Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); } diff --git a/test/OpenTelemetry.Tests/Trace/LinkTest.cs b/test/OpenTelemetry.Tests/Trace/LinkTest.cs index fbfd543da1c..b0a64793597 100644 --- a/test/OpenTelemetry.Tests/Trace/LinkTest.cs +++ b/test/OpenTelemetry.Tests/Trace/LinkTest.cs @@ -50,9 +50,10 @@ public void FromSpanContext_WithAttributes() Assert.Equal(this.spanContext.TraceId, link.Context.TraceId); Assert.Equal(this.spanContext.SpanId, link.Context.SpanId); + Assert.NotNull(link.Attributes); foreach (var attributemap in this.attributesMap) { - Assert.Equal(attributemap.Value, link.Attributes.FirstOrDefault(a => a.Key == attributemap.Key).Value); + Assert.Equal(attributemap.Value, link.Attributes!.FirstOrDefault(a => a.Key == attributemap.Key).Value); } } diff --git a/test/OpenTelemetry.Tests/Trace/ParentBasedSamplerTests.cs b/test/OpenTelemetry.Tests/Trace/ParentBasedSamplerTests.cs index 0861a224ca9..7f141da4ded 100644 --- a/test/OpenTelemetry.Tests/Trace/ParentBasedSamplerTests.cs +++ b/test/OpenTelemetry.Tests/Trace/ParentBasedSamplerTests.cs @@ -119,7 +119,7 @@ public void CustomSamplers(bool parentIsRemote, bool parentIsSampled) [Fact] public void DisallowNullRootSampler() { - Assert.Throws(() => new ParentBasedSampler(null)); + Assert.Throws(() => new ParentBasedSampler(null!)); } private static SamplingParameters MakeTestParameters(bool parentIsRemote, bool parentIsSampled) diff --git a/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs b/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs index 8fbd20f11de..9c3f566b380 100644 --- a/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs +++ b/test/OpenTelemetry.Tests/Trace/Propagation/TraceContextPropagatorTest.cs @@ -313,7 +313,10 @@ private static string CallTraceContextPropagator(string tracestate) }; var f = new TraceContextPropagator(); var ctx = f.Extract(default, headers, Getter); - return ctx.ActivityContext.TraceState; + + var traceState = ctx.ActivityContext.TraceState; + Assert.NotNull(traceState); + return traceState; } private static string CallTraceContextPropagator(string[] tracestate) @@ -325,6 +328,9 @@ private static string CallTraceContextPropagator(string[] tracestate) }; var f = new TraceContextPropagator(); var ctx = f.Extract(default, headers, ArrayGetter); - return ctx.ActivityContext.TraceState; + + var traceState = ctx.ActivityContext.TraceState; + Assert.NotNull(traceState); + return traceState; } } diff --git a/test/OpenTelemetry.Tests/Trace/SamplersTest.cs b/test/OpenTelemetry.Tests/Trace/SamplersTest.cs index 94f158e910c..2c4b85fe523 100644 --- a/test/OpenTelemetry.Tests/Trace/SamplersTest.cs +++ b/test/OpenTelemetry.Tests/Trace/SamplersTest.cs @@ -88,7 +88,7 @@ public void TracerProviderSdkSamplerAttributesAreAppliedToLegacyActivity(Samplin Assert.NotNull(activity); if (samplingDecision != SamplingDecision.Drop) { - Assert.Contains(new KeyValuePair("tagkeybysampler", "tagvalueaddedbysampler"), activity.TagObjects); + Assert.Contains(new KeyValuePair("tagkeybysampler", "tagvalueaddedbysampler"), activity.TagObjects); } activity.Stop(); @@ -200,6 +200,7 @@ public void SamplersCanModifyTraceState(SamplingDecision sampling) using var activity = activitySource.StartActivity("root", ActivityKind.Server, parentContext); if (sampling != SamplingDecision.Drop) { + Assert.NotNull(activity); Assert.Equal(newTraceState, activity.TraceStateString); } } @@ -237,6 +238,7 @@ public void SamplersDoesNotImpactTraceStateWhenUsingNull(SamplingDecision sampli using var activity = activitySource.StartActivity("root", ActivityKind.Server, parentContext); if (sampling != SamplingDecision.Drop) { + Assert.NotNull(activity); Assert.Equal(parentTraceState, activity.TraceStateString); } } diff --git a/test/OpenTelemetry.Tests/Trace/SimpleExportActivityProcessorTest.cs b/test/OpenTelemetry.Tests/Trace/SimpleExportActivityProcessorTest.cs index 5cc52c6eee8..2743c48ca80 100644 --- a/test/OpenTelemetry.Tests/Trace/SimpleExportActivityProcessorTest.cs +++ b/test/OpenTelemetry.Tests/Trace/SimpleExportActivityProcessorTest.cs @@ -12,7 +12,7 @@ public class SimpleExportActivityProcessorTest [Fact] public void CheckNullExporter() { - Assert.Throws(() => new SimpleActivityExportProcessor(null)); + Assert.Throws(() => new SimpleActivityExportProcessor(null!)); } [Fact] diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs index e7b2e7bfc45..c07e05fcb24 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs @@ -29,7 +29,7 @@ public void SetErrorStatusOnExceptionEnabled() .SetErrorStatusOnException() .Build(); - Activity activity = null; + Activity? activity = null; try { @@ -42,6 +42,7 @@ public void SetErrorStatusOnExceptionEnabled() { } + Assert.NotNull(activity); Assert.Equal(StatusCode.Error, activity.GetStatus().StatusCode); Assert.Equal(ActivityStatusCode.Error, activity.Status); } @@ -58,7 +59,7 @@ public void SetErrorStatusOnExceptionDisabled() .SetErrorStatusOnException(false) .Build(); - Activity activity = null; + Activity? activity = null; try { @@ -71,6 +72,7 @@ public void SetErrorStatusOnExceptionDisabled() { } + Assert.NotNull(activity); Assert.Equal(StatusCode.Unset, activity.GetStatus().StatusCode); Assert.Equal(ActivityStatusCode.Unset, activity.Status); } @@ -85,7 +87,7 @@ public void SetErrorStatusOnExceptionDefault() .SetSampler(new AlwaysOnSampler()) .Build(); - Activity activity = null; + Activity? activity = null; try { @@ -98,6 +100,7 @@ public void SetErrorStatusOnExceptionDefault() { } + Assert.NotNull(activity); Assert.Equal(StatusCode.Unset, activity.GetStatus().StatusCode); } @@ -106,7 +109,7 @@ public void ServiceLifecycleAvailableToSDKBuilderTest() { var builder = Sdk.CreateTracerProviderBuilder(); - MyInstrumentation myInstrumentation = null; + MyInstrumentation? myInstrumentation = null; RunBuilderServiceLifecycleTest( builder, @@ -310,6 +313,7 @@ public void AddProcessorUsingDependencyInjectionTest() using var provider = builder.Build() as TracerProviderSdk; Assert.NotNull(provider); + Assert.NotNull(provider.OwnedServiceProvider); var processors = ((IServiceProvider)provider.OwnedServiceProvider).GetServices(); @@ -328,13 +332,13 @@ public void AddProcessorUsingDependencyInjectionTest() [Fact] public void AddInstrumentationTest() { - List instrumentation = null; + List? instrumentation = null; using (var provider = Sdk.CreateTracerProviderBuilder() .AddInstrumentation() .AddInstrumentation((sp, provider) => new MyInstrumentation() { Provider = provider }) .AddInstrumentation(new MyInstrumentation()) - .AddInstrumentation(() => (object)null) + .AddInstrumentation(() => (object?)null) .Build() as TracerProviderSdk) { Assert.NotNull(provider); @@ -399,7 +403,7 @@ public void SetAndConfigureResourceTest() Assert.True(serviceProviderTestExecuted); Assert.Equal(2, configureInvocations); - + Assert.NotNull(provider); Assert.Single(provider.Resource.Attributes); Assert.Contains(provider.Resource.Attributes, kvp => kvp.Key == "key2" && (string)kvp.Value == "value2"); } @@ -418,7 +422,7 @@ public void ConfigureBuilderIConfigurationAvailableTest() configureBuilderCalled = true; - var testKeyValue = configuration.GetValue("TEST_KEY", null); + var testKeyValue = configuration.GetValue("TEST_KEY", null); Assert.Equal("TEST_KEY_VALUE", testKeyValue); }) @@ -438,7 +442,7 @@ public void ConfigureBuilderIConfigurationModifiableTest() .ConfigureServices(services => { var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { ["TEST_KEY_2"] = "TEST_KEY_2_VALUE" }) + .AddInMemoryCollection(new Dictionary { ["TEST_KEY_2"] = "TEST_KEY_2_VALUE" }) .Build(); services.AddSingleton(configuration); @@ -449,7 +453,7 @@ public void ConfigureBuilderIConfigurationModifiableTest() configureBuilderCalled = true; - var testKey2Value = configuration.GetValue("TEST_KEY_2", null); + var testKey2Value = configuration.GetValue("TEST_KEY_2", null); Assert.Equal("TEST_KEY_2_VALUE", testKey2Value); }) @@ -652,7 +656,7 @@ public override SamplingResult ShouldSample(in SamplingParameters samplingParame private sealed class MyInstrumentation : IDisposable { - internal TracerProvider Provider; + internal TracerProvider? Provider; internal bool Disposed; public void Dispose() @@ -663,7 +667,7 @@ public void Dispose() private sealed class MyProcessor : BaseProcessor { - public string Name; + public string? Name; public bool Disposed; protected override void Dispose(bool disposing) diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs index 044d40c1c63..a94ebfeee1e 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs @@ -128,8 +128,10 @@ public void TracerProviderSdkInvokesSamplingWithCorrectParameters() using (var parent = activitySource.StartActivity("parent", ActivityKind.Client)) { + Assert.NotNull(parent); Assert.Equal(parent.TraceId, testSampler.LatestSamplingParameters.TraceId); using var child = activitySource.StartActivity("child"); + Assert.NotNull(child); Assert.Equal(child.TraceId, testSampler.LatestSamplingParameters.TraceId); Assert.Null(testSampler.LatestSamplingParameters.Tags); Assert.Null(testSampler.LatestSamplingParameters.Links); @@ -145,6 +147,7 @@ public void TracerProviderSdkInvokesSamplingWithCorrectParameters() using (var fromCustomContext = activitySource.StartActivity("customContext", ActivityKind.Client, customContext)) { + Assert.NotNull(fromCustomContext); Assert.Equal(fromCustomContext.TraceId, testSampler.LatestSamplingParameters.TraceId); Assert.Null(testSampler.LatestSamplingParameters.Tags); Assert.Null(testSampler.LatestSamplingParameters.Links); @@ -158,6 +161,7 @@ public void TracerProviderSdkInvokesSamplingWithCorrectParameters() initialTags["tagA"] = "tagAValue"; using (var withInitialTags = activitySource.StartActivity("withInitialTags", ActivityKind.Client, default(ActivityContext), initialTags)) { + Assert.NotNull(withInitialTags); Assert.Equal(withInitialTags.TraceId, testSampler.LatestSamplingParameters.TraceId); Assert.Equal(initialTags, testSampler.LatestSamplingParameters.Tags); } @@ -173,6 +177,7 @@ public void TracerProviderSdkInvokesSamplingWithCorrectParameters() using (var withInitialTags = activitySource.StartActivity("withLinks", ActivityKind.Client, default(ActivityContext), links: links)) { + Assert.NotNull(withInitialTags); Assert.Equal(withInitialTags.TraceId, testSampler.LatestSamplingParameters.TraceId); Assert.Null(testSampler.LatestSamplingParameters.Tags); Assert.Equal(links, testSampler.LatestSamplingParameters.Links); @@ -189,6 +194,7 @@ public void TracerProviderSdkInvokesSamplingWithCorrectParameters() using (var fromCustomContextAsString = activitySource.StartActivity("customContext", ActivityKind.Client, customContextAsString)) { + Assert.NotNull(fromCustomContextAsString); Assert.Equal(fromCustomContextAsString.TraceId, testSampler.LatestSamplingParameters.TraceId); Assert.Equal(expectedTraceId, fromCustomContextAsString.TraceId); Assert.Equal(expectedParentSpanId, fromCustomContextAsString.ParentSpanId); @@ -237,7 +243,7 @@ public void TracerProviderSdkSamplerAttributesAreAppliedToActivity(SamplingDecis Assert.Equal(rootActivity.TraceId, testSampler.LatestSamplingParameters.TraceId); if (sampling != SamplingDecision.Drop) { - Assert.Contains(new KeyValuePair("tagkeybysampler", "tagvalueaddedbysampler"), rootActivity.TagObjects); + Assert.Contains(new KeyValuePair("tagkeybysampler", "tagvalueaddedbysampler"), rootActivity.TagObjects); } } @@ -421,6 +427,8 @@ public void ProcessorDoesNotReceiveNotRecordDecisionSpan() using ActivitySource source = new ActivitySource(activitySourceName); using var activity = source.StartActivity("somename"); + + Assert.NotNull(activity); activity.Stop(); Assert.False(activity.IsAllDataRequested); @@ -1054,11 +1062,11 @@ public void SdkPopulatesSamplingParamsCorrectlyForLegacyActivityWithInProcParent [InlineData("parentbased_traceidratio", "0.111", "ParentBased{TraceIdRatioBasedSampler{0.111000}}")] [InlineData("parentbased_traceidratio", "not_a_double", "ParentBased{TraceIdRatioBasedSampler{1.000000}}")] [InlineData("ParentBased_TraceIdRatio", "0.000001", "ParentBased{TraceIdRatioBasedSampler{0.000001}}")] - public void TestSamplerSetFromConfiguration(string configValue, string argValue, string samplerDescription) + public void TestSamplerSetFromConfiguration(string? configValue, string? argValue, string samplerDescription) { var configBuilder = new ConfigurationBuilder(); - configBuilder.AddInMemoryCollection(new Dictionary + configBuilder.AddInMemoryCollection(new Dictionary { [TracerProviderSdk.TracesSamplerConfigKey] = configValue, [TracerProviderSdk.TracesSamplerArgConfigKey] = argValue, @@ -1078,7 +1086,7 @@ public void TestSamplerSetFromConfiguration(string configValue, string argValue, public void TestSamplerConfigurationIgnoredWhenSetProgrammatically() { var configBuilder = new ConfigurationBuilder(); - configBuilder.AddInMemoryCollection(new Dictionary + configBuilder.AddInMemoryCollection(new Dictionary { [TracerProviderSdk.TracesSamplerConfigKey] = "always_off", }); @@ -1098,7 +1106,7 @@ public void TestSamplerConfigurationIgnoredWhenSetProgrammatically() [Fact] public void TracerProvideSdkCreatesAndDiposesInstrumentation() { - TestInstrumentation testInstrumentation = null; + TestInstrumentation? testInstrumentation = null; var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddInstrumentation(() => { @@ -1132,10 +1140,10 @@ public void TracerProviderSdkBuildsWithDefaultResource() [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void AddLegacyOperationName_BadArgs(string operationName) + public void AddLegacyOperationName_BadArgs(string? operationName) { var builder = Sdk.CreateTracerProviderBuilder(); - Assert.Throws(() => builder.AddLegacySource(operationName)); + Assert.Throws(() => builder.AddLegacySource(operationName!)); } [Fact] @@ -1254,6 +1262,8 @@ public void SdkSamplesAndProcessesLegacySourceWhenAddLegacySourceIsCalledWithWil // Ensure we can still process "normal" activities when in legacy wildcard mode. using var nonLegacyActivity = activitySource.StartActivity("TestActivity"); + + Assert.NotNull(nonLegacyActivity); nonLegacyActivity.Start(); nonLegacyActivity.Stop(); @@ -1300,8 +1310,10 @@ public void Dispose() private static Action CreateActivitySourceSetter() { - return (Action)typeof(Activity).GetProperty("Source") - .SetMethod.CreateDelegate(typeof(Action)); + var setMethod = typeof(Activity).GetProperty("Source")?.SetMethod + ?? throw new InvalidOperationException("Could not build Activity.Source setter delegate"); + + return (Action)setMethod.CreateDelegate(typeof(Action)); } private sealed class TestTracerProviderBuilder : TracerProviderBuilderBase From 8df7670dd1d73b815ff2a050ac782a90903b1812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 14 Oct 2024 18:09:59 +0200 Subject: [PATCH 110/133] [docs] Nullable annotations (#5900) --- docs/logs/redaction/MyRedactionProcessor.cs | 12 ++++++------ docs/logs/redaction/redaction.csproj | 4 ---- .../customizing-the-sdk/customizing-the-sdk.csproj | 4 ---- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/docs/logs/redaction/MyRedactionProcessor.cs b/docs/logs/redaction/MyRedactionProcessor.cs index 7959faf3d60..cec1edc4504 100644 --- a/docs/logs/redaction/MyRedactionProcessor.cs +++ b/docs/logs/redaction/MyRedactionProcessor.cs @@ -15,18 +15,18 @@ public override void OnEnd(LogRecord logRecord) } } - internal sealed class MyClassWithRedactionEnumerator : IReadOnlyList> + internal sealed class MyClassWithRedactionEnumerator : IReadOnlyList> { - private readonly IReadOnlyList> state; + private readonly IReadOnlyList> state; - public MyClassWithRedactionEnumerator(IReadOnlyList> state) + public MyClassWithRedactionEnumerator(IReadOnlyList> state) { this.state = state; } public int Count => this.state.Count; - public KeyValuePair this[int index] + public KeyValuePair this[int index] { get { @@ -34,14 +34,14 @@ public KeyValuePair this[int index] var entryVal = item.Value?.ToString(); if (entryVal != null && entryVal.Contains("")) { - return new KeyValuePair(item.Key, "newRedactedValueHere"); + return new KeyValuePair(item.Key, "newRedactedValueHere"); } return item; } } - public IEnumerator> GetEnumerator() + public IEnumerator> GetEnumerator() { for (var i = 0; i < this.Count; i++) { diff --git a/docs/logs/redaction/redaction.csproj b/docs/logs/redaction/redaction.csproj index 2dc5d8deb63..19aa9791432 100644 --- a/docs/logs/redaction/redaction.csproj +++ b/docs/logs/redaction/redaction.csproj @@ -1,8 +1,4 @@ - - - disable - diff --git a/docs/trace/customizing-the-sdk/customizing-the-sdk.csproj b/docs/trace/customizing-the-sdk/customizing-the-sdk.csproj index 2dc5d8deb63..19aa9791432 100644 --- a/docs/trace/customizing-the-sdk/customizing-the-sdk.csproj +++ b/docs/trace/customizing-the-sdk/customizing-the-sdk.csproj @@ -1,8 +1,4 @@ - - - disable - From 1a68b49ed61710ea1e334f5fd8c818cc687a96ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 14 Oct 2024 18:24:06 +0200 Subject: [PATCH 111/133] [repo] cleanup #nullable disable (#5901) Co-authored-by: Mikel Blanchard --- CONTRIBUTING.md | 17 ----------------- .../Implementation/ConsoleTagWriter.cs | 2 -- .../Implementation/ZipkinTagWriter.cs | 2 -- src/Shared/ActivityHelperExtensions.cs | 2 -- src/Shared/AssemblyVersionExtensions.cs | 2 -- .../IConfigurationExtensionsLogger.cs | 2 -- .../OpenTelemetryConfigurationExtensions.cs | 2 -- src/Shared/DiagnosticDefinitions.cs | 2 -- src/Shared/ExceptionExtensions.cs | 2 -- src/Shared/Guard.cs | 2 -- .../Base2ExponentialBucketHistogramHelper.cs | 2 -- src/Shared/Options/DelegatingOptionsFactory.cs | 2 -- ...OptionsFactoryServiceCollectionExtensions.cs | 2 -- src/Shared/Options/SingletonOptionsManager.cs | 2 -- src/Shared/PeerServiceResolver.cs | 2 -- .../PeriodicExportingMetricReaderHelper.cs | 2 -- src/Shared/PooledList.cs | 2 -- src/Shared/ResourceSemanticConventions.cs | 2 -- src/Shared/SemanticConventions.cs | 2 -- src/Shared/SpanAttributeConstants.cs | 2 -- src/Shared/StatusHelper.cs | 2 -- src/Shared/TagWriter/ArrayTagWriter.cs | 2 -- .../TagWriter/JsonStringArrayTagWriter.cs | 2 -- src/Shared/TagWriter/TagWriter.cs | 2 -- test/OpenTelemetry.Api.Tests/BaggageTests.cs | 2 -- .../Context/RuntimeContextTest.cs | 2 -- .../OtlpRetryTests.cs | 2 -- .../OtlpSpecConfigDefinitionTests.cs | 2 -- .../UseOtlpExporterExtensionTests.cs | 2 -- .../VersionHelper.cs | 2 -- .../Internal/AssemblyVersionExtensionsTests.cs | 2 -- .../Internal/JsonStringArrayTagWriterTests.cs | 2 -- .../PeriodicExportingMetricReaderHelperTests.cs | 2 -- .../SelfDiagnosticsConfigRefresherTest.cs | 2 -- .../BatchExportLogRecordProcessorOptionsTest.cs | 2 -- .../Logs/LogRecordSharedPoolTests.cs | 2 -- .../Logs/LogRecordStateProcessorTests.cs | 2 -- .../Logs/LogRecordThreadStaticPoolTests.cs | 2 -- .../LoggerProviderBuilderExtensionsTests.cs | 2 -- .../Logs/LoggerProviderExtensionsTests.cs | 2 -- .../Logs/LoggerProviderSdkTests.cs | 2 -- .../Logs/OpenTelemetryLoggingExtensionsTests.cs | 2 -- .../Metrics/AggregatorTestsBase.cs | 2 -- .../Metrics/MetricApiTestsBase.cs | 2 -- .../Metrics/MetricExemplarTests.cs | 2 -- .../Metrics/MetricTestsBase.cs | 2 -- .../Metrics/MetricViewTests.cs | 2 -- .../OpenTelemetrySdkTests.cs | 2 -- .../Shared/EventSourceTestHelper.cs | 2 -- .../SkipUnlessEnvVarFoundFactAttribute.cs | 2 -- .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 2 -- .../Shared/TestActivityProcessor.cs | 2 -- .../Shared/TestEventListener.cs | 2 -- .../Shared/TestHttpServer.cs | 2 -- .../Trace/TracerProviderBuilderBaseTests.cs | 2 -- 55 files changed, 125 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7f53dfbe35b..02f8d2dd573 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -308,23 +308,6 @@ analysis](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/overview [Common.props](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/build/Common.props) new projects must NOT manually override these settings. -## New code - -New code files MUST enable [nullable reference -types](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/nullable-reference-types) -manually in projects where it is not automatically enabled project-wide. This is -done by specifying `#nullable enable` towards the top of the file (usually after -the copyright header). We are currently working towards enabling nullable -context in every project by updating code as it is worked on, this requirement -is to make sure the surface area of code needing updates is shrinking and not -expanding. - -> [!NOTE] -> The first time a project is updated to use nullable context in public APIs -some housekeeping needs to be done in public API definitions (`.publicApi` -folder). This can be done automatically via a code fix offered by the public API -analyzer. - ## License requirements OpenTelemetry .NET is licensed under the [Apache License, Version diff --git a/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs b/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs index da8e6076f30..fcaf9cdb43c 100644 --- a/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs +++ b/src/OpenTelemetry.Exporter.Console/Implementation/ConsoleTagWriter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinTagWriter.cs b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinTagWriter.cs index d40d126b92e..30e1eb112ee 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinTagWriter.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinTagWriter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Buffers.Text; using System.Globalization; using System.Text.Json; diff --git a/src/Shared/ActivityHelperExtensions.cs b/src/Shared/ActivityHelperExtensions.cs index 0540ce7c5ca..4fd1f517dab 100644 --- a/src/Shared/ActivityHelperExtensions.cs +++ b/src/Shared/ActivityHelperExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Runtime.CompilerServices; using OpenTelemetry.Internal; diff --git a/src/Shared/AssemblyVersionExtensions.cs b/src/Shared/AssemblyVersionExtensions.cs index b3e43d5bc9f..67926d99c03 100644 --- a/src/Shared/AssemblyVersionExtensions.cs +++ b/src/Shared/AssemblyVersionExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; diff --git a/src/Shared/Configuration/IConfigurationExtensionsLogger.cs b/src/Shared/Configuration/IConfigurationExtensionsLogger.cs index 0835cf6ff89..196a485bf33 100644 --- a/src/Shared/Configuration/IConfigurationExtensionsLogger.cs +++ b/src/Shared/Configuration/IConfigurationExtensionsLogger.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace Microsoft.Extensions.Configuration; internal interface IConfigurationExtensionsLogger diff --git a/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs b/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs index d591ae22076..c713fd166dd 100644 --- a/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs +++ b/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; #if !NETFRAMEWORK && !NETSTANDARD2_0 using System.Diagnostics.CodeAnalysis; diff --git a/src/Shared/DiagnosticDefinitions.cs b/src/Shared/DiagnosticDefinitions.cs index 94bf1c5f52d..75ed3187d70 100644 --- a/src/Shared/DiagnosticDefinitions.cs +++ b/src/Shared/DiagnosticDefinitions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Internal; internal static class DiagnosticDefinitions diff --git a/src/Shared/ExceptionExtensions.cs b/src/Shared/ExceptionExtensions.cs index 9070b59c206..5071a8feebb 100644 --- a/src/Shared/ExceptionExtensions.cs +++ b/src/Shared/ExceptionExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Globalization; namespace OpenTelemetry.Internal; diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index abf894243aa..167d466facb 100644 --- a/src/Shared/Guard.cs +++ b/src/Shared/Guard.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; diff --git a/src/Shared/Metrics/Base2ExponentialBucketHistogramHelper.cs b/src/Shared/Metrics/Base2ExponentialBucketHistogramHelper.cs index acdc9fa1038..27f498c0bda 100644 --- a/src/Shared/Metrics/Base2ExponentialBucketHistogramHelper.cs +++ b/src/Shared/Metrics/Base2ExponentialBucketHistogramHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Metrics; /// diff --git a/src/Shared/Options/DelegatingOptionsFactory.cs b/src/Shared/Options/DelegatingOptionsFactory.cs index 3e9b2914e36..995b69ae49c 100644 --- a/src/Shared/Options/DelegatingOptionsFactory.cs +++ b/src/Shared/Options/DelegatingOptionsFactory.cs @@ -13,8 +13,6 @@ we take a dependency on Microsoft.Extensions.Options v5.0.0 (or greater), much example of how that works. */ -#nullable enable - using System.Diagnostics; #if NET using System.Diagnostics.CodeAnalysis; diff --git a/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs b/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs index b3b97362770..81e9ac0a664 100644 --- a/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs +++ b/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; #if NET using System.Diagnostics.CodeAnalysis; diff --git a/src/Shared/Options/SingletonOptionsManager.cs b/src/Shared/Options/SingletonOptionsManager.cs index 4c7718e78c9..d3b1928d55a 100644 --- a/src/Shared/Options/SingletonOptionsManager.cs +++ b/src/Shared/Options/SingletonOptionsManager.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET using System.Diagnostics.CodeAnalysis; #endif diff --git a/src/Shared/PeerServiceResolver.cs b/src/Shared/PeerServiceResolver.cs index d4c0b8fcd13..21201b38368 100644 --- a/src/Shared/PeerServiceResolver.cs +++ b/src/Shared/PeerServiceResolver.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Runtime.CompilerServices; using OpenTelemetry.Trace; diff --git a/src/Shared/PeriodicExportingMetricReaderHelper.cs b/src/Shared/PeriodicExportingMetricReaderHelper.cs index d24c74c8f9c..e7dc244a94c 100644 --- a/src/Shared/PeriodicExportingMetricReaderHelper.cs +++ b/src/Shared/PeriodicExportingMetricReaderHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Metrics; internal static class PeriodicExportingMetricReaderHelper diff --git a/src/Shared/PooledList.cs b/src/Shared/PooledList.cs index 817eb482f4a..7027dc4e4b1 100644 --- a/src/Shared/PooledList.cs +++ b/src/Shared/PooledList.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Buffers; using System.Collections; using System.Diagnostics.CodeAnalysis; diff --git a/src/Shared/ResourceSemanticConventions.cs b/src/Shared/ResourceSemanticConventions.cs index a3f93c02fa8..aa5dae4005f 100644 --- a/src/Shared/ResourceSemanticConventions.cs +++ b/src/Shared/ResourceSemanticConventions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Resources; internal static class ResourceSemanticConventions diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index 2624acd29cd..f84bd6de490 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Trace; /// diff --git a/src/Shared/SpanAttributeConstants.cs b/src/Shared/SpanAttributeConstants.cs index dcd7e5b8ef4..a3467bdf4ab 100644 --- a/src/Shared/SpanAttributeConstants.cs +++ b/src/Shared/SpanAttributeConstants.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Trace; /// diff --git a/src/Shared/StatusHelper.cs b/src/Shared/StatusHelper.cs index 5d9245010c9..00e5a587f9e 100644 --- a/src/Shared/StatusHelper.cs +++ b/src/Shared/StatusHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Runtime.CompilerServices; using OpenTelemetry.Trace; diff --git a/src/Shared/TagWriter/ArrayTagWriter.cs b/src/Shared/TagWriter/ArrayTagWriter.cs index ac5bba8bf0d..c8859acbb2f 100644 --- a/src/Shared/TagWriter/ArrayTagWriter.cs +++ b/src/Shared/TagWriter/ArrayTagWriter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Internal; internal abstract class ArrayTagWriter diff --git a/src/Shared/TagWriter/JsonStringArrayTagWriter.cs b/src/Shared/TagWriter/JsonStringArrayTagWriter.cs index 8dd2c086d79..8eefc4b4f94 100644 --- a/src/Shared/TagWriter/JsonStringArrayTagWriter.cs +++ b/src/Shared/TagWriter/JsonStringArrayTagWriter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Text.Json; diff --git a/src/Shared/TagWriter/TagWriter.cs b/src/Shared/TagWriter/TagWriter.cs index 473090f6dcc..941fa6d6f01 100644 --- a/src/Shared/TagWriter/TagWriter.cs +++ b/src/Shared/TagWriter/TagWriter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Globalization; diff --git a/test/OpenTelemetry.Api.Tests/BaggageTests.cs b/test/OpenTelemetry.Api.Tests/BaggageTests.cs index d4fc1e26c45..904cba58968 100644 --- a/test/OpenTelemetry.Api.Tests/BaggageTests.cs +++ b/test/OpenTelemetry.Api.Tests/BaggageTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs b/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs index f8c53bc7f1d..ff80bdd76d1 100644 --- a/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs +++ b/test/OpenTelemetry.Api.Tests/Context/RuntimeContextTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Context.Tests; diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs index bbc44f82fc4..23ba18d0f6e 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Net; using System.Net.Http.Headers; #if NETFRAMEWORK diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpSpecConfigDefinitionTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpSpecConfigDefinitionTests.cs index 4e4e5469183..7ad28e67529 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpSpecConfigDefinitionTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpSpecConfigDefinitionTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Collections; using Microsoft.Extensions.Configuration; using OpenTelemetry.Metrics; diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs index 8a03a8e47b7..467ed6c0c25 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs index 57b1b8a9f53..65c96a2e504 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using NuGet.Versioning; using OpenTelemetry.Internal; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Tests/Internal/AssemblyVersionExtensionsTests.cs b/test/OpenTelemetry.Tests/Internal/AssemblyVersionExtensionsTests.cs index 22cf81be0ee..b009846c8d7 100644 --- a/test/OpenTelemetry.Tests/Internal/AssemblyVersionExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Internal/AssemblyVersionExtensionsTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Reflection; using Xunit; diff --git a/test/OpenTelemetry.Tests/Internal/JsonStringArrayTagWriterTests.cs b/test/OpenTelemetry.Tests/Internal/JsonStringArrayTagWriterTests.cs index 0e7a8d45fa7..fbdc3da9cf7 100644 --- a/test/OpenTelemetry.Tests/Internal/JsonStringArrayTagWriterTests.cs +++ b/test/OpenTelemetry.Tests/Internal/JsonStringArrayTagWriterTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Text; using Xunit; diff --git a/test/OpenTelemetry.Tests/Internal/PeriodicExportingMetricReaderHelperTests.cs b/test/OpenTelemetry.Tests/Internal/PeriodicExportingMetricReaderHelperTests.cs index d0da994e018..f1d5f843277 100644 --- a/test/OpenTelemetry.Tests/Internal/PeriodicExportingMetricReaderHelperTests.cs +++ b/test/OpenTelemetry.Tests/Internal/PeriodicExportingMetricReaderHelperTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Microsoft.Extensions.Configuration; using OpenTelemetry.Exporter; using OpenTelemetry.Metrics; diff --git a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigRefresherTest.cs b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigRefresherTest.cs index 10c0be18fa2..939e64671f1 100644 --- a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigRefresherTest.cs +++ b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigRefresherTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Text; using OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Tests/Logs/BatchExportLogRecordProcessorOptionsTest.cs b/test/OpenTelemetry.Tests/Logs/BatchExportLogRecordProcessorOptionsTest.cs index 2030e402c24..d6ebbc74e07 100644 --- a/test/OpenTelemetry.Tests/Logs/BatchExportLogRecordProcessorOptionsTest.cs +++ b/test/OpenTelemetry.Tests/Logs/BatchExportLogRecordProcessorOptionsTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Microsoft.Extensions.Configuration; using Xunit; diff --git a/test/OpenTelemetry.Tests/Logs/LogRecordSharedPoolTests.cs b/test/OpenTelemetry.Tests/Logs/LogRecordSharedPoolTests.cs index d4be69397b1..d38c82d1a0c 100644 --- a/test/OpenTelemetry.Tests/Logs/LogRecordSharedPoolTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LogRecordSharedPoolTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Logs.Tests; diff --git a/test/OpenTelemetry.Tests/Logs/LogRecordStateProcessorTests.cs b/test/OpenTelemetry.Tests/Logs/LogRecordStateProcessorTests.cs index 24acd8869a7..8b7cb43a4ec 100644 --- a/test/OpenTelemetry.Tests/Logs/LogRecordStateProcessorTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LogRecordStateProcessorTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Logging; using Xunit; diff --git a/test/OpenTelemetry.Tests/Logs/LogRecordThreadStaticPoolTests.cs b/test/OpenTelemetry.Tests/Logs/LogRecordThreadStaticPoolTests.cs index 59c0b53454e..4fd6f588c85 100644 --- a/test/OpenTelemetry.Tests/Logs/LogRecordThreadStaticPoolTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LogRecordThreadStaticPoolTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Logs.Tests; diff --git a/test/OpenTelemetry.Tests/Logs/LoggerProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/LoggerProviderBuilderExtensionsTests.cs index 79907a3d2c7..ea25d748604 100644 --- a/test/OpenTelemetry.Tests/Logs/LoggerProviderBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LoggerProviderBuilderExtensionsTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Resources; using Xunit; diff --git a/test/OpenTelemetry.Tests/Logs/LoggerProviderExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/LoggerProviderExtensionsTests.cs index 0324027f7f2..d059dfd4864 100644 --- a/test/OpenTelemetry.Tests/Logs/LoggerProviderExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LoggerProviderExtensionsTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using OpenTelemetry.Exporter; using Xunit; diff --git a/test/OpenTelemetry.Tests/Logs/LoggerProviderSdkTests.cs b/test/OpenTelemetry.Tests/Logs/LoggerProviderSdkTests.cs index 7122dd089e1..182490cbc8b 100644 --- a/test/OpenTelemetry.Tests/Logs/LoggerProviderSdkTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LoggerProviderSdkTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Exporter; diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index e0c59ca7bf7..4839964c0ee 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Reflection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; diff --git a/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs index dd7b21c6ccc..116f1e15259 100644 --- a/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/AggregatorTestsBase.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Diagnostics.Metrics; using Xunit; diff --git a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs index 2dfa7373334..c84b1b1ef7d 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Diagnostics.Metrics; using Microsoft.Extensions.Configuration; diff --git a/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs index fe7fb5244d9..7ed01e46a72 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Diagnostics.Metrics; using Microsoft.Extensions.Configuration; diff --git a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs index ee1162f4789..92b65f2b97f 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if BUILDING_HOSTING_TESTS using System.Diagnostics; #endif diff --git a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs index 6dae582151e..10eb9709842 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.Metrics; using OpenTelemetry.Internal; using OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs b/test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs index 3c8522cb554..ba456cbc4e0 100644 --- a/test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs +++ b/test/OpenTelemetry.Tests/OpenTelemetrySdkTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Microsoft.Extensions.Logging.Abstractions; using OpenTelemetry.Logs; using OpenTelemetry.Metrics; diff --git a/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs index 26d82bb6a0b..deb638e6552 100644 --- a/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.Tracing; using System.Globalization; using System.Reflection; diff --git a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs index 0fb748ba2c2..a465db2ee6c 100644 --- a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs +++ b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index 056c37036dc..0e955e7dd2c 100644 --- a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs index 56c2c25eaef..a85511da51c 100644 --- a/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Tests/Shared/TestActivityProcessor.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Tests/Shared/TestEventListener.cs b/test/OpenTelemetry.Tests/Shared/TestEventListener.cs index 4e9d79c4735..fb497190f5e 100644 --- a/test/OpenTelemetry.Tests/Shared/TestEventListener.cs +++ b/test/OpenTelemetry.Tests/Shared/TestEventListener.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.Tracing; namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs b/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs index 9d86ae2a2aa..bcfcc7d9fda 100644 --- a/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs +++ b/test/OpenTelemetry.Tests/Shared/TestHttpServer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Net; namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderBaseTests.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderBaseTests.cs index 6c0da445af6..ed9a337c6b3 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderBaseTests.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderBaseTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Xunit; namespace OpenTelemetry.Trace.Tests; From bb832226d3cc3ec089b921739e37e72cda910720 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:50:59 +0000 Subject: [PATCH 112/133] [sdk-metrics] Use FrozenSet when looking up explicit bounds (#5899) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry/Metrics/Metric.cs | 31 +++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry/Metrics/Metric.cs b/src/OpenTelemetry/Metrics/Metric.cs index 37dd3198b71..7ecb10e519f 100644 --- a/src/OpenTelemetry/Metrics/Metric.cs +++ b/src/OpenTelemetry/Metrics/Metric.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if NET +using System.Collections.Frozen; +#endif using System.Diagnostics.Metrics; namespace OpenTelemetry.Metrics; @@ -18,7 +21,13 @@ public sealed class Metric // Short default histogram bounds. Based on the recommended semantic convention values for http.server.request.duration. internal static readonly double[] DefaultHistogramBoundsShortSeconds = new double[] { 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 }; - internal static readonly HashSet<(string, string)> DefaultHistogramBoundShortMappings = new() + internal static readonly +#if NET + FrozenSet<(string, string)> +#else + HashSet<(string, string)> +#endif + DefaultHistogramBoundShortMappings = new HashSet<(string, string)> { ("Microsoft.AspNetCore.Hosting", "http.server.request.duration"), ("Microsoft.AspNetCore.RateLimiting", "aspnetcore.rate_limiting.request.time_in_queue"), @@ -30,16 +39,30 @@ public sealed class Metric ("System.Net.Http", "http.client.request.duration"), ("System.Net.Http", "http.client.request.time_in_queue"), ("System.Net.NameResolution", "dns.lookup.duration"), - }; + } +#if NET + .ToFrozenSet() +#endif + ; // Long default histogram bounds. Not based on a standard. May change in the future. internal static readonly double[] DefaultHistogramBoundsLongSeconds = new double[] { 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 }; - internal static readonly HashSet<(string, string)> DefaultHistogramBoundLongMappings = new() + internal static readonly +#if NET + FrozenSet<(string, string)> +#else + HashSet<(string, string)> +#endif + DefaultHistogramBoundLongMappings = new HashSet<(string, string)> { ("Microsoft.AspNetCore.Http.Connections", "signalr.server.connection.duration"), ("Microsoft.AspNetCore.Server.Kestrel", "kestrel.connection.duration"), ("System.Net.Http", "http.client.connection.duration"), - }; + } +#if NET + .ToFrozenSet() +#endif + ; internal readonly AggregatorStore AggregatorStore; From dba7d251f6c2b037edcc220bbbf58006722fa11c Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Mon, 14 Oct 2024 14:35:26 -0700 Subject: [PATCH 113/133] [repo] Update stale.yml - reduce days before stale to 300 (#5902) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 7a7b91c3e67..9be0713edb6 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,7 +18,7 @@ jobs: close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' operations-per-run: 400 days-before-pr-stale: 7 - days-before-issue-stale: 450 + days-before-issue-stale: 300 days-before-pr-close: 7 days-before-issue-close: 7 exempt-all-issue-milestones: true From 963ec41598baa577c44d543091c445074df7630e Mon Sep 17 00:00:00 2001 From: Richard Chukwu <79311274+RichardChukwu@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:01:10 +0100 Subject: [PATCH 114/133] [repo] Add RELEASENOTES and READMEs to NuGet packages (#5885) Co-authored-by: Reiley Yang Co-authored-by: Mikel Blanchard --- build/Common.prod.props | 65 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/build/Common.prod.props b/build/Common.prod.props index 1b58605b4d1..3738c0a691d 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -25,6 +25,9 @@ true $(RepoRoot)\LICENSE.TXT $(RepoRoot)\THIRD-PARTY-NOTICES.TXT + README.md + CHANGELOG.md + $(RepoRoot)\RELEASENOTES.md @@ -57,7 +60,7 @@ - + + + + + + + + + + + + + + \[([^]]+?)\]\(\.(.+?)\) + $(GitOriginConsoleOutput.Replace('.git','')) + $(GitHubRepoUrl)/blob/$(PackTag) + $(GitHubRepoUrl)/blob/$(GitCommitConsoleOutput) + + + + + + + + + + + + + + + + <_PackageReleaseNotesFilePath>$([System.IO.Path]::GetFullPath('$(PackageReleaseNotesFile)').Replace('$(RepoRoot)', '').Replace('\', '/')) + <_PackageChangelogFilePath>$([System.IO.Path]::GetFullPath('$(PackageChangelogFile)').Replace('$(RepoRoot)', '').Replace('\', '/')) + + For highlights and announcements see: $(GitHubPermalinkUrl)$(_PackageReleaseNotesFilePath). + + For detailed changes see: $(GitHubPermalinkUrl)$(_PackageChangelogFilePath). + + + + + + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/gen_test_cert.ps1 b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/gen_test_cert.ps1 new file mode 100644 index 00000000000..d9443ca85fa --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/gen_test_cert.ps1 @@ -0,0 +1,90 @@ +using namespace System.Security.Cryptography; +using namespace System.Security.Cryptography.X509Certificates; + +param ( + [string] $OutDir +) + +function Write-Certificate { + param ( + [X509Certificate2] $Cert, + [string] $Name, + [string] $Dir + ) + + # write cert content + $certPem = $Cert.ExportCertificatePem(); + $certPemPath = Join-Path $Dir -ChildPath "$Name-cert.pem"; + [System.IO.File]::WriteAllText($certPemPath, $certPem); + + # write pkey + [AsymmetricAlgorithm] $pkey = [RSACertificateExtensions]::GetRSAPrivateKey($Cert); + [string] $pkeyPem = $null; + + if ($null -ne $pkey) { + $pkeyPem = $pkey.ExportRSAPrivateKeyPem(); + } + + if ($null -eq $pkey) { + $pkey = [ECDsaCertificateExtensions]::GetECDsaPrivateKey($Cert); + $pkeyPem = $pkey.ExportECPrivateKeyPem(); + } + + if ($null -eq $pkeyPem) { + return; + } + + + $pKeyPath = Join-Path $Dir -ChildPath "$Name-key.pem"; + [System.IO.File]::WriteAllText($pKeyPath, $pkeyPem); +} + +$ca = New-SelfSignedCertificate -CertStoreLocation 'Cert:\CurrentUser\My' ` + -DnsName "otel-test-ca" ` + -NotAfter (Get-Date).AddYears(20) ` + -FriendlyName "otel-test-ca" ` + -KeyAlgorithm ECDSA_nistP256 ` + -KeyExportPolicy Exportable ` + -KeyUsageProperty All -KeyUsage CertSign, CRLSign, DigitalSignature; + + +try { + Write-Certificate -Cert $ca -Name "otel-test-ca" -Dir $OutDir; + $serverCert = New-SelfSignedCertificate -CertStoreLocation 'Cert:\CurrentUser\My' ` + -DnsName "otel-collector" ` + -Signer $ca ` + -NotAfter (Get-Date).AddYears(20) ` + -FriendlyName "otel-test-server" ` + -KeyAlgorithm ECDSA_nistP256 ` + -KeyUsageProperty All ` + -KeyExportPolicy Exportable ` + -KeyUsage CertSign, CRLSign, DigitalSignature ` + -TextExtension @("2.5.29.19={text}CA=1&pathlength=1", "2.5.29.37={text}1.3.6.1.5.5.7.3.1"); + + try { + Write-Certificate -Cert $serverCert -Name "otel-test-server" -Dir $OutDir; + + $clientCert = New-SelfSignedCertificate -CertStoreLocation 'Cert:\CurrentUser\My' ` + -DnsName "otel-test-client" ` + -Signer $ca ` + -NotAfter (Get-Date).AddYears(20) ` + -FriendlyName "otel-test-client" ` + -KeyAlgorithm ECDSA_nistP256 ` + -KeyUsageProperty All ` + -KeyExportPolicy Exportable ` + -KeyUsage CertSign, CRLSign, DigitalSignature ` + -TextExtension @("2.5.29.19={text}CA=1&pathlength=1", "2.5.29.37={text}1.3.6.1.5.5.7.3.2"); + try { + Write-Certificate -Cert $clientCert -Name "otel-test-client" -Dir $OutDir; + } + finally { + Get-Item -Path "Cert:\CurrentUser\My\$($clientCert.Thumbprint)" | Remove-Item; + } + } + finally { + Get-Item -Path "Cert:\CurrentUser\My\$($serverCert.Thumbprint)" | Remove-Item; + } +} +finally { + Get-Item -Path "Cert:\CurrentUser\My\$($ca.Thumbprint)" | Remove-Item; +} diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/gen_test_cert.sh b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/gen_test_cert.sh new file mode 100644 index 00000000000..bd129a4b838 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/gen_test_cert.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# Set output directory, default is the current directory +OUT_DIR=${1:-"."} + +# Create output directory if it doesn't exist +mkdir -p "$OUT_DIR" + +# Generate CA certificate (Certificate Authority) +openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \ + -subj "/CN=otel-test-ca" \ + -keyout "$OUT_DIR/otel-test-ca-key.pem" -out "$OUT_DIR/otel-test-ca-cert.pem" + +# Create the extension configuration file for the server certificate +cat > "$OUT_DIR/server_cert_ext.cnf" < "$OUT_DIR/client_cert_ext.cnf" < Date: Mon, 21 Oct 2024 19:30:53 +0200 Subject: [PATCH 117/133] [Examples.AspNetCore] Bump OTel Collector to 0.111.0 (#5913) --- examples/AspNetCore/docker-compose.yaml | 2 +- examples/AspNetCore/otel-collector.yaml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/AspNetCore/docker-compose.yaml b/examples/AspNetCore/docker-compose.yaml index c8cc94fa4b1..7cdb95106e1 100644 --- a/examples/AspNetCore/docker-compose.yaml +++ b/examples/AspNetCore/docker-compose.yaml @@ -3,7 +3,7 @@ services: # OTEL Collector to receive logs, metrics and traces from the application otel-collector: - image: otel/opentelemetry-collector:0.70.0 + image: otel/opentelemetry-collector:0.111.0 command: [ "--config=/etc/otel-collector.yaml" ] volumes: - ./otel-collector.yaml:/etc/otel-collector.yaml diff --git a/examples/AspNetCore/otel-collector.yaml b/examples/AspNetCore/otel-collector.yaml index 15df605c542..fa9999d66c9 100644 --- a/examples/AspNetCore/otel-collector.yaml +++ b/examples/AspNetCore/otel-collector.yaml @@ -2,7 +2,9 @@ receivers: otlp: protocols: grpc: + endpoint: 0.0.0.0:4317 http: + endpoint: 0.0.0.0:4318 exporters: debug: From 0eebf97a4b62583919d5373f12fd655bdd86aa9d Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 21 Oct 2024 12:53:42 -0700 Subject: [PATCH 118/133] [otlp] OTLP Exporter Custom serializer Part 1 - WritingPrimitives (#5910) Co-authored-by: Mikel Blanchard --- .../Serializer/ProtobufSerializer.cs | 254 +++++++++++++ .../Serializer/ProtobufWireType.cs | 47 +++ ...etry.Exporter.OpenTelemetryProtocol.csproj | 1 + .../Serializer/ProtobufSerializerTests.cs | 333 ++++++++++++++++++ 4 files changed, 635 insertions(+) create mode 100644 src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufWireType.cs create mode 100644 test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs new file mode 100644 index 00000000000..b8bd31b682a --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs @@ -0,0 +1,254 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Buffers.Binary; +using System.Diagnostics; +using System.Runtime.CompilerServices; +#if NETFRAMEWORK || NETSTANDARD2_0 +using System.Runtime.InteropServices; +#endif +using System.Text; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; + +internal static class ProtobufSerializer +{ + private const uint UInt128 = 0x80; + private const ulong ULong128 = 0x80; + private const int Fixed32Size = 4; + private const int Fixed64Size = 8; + + private static readonly Encoding Utf8Encoding = Encoding.UTF8; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static uint GetTagValue(int fieldNumber, ProtobufWireType wireType) => ((uint)(fieldNumber << 3)) | (uint)wireType; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteTag(byte[] buffer, int writePosition, int fieldNumber, ProtobufWireType type) => WriteVarInt32(buffer, writePosition, GetTagValue(fieldNumber, type)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteLength(byte[] buffer, int writePosition, int length) => WriteVarInt32(buffer, writePosition, (uint)length); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteTagAndLength(byte[] buffer, int writePosition, int contentLength, int fieldNumber, ProtobufWireType type) + { + writePosition = WriteTag(buffer, writePosition, fieldNumber, type); + writePosition = WriteLength(buffer, writePosition, contentLength); + + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteReservedLength(byte[] buffer, int writePosition, int length) + { + int byteLength = 0; + int? firstByte = null; + int? secondByte = null; + int? thirdByte = null; + int? fourthByte = null; + + do + { + switch (byteLength) + { + case 0: + firstByte = length & 0x7F; + break; + case 1: + secondByte = length & 0x7F; + break; + case 2: + thirdByte = length & 0x7F; + break; + case 3: + fourthByte = length & 0x7F; + break; + } + + length >>= 7; + byteLength++; + } + while (length > 0); + + if (fourthByte.HasValue) + { + buffer[writePosition++] = (byte)(firstByte!.Value | 0x80); + buffer[writePosition++] = (byte)(secondByte!.Value | 0x80); + buffer[writePosition++] = (byte)(thirdByte!.Value | 0x80); + buffer[writePosition++] = (byte)fourthByte!.Value; + } + else if (thirdByte.HasValue) + { + buffer[writePosition++] = (byte)(firstByte!.Value | 0x80); + buffer[writePosition++] = (byte)(secondByte!.Value | 0x80); + buffer[writePosition++] = (byte)(thirdByte!.Value | 0x80); + buffer[writePosition++] = 0; + } + else if (secondByte.HasValue) + { + buffer[writePosition++] = (byte)(firstByte!.Value | 0x80); + buffer[writePosition++] = (byte)(secondByte!.Value | 0x80); + buffer[writePosition++] = 0x80; + buffer[writePosition++] = 0; + } + else + { + buffer[writePosition++] = (byte)(firstByte!.Value | 0x80); + buffer[writePosition++] = 0x80; + buffer[writePosition++] = 0x80; + buffer[writePosition++] = 0; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteBoolWithTag(byte[] buffer, int writePosition, int fieldNumber, bool value) + { + writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.VARINT); + buffer[writePosition++] = value ? (byte)1 : (byte)0; + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteEnumWithTag(byte[] buffer, int writePosition, int fieldNumber, int value) + { + writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.VARINT); + buffer[writePosition++] = (byte)value; + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteFixed32LittleEndianFormat(byte[] buffer, int writePosition, uint value) + { + Span span = new(buffer, writePosition, Fixed32Size); + BinaryPrimitives.WriteUInt32LittleEndian(span, value); + writePosition += Fixed32Size; + + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteFixed64LittleEndianFormat(byte[] buffer, int writePosition, ulong value) + { + Span span = new(buffer, writePosition, Fixed64Size); + BinaryPrimitives.WriteUInt64LittleEndian(span, value); + writePosition += Fixed64Size; + + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteFixed32WithTag(byte[] buffer, int writePosition, int fieldNumber, uint value) + { + writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.I32); + writePosition = WriteFixed32LittleEndianFormat(buffer, writePosition, value); + + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteFixed64WithTag(byte[] buffer, int writePosition, int fieldNumber, ulong value) + { + writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.I64); + writePosition = WriteFixed64LittleEndianFormat(buffer, writePosition, value); + + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteVarInt32(byte[] buffer, int writePosition, uint value) + { + while (value >= UInt128) + { + buffer[writePosition++] = (byte)(0x80 | (value & 0x7F)); + value >>= 7; + } + + buffer[writePosition++] = (byte)value; + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteVarInt64(byte[] buffer, int writePosition, ulong value) + { + while (value >= ULong128) + { + buffer[writePosition++] = (byte)(0x80 | (value & 0x7F)); + value >>= 7; + } + + buffer[writePosition++] = (byte)value; + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteInt64WithTag(byte[] buffer, int writePosition, int fieldNumber, ulong value) + { + writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.VARINT); + writePosition = WriteVarInt64(buffer, writePosition, value); + + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteDoubleWithTag(byte[] buffer, int writePosition, int fieldNumber, double value) + { + writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.I64); + writePosition = WriteFixed64LittleEndianFormat(buffer, writePosition, (ulong)BitConverter.DoubleToInt64Bits(value)); + + return writePosition; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, string value) + { + Debug.Assert(value != null, "value was null"); + + return WriteStringWithTag(buffer, writePosition, fieldNumber, value.AsSpan()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, ReadOnlySpan value) + { +#if NETFRAMEWORK || NETSTANDARD2_0 + int numberOfUtf8CharsInString; + unsafe + { + fixed (char* strPtr = &GetNonNullPinnableReference(value)) + { + numberOfUtf8CharsInString = Utf8Encoding.GetByteCount(strPtr, value.Length); + } + } +#else + int numberOfUtf8CharsInString = Utf8Encoding.GetByteCount(value); +#endif + + writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN); + writePosition = WriteLength(buffer, writePosition, numberOfUtf8CharsInString); + +#if NETFRAMEWORK || NETSTANDARD2_0 + unsafe + { + fixed (char* strPtr = &GetNonNullPinnableReference(value)) + { + fixed (byte* bufferPtr = buffer) + { + var bytesWritten = Utf8Encoding.GetBytes(strPtr, value.Length, bufferPtr + writePosition, numberOfUtf8CharsInString); + Debug.Assert(bytesWritten == numberOfUtf8CharsInString, "bytesWritten did not match numberOfUtf8CharsInString"); + } + } + } +#else + var bytesWritten = Utf8Encoding.GetBytes(value, buffer.AsSpan().Slice(writePosition)); + Debug.Assert(bytesWritten == numberOfUtf8CharsInString, "bytesWritten did not match numberOfUtf8CharsInString"); +#endif + + writePosition += numberOfUtf8CharsInString; + return writePosition; + } + +#if NETFRAMEWORK || NETSTANDARD2_0 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe ref T GetNonNullPinnableReference(ReadOnlySpan span) + => ref (span.Length != 0) ? ref Unsafe.AsRef(in MemoryMarshal.GetReference(span)) : ref Unsafe.AsRef((void*)1); +#endif +} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufWireType.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufWireType.cs new file mode 100644 index 00000000000..b3b5fe40319 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufWireType.cs @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; + +/// +/// Wire types within protobuf encoding. +/// https://protobuf.dev/programming-guides/encoding/#structure. +/// +internal enum ProtobufWireType : uint +{ + /// + /// Variable-length integer. + /// Used for int32, int64, uint32, uint64, sint32, sint64, bool, enum. + /// + VARINT = 0, + + /// + /// A fixed-length 64-bit value. + /// Used for fixed64, sfixed64, double. + /// + I64 = 1, + + /// + /// A length-delimited value. + /// Used for string, bytes, embedded messages, packed repeated fields. + /// + LEN = 2, + + /// + /// Group Start value. + /// (Deprecated). + /// + SGROUP = 3, + + /// + /// Group End value. + /// (Deprecated). + /// + EGROUP = 4, + + /// + /// A fixed-length 32-bit value. + /// Used for fixed32, sfixed32, float. + /// + I32 = 5, +} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj index 2c933d89a33..cfeae2fa85d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj @@ -16,6 +16,7 @@ https://github.com/open-telemetry/opentelemetry-dotnet/pull/5520#discussion_r1556221048 and https://github.com/dotnet/runtime/issues/92509 --> $(NoWarn);SYSLIB1100;SYSLIB1101 + true diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs new file mode 100644 index 00000000000..0ee13a5b834 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs @@ -0,0 +1,333 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Text; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; +using Xunit; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.Implementation.Serializer; + +public class ProtobufSerializerTests +{ + [Fact] + public void GetTagValue_ReturnsCorrectValue() + { + Assert.Equal(8u, ProtobufSerializer.GetTagValue(1, ProtobufWireType.VARINT)); + Assert.Equal(17u, ProtobufSerializer.GetTagValue(2, ProtobufWireType.I64)); + Assert.Equal(26u, ProtobufSerializer.GetTagValue(3, ProtobufWireType.LEN)); + } + + [Fact] + public void WriteTag_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteTag(buffer, 0, 1, ProtobufWireType.VARINT); + Assert.Equal(1, position); + Assert.Equal(8, buffer[0]); + } + + [Fact] + public void WriteLength_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteLength(buffer, 0, 300); + Assert.Equal(2, position); + Assert.Equal(0xAC, buffer[0]); + Assert.Equal(0x02, buffer[1]); + } + + [Fact] + public void WriteBoolWithTag_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteBoolWithTag(buffer, 0, 1, true); + Assert.Equal(2, position); + Assert.Equal(8, buffer[0]); + Assert.Equal(1, buffer[1]); + } + + [Fact] + public void WriteFixed32WithTag_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteFixed32WithTag(buffer, 0, 1, 0x12345678); + Assert.Equal(5, position); + Assert.Equal(13, buffer[0]); + Assert.Equal(0x78, buffer[1]); + Assert.Equal(0x56, buffer[2]); + Assert.Equal(0x34, buffer[3]); + Assert.Equal(0x12, buffer[4]); + } + + [Fact] + public void WriteFixed64WithTag_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteFixed64WithTag(buffer, 0, 1, 0x123456789ABCDEF0); + Assert.Equal(9, position); + Assert.Equal(9, buffer[0]); // Tag + Assert.Equal(0xF0, buffer[1]); + Assert.Equal(0xDE, buffer[2]); + Assert.Equal(0xBC, buffer[3]); + Assert.Equal(0x9A, buffer[4]); + Assert.Equal(0x78, buffer[5]); + Assert.Equal(0x56, buffer[6]); + Assert.Equal(0x34, buffer[7]); + Assert.Equal(0x12, buffer[8]); + } + + [Fact] + public void WriteStringWithTag_WritesCorrectly() + { + byte[] buffer = new byte[20]; + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, "Hello"); + Assert.Equal(7, position); + Assert.Equal(10, buffer[0]); + Assert.Equal(5, buffer[1]); + Assert.Equal((byte)'H', buffer[2]); + Assert.Equal((byte)'e', buffer[3]); + Assert.Equal((byte)'l', buffer[4]); + Assert.Equal((byte)'l', buffer[5]); + Assert.Equal((byte)'o', buffer[6]); + } + + [Theory] + [InlineData(300, new byte[] { 0xAC, 0x82, 0x80, 0x00 })] // Normal case with 300 + [InlineData(127, new byte[] { 0xFF, 0x80, 0x80, 0x00 })] // Boundary case: max 1-byte value + [InlineData(128, new byte[] { 0x80, 0x81, 0x80, 0x00 })] // Boundary case: min 2-byte value + [InlineData(16383, new byte[] { 0xFF, 0xFF, 0x80, 0x00 })] // Max 2-byte value + [InlineData(16384, new byte[] { 0x80, 0x80, 0x81, 0x00 })] // Min 3-byte value + [InlineData(2097151, new byte[] { 0xFF, 0xFF, 0xFF, 0x00 })] // Max 3-byte value + [InlineData(2097152, new byte[] { 0x80, 0x80, 0x80, 0x01 })] // Min 4-byte value + [InlineData(268435455, new byte[] { 0xFF, 0xFF, 0xFF, 0x7F })] // Max 4-byte value + public void WriteReservedLength_WritesCorrectly(int length, byte[] expectedBytes) + { + byte[] buffer = new byte[10]; + ProtobufSerializer.WriteReservedLength(buffer, 0, length); + + for (int i = 0; i < expectedBytes.Length; i++) + { + Assert.Equal(expectedBytes[i], buffer[i]); + } + } + + [Fact] + public void WriteTagAndLength_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteTagAndLength(buffer, 0, 300, 1, ProtobufWireType.LEN); + Assert.Equal(3, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(0xAC, buffer[1]); // Length (300 in varint encoding) + Assert.Equal(0x02, buffer[2]); + } + + [Fact] + public void WriteEnumWithTag_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteEnumWithTag(buffer, 0, 1, 5); + Assert.Equal(2, position); + Assert.Equal(8, buffer[0]); // Tag + Assert.Equal(5, buffer[1]); // Enum value + } + + [Fact] + public void WriteVarInt64_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteVarInt64(buffer, 0, 300); + Assert.Equal(2, position); + Assert.Equal(0xAC, buffer[0]); + Assert.Equal(0x02, buffer[1]); + } + + [Fact] + public void WriteInt64WithTag_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteInt64WithTag(buffer, 0, 1, 300); + Assert.Equal(3, position); + Assert.Equal(8, buffer[0]); // Tag + Assert.Equal(0xAC, buffer[1]); + Assert.Equal(0x02, buffer[2]); + } + + [Fact] + public void WriteDoubleWithTag_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteDoubleWithTag(buffer, 0, 1, 123.456); + Assert.Equal(9, position); + Assert.Equal(9, buffer[0]); // Tag + + // The next 8 bytes represent 123.456 in IEEE 754 double-precision format + Assert.Equal(0x77, buffer[1]); + Assert.Equal(0xBE, buffer[2]); + Assert.Equal(0x9F, buffer[3]); + Assert.Equal(0x1A, buffer[4]); + Assert.Equal(0x2F, buffer[5]); + Assert.Equal(0xDD, buffer[6]); + Assert.Equal(0x5E, buffer[7]); + Assert.Equal(0x40, buffer[8]); + } + + [Fact] + public void WriteVarInt32_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteVarInt32(buffer, 0, 300); + Assert.Equal(2, position); + Assert.Equal(0xAC, buffer[0]); + Assert.Equal(0x02, buffer[1]); + } + + [Fact] + public void WriteVarInt32_MaxValue_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteVarInt32(buffer, 0, uint.MaxValue); + Assert.Equal(5, position); + Assert.Equal(0xFF, buffer[0]); + Assert.Equal(0xFF, buffer[1]); + Assert.Equal(0xFF, buffer[2]); + Assert.Equal(0xFF, buffer[3]); + Assert.Equal(0x0F, buffer[4]); + } + + [Fact] + public void WriteVarInt64_MaxValue_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteVarInt64(buffer, 0, ulong.MaxValue); + Assert.Equal(10, position); + for (int i = 0; i < 9; i++) + { + Assert.Equal(0xFF, buffer[i]); + } + + Assert.Equal(0x01, buffer[9]); + } + + [Fact] + public void WriteStringWithTag_EmptyString_WritesCorrectly() + { + byte[] buffer = new byte[10]; + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, string.Empty); + Assert.Equal(2, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(0, buffer[1]); // Length + } + + [Fact] + public void WriteStringWithTag_ASCIIString_WritesCorrectly() + { + byte[] buffer = new byte[20]; + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, "Hello"); + Assert.Equal(7, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(5, buffer[1]); // Length + + byte[] expectedContent = Encoding.ASCII.GetBytes("Hello"); + byte[] actualContent = new byte[5]; + Array.Copy(buffer, 2, actualContent, 0, 5); + Assert.True(expectedContent.SequenceEqual(actualContent)); + } + + [Fact] + public void WriteStringWithTag_UnicodeString_WritesCorrectly() + { + byte[] buffer = new byte[20]; + string unicodeString = "\u3053\u3093\u306b\u3061\u306f"; // "Hello" in Japanese + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, unicodeString); + Assert.Equal(17, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(15, buffer[1]); // Length (3 bytes per character in UTF-8) + + byte[] expectedContent = Encoding.UTF8.GetBytes(unicodeString); + byte[] actualContent = new byte[15]; + Array.Copy(buffer, 2, actualContent, 0, 15); + Assert.True(expectedContent.SequenceEqual(actualContent)); + } + + [Fact] + public void WriteStringWithTag_LongString_WritesCorrectly() + { + string longString = new string('a', 1000); + byte[] buffer = new byte[1100]; + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, longString); + Assert.Equal(1003, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(0xE8, buffer[1]); // Length (1000 in varint encoding) + Assert.Equal(0x07, buffer[2]); + + byte[] expectedContent = Encoding.UTF8.GetBytes(longString); + byte[] actualContent = new byte[1000]; + Array.Copy(buffer, 3, actualContent, 0, 1000); + Assert.True(expectedContent.SequenceEqual(actualContent)); + } + + [Fact] + public void WriteStringWithTag_MixedEncodingString_WritesCorrectly() + { + byte[] buffer = new byte[30]; + string mixedString = "Hello\u4e16\u754c"; // "Hello World" with "World" in Chinese + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, mixedString); + Assert.Equal(13, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(11, buffer[1]); // Length (5 for "Hello" + 6 for Chinese "World" in UTF-8) + + byte[] expectedContent = Encoding.UTF8.GetBytes(mixedString); + byte[] actualContent = new byte[11]; + Array.Copy(buffer, 2, actualContent, 0, 11); + Assert.True(expectedContent.SequenceEqual(actualContent)); + } + + [Fact] + public void WriteStringWithTag_StringWithSpecialCharacters_WritesCorrectly() + { + byte[] buffer = new byte[30]; + string specialString = "Hello\n\t\"World\""; + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, specialString); + Assert.Equal(16, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(14, buffer[1]); // Length + + byte[] expectedContent = Encoding.UTF8.GetBytes(specialString); + byte[] actualContent = new byte[14]; + Array.Copy(buffer, 2, actualContent, 0, 14); + Assert.True(expectedContent.SequenceEqual(actualContent)); + } + + [Fact] + public void WriteStringWithTag_StringWithNullCharacters_WritesCorrectly() + { + byte[] buffer = new byte[20]; + string stringWithNull = "Hello\0World"; + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, stringWithNull); + Assert.Equal(13, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(11, buffer[1]); // Length + + byte[] expectedContent = Encoding.UTF8.GetBytes(stringWithNull); + byte[] actualContent = new byte[11]; + Array.Copy(buffer, 2, actualContent, 0, 11); + Assert.True(expectedContent.SequenceEqual(actualContent)); + } + + [Fact] + public void WriteStringWithTag_SurrogatePairs_WritesCorrectly() + { + byte[] buffer = new byte[20]; + string surrogatePairString = "\uD83D\uDCD6"; // Books emoji + int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, surrogatePairString); + Assert.Equal(6, position); + Assert.Equal(10, buffer[0]); // Tag + Assert.Equal(4, buffer[1]); // Length (4 bytes for the surrogate pair in UTF-8) + + byte[] expectedContent = Encoding.UTF8.GetBytes(surrogatePairString); + byte[] actualContent = new byte[4]; + Array.Copy(buffer, 2, actualContent, 0, 4); + Assert.True(expectedContent.SequenceEqual(actualContent)); + } +} From 25a9366679e7895bdfa9daf4ac53bbc65c781ab0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 21 Oct 2024 14:40:11 -0700 Subject: [PATCH 119/133] [sdk-metrics] Fix a race condition when a metric is deactivated and re-activated in the same collection cycle (#5908) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs index def0591d0d4..f22208c8b61 100644 --- a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.Metrics; public abstract partial class MetricReader { private readonly HashSet metricStreamNames = new(StringComparer.OrdinalIgnoreCase); - private readonly ConcurrentDictionary instrumentIdentityToMetric = new(); + private readonly ConcurrentDictionary instrumentIdentityToMetric = new(); private readonly Lock instrumentCreationLock = new(); private int metricLimit; private int cardinalityLimit; @@ -201,7 +201,7 @@ internal void ApplyParentProviderSettings( private bool TryGetExistingMetric(in MetricStreamIdentity metricStreamIdentity, [NotNullWhen(true)] out Metric? existingMetric) => this.instrumentIdentityToMetric.TryGetValue(metricStreamIdentity, out existingMetric) - && existingMetric.Active; + && existingMetric != null && existingMetric.Active; private void CreateOrUpdateMetricStreamRegistration(in MetricStreamIdentity metricStreamIdentity) { @@ -268,8 +268,12 @@ private void RemoveMetric(ref Metric? metric) OpenTelemetrySdkEventSource.Log.MetricInstrumentRemoved(metric!.Name, metric.MeterName); - var result = this.instrumentIdentityToMetric.TryRemove(metric.InstrumentIdentity, out var _); - Debug.Assert(result, "result was false"); + // Note: This is using TryUpdate and NOT TryRemove because there is a + // race condition. If a metric is deactivated and then reactivated in + // the same collection cycle + // instrumentIdentityToMetric[metric.InstrumentIdentity] may already + // point to the new activated metric and not the old deactivated one. + this.instrumentIdentityToMetric.TryUpdate(metric.InstrumentIdentity, null, metric); // Note: metric is a reference to the array storage so // this clears the metric out of the array. From 5dff99f8a0b26ff75248d5f2e478b9c3c42f5678 Mon Sep 17 00:00:00 2001 From: Weihan Li <7604648+WeihanLi@users.noreply.github.com> Date: Wed, 23 Oct 2024 08:46:00 +0800 Subject: [PATCH 120/133] [shared] Use nameof for CallerArgumentExpression in Guard helpers (#5917) --- src/Shared/Guard.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index 167d466facb..dbbe87e0e8f 100644 --- a/src/Shared/Guard.cs +++ b/src/Shared/Guard.cs @@ -55,7 +55,7 @@ internal static class Guard /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNull([NotNull] object? value, [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfNull([NotNull] object? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) { if (value is null) { @@ -70,7 +70,7 @@ public static void ThrowIfNull([NotNull] object? value, [CallerArgumentExpressio /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNullOrEmpty([NotNull] string? value, [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfNullOrEmpty([NotNull] string? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) #pragma warning disable CS8777 // Parameter must have a non-null value when exiting. { if (string.IsNullOrEmpty(value)) @@ -87,7 +87,7 @@ public static void ThrowIfNullOrEmpty([NotNull] string? value, [CallerArgumentEx /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNullOrWhitespace([NotNull] string? value, [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfNullOrWhitespace([NotNull] string? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) #pragma warning disable CS8777 // Parameter must have a non-null value when exiting. { if (string.IsNullOrWhiteSpace(value)) @@ -105,7 +105,7 @@ public static void ThrowIfNullOrWhitespace([NotNull] string? value, [CallerArgum /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfZero(int value, string message = "Must not be zero", [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfZero(int value, string message = "Must not be zero", [CallerArgumentExpression(nameof(value))] string? paramName = null) { if (value == 0) { @@ -120,7 +120,7 @@ public static void ThrowIfZero(int value, string message = "Must not be zero", [ /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfInvalidTimeout(int value, [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfInvalidTimeout(int value, [CallerArgumentExpression(nameof(value))] string? paramName = null) { ThrowIfOutOfRange(value, paramName, min: Timeout.Infinite, message: $"Must be non-negative or '{nameof(Timeout)}.{nameof(Timeout.Infinite)}'"); } @@ -137,7 +137,7 @@ public static void ThrowIfInvalidTimeout(int value, [CallerArgumentExpression("v /// An optional custom message to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfOutOfRange(int value, [CallerArgumentExpression("value")] string? paramName = null, int min = int.MinValue, int max = int.MaxValue, string? minName = null, string? maxName = null, string? message = null) + public static void ThrowIfOutOfRange(int value, [CallerArgumentExpression(nameof(value))] string? paramName = null, int min = int.MinValue, int max = int.MaxValue, string? minName = null, string? maxName = null, string? message = null) { Range(value, paramName, min, max, minName, maxName, message); } @@ -154,7 +154,7 @@ public static void ThrowIfOutOfRange(int value, [CallerArgumentExpression("value /// An optional custom message to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression("value")] string? paramName = null, double min = double.MinValue, double max = double.MaxValue, string? minName = null, string? maxName = null, string? message = null) + public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression(nameof(value))] string? paramName = null, double min = double.MinValue, double max = double.MaxValue, string? minName = null, string? maxName = null, string? message = null) { Range(value, paramName, min, max, minName, maxName, message); } @@ -168,7 +168,7 @@ public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression("va /// The value casted to the specified type. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ThrowIfNotOfType([NotNull] object? value, [CallerArgumentExpression("value")] string? paramName = null) + public static T ThrowIfNotOfType([NotNull] object? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) { if (value is not T result) { From 5efc683279f8c0bfe67aea29b038a1ffe516c2fb Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Fri, 25 Oct 2024 09:46:33 -0700 Subject: [PATCH 121/133] [otlp] OTLP Exporter Custom serializer Part 2 - Resources (#5916) Co-authored-by: Mikel Blanchard --- .../ProtobufOtlpFieldNumberConstants.cs | 90 +++++++++++ .../ProtobufOtlpResourceSerializer.cs | 80 ++++++++++ .../Serializer/ProtobufOtlpTagWriter.cs | 150 ++++++++++++++++++ .../Serializer/ProtobufSerializer.cs | 85 +++++++++- .../ResourceProtoSerializerTests.cs | 66 ++++++++ .../OtlpResourceTests.cs | 30 +++- 6 files changed, 496 insertions(+), 5 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpFieldNumberConstants.cs create mode 100644 src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs create mode 100644 test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ResourceProtoSerializerTests.cs diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpFieldNumberConstants.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpFieldNumberConstants.cs new file mode 100644 index 00000000000..7c4be7d8e86 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpFieldNumberConstants.cs @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; + +internal static class ProtobufOtlpFieldNumberConstants +{ + // Resource spans +#pragma warning disable SA1310 // Field names should not contain underscore + internal const int ResourceSpans_Resource = 1; + internal const int ResourceSpans_Scope_Spans = 2; + internal const int ResourceSpans_Schema_Url = 3; + + // Resource + internal const int Resource_Attributes = 1; + + // ScopeSpans + internal const int ScopeSpans_Scope = 1; + internal const int ScopeSpans_Span = 2; + internal const int ScopeSpans_Schema_Url = 3; + + // Span + internal const int Span_Trace_Id = 1; + internal const int Span_Span_Id = 2; + internal const int Span_Trace_State = 3; + internal const int Span_Parent_Span_Id = 4; + internal const int Span_Name = 5; + internal const int Span_Kind = 6; + internal const int Span_Start_Time_Unix_Nano = 7; + internal const int Span_End_Time_Unix_Nano = 8; + internal const int Span_Attributes = 9; + internal const int Span_Dropped_Attributes_Count = 10; + internal const int Span_Events = 11; + internal const int Span_Dropped_Events_Count = 12; + internal const int Span_Links = 13; + internal const int Span_Dropped_Links_Count = 14; + internal const int Span_Status = 15; + internal const int Span_Flags = 16; + + // SpanKind + internal const int SpanKind_Internal = 2; + internal const int SpanKind_Server = 3; + internal const int SpanKind_Client = 4; + internal const int SpanKind_Producer = 5; + internal const int SpanKind_Consumer = 6; + + // Events + internal const int Event_Time_Unix_Nano = 1; + internal const int Event_Name = 2; + internal const int Event_Attributes = 3; + internal const int Event_Dropped_Attributes_Count = 4; + + // Links + internal const int Link_Trace_Id = 1; + internal const int Link_Span_Id = 2; + internal const int Link_Trace_State = 3; + internal const int Link_Attributes = 4; + internal const int Link_Dropped_Attributes_Count = 5; + internal const int Link_Flags = 6; + + // Status + internal const int Status_Message = 2; + internal const int Status_Code = 3; + + // StatusCode + internal const int StatusCode_Unset = 0; + internal const int StatusCode_Ok = 1; + internal const int StatusCode_Error = 2; + + // InstrumentationScope + internal const int InstrumentationScope_Name = 1; + internal const int InstrumentationScope_Version = 2; + + // KeyValue + internal const int KeyValue_Key = 1; + internal const int KeyValue_Value = 2; + + // AnyValue + internal const int AnyValue_String_Value = 1; + internal const int AnyValue_Bool_Value = 2; + internal const int AnyValue_Int_Value = 3; + internal const int AnyValue_Double_Value = 4; + internal const int AnyValue_Array_Value = 5; + internal const int AnyValue_Kvlist_Value = 6; + internal const int AnyValue_Bytes_Value = 7; + + internal const int ArrayValue_Value = 1; +#pragma warning restore SA1310 // Field names should not contain underscore +} + diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs new file mode 100644 index 00000000000..9667c4328f5 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs @@ -0,0 +1,80 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; + +internal static class ProtobufOtlpResourceSerializer +{ + private const int ReserveSizeForLength = 4; + + private static readonly string DefaultServiceName = ResourceBuilder.CreateDefault().Build().Attributes.FirstOrDefault( + kvp => kvp.Key == ResourceSemanticConventions.AttributeServiceName).Value as string ?? "unknown_service"; + + internal static int WriteResource(byte[] buffer, int writePosition, Resource? resource) + { + ProtobufOtlpTagWriter.OtlpTagWriterState otlpTagWriterState = new ProtobufOtlpTagWriter.OtlpTagWriterState + { + Buffer = buffer, + WritePosition = writePosition, + }; + + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.ResourceSpans_Resource, ProtobufWireType.LEN); + int resourceLengthPosition = otlpTagWriterState.WritePosition; + otlpTagWriterState.WritePosition += ReserveSizeForLength; + + bool isServiceNamePresent = false; + if (resource != null && resource != Resource.Empty) + { + if (resource.Attributes is IReadOnlyList> resourceAttributesList) + { + for (int i = 0; i < resourceAttributesList.Count; i++) + { + var attribute = resourceAttributesList[i]; + if (attribute.Key == ResourceSemanticConventions.AttributeServiceName) + { + isServiceNamePresent = true; + } + + otlpTagWriterState = ProcessResourceAttribute(ref otlpTagWriterState, attribute); + } + } + else + { + foreach (var attribute in resource.Attributes) + { + if (attribute.Key == ResourceSemanticConventions.AttributeServiceName) + { + isServiceNamePresent = true; + } + + otlpTagWriterState = ProcessResourceAttribute(ref otlpTagWriterState, attribute); + } + } + } + + if (!isServiceNamePresent) + { + otlpTagWriterState = ProcessResourceAttribute(ref otlpTagWriterState, new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, DefaultServiceName)); + } + + var resourceLength = otlpTagWriterState.WritePosition - (resourceLengthPosition + ReserveSizeForLength); + ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, resourceLengthPosition, resourceLength); + + return otlpTagWriterState.WritePosition; + } + + private static ProtobufOtlpTagWriter.OtlpTagWriterState ProcessResourceAttribute(ref ProtobufOtlpTagWriter.OtlpTagWriterState otlpTagWriterState, KeyValuePair attribute) + { + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.Resource_Attributes, ProtobufWireType.LEN); + int resourceAttributesLengthPosition = otlpTagWriterState.WritePosition; + otlpTagWriterState.WritePosition += ReserveSizeForLength; + + ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, attribute.Key, attribute.Value); + + var resourceAttributesLength = otlpTagWriterState.WritePosition - (resourceAttributesLengthPosition + ReserveSizeForLength); + ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, resourceAttributesLengthPosition, resourceAttributesLength); + return otlpTagWriterState; + } +} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs new file mode 100644 index 00000000000..65fef4fe110 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs @@ -0,0 +1,150 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; + +internal sealed class ProtobufOtlpTagWriter : TagWriter +{ + private ProtobufOtlpTagWriter() + : base(new OtlpArrayTagWriter()) + { + } + + public static ProtobufOtlpTagWriter Instance { get; } = new(); + + protected override void WriteIntegralTag(ref OtlpTagWriterState state, string key, long value) + { + // Write KeyValue tag + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.KeyValue_Key, key); + + // Write KeyValue.Value tag, length and value. + var size = ProtobufSerializer.ComputeVarInt64Size((ulong)value) + 1; // ComputeVarint64Size(ulong) + TagSize + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, size, ProtobufOtlpFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); + state.WritePosition = ProtobufSerializer.WriteInt64WithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_Int_Value, (ulong)value); + } + + protected override void WriteFloatingPointTag(ref OtlpTagWriterState state, string key, double value) + { + // Write KeyValue tag + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.KeyValue_Key, key); + + // Write KeyValue.Value tag, length and value. + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 9, ProtobufOtlpFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // 8 + TagSize + state.WritePosition = ProtobufSerializer.WriteDoubleWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_Double_Value, value); + } + + protected override void WriteBooleanTag(ref OtlpTagWriterState state, string key, bool value) + { + // Write KeyValue tag + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.KeyValue_Key, key); + + // Write KeyValue.Value tag, length and value. + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 2, ProtobufOtlpFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // 1 + TagSize + state.WritePosition = ProtobufSerializer.WriteBoolWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_Bool_Value, value); + } + + protected override void WriteStringTag(ref OtlpTagWriterState state, string key, ReadOnlySpan value) + { + // Write KeyValue tag + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.KeyValue_Key, key); + + // Write KeyValue.Value tag, length and value. + var numberOfUtf8CharsInString = ProtobufSerializer.GetNumberOfUtf8CharsInString(value); + var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)numberOfUtf8CharsInString); + + // length = numberOfUtf8CharsInString + tagSize + length field size. + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); + } + + protected override void WriteArrayTag(ref OtlpTagWriterState state, string key, ref OtlpTagWriterArrayState value) + { + // TODO: Expand OtlpTagWriterArrayState.Buffer on IndexOutOfRangeException. + // Write KeyValue tag + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.KeyValue_Key, key); + + // Write KeyValue.Value tag and length + var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)value.WritePosition); + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, value.WritePosition + 1 + serializedLengthSize, ProtobufOtlpFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // Array content length + Array tag size + length field size + + // Write Array tag and length + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, value.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_Array_Value, ProtobufWireType.LEN); + Buffer.BlockCopy(value.Buffer, 0, state.Buffer, state.WritePosition, value.WritePosition); + state.WritePosition += value.WritePosition; + } + + protected override void OnUnsupportedTagDropped( + string tagKey, + string tagValueTypeFullName) => OpenTelemetryProtocolExporterEventSource.Log.UnsupportedAttributeType( + tagValueTypeFullName, + tagKey); + + internal struct OtlpTagWriterState + { + public byte[] Buffer; + public int WritePosition; + } + + internal struct OtlpTagWriterArrayState + { + public byte[] Buffer; + public int WritePosition; + } + + private sealed class OtlpArrayTagWriter : ArrayTagWriter + { + [ThreadStatic] + private static byte[]? threadBuffer; + + public override OtlpTagWriterArrayState BeginWriteArray() + { + threadBuffer ??= new byte[2048]; + + return new OtlpTagWriterArrayState + { + Buffer = threadBuffer, + WritePosition = 0, + }; + } + + public override void WriteNullValue(ref OtlpTagWriterArrayState state) + { + } + + public override void WriteIntegralValue(ref OtlpTagWriterArrayState state, long value) + { + var size = ProtobufSerializer.ComputeVarInt64Size((ulong)value) + 1; + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, size, ProtobufOtlpFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition = ProtobufSerializer.WriteInt64WithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_Int_Value, (ulong)value); + } + + public override void WriteFloatingPointValue(ref OtlpTagWriterArrayState state, double value) + { + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 9, ProtobufOtlpFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition = ProtobufSerializer.WriteDoubleWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_Double_Value, value); + } + + public override void WriteBooleanValue(ref OtlpTagWriterArrayState state, bool value) + { + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 2, ProtobufOtlpFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition = ProtobufSerializer.WriteBoolWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_Bool_Value, value); + } + + public override void WriteStringValue(ref OtlpTagWriterArrayState state, ReadOnlySpan value) + { + // Write KeyValue.Value tag, length and value. + var numberOfUtf8CharsInString = ProtobufSerializer.GetNumberOfUtf8CharsInString(value); + var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)numberOfUtf8CharsInString); + + // length = numberOfUtf8CharsInString + tagSize + length field size. + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); + } + + public override void EndWriteArray(ref OtlpTagWriterArrayState state) + { + } + } +} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs index b8bd31b682a..763a56db97c 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs @@ -198,6 +198,77 @@ internal static int WriteDoubleWithTag(byte[] buffer, int writePosition, int fie return writePosition; } + /// + /// Computes the number of bytes required to encode a 64-bit unsigned integer in Protocol Buffers' varint format. + /// + /// + /// Protocol Buffers uses variable-length encoding (varint) to serialize integers efficiently: + /// - Each byte uses 7 bits to encode the number and 1 bit (MSB) to indicate if more bytes follow + /// - The algorithm checks how many significant bits the number contains by shifting and masking + /// - Numbers are encoded in groups of 7 bits, from least to most significant + /// - Each group requires one byte, so the method returns the number of 7-bit groups needed + /// + /// Examples: + /// - Values 0-127 (7 bits) require 1 byte + /// - Values 128-16383 (14 bits) require 2 bytes + /// - Values 16384-2097151 (21 bits) require 3 bytes + /// And so on... + /// + /// For more details, see: + /// - Protocol Buffers encoding reference: https://developers.google.com/protocol-buffers/docs/encoding#varints. + /// + /// The unsigned 64-bit integer to be encoded. + /// Number of bytes needed to encode the value. + internal static int ComputeVarInt64Size(ulong value) + { + if ((value & (0xffffffffffffffffL << 7)) == 0) + { + return 1; + } + + if ((value & (0xffffffffffffffffL << 14)) == 0) + { + return 2; + } + + if ((value & (0xffffffffffffffffL << 21)) == 0) + { + return 3; + } + + if ((value & (0xffffffffffffffffL << 28)) == 0) + { + return 4; + } + + if ((value & (0xffffffffffffffffL << 35)) == 0) + { + return 5; + } + + if ((value & (0xffffffffffffffffL << 42)) == 0) + { + return 6; + } + + if ((value & (0xffffffffffffffffL << 49)) == 0) + { + return 7; + } + + if ((value & (0xffffffffffffffffL << 56)) == 0) + { + return 8; + } + + if ((value & (0xffffffffffffffffL << 63)) == 0) + { + return 9; + } + + return 10; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, string value) { @@ -207,7 +278,7 @@ internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fie } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, ReadOnlySpan value) + internal static int GetNumberOfUtf8CharsInString(ReadOnlySpan value) { #if NETFRAMEWORK || NETSTANDARD2_0 int numberOfUtf8CharsInString; @@ -221,7 +292,19 @@ internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fie #else int numberOfUtf8CharsInString = Utf8Encoding.GetByteCount(value); #endif + return numberOfUtf8CharsInString; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, ReadOnlySpan value) + { + var numberOfUtf8CharsInString = GetNumberOfUtf8CharsInString(value); + return WriteStringWithTag(buffer, writePosition, fieldNumber, numberOfUtf8CharsInString, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, int numberOfUtf8CharsInString, ReadOnlySpan value) + { writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN); writePosition = WriteLength(buffer, writePosition, numberOfUtf8CharsInString); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ResourceProtoSerializerTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ResourceProtoSerializerTests.cs new file mode 100644 index 00000000000..0deb4c585a5 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ResourceProtoSerializerTests.cs @@ -0,0 +1,66 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; +using OpenTelemetry.Proto.Trace.V1; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.Implementation.Serializer; + +public class ResourceProtoSerializerTests +{ + [Fact] + public void CreateResource_SupportedAttributeTypes() + { + // Arrange + byte[] buffer = new byte[1024]; + var attributes = new Dictionary + { + { "string", "stringValue" }, + { "bool", true }, + { "double", 0.1d }, + { "long", 1L }, + + // int and float supported by conversion to long and double + { "int", 1 }, + { "short", (short)1 }, + { "float", 0.1f }, + + // natively supported array types + { "string arr", new string[] { "stringValue1", "stringValue2" } }, + { "bool arr", new bool[] { true } }, + { "double arr", new double[] { 0.1d } }, + { "long arr", new long[] { 1L } }, + + // have to convert to other primitive array types + { "int arr", new int[] { 1, 2, 3 } }, + { "short arr", new short[] { (short)1 } }, + { "float arr", new float[] { 0.1f } }, + }; + + // Act + var resource = ResourceBuilder.CreateEmpty().AddAttributes(attributes).Build(); + var writePosition = ProtobufOtlpResourceSerializer.WriteResource(buffer, 0, resource); + var otlpResource = resource.ToOtlpResource(); + var expectedResourceSpans = new ResourceSpans + { + Resource = otlpResource, + }; + + // Deserialize the ResourceSpans and validate the attributes. + ResourceSpans actualResourceSpans; + using (var stream = new MemoryStream(buffer, 0, writePosition)) + { + actualResourceSpans = ResourceSpans.Parser.ParseFrom(stream); + } + + // Assert + Assert.Equal(expectedResourceSpans.Resource.Attributes.Count, actualResourceSpans.Resource.Attributes.Count); + foreach (var actualAttribute in actualResourceSpans.Resource.Attributes) + { + Assert.Contains(actualAttribute, expectedResourceSpans.Resource.Attributes); + } + } +} diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpResourceTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpResourceTests.cs index 4a82310103f..57b1c58fdf2 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpResourceTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpResourceTests.cs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; +using OpenTelemetry.Proto.Trace.V1; using OpenTelemetry.Resources; using Xunit; @@ -10,9 +12,11 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; public class OtlpResourceTests { [Theory] - [InlineData(true)] - [InlineData(false)] - public void ToOtlpResourceTest(bool includeServiceNameInResource) + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(true, true)] + [InlineData(false, true)] + public void ToOtlpResourceTest(bool includeServiceNameInResource, bool useCustomSerializer) { // Targeted test to cover OTel Resource to OTLP Resource // conversion, independent of signals. @@ -23,7 +27,25 @@ public void ToOtlpResourceTest(bool includeServiceNameInResource) } var resource = resourceBuilder.Build(); - var otlpResource = resource.ToOtlpResource(); + Proto.Resource.V1.Resource otlpResource; + + if (useCustomSerializer) + { + byte[] buffer = new byte[1024]; + var writePosition = ProtobufOtlpResourceSerializer.WriteResource(buffer, 0, resource); + + // Deserialize the ResourceSpans and validate the attributes. + using (var stream = new MemoryStream(buffer, 0, writePosition)) + { + var resourceSpans = ResourceSpans.Parser.ParseFrom(stream); + otlpResource = resourceSpans.Resource; + } + } + else + { + otlpResource = resource.ToOtlpResource(); + } + if (includeServiceNameInResource) { Assert.Contains(otlpResource.Attributes, (kvp) => kvp.Key == ResourceSemanticConventions.AttributeServiceName && kvp.Value.StringValue == "service-name"); From 9f41eadf03f3dcc5e76c686b61fb39849f046312 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 25 Oct 2024 10:58:18 -0700 Subject: [PATCH 122/133] [sdk-metrics] Promote overflow attribute from experimental to stable (#5909) Co-authored-by: Reiley Yang Co-authored-by: Mikel Blanchard --- docs/metrics/README.md | 25 ++--- src/OpenTelemetry/CHANGELOG.md | 25 +++++ src/OpenTelemetry/Metrics/AggregatorStore.cs | 47 ++------- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 10 +- src/OpenTelemetry/Metrics/Metric.cs | 2 - .../Metrics/Reader/MetricReaderExt.cs | 5 - .../Metrics/AggregatorTestsBase.cs | 29 +----- .../Metrics/MetricApiTestsBase.cs | 32 +----- .../MetricOverflowAttributeTestsBase.cs | 98 ------------------- .../Metrics/MetricPointReclaimTestsBase.cs | 20 +--- .../Metrics/MetricSnapshotTestsBase.cs | 23 +---- .../Metrics/MetricTestsBase.cs | 1 - 12 files changed, 60 insertions(+), 257 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index db91e62f529..0394f63451b 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -10,11 +10,13 @@ * [Instruments](#instruments) * [MeterProvider Management](#meterprovider-management) * [Memory Management](#memory-management) + * [Example](#example) * [Pre-Aggregation](#pre-aggregation) * [Cardinality Limits](#cardinality-limits) * [Memory Preallocation](#memory-preallocation) * [Metrics Correlation](#metrics-correlation) * [Metrics Enrichment](#metrics-enrichment) +* [Common issues that lead to missing metrics](#common-issues-that-lead-to-missing-metrics) @@ -386,22 +388,13 @@ and the `MetricStreamConfiguration.CardinalityLimit` setting. Refer to this [doc](../../docs/metrics/customizing-the-sdk/README.md#changing-the-cardinality-limit-for-a-metric) for more information. -Given a metric, once the cardinality limit is reached, any new measurement which -cannot be independently aggregated because of the limit will be dropped or -aggregated using the [overflow -attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) -(if enabled). When NOT using the overflow attribute feature a warning is written -to the [self-diagnostic log](../../src/OpenTelemetry/README.md#self-diagnostics) -the first time an overflow is detected for a given metric. - -> [!NOTE] -> Overflow attribute was introduced in OpenTelemetry .NET - [1.6.0-rc.1](../../src/OpenTelemetry/CHANGELOG.md#160-rc1). It is currently an - experimental feature which can be turned on by setting the environment - variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE=true`. Once - the [OpenTelemetry - Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) - become stable, this feature will be turned on by default. +Given a metric, once the cardinality limit is reached, any new measurement +that could not be independently aggregated will be aggregated using the +[overflow attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute). +In versions prior to 1.10.0, the default behavior when cardinality limit was +reached was to drop the measurement. Users had the ability to opt-in to use +overflow attribute instead, but this behavior is the default and the only +allowed behavior starting with version 1.10.0. When [Delta Aggregation Temporality](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#temporality) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index d14170c35f1..0f2bbd74d7c 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,6 +6,31 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Promoted overflow attribute from experimental to stable and removed the + `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` environment variable. + + **Previous Behavior:** + By default, when the cardinality limit was reached, measurements were dropped, + and an internal log was emitted the first time this occurred. Users could + opt-in to experimental overflow attribute feature with + `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE=true`. + With this setting, the SDK would use an overflow attribute + (`otel.metric.overflow = true`) to aggregate measurements instead of dropping + measurements. No internal log was emitted in this case. + + **New Behavior:** + The SDK now always uses the overflow attribute (`otel.metric.overflow = true`) + to aggregate measurements when the cardinality limit is reached. The previous + approach of dropping measurements has been removed. No internal logs are + emitted when the limit is hit. + + The default cardinality limit remains 2000 per metric. To set the cardinality + limit for an individual metric, use the [changing cardinality limit for a + Metric](../../docs/metrics/customizing-the-sdk/README.md#changing-the-cardinality-limit-for-a-metric). + + There is NO ability to revert to old behavior. + ([#5909](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5909)) + ## 1.10.0-beta.1 Released 2024-Sep-30 diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index fbbd598a67a..b7d560b559f 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -22,13 +22,11 @@ internal sealed class AggregatorStore internal readonly bool OutputDelta; internal readonly bool OutputDeltaWithUnusedMetricPointReclaimEnabled; internal readonly int NumberOfMetricPoints; - internal readonly bool EmitOverflowAttribute; internal readonly ConcurrentDictionary? TagsToMetricPointIndexDictionaryDelta; internal readonly Func? ExemplarReservoirFactory; internal long DroppedMeasurements = 0; private const ExemplarFilterType DefaultExemplarFilter = ExemplarFilterType.AlwaysOff; - private static readonly string MetricPointCapHitFixMessage = "Consider opting in for the experimental SDK feature to emit all the throttled metrics under the overflow attribute by setting env variable OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE = true. You could also modify instrumentation to reduce the number of unique key/value pair combinations. Or use Views to drop unwanted tags. Or use MeterProviderBuilder.SetMaxMetricPointsPerMetricStream to set higher limit."; private static readonly Comparison> DimensionComparisonDelegate = (x, y) => x.Key.CompareTo(y.Key); private readonly Lock lockZeroTags = new(); @@ -42,7 +40,6 @@ internal sealed class AggregatorStore new(); private readonly string name; - private readonly string metricPointCapHitMessage; private readonly MetricPoint[] metricPoints; private readonly int[] currentMetricPointBatch; private readonly AggregationType aggType; @@ -56,7 +53,6 @@ internal sealed class AggregatorStore private int metricPointIndex = 0; private int batchSize = 0; - private int metricCapHitMessageLogged; private bool zeroTagMetricPointInitialized; private bool overflowTagMetricPointInitialized; @@ -65,7 +61,6 @@ internal AggregatorStore( AggregationType aggType, AggregationTemporality temporality, int cardinalityLimit, - bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, ExemplarFilterType? exemplarFilter = null, Func? exemplarReservoirFactory = null) @@ -77,7 +72,6 @@ internal AggregatorStore( // Previously, these were included within the original cardinalityLimit, but now they are explicitly added to enhance clarity. this.NumberOfMetricPoints = cardinalityLimit + 2; - this.metricPointCapHitMessage = $"Maximum MetricPoints limit reached for this Metric stream. Configured limit: {cardinalityLimit}"; this.metricPoints = new MetricPoint[this.NumberOfMetricPoints]; this.currentMetricPointBatch = new int[this.NumberOfMetricPoints]; this.aggType = aggType; @@ -105,8 +99,6 @@ internal AggregatorStore( this.tagsKeysInterestingCount = hs.Count; } - this.EmitOverflowAttribute = emitOverflowAttribute; - this.exemplarFilter = exemplarFilter ?? DefaultExemplarFilter; Debug.Assert( this.exemplarFilter == ExemplarFilterType.AlwaysOff @@ -245,17 +237,14 @@ internal void SnapshotDeltaWithMetricPointReclaim() this.batchSize++; } - if (this.EmitOverflowAttribute) + // TakeSnapshot for the MetricPoint for overflow + ref var metricPointForOverflow = ref this.metricPoints[1]; + if (metricPointForOverflow.MetricPointStatus != MetricPointStatus.NoCollectPending) { - // TakeSnapshot for the MetricPoint for overflow - ref var metricPointForOverflow = ref this.metricPoints[1]; - if (metricPointForOverflow.MetricPointStatus != MetricPointStatus.NoCollectPending) - { - this.TakeMetricPointSnapshot(ref metricPointForOverflow, outputDelta: true); + this.TakeMetricPointSnapshot(ref metricPointForOverflow, outputDelta: true); - this.currentMetricPointBatch[this.batchSize] = 1; - this.batchSize++; - } + this.currentMetricPointBatch[this.batchSize] = 1; + this.batchSize++; } // Index 0 and 1 are reserved for no tags and overflow @@ -994,16 +983,8 @@ private void UpdateLongMetricPoint(int metricPointIndex, long value, ReadOnlySpa if (metricPointIndex < 0) { Interlocked.Increment(ref this.DroppedMeasurements); - - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - } - else if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); return; } @@ -1049,16 +1030,8 @@ private void UpdateDoubleMetricPoint(int metricPointIndex, double value, ReadOnl if (metricPointIndex < 0) { Interlocked.Increment(ref this.DroppedMeasurements); - - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - } - else if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); return; } diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 0ec16a9c20a..a83666bb4c3 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -13,7 +13,6 @@ namespace OpenTelemetry.Metrics; internal sealed class MeterProviderSdk : MeterProvider { - internal const string EmitOverFlowAttributeConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE"; internal const string ReclaimUnusedMetricPointsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS"; internal const string ExemplarFilterConfigKey = "OTEL_METRICS_EXEMPLAR_FILTER"; internal const string ExemplarFilterHistogramsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EXEMPLAR_FILTER_HISTOGRAMS"; @@ -22,7 +21,6 @@ internal sealed class MeterProviderSdk : MeterProvider internal readonly IDisposable? OwnedServiceProvider; internal int ShutdownCount; internal bool Disposed; - internal bool EmitOverflowAttribute; internal bool ReclaimUnusedMetricPoints; internal ExemplarFilterType? ExemplarFilter; internal ExemplarFilterType? ExemplarFilterForHistograms; @@ -75,7 +73,7 @@ internal MeterProviderSdk( this.viewConfigs = state.ViewConfigs; OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent( - $"MeterProvider configuration: {{MetricLimit={state.MetricLimit}, CardinalityLimit={state.CardinalityLimit}, EmitOverflowAttribute={this.EmitOverflowAttribute}, ReclaimUnusedMetricPoints={this.ReclaimUnusedMetricPoints}, ExemplarFilter={this.ExemplarFilter}, ExemplarFilterForHistograms={this.ExemplarFilterForHistograms}}}."); + $"MeterProvider configuration: {{MetricLimit={state.MetricLimit}, CardinalityLimit={state.CardinalityLimit}, ReclaimUnusedMetricPoints={this.ReclaimUnusedMetricPoints}, ExemplarFilter={this.ExemplarFilter}, ExemplarFilterForHistograms={this.ExemplarFilterForHistograms}}}."); foreach (var reader in state.Readers) { @@ -86,7 +84,6 @@ internal MeterProviderSdk( reader.ApplyParentProviderSettings( state.MetricLimit, state.CardinalityLimit, - this.EmitOverflowAttribute, this.ReclaimUnusedMetricPoints, this.ExemplarFilter, this.ExemplarFilterForHistograms); @@ -486,11 +483,6 @@ protected override void Dispose(bool disposing) private void ApplySpecificationConfigurationKeys(IConfiguration configuration) { - if (configuration.TryGetBoolValue(OpenTelemetrySdkEventSource.Log, EmitOverFlowAttributeConfigKey, out this.EmitOverflowAttribute)) - { - OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Overflow attribute feature enabled via configuration."); - } - if (configuration.TryGetBoolValue(OpenTelemetrySdkEventSource.Log, ReclaimUnusedMetricPointsConfigKey, out this.ReclaimUnusedMetricPoints)) { OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Reclaim unused metric point feature enabled via configuration."); diff --git a/src/OpenTelemetry/Metrics/Metric.cs b/src/OpenTelemetry/Metrics/Metric.cs index 7ecb10e519f..38abf4cc622 100644 --- a/src/OpenTelemetry/Metrics/Metric.cs +++ b/src/OpenTelemetry/Metrics/Metric.cs @@ -70,7 +70,6 @@ internal Metric( MetricStreamIdentity instrumentIdentity, AggregationTemporality temporality, int cardinalityLimit, - bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, ExemplarFilterType? exemplarFilter = null, Func? exemplarReservoirFactory = null) @@ -193,7 +192,6 @@ internal Metric( aggType, temporality, cardinalityLimit, - emitOverflowAttribute, shouldReclaimUnusedMetricPoints, exemplarFilter, exemplarReservoirFactory); diff --git a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs index f22208c8b61..194383a37a8 100644 --- a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs @@ -22,7 +22,6 @@ public abstract partial class MetricReader private Metric?[]? metrics; private Metric[]? metricsCurrentBatch; private int metricIndex = -1; - private bool emitOverflowAttribute; private bool reclaimUnusedMetricPoints; private ExemplarFilterType? exemplarFilter; private ExemplarFilterType? exemplarFilterForHistograms; @@ -82,7 +81,6 @@ internal virtual List AddMetricWithNoViews(Instrument instrument) metricStreamIdentity, this.GetAggregationTemporality(metricStreamIdentity.InstrumentType), this.cardinalityLimit, - this.emitOverflowAttribute, this.reclaimUnusedMetricPoints, exemplarFilter); } @@ -164,7 +162,6 @@ internal virtual List AddMetricWithViews(Instrument instrument, List AddMetricWithViews(Instrument instrument, List>()); @@ -525,15 +520,7 @@ public ThreadArguments(MetricPoint histogramPoint, ManualResetEvent mreToEnsureA public class AggregatorTests : AggregatorTestsBase { public AggregatorTests() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: false) - { - } -} - -public class AggregatorTestsWithOverflowAttribute : AggregatorTestsBase -{ - public AggregatorTestsWithOverflowAttribute() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: false) + : base(shouldReclaimUnusedMetricPoints: false) { } } @@ -541,15 +528,7 @@ public AggregatorTestsWithOverflowAttribute() public class AggregatorTestsWithReclaimAttribute : AggregatorTestsBase { public AggregatorTestsWithReclaimAttribute() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: true) - { - } -} - -public class AggregatorTestsWithBothReclaimAndOverflowAttributes : AggregatorTestsBase -{ - public AggregatorTestsWithBothReclaimAndOverflowAttributes() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: true) + : base(shouldReclaimUnusedMetricPoints: true) { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs index c84b1b1ef7d..9c6735f7bcb 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs @@ -23,8 +23,8 @@ public abstract class MetricApiTestsBase : MetricTestsBase private static readonly int NumberOfMetricUpdateByEachThread = 100000; private readonly ITestOutputHelper output; - protected MetricApiTestsBase(ITestOutputHelper output, bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) - : base(BuildConfiguration(emitOverflowAttribute, shouldReclaimUnusedMetricPoints)) + protected MetricApiTestsBase(ITestOutputHelper output, bool shouldReclaimUnusedMetricPoints) + : base(BuildConfiguration(shouldReclaimUnusedMetricPoints)) { this.output = output; } @@ -1410,7 +1410,6 @@ int MetricPointCount() enumerator.MoveNext(); // Second element reserved for overflow attribute. // Validate second element is overflow attribute. - // Overflow attribute is behind experimental flag. So, it is not guaranteed to be present. var tagEnumerator = enumerator.Current.Tags.GetEnumerator(); tagEnumerator.MoveNext(); if (!tagEnumerator.Current.Key.Contains("otel.metric.overflow")) @@ -1704,15 +1703,10 @@ public void GaugeHandlesNoNewMeasurementsCorrectlyWithTemporality(MetricReaderTe } } - internal static IConfiguration BuildConfiguration(bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) + internal static IConfiguration BuildConfiguration(bool shouldReclaimUnusedMetricPoints) { var configurationData = new Dictionary(); - if (emitOverflowAttribute) - { - configurationData[EmitOverFlowAttributeConfigKey] = "true"; - } - if (shouldReclaimUnusedMetricPoints) { configurationData[ReclaimUnusedMetricPointsConfigKey] = "true"; @@ -1894,15 +1888,7 @@ public UpdateThreadArguments(ManualResetEvent mreToBlockUpdateThread, ManualRese public class MetricApiTest : MetricApiTestsBase { public MetricApiTest(ITestOutputHelper output) - : base(output, emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: false) - { - } -} - -public class MetricApiTestWithOverflowAttribute : MetricApiTestsBase -{ - public MetricApiTestWithOverflowAttribute(ITestOutputHelper output) - : base(output, emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: false) + : base(output, shouldReclaimUnusedMetricPoints: false) { } } @@ -1910,15 +1896,7 @@ public MetricApiTestWithOverflowAttribute(ITestOutputHelper output) public class MetricApiTestWithReclaimAttribute : MetricApiTestsBase { public MetricApiTestWithReclaimAttribute(ITestOutputHelper output) - : base(output, emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: true) - { - } -} - -public class MetricApiTestWithBothOverflowAndReclaimAttributes : MetricApiTestsBase -{ - public MetricApiTestWithBothOverflowAndReclaimAttributes(ITestOutputHelper output) - : base(output, emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: true) + : base(output, shouldReclaimUnusedMetricPoints: true) { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs index 43d91819232..6145de4d98a 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs @@ -16,7 +16,6 @@ public abstract class MetricOverflowAttributeTestsBase private readonly bool shouldReclaimUnusedMetricPoints; private readonly Dictionary configurationData = new() { - [MetricTestsBase.EmitOverFlowAttributeConfigKey] = "true", }; private readonly IConfiguration configuration; @@ -35,103 +34,6 @@ public MetricOverflowAttributeTestsBase(bool shouldReclaimUnusedMetricPoints) .Build(); } - [Theory] - [InlineData("false", false)] - [InlineData("False", false)] - [InlineData("FALSE", false)] - [InlineData("true", true)] - [InlineData("True", true)] - [InlineData("TRUE", true)] - public void TestEmitOverflowAttributeConfigWithEnvVar(string value, bool isEmitOverflowAttributeKeySet) - { - // Clear the environment variable value first - Environment.SetEnvironmentVariable(MetricTestsBase.EmitOverFlowAttributeConfigKey, null); - - // Set the environment variable to the value provided in the test input - Environment.SetEnvironmentVariable(MetricTestsBase.EmitOverFlowAttributeConfigKey, value); - - var exportedItems = new List(); - - var meter = new Meter(Utils.GetCurrentMethodName()); - var counter = meter.CreateCounter("TestCounter"); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter(meter.Name) - .AddInMemoryExporter(exportedItems) - .Build(); - - counter.Add(10); - - meterProvider.ForceFlush(); - - Assert.Single(exportedItems); - Assert.Equal(isEmitOverflowAttributeKeySet, exportedItems[0].AggregatorStore.EmitOverflowAttribute); - } - - [Theory] - [InlineData("false", false)] - [InlineData("False", false)] - [InlineData("FALSE", false)] - [InlineData("true", true)] - [InlineData("True", true)] - [InlineData("TRUE", true)] - public void TestEmitOverflowAttributeConfigWithOtherConfigProvider(string value, bool isEmitOverflowAttributeKeySet) - { - var exportedItems = new List(); - - var meter = new Meter(Utils.GetCurrentMethodName()); - var counter = meter.CreateCounter("TestCounter"); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .ConfigureServices(services => - { - var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [MetricTestsBase.EmitOverFlowAttributeConfigKey] = value }) - .Build(); - - services.AddSingleton(configuration); - }) - .AddMeter(meter.Name) - .AddInMemoryExporter(exportedItems) - .Build(); - - counter.Add(10); - - meterProvider.ForceFlush(); - - Assert.Single(exportedItems); - Assert.Equal(isEmitOverflowAttributeKeySet, exportedItems[0].AggregatorStore.EmitOverflowAttribute); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - [InlineData(10)] - public void EmitOverflowAttributeIsNotDependentOnMaxMetricPoints(int maxMetricPoints) - { - var exportedItems = new List(); - - var meter = new Meter(Utils.GetCurrentMethodName()); - var counter = meter.CreateCounter("TestCounter"); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .ConfigureServices(services => - { - services.AddSingleton(this.configuration); - }) - .SetMaxMetricPointsPerMetricStream(maxMetricPoints) - .AddMeter(meter.Name) - .AddInMemoryExporter(exportedItems) - .Build(); - - counter.Add(10); - - meterProvider.ForceFlush(); - - Assert.Single(exportedItems); - Assert.True(exportedItems[0].AggregatorStore.EmitOverflowAttribute); - } - [Theory] [InlineData(MetricReaderTemporalityPreference.Delta)] [InlineData(MetricReaderTemporalityPreference.Cumulative)] diff --git a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs index f455967884a..effe208eda3 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs @@ -20,13 +20,8 @@ public abstract class MetricPointReclaimTestsBase private readonly IConfiguration configuration; - protected MetricPointReclaimTestsBase(bool emitOverflowAttribute) + protected MetricPointReclaimTestsBase() { - if (emitOverflowAttribute) - { - this.configurationData[MetricTestsBase.EmitOverFlowAttributeConfigKey] = "true"; - } - this.configuration = new ConfigurationBuilder() .AddInMemoryCollection(this.configurationData) .Build(); @@ -213,8 +208,7 @@ public void MeasurementsAreAggregatedEvenAfterTheyAreDropped(bool emitMetricWith .Build(); // Add 10 distinct combinations of dimensions to surpass the max metric points limit of 10. - // Note that one MetricPoint is reserved for zero tags and one MetricPoint is optionally - // reserved for the overflow tag depending on the user's input. + // Note that one MetricPoint is reserved for zero tags and one MetricPoint is reserved for the overflow tag. // This would lead to dropping a few measurements. We want to make sure that they can still be // aggregated later on when there are free MetricPoints available. for (int i = 0; i < 10; i++) @@ -333,15 +327,7 @@ public override ExportResult Export(in Batch batch) public class MetricPointReclaimTests : MetricPointReclaimTestsBase { public MetricPointReclaimTests() - : base(emitOverflowAttribute: false) - { - } -} - -public class MetricPointReclaimTestsWithEmitOverflowAttribute : MetricPointReclaimTestsBase -{ - public MetricPointReclaimTestsWithEmitOverflowAttribute() - : base(emitOverflowAttribute: true) + : base() { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs index 08ce90ffe44..54b8ed95868 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs @@ -16,10 +16,9 @@ public abstract class MetricSnapshotTestsBase { private readonly IConfiguration configuration; - protected MetricSnapshotTestsBase(bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) + protected MetricSnapshotTestsBase(bool shouldReclaimUnusedMetricPoints) { this.configuration = MetricApiTestsBase.BuildConfiguration( - emitOverflowAttribute, shouldReclaimUnusedMetricPoints); } @@ -298,15 +297,7 @@ public void VerifySnapshot_ExponentialHistogram() public class MetricSnapshotTests : MetricSnapshotTestsBase { public MetricSnapshotTests() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: false) - { - } -} - -public class MetricSnapshotTestsWithOverflowAttribute : MetricSnapshotTestsBase -{ - public MetricSnapshotTestsWithOverflowAttribute() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: false) + : base(shouldReclaimUnusedMetricPoints: false) { } } @@ -314,15 +305,7 @@ public MetricSnapshotTestsWithOverflowAttribute() public class MetricSnapshotTestsWithReclaimAttribute : MetricSnapshotTestsBase { public MetricSnapshotTestsWithReclaimAttribute() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: true) - { - } -} - -public class MetricSnapshotTestsWithBothAttributes : MetricSnapshotTestsBase -{ - public MetricSnapshotTestsWithBothAttributes() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: true) + : base(shouldReclaimUnusedMetricPoints: true) { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs index 92b65f2b97f..746c3b6aeb3 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs @@ -16,7 +16,6 @@ namespace OpenTelemetry.Metrics.Tests; public class MetricTestsBase { - public const string EmitOverFlowAttributeConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE"; public const string ReclaimUnusedMetricPointsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS"; protected readonly IConfiguration? configuration; From 8de335c48682da1fd6daa4338602a74d7d24488e Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 28 Oct 2024 09:51:10 -0700 Subject: [PATCH 123/133] [sdk-metrics] Promote cardinality limit view API from experimental to stable (#5926) Co-authored-by: Rajkumar Rangaraj --- OpenTelemetry.sln | 1 - build/Common.props | 2 +- .../diagnostics/experimental-apis/OTEL1003.md | 47 ------------------- docs/diagnostics/experimental-apis/README.md | 14 +++--- docs/metrics/customizing-the-sdk/README.md | 10 +--- .../Experimental/PublicAPI.Unshipped.txt | 2 - .../.publicApi/Stable/PublicAPI.Unshipped.txt | 2 + src/OpenTelemetry/CHANGELOG.md | 5 ++ .../Builder/MeterProviderBuilderExtensions.cs | 4 +- .../Metrics/View/MetricStreamConfiguration.cs | 12 +---- src/Shared/DiagnosticDefinitions.cs | 2 +- .../Metrics/MetricViewTests.cs | 2 +- 12 files changed, 22 insertions(+), 81 deletions(-) delete mode 100644 docs/diagnostics/experimental-apis/OTEL1003.md diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index cea58bc408a..1b3928c1163 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -305,7 +305,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "experimental-apis", "experi ProjectSection(SolutionItems) = preProject docs\diagnostics\experimental-apis\OTEL1000.md = docs\diagnostics\experimental-apis\OTEL1000.md docs\diagnostics\experimental-apis\OTEL1001.md = docs\diagnostics\experimental-apis\OTEL1001.md - docs\diagnostics\experimental-apis\OTEL1003.md = docs\diagnostics\experimental-apis\OTEL1003.md docs\diagnostics\experimental-apis\OTEL1004.md = docs\diagnostics\experimental-apis\OTEL1004.md docs\diagnostics\experimental-apis\README.md = docs\diagnostics\experimental-apis\README.md EndProjectSection diff --git a/build/Common.props b/build/Common.props index b625439458e..c1a4874c57f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -13,7 +13,7 @@ all low - $(NoWarn);OTEL1000;OTEL1001;OTEL1002;OTEL1003;OTEL1004 + $(NoWarn);OTEL1000;OTEL1001;OTEL1002;OTEL1004 diff --git a/docs/diagnostics/experimental-apis/OTEL1003.md b/docs/diagnostics/experimental-apis/OTEL1003.md deleted file mode 100644 index 5f62f03575f..00000000000 --- a/docs/diagnostics/experimental-apis/OTEL1003.md +++ /dev/null @@ -1,47 +0,0 @@ -# OpenTelemetry .NET Diagnostic: OTEL1003 - -## Overview - -This is an Experimental API diagnostic covering the following API: - -* `MetricStreamConfiguration.CardinalityLimit.get` -* `MetricStreamConfiguration.CardinalityLimit.set` - -Experimental APIs may be changed or removed in the future. - -## Details - -From the specification: - -> The cardinality limit for an aggregation is defined in one of three ways: -> -> 1. A view with criteria matching the instrument an aggregation is created for -> has an `aggregation_cardinality_limit` value defined for the stream, that -> value SHOULD be used. -> 2. If there is no matching view, but the `MetricReader` defines a default -> cardinality limit value based on the instrument an aggregation is created -> for, that value SHOULD be used. -> 3. If none of the previous values are defined, the default value of 2000 -> SHOULD be used. - -We are exposing these APIs experimentally until the specification declares them -stable. - -### Setting cardinality limit for a specific Metric via the View API - -The OpenTelemetry Specification defines the [cardinality -limit](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#cardinality-limits) -of a metric can be set by the matching view. - -```csharp -using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddView( - instrumentName: "MyFruitCounter", - new MetricStreamConfiguration { CardinalityLimit = 10 }) - .Build(); -``` - -### Setting cardinality limit for a specific MetricReader - -[This is not currently supported by OpenTelemetry -.NET.](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5331) diff --git a/docs/diagnostics/experimental-apis/README.md b/docs/diagnostics/experimental-apis/README.md index 6c581030b4c..daa80d34b38 100644 --- a/docs/diagnostics/experimental-apis/README.md +++ b/docs/diagnostics/experimental-apis/README.md @@ -27,12 +27,6 @@ Description: Logs Bridge API Details: [OTEL1001](./OTEL1001.md) -### OTEL1003 - -Description: MetricStreamConfiguration CardinalityLimit Support - -Details: [OTEL1003](./OTEL1003.md) - ### OTEL1004 Description: ExemplarReservoir Support @@ -58,3 +52,11 @@ Description: Metrics Exemplar Support Details: [OTEL1002](https://github.com/open-telemetry/opentelemetry-dotnet/blob/b8ea807bae1a5d9b0f3d6d23b1e1e10f5e096a25/docs/diagnostics/experimental-apis/OTEL1002.md) Released stable: `1.9.0` + +### OTEL1003 + +Description: MetricStreamConfiguration CardinalityLimit Support + +Details: [OTEL1003](https://github.com/open-telemetry/opentelemetry-dotnet/blob/9f41eadf03f3dcc5e76c686b61fb39849f046312/docs/diagnostics/experimental-apis/OTEL1003.md) + +Released stable: `1.10.0` diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index 8aaeef19fad..560149e20e6 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -403,9 +403,8 @@ metrics managed by a given `MeterProvider`, use the > [!CAUTION] > `MeterProviderBuilder.SetMaxMetricPointsPerMetricStream` is marked `Obsolete` - in pre-release builds and has been replaced by - `MetricStreamConfiguration.CardinalityLimit`. For details see: - [OTEL1003](../../diagnostics/experimental-apis/OTEL1003.md). + in stable builds since 1.10.0 and has been replaced by + `MetricStreamConfiguration.CardinalityLimit`. ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -421,11 +420,6 @@ To set the [cardinality limit](../README.md#cardinality-limits) for an individual metric, use the `MetricStreamConfiguration.CardinalityLimit` property on the View API: -> [!NOTE] -> `MetricStreamConfiguration.CardinalityLimit` is an experimental API only - available in pre-release builds. For details see: - [OTEL1003](../../diagnostics/experimental-apis/OTEL1003.md). - ```csharp var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter("MyCompany.MyProduct.MyLibrary") diff --git a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt index a6594de1a9c..7c9a6d046ae 100644 --- a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -17,8 +17,6 @@ OpenTelemetry.Metrics.FixedSizeExemplarReservoir.Capacity.get -> int OpenTelemetry.Metrics.FixedSizeExemplarReservoir.FixedSizeExemplarReservoir(int capacity) -> void OpenTelemetry.Metrics.FixedSizeExemplarReservoir.UpdateExemplar(int exemplarIndex, in OpenTelemetry.Metrics.ExemplarMeasurement measurement) -> void OpenTelemetry.Metrics.FixedSizeExemplarReservoir.UpdateExemplar(int exemplarIndex, in OpenTelemetry.Metrics.ExemplarMeasurement measurement) -> void -OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.get -> int? -OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.set -> void OpenTelemetry.Metrics.MetricStreamConfiguration.ExemplarReservoirFactory.get -> System.Func? OpenTelemetry.Metrics.MetricStreamConfiguration.ExemplarReservoirFactory.set -> void override sealed OpenTelemetry.Metrics.FixedSizeExemplarReservoir.Collect() -> OpenTelemetry.Metrics.ReadOnlyExemplarCollection diff --git a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt index 7dc29c7de2d..5f0fd41cd26 100644 --- a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -1,3 +1,5 @@ +OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.get -> int? +OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.set -> void OpenTelemetry.OpenTelemetrySdk OpenTelemetry.OpenTelemetrySdk.Dispose() -> void OpenTelemetry.OpenTelemetrySdk.LoggerProvider.get -> OpenTelemetry.Logs.LoggerProvider! diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 0f2bbd74d7c..6e33534e9c5 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,6 +6,11 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* The experimental APIs previously covered by `OTEL1003` + (`MetricStreamConfiguration.CardinalityLimit`) will now be part of the public + API and supported in stable builds. + ([#5926](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5926)) + * Promoted overflow attribute from experimental to stable and removed the `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` environment variable. diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index 2808cfa51d4..1a5c1d950c3 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -238,9 +238,7 @@ public static MeterProviderBuilder SetMaxMetricStreams(this MeterProviderBuilder /// . /// Maximum number of metric points allowed per metric stream. /// The supplied for chaining. -#if EXPOSE_EXPERIMENTAL_FEATURES - [Obsolete("Use MetricStreamConfiguration.CardinalityLimit via the AddView API instead. This method will be removed in a future version.")] -#endif + [Obsolete("Use MetricStreamConfiguration.CardinalityLimit via the AddView API instead. This method is marked as obsolete in version 1.10.0 and will be removed in a future version.")] public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) { Guard.ThrowIfOutOfRange(maxMetricPointsPerMetricStream, min: 1); diff --git a/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs b/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs index cc36941ce68..cf5e06661a0 100644 --- a/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs +++ b/src/OpenTelemetry/Metrics/View/MetricStreamConfiguration.cs @@ -98,14 +98,11 @@ public string[]? TagKeys } } -#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Gets or sets a positive integer value defining the maximum number of /// data points allowed for the metric managed by the view. /// /// - /// WARNING: This is an experimental API which might change or - /// be removed in the future. Use at your own risk. /// Spec reference: Cardinality /// limits. @@ -116,14 +113,7 @@ public string[]? TagKeys /// If not set the default /// MeterProvider cardinality limit of 2000 will apply. /// -#if NET - [Experimental(DiagnosticDefinitions.CardinalityLimitExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] -#endif - public -#else - internal -#endif - int? CardinalityLimit + public int? CardinalityLimit { get => this.cardinalityLimit; set diff --git a/src/Shared/DiagnosticDefinitions.cs b/src/Shared/DiagnosticDefinitions.cs index 75ed3187d70..f6b449352ff 100644 --- a/src/Shared/DiagnosticDefinitions.cs +++ b/src/Shared/DiagnosticDefinitions.cs @@ -9,10 +9,10 @@ internal static class DiagnosticDefinitions public const string LoggerProviderExperimentalApi = "OTEL1000"; public const string LogsBridgeExperimentalApi = "OTEL1001"; - public const string CardinalityLimitExperimentalApi = "OTEL1003"; public const string ExemplarReservoirExperimentalApi = "OTEL1004"; /* Definitions which have been released stable: public const string ExemplarExperimentalApi = "OTEL1002"; + public const string CardinalityLimitExperimentalApi = "OTEL1003"; */ } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs index 10eb9709842..50c9be30d31 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs @@ -1093,7 +1093,7 @@ public void ViewConflict_OneInstrument_DifferentDescription() [Theory] [InlineData(true)] [InlineData(false)] - public void CardinalityLimitofMatchingViewTakesPrecedenceOverMeterProvider(bool setDefault) + public void CardinalityLimitOfMatchingViewTakesPrecedenceOverMeterProvider(bool setDefault) { using var meter = new Meter(Utils.GetCurrentMethodName()); var exportedItems = new List(); From d45060b434e469ec5c1a6cd7a3d06faa2eac4a9b Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 28 Oct 2024 10:08:30 -0700 Subject: [PATCH 124/133] [otlp] OTLP Exporter Custom serializer - Spans (#5928) Co-authored-by: Mikel Blanchard --- .../Serializer/ProtobufOtlpTagWriter.cs | 1 + .../Serializer/ProtobufOtlpTraceSerializer.cs | 335 ++++++++++++++++++ .../OtlpTraceExporterTests.cs | 91 +++-- 3 files changed, 396 insertions(+), 31 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs index 65fef4fe110..2cc0fb4fb81 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs @@ -111,6 +111,7 @@ public override OtlpTagWriterArrayState BeginWriteArray() public override void WriteNullValue(ref OtlpTagWriterArrayState state) { + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 0, ProtobufOtlpFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); } public override void WriteIntegralValue(ref OtlpTagWriterArrayState state, long value) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs new file mode 100644 index 00000000000..813b691e67f --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs @@ -0,0 +1,335 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; + +internal static class ProtobufOtlpTraceSerializer +{ + private const int ReserveSizeForLength = 4; + private const string UnsetStatusCodeTagValue = "UNSET"; + private const string OkStatusCodeTagValue = "OK"; + private const string ErrorStatusCodeTagValue = "ERROR"; + private const int TraceIdSize = 16; + private const int SpanIdSize = 8; + + internal static int WriteSpan(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, Activity activity) + { + writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.ScopeSpans_Span, ProtobufWireType.LEN); + int spanLengthPosition = writePosition; + writePosition += ReserveSizeForLength; + + writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, TraceIdSize, ProtobufOtlpFieldNumberConstants.Span_Trace_Id, ProtobufWireType.LEN); + writePosition = WriteTraceId(buffer, writePosition, activity.TraceId); + + writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, SpanIdSize, ProtobufOtlpFieldNumberConstants.Span_Span_Id, ProtobufWireType.LEN); + writePosition = WriteSpanId(buffer, writePosition, activity.SpanId); + + if (activity.TraceStateString != null) + { + writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Trace_State, activity.TraceStateString); + } + + if (activity.ParentSpanId != default) + { + writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, SpanIdSize, ProtobufOtlpFieldNumberConstants.Span_Parent_Span_Id, ProtobufWireType.LEN); + writePosition = WriteSpanId(buffer, writePosition, activity.ParentSpanId); + } + + writePosition = WriteTraceFlags(buffer, writePosition, activity.ActivityTraceFlags, activity.HasRemoteParent, ProtobufOtlpFieldNumberConstants.Span_Flags); + writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Name, activity.DisplayName); + writePosition = ProtobufSerializer.WriteEnumWithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Kind, (int)activity.Kind + 1); + writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Start_Time_Unix_Nano, (ulong)activity.StartTimeUtc.ToUnixTimeNanoseconds()); + writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_End_Time_Unix_Nano, (ulong)(activity.StartTimeUtc.ToUnixTimeNanoseconds() + activity.Duration.ToNanoseconds())); + + (writePosition, StatusCode? statusCode, string? statusMessage) = WriteActivityTags(buffer, writePosition, sdkLimitOptions, activity); + writePosition = WriteSpanEvents(buffer, writePosition, sdkLimitOptions, activity); + writePosition = WriteSpanLinks(buffer, writePosition, sdkLimitOptions, activity); + writePosition = WriteSpanStatus(buffer, writePosition, activity, statusCode, statusMessage); + ProtobufSerializer.WriteReservedLength(buffer, spanLengthPosition, writePosition - (spanLengthPosition + ReserveSizeForLength)); + + return writePosition; + } + + internal static int WriteTraceId(byte[] buffer, int position, ActivityTraceId activityTraceId) + { + var traceBytes = new Span(buffer, position, TraceIdSize); + activityTraceId.CopyTo(traceBytes); + return position + TraceIdSize; + } + + internal static int WriteSpanId(byte[] buffer, int position, ActivitySpanId activitySpanId) + { + var spanIdBytes = new Span(buffer, position, SpanIdSize); + activitySpanId.CopyTo(spanIdBytes); + return position + SpanIdSize; + } + + internal static int WriteTraceFlags(byte[] buffer, int position, ActivityTraceFlags activityTraceFlags, bool hasRemoteParent, int fieldNumber) + { + uint spanFlags = (uint)activityTraceFlags & (byte)0x000000FF; + + spanFlags |= 0x00000100; + if (hasRemoteParent) + { + spanFlags |= 0x00000200; + } + + position = ProtobufSerializer.WriteFixed32WithTag(buffer, position, fieldNumber, spanFlags); + + return position; + } + + internal static (int Position, StatusCode? StatusCode, string? StatusMessage) WriteActivityTags(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, Activity activity) + { + StatusCode? statusCode = null; + string? statusMessage = null; + int maxAttributeCount = sdkLimitOptions.SpanAttributeCountLimit ?? int.MaxValue; + int maxAttributeValueLength = sdkLimitOptions.AttributeValueLengthLimit ?? int.MaxValue; + int attributeCount = 0; + int droppedAttributeCount = 0; + + ProtobufOtlpTagWriter.OtlpTagWriterState otlpTagWriterState = new ProtobufOtlpTagWriter.OtlpTagWriterState + { + Buffer = buffer, + WritePosition = writePosition, + }; + + foreach (ref readonly var tag in activity.EnumerateTagObjects()) + { + switch (tag.Key) + { + case "otel.status_code": + + statusCode = tag.Value switch + { + /* + * Note: Order here does matter for perf. Unset is + * first because assumption is most spans will be + * Unset, then Error. Ok is not set by the SDK. + */ + not null when UnsetStatusCodeTagValue.Equals(tag.Value as string, StringComparison.OrdinalIgnoreCase) => StatusCode.Unset, + not null when ErrorStatusCodeTagValue.Equals(tag.Value as string, StringComparison.OrdinalIgnoreCase) => StatusCode.Error, + not null when OkStatusCodeTagValue.Equals(tag.Value as string, StringComparison.OrdinalIgnoreCase) => StatusCode.Ok, + _ => null, + }; + continue; + case "otel.status_description": + statusMessage = tag.Value as string; + continue; + } + + if (attributeCount < maxAttributeCount) + { + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.Span_Attributes, ProtobufWireType.LEN); + int spanAttributesLengthPosition = otlpTagWriterState.WritePosition; + otlpTagWriterState.WritePosition += ReserveSizeForLength; + + ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, tag.Key, tag.Value, maxAttributeValueLength); + + ProtobufSerializer.WriteReservedLength(buffer, spanAttributesLengthPosition, otlpTagWriterState.WritePosition - (spanAttributesLengthPosition + 4)); + attributeCount++; + } + else + { + droppedAttributeCount++; + } + } + + if (droppedAttributeCount > 0) + { + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.Span_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)droppedAttributeCount); + } + + return (otlpTagWriterState.WritePosition, statusCode, statusMessage); + } + + internal static int WriteSpanEvents(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, Activity activity) + { + int maxEventCountLimit = sdkLimitOptions.SpanEventCountLimit ?? int.MaxValue; + int eventCount = 0; + int droppedEventCount = 0; + foreach (ref readonly var evnt in activity.EnumerateEvents()) + { + if (eventCount < maxEventCountLimit) + { + writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Events, ProtobufWireType.LEN); + int spanEventsLengthPosition = writePosition; + writePosition += ReserveSizeForLength; // Reserve 4 bytes for length + + writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Event_Name, evnt.Name); + writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Event_Time_Unix_Nano, (ulong)evnt.Timestamp.ToUnixTimeNanoseconds()); + writePosition = WriteEventAttributes(ref buffer, writePosition, sdkLimitOptions, evnt); + + ProtobufSerializer.WriteReservedLength(buffer, spanEventsLengthPosition, writePosition - (spanEventsLengthPosition + ReserveSizeForLength)); + eventCount++; + } + else + { + droppedEventCount++; + } + } + + if (droppedEventCount > 0) + { + writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Dropped_Events_Count, ProtobufWireType.VARINT); + writePosition = ProtobufSerializer.WriteVarInt32(buffer, writePosition, (uint)droppedEventCount); + } + + return writePosition; + } + + internal static int WriteEventAttributes(ref byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, ActivityEvent evnt) + { + int maxAttributeCount = sdkLimitOptions.SpanEventAttributeCountLimit ?? int.MaxValue; + int maxAttributeValueLength = sdkLimitOptions.AttributeValueLengthLimit ?? int.MaxValue; + int attributeCount = 0; + int droppedAttributeCount = 0; + + ProtobufOtlpTagWriter.OtlpTagWriterState otlpTagWriterState = new ProtobufOtlpTagWriter.OtlpTagWriterState + { + Buffer = buffer, + WritePosition = writePosition, + }; + + foreach (ref readonly var tag in evnt.EnumerateTagObjects()) + { + if (attributeCount < maxAttributeCount) + { + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.Event_Attributes, ProtobufWireType.LEN); + int eventAttributesLengthPosition = otlpTagWriterState.WritePosition; + otlpTagWriterState.WritePosition += ReserveSizeForLength; + ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, tag.Key, tag.Value, maxAttributeValueLength); + ProtobufSerializer.WriteReservedLength(buffer, eventAttributesLengthPosition, otlpTagWriterState.WritePosition - (eventAttributesLengthPosition + ReserveSizeForLength)); + attributeCount++; + } + else + { + droppedAttributeCount++; + } + } + + if (droppedAttributeCount > 0) + { + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.Event_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)droppedAttributeCount); + } + + return otlpTagWriterState.WritePosition; + } + + internal static int WriteSpanLinks(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, Activity activity) + { + int maxLinksCount = sdkLimitOptions.SpanLinkCountLimit ?? int.MaxValue; + int linkCount = 0; + int droppedLinkCount = 0; + + foreach (ref readonly var link in activity.EnumerateLinks()) + { + if (linkCount < maxLinksCount) + { + writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Links, ProtobufWireType.LEN); + int spanLinksLengthPosition = writePosition; + writePosition += ReserveSizeForLength; // Reserve 4 bytes for length + + writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, TraceIdSize, ProtobufOtlpFieldNumberConstants.Link_Trace_Id, ProtobufWireType.LEN); + writePosition = WriteTraceId(buffer, writePosition, link.Context.TraceId); + writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, SpanIdSize, ProtobufOtlpFieldNumberConstants.Link_Span_Id, ProtobufWireType.LEN); + writePosition = WriteSpanId(buffer, writePosition, link.Context.SpanId); + if (link.Context.TraceState != null) + { + writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Trace_State, link.Context.TraceState); + } + + writePosition = WriteLinkAttributes(buffer, writePosition, sdkLimitOptions, link); + writePosition = WriteTraceFlags(buffer, writePosition, link.Context.TraceFlags, link.Context.IsRemote, ProtobufOtlpFieldNumberConstants.Link_Flags); + + ProtobufSerializer.WriteReservedLength(buffer, spanLinksLengthPosition, writePosition - (spanLinksLengthPosition + ReserveSizeForLength)); + linkCount++; + } + else + { + droppedLinkCount++; + } + } + + if (droppedLinkCount > 0) + { + writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpFieldNumberConstants.Span_Dropped_Links_Count, ProtobufWireType.VARINT); + writePosition = ProtobufSerializer.WriteVarInt32(buffer, writePosition, (uint)droppedLinkCount); + } + + return writePosition; + } + + internal static int WriteLinkAttributes(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, ActivityLink link) + { + int maxAttributeCount = sdkLimitOptions.SpanLinkAttributeCountLimit ?? int.MaxValue; + int maxAttributeValueLength = sdkLimitOptions.AttributeValueLengthLimit ?? int.MaxValue; + int attributeCount = 0; + int droppedAttributeCount = 0; + + ProtobufOtlpTagWriter.OtlpTagWriterState otlpTagWriterState = new ProtobufOtlpTagWriter.OtlpTagWriterState + { + Buffer = buffer, + WritePosition = writePosition, + }; + + foreach (ref readonly var tag in link.EnumerateTagObjects()) + { + if (attributeCount < maxAttributeCount) + { + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.Link_Attributes, ProtobufWireType.LEN); + int linkAttributesLengthPosition = otlpTagWriterState.WritePosition; + otlpTagWriterState.WritePosition += ReserveSizeForLength; + ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, tag.Key, tag.Value, maxAttributeValueLength); + ProtobufSerializer.WriteReservedLength(buffer, linkAttributesLengthPosition, otlpTagWriterState.WritePosition - (linkAttributesLengthPosition + ReserveSizeForLength)); + attributeCount++; + } + else + { + droppedAttributeCount++; + } + } + + if (droppedAttributeCount > 0) + { + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpFieldNumberConstants.Link_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)droppedAttributeCount); + } + + return otlpTagWriterState.WritePosition; + } + + internal static int WriteSpanStatus(byte[] buffer, int position, Activity activity, StatusCode? statusCode, string? statusMessage) + { + if (activity.Status == ActivityStatusCode.Unset && statusCode == null) + { + return position; + } + + var useActivity = activity.Status != ActivityStatusCode.Unset; + var isError = useActivity ? activity.Status == ActivityStatusCode.Error : statusCode == StatusCode.Error; + var description = useActivity ? activity.StatusDescription : statusMessage; + + if (isError && description != null) + { + var descriptionSpan = description.AsSpan(); + var numberOfUtf8CharsInString = ProtobufSerializer.GetNumberOfUtf8CharsInString(descriptionSpan); + position = ProtobufSerializer.WriteTagAndLength(buffer, position, numberOfUtf8CharsInString + 4, ProtobufOtlpFieldNumberConstants.Span_Status, ProtobufWireType.LEN); + position = ProtobufSerializer.WriteStringWithTag(buffer, position, ProtobufOtlpFieldNumberConstants.Status_Message, numberOfUtf8CharsInString, descriptionSpan); + } + else + { + position = ProtobufSerializer.WriteTagAndLength(buffer, position, 2, ProtobufOtlpFieldNumberConstants.Span_Status, ProtobufWireType.LEN); + } + + var finalStatusCode = useActivity ? (int)activity.Status : (statusCode != null && statusCode != StatusCode.Unset) ? (int)statusCode! : (int)StatusCode.Unset; + position = ProtobufSerializer.WriteEnumWithTag(buffer, position, ProtobufOtlpFieldNumberConstants.Status_Code, finalStatusCode); + + return position; + } +} diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index bb76069214a..97d62b75345 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -5,6 +5,7 @@ using Google.Protobuf.Collections; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Serializer; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -370,8 +371,10 @@ void RunTest(SdkLimitOptions sdkOptions, Batch batch) } } - [Fact] - public void SpanLimitsTest() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void SpanLimitsTest(bool useCustomSerializer) { var sdkOptions = new SdkLimitOptions() { @@ -406,7 +409,7 @@ public void SpanLimitsTest() activity.AddEvent(event1); activity.AddEvent(event2); - var otlpSpan = activity.ToOtlpSpan(sdkOptions); + var otlpSpan = useCustomSerializer ? ToOtlpSpan(sdkOptions, activity) : activity.ToOtlpSpan(sdkOptions); Assert.NotNull(otlpSpan); Assert.Equal(3, otlpSpan.Attributes.Count); @@ -432,8 +435,10 @@ public void SpanLimitsTest() Assert.Equal(new object().ToString()!.Substring(0, 4), otlpSpan.Links[0].Attributes[2].Value.StringValue); } - [Fact] - public void ToOtlpSpanTest() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ToOtlpSpanTest(bool useCustomSerializer) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -475,7 +480,7 @@ public void ToOtlpSpanTest() rootActivity.TraceId.CopyTo(traceIdSpan); var traceId = traceIdSpan.ToArray(); - var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); + var otlpSpan = useCustomSerializer ? ToOtlpSpan(DefaultSdkLimitOptions, rootActivity) : rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); Assert.NotNull(otlpSpan); Assert.Equal("root", otlpSpan.Name); @@ -511,7 +516,7 @@ public void ToOtlpSpanTest() rootActivity.Context.SpanId.CopyTo(parentIdSpan); var parentId = parentIdSpan.ToArray(); - otlpSpan = childActivity.ToOtlpSpan(DefaultSdkLimitOptions); + otlpSpan = useCustomSerializer ? ToOtlpSpan(DefaultSdkLimitOptions, childActivity) : childActivity.ToOtlpSpan(DefaultSdkLimitOptions); Assert.NotNull(otlpSpan); Assert.Equal("child", otlpSpan.Name); @@ -546,8 +551,10 @@ public void ToOtlpSpanTest() Assert.False(flags.HasFlag(OtlpTrace.SpanFlags.ContextIsRemoteMask)); } - [Fact] - public void ToOtlpSpanActivitiesWithNullArrayTest() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ToOtlpSpanActivitiesWithNullArrayTest(bool useCustomSerializer) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -557,7 +564,7 @@ public void ToOtlpSpanActivitiesWithNullArrayTest() var stringArr = new string?[] { "test", string.Empty, null }; rootActivity.SetTag("stringArray", stringArr); - var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); + var otlpSpan = useCustomSerializer ? ToOtlpSpan(DefaultSdkLimitOptions, rootActivity) : rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); Assert.NotNull(otlpSpan); @@ -570,17 +577,20 @@ public void ToOtlpSpanActivitiesWithNullArrayTest() } [Theory] - [InlineData(ActivityStatusCode.Unset, "Description will be ignored if status is Unset.")] - [InlineData(ActivityStatusCode.Ok, "Description will be ignored if status is Okay.")] - [InlineData(ActivityStatusCode.Error, "Description will be kept if status is Error.")] - public void ToOtlpSpanNativeActivityStatusTest(ActivityStatusCode expectedStatusCode, string statusDescription) + [InlineData(ActivityStatusCode.Unset, "Description will be ignored if status is Unset.", true)] + [InlineData(ActivityStatusCode.Ok, "Description will be ignored if status is Okay.", true)] + [InlineData(ActivityStatusCode.Error, "Description will be kept if status is Error.", true)] + [InlineData(ActivityStatusCode.Unset, "Description will be ignored if status is Unset.", false)] + [InlineData(ActivityStatusCode.Ok, "Description will be ignored if status is Okay.", false)] + [InlineData(ActivityStatusCode.Error, "Description will be kept if status is Error.", false)] + public void ToOtlpSpanNativeActivityStatusTest(ActivityStatusCode expectedStatusCode, string statusDescription, bool useCustomSerializer) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); Assert.NotNull(activity); activity.SetStatus(expectedStatusCode, statusDescription); - var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); + var otlpSpan = useCustomSerializer ? ToOtlpSpan(DefaultSdkLimitOptions, activity) : activity.ToOtlpSpan(DefaultSdkLimitOptions); Assert.NotNull(otlpSpan); if (expectedStatusCode == ActivityStatusCode.Unset) { @@ -690,9 +700,11 @@ public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivitySta } [Theory] - [InlineData(true)] - [InlineData(false)] - public void ToOtlpSpanTraceStateTest(bool traceStateWasSet) + [InlineData(true, true)] + [InlineData(false, true)] + [InlineData(true, false)] + [InlineData(false, false)] + public void ToOtlpSpanTraceStateTest(bool traceStateWasSet, bool useCustomSerializer) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var activity = activitySource.StartActivity("Name"); @@ -703,7 +715,7 @@ public void ToOtlpSpanTraceStateTest(bool traceStateWasSet) activity.TraceStateString = tracestate; } - var otlpSpan = activity.ToOtlpSpan(DefaultSdkLimitOptions); + var otlpSpan = useCustomSerializer ? ToOtlpSpan(DefaultSdkLimitOptions, activity) : activity.ToOtlpSpan(DefaultSdkLimitOptions); Assert.NotNull(otlpSpan); if (traceStateWasSet) @@ -892,11 +904,15 @@ public void NamedOptionsMutateSeparateInstancesTest() } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void SpanFlagsTest(bool isRecorded, bool isRemote) + [InlineData(true, true, true)] + [InlineData(true, false, true)] + [InlineData(false, true, true)] + [InlineData(false, false, true)] + [InlineData(true, true, false)] + [InlineData(true, false, false)] + [InlineData(false, true, false)] + [InlineData(false, false, false)] + public void SpanFlagsTest(bool isRecorded, bool isRemote, bool useCustomSerializer) { using var activitySource = new ActivitySource(nameof(this.SpanFlagsTest)); @@ -909,7 +925,7 @@ public void SpanFlagsTest(bool isRecorded, bool isRemote) using var rootActivity = activitySource.StartActivity("root", ActivityKind.Server, ctx); Assert.NotNull(rootActivity); - var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); + var otlpSpan = useCustomSerializer ? ToOtlpSpan(DefaultSdkLimitOptions, rootActivity) : rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); Assert.NotNull(otlpSpan); var flags = (OtlpTrace.SpanFlags)otlpSpan.Flags; @@ -938,11 +954,15 @@ public void SpanFlagsTest(bool isRecorded, bool isRemote) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void SpanLinkFlagsTest(bool isRecorded, bool isRemote) + [InlineData(true, true, true)] + [InlineData(true, false, true)] + [InlineData(false, true, true)] + [InlineData(false, false, true)] + [InlineData(true, true, false)] + [InlineData(true, false, false)] + [InlineData(false, true, false)] + [InlineData(false, false, false)] + public void SpanLinkFlagsTest(bool isRecorded, bool isRemote, bool useCustomSerializer) { using var activitySource = new ActivitySource(nameof(this.SpanLinkFlagsTest)); @@ -960,7 +980,7 @@ public void SpanLinkFlagsTest(bool isRecorded, bool isRemote) using var rootActivity = activitySource.StartActivity("root", ActivityKind.Server, default(ActivityContext), links: links); Assert.NotNull(rootActivity); - var otlpSpan = rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); + var otlpSpan = useCustomSerializer ? ToOtlpSpan(DefaultSdkLimitOptions, rootActivity) : rootActivity.ToOtlpSpan(DefaultSdkLimitOptions); Assert.NotNull(otlpSpan); var spanLink = Assert.Single(otlpSpan.Links); @@ -990,6 +1010,15 @@ public void SpanLinkFlagsTest(bool isRecorded, bool isRemote) } } + private static OtlpTrace.Span? ToOtlpSpan(SdkLimitOptions sdkOptions, Activity activity) + { + var buffer = new byte[4096]; + var writePosition = ProtobufOtlpTraceSerializer.WriteSpan(buffer, 0, sdkOptions, activity); + using var stream = new MemoryStream(buffer, 0, writePosition); + var scopeSpans = OtlpTrace.ScopeSpans.Parser.ParseFrom(stream); + return scopeSpans.Spans.FirstOrDefault(); + } + private void ArrayValueAsserts(RepeatedField values) { var expectedStringArray = new string?[] { "1234", "1234", string.Empty, null }; From 84ff215a5d473bd92bb287b73ff347112e1e6594 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Mon, 28 Oct 2024 15:31:21 -0700 Subject: [PATCH 125/133] [BUILD] Signing OpenTelemetry .NET DLLs Using Sigstore certificate (#5880) Co-authored-by: Mikel Blanchard --- .github/workflows/publish-packages-1.0.yml | 27 ++++++++++++++++++++++ build/Common.prod.props | 13 +++++++++++ 2 files changed, 40 insertions(+) diff --git a/.github/workflows/publish-packages-1.0.yml b/.github/workflows/publish-packages-1.0.yml index 7553bd66627..df29e3af554 100644 --- a/.github/workflows/publish-packages-1.0.yml +++ b/.github/workflows/publish-packages-1.0.yml @@ -23,6 +23,12 @@ jobs: build-pack-publish: runs-on: windows-latest + permissions: + contents: read + id-token: write + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COSIGN_YES: "yes" outputs: artifact-url: ${{ steps.upload-artifacts.outputs.artifact-url }} @@ -39,12 +45,33 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 + - name: Install Cosign + uses: sigstore/cosign-installer@v3 + with: + cosign-release: v2.4.0 + - name: dotnet restore run: dotnet restore ./build/OpenTelemetry.proj -p:RunningDotNetPack=true - name: dotnet build run: dotnet build ./build/OpenTelemetry.proj --configuration Release --no-restore -p:Deterministic=true -p:BuildNumber=${{ github.run_number }} -p:RunningDotNetPack=true + - name: Sign DLLs with Cosign Keyless + shell: pwsh + run: | + $projectFiles = Get-ChildItem -Path src/*/*.csproj -File + + foreach ($projectFile in $projectFiles) { + $projectName = [System.IO.Path]::GetFileNameWithoutExtension($projectFile) + + Get-ChildItem -Path src/$projectName/bin/Release/*/$projectName.dll -File | ForEach-Object { + $fileFullPath = $_.FullName + Write-Host "Signing $fileFullPath" + + cosign.exe sign-blob $fileFullPath --yes --output-signature $fileFullPath-keyless.sig --output-certificate $fileFullPath-keyless.pem + } + } + - name: dotnet pack run: dotnet pack ./build/OpenTelemetry.proj --configuration Release --no-restore --no-build -p:PackTag=${{ github.ref_type == 'tag' && github.ref_name || '' }} diff --git a/build/Common.prod.props b/build/Common.prod.props index 3738c0a691d..832306e1405 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -60,6 +60,19 @@ + + + + + + + + + + + + +